@educa-corp/sdd-framework 0.9.7 → 0.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/bin/qc-base-map.json +13 -11
  2. package/bin/self-check.js +49 -4
  3. package/bin/trace-schema.json +3226 -3187
  4. package/core/FRAMEWORK_VERSION +1 -1
  5. package/core/commands/qc-analyze.md +2 -2
  6. package/core/commands/qc-automation-assess.md +3 -3
  7. package/core/commands/qc-design-script.md +60 -30
  8. package/core/commands/qc-design-test.md +79 -7
  9. package/core/commands/qc-plan.md +1 -1
  10. package/core/commands/qc-report.md +85 -76
  11. package/core/commands/qc-review-script.md +25 -16
  12. package/core/commands/qc-review-testcase.md +8 -7
  13. package/core/commands/qc-run-manualtest.md +1 -1
  14. package/core/commands/qc-run-script.md +15 -8
  15. package/core/modules/qc-playwright-ts/module.yaml +13 -0
  16. package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
  17. package/core/modules/qc-wdio-appium/module.yaml +20 -0
  18. package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
  19. package/core/skills/qc/qa-analyst/data-flow.md +1 -1
  20. package/core/skills/qc/qa-automation-assess/matrix.md +6 -3
  21. package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
  22. package/core/skills/qc/qa-designer/functional/api.md +1 -1
  23. package/core/skills/qc/qa-designer/functional/job.md +128 -0
  24. package/core/skills/qc/qa-designer/integration/api.md +1 -1
  25. package/core/skills/qc/qa-designer/integration/db.md +1 -1
  26. package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +20 -4
  27. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
  28. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +17 -0
  29. package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
  30. package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
  31. package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
  32. package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
  33. package/core/skills/qc/qa-reviewer/script/exploratory.md +2 -2
  34. package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
  35. package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
  36. package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
  37. package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
  38. package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
  39. package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
  40. package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
  41. package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
  42. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
  43. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +26 -7
  44. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  45. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  46. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  47. package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
  48. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  49. package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
  50. package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
  51. package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
  52. package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
  53. package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
  54. package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
  55. package/core/skills/qc/qa-script-designer/api/security.md +41 -0
  56. package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
  57. package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
  58. package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
  59. package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
  60. package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
  61. package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
  62. package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
  63. package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
  64. package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
  65. package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
  66. package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
  67. package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
  68. package/core/skills/qc/qa-script-runner/report.md +41 -0
  69. package/core/skills/qc/qa-script-runner/web/run.md +48 -0
  70. package/core/steps/qc-scope.md +43 -0
  71. package/core/steps/report-footer.md +2 -2
  72. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  73. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +10 -10
  74. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +1 -1
  75. package/docs/02-concepts/traceability.md +1 -1
  76. package/docs/03-guides/developer.md +1 -1
  77. package/docs/03-guides/tester-qa.md +40 -12
  78. package/docs/04-reference/commands.md +1 -1
  79. package/docs/04-reference/modules.md +2 -1
  80. package/docs/explain/17-qc-design-test.md +2 -2
  81. package/docs/explain/19-qc-run-test.md +4 -4
  82. package/docs/explain/20-qc-report.md +1 -1
  83. package/docs/explain/23-fix-bug.md +2 -2
  84. package/docs/plans/qc-surgery/01-checklist.md +18 -6
  85. package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
  86. package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
  87. package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
  88. package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
  89. package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
  90. package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
  91. package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
  92. package/package.json +1 -1
  93. package/core/modules/qc-playwright/stack-profile.yaml +0 -66
  94. package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
  95. package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
  96. package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
  97. package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
  98. package/core/skills/qc/qa-runner/e2e.md +0 -49
  99. package/core/skills/qc/qa-runner/functional/api.md +0 -35
  100. package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
  101. package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
  102. package/core/skills/qc/qa-runner/integration.md +0 -47
  103. package/core/skills/qc/qa-runner/non-functional.md +0 -49
  104. package/core/skills/qc/qa-runner/report/report.md +0 -37
@@ -58,9 +58,9 @@
58
58
  },
59
59
  {
60
60
  "upstream": "agents/6-qa-runner.md",
61
- "targets": [],
62
- "state": "undecided",
63
- "why": "dinh nghia agent cua upstream; framework dung command + gate _agent_mode thay cho agent file"
61
+ "targets": ["commands/qc-design-script.tmpl", "commands/qc-run-script.tmpl"],
62
+ "state": "replaced",
63
+ "why": "Dinh nghia agent cua upstream; framework dung LENH thay cho agent. Vai nay nay tach lam hai lenh: /qc-design-script (sinh) va /qc-run-script (chay + cham) Dot 2 · b2. Chot o Buoc S · S2."
64
64
  },
65
65
  {
66
66
  "upstream": "agents/7-qa-gate.md",
@@ -126,14 +126,14 @@
126
126
  {
127
127
  "upstream": "skills/qa-gate/styled-report-feat011.py",
128
128
  "targets": [],
129
- "state": "undecided",
130
- "why": "script chay duoc, khong phai promptframework QC hien 100% markdown-first"
129
+ "state": "skipped",
130
+ "why": "Bao cao do CONG CU sinh, khong do script tu viet: Automation-Standards §1 + OQ-01 (dong 2026-06-02) chot Playwright HTML Report cho web/api; Mobile-Automation-Standards §1 chot Allure Report v2.x cho app. Hai file .py nay khong con dich de port bo o Buoc S · S5 (2026-09-17). Lane QC van 100% markdown-first: do duoc 0 file chay duoc trong skills/qc."
131
131
  },
132
132
  {
133
133
  "upstream": "skills/qa-gate/styled-report-template.py",
134
134
  "targets": [],
135
- "state": "undecided",
136
- "why": "script chay duoc, khong phai promptframework QC hien 100% markdown-first"
135
+ "state": "skipped",
136
+ "why": "Bao cao do CONG CU sinh, khong do script tu viet: Automation-Standards §1 + OQ-01 (dong 2026-06-02) chot Playwright HTML Report cho web/api; Mobile-Automation-Standards §1 chot Allure Report v2.x cho app. Hai file .py nay khong con dich de port bo o Buoc S · S5 (2026-09-17). Lane QC van 100% markdown-first: do duoc 0 file chay duoc trong skills/qc."
137
137
  },
138
138
  {
139
139
  "upstream": "skills/qa-io-contract/injection-scanner.md",
@@ -157,13 +157,15 @@
157
157
  },
158
158
  {
159
159
  "upstream": "skills/qa-runner/script-writer.md",
160
- "targets": [],
161
- "state": "undecided"
160
+ "targets": ["skills/qc/qa-script-designer/web/", "skills/qc/qa-script-designer/mobile/", "skills/qc/qa-script-designer/api/", "skills/qc/qa-script-designer/_shared/"],
161
+ "state": "replaced",
162
+ "why": "Tach lam hai: phan SINH script -> qa-script-designer (Buoc S · S2, 2026-09-17), ba lane web/mobile/api theo active_platform. Stack doi tu Python sang TypeScript + Playwright/WDIO-Appium theo qc-base-new (Approved)."
162
163
  },
163
164
  {
164
165
  "upstream": "skills/qa-runner/test-executor.md",
165
- "targets": [],
166
- "state": "undecided"
166
+ "targets": ["skills/qc/qa-script-runner/web/run.md", "skills/qc/qa-script-runner/mobile/run.md", "skills/qc/qa-script-runner/report.md"],
167
+ "state": "replaced",
168
+ "why": "Tach lam hai: phan CHAY + cham -> qa-script-runner (Buoc S · S2). Truoc day gop chung voi phan sinh script trong qa-runner, nen sua phan cham phai mo trang day cach viet."
167
169
  },
168
170
  {
169
171
  "upstream": "skills/qa-tc-analyst/acceptance-criteria.md",
package/bin/self-check.js CHANGED
@@ -103,8 +103,26 @@ function allSourceFiles() {
103
103
  push(path.join(ROOT, 'templates'), () => true);
104
104
  push(path.join(ROOT, 'rules'), f => f.endsWith('.md'));
105
105
  push(path.join(ROOT, 'modules'), f => f.endsWith('.yaml') || f.endsWith('.md'));
106
+ // skills/ vào scan set từ Bước S · S0 (2026-09-17). Trước đó R4/R5/R6 mù với toàn bộ
107
+ // skills/ — và 21 trong 27 file mang stack QC cũ nằm đúng ở đó, nên R5 không canh được
108
+ // việc một stack đã bỏ quay trở lại. Đo trước khi mở: 11 pattern đang có × 64 file
109
+ // skills/**/*.md = 0 hit, tức mở scan set không làm đỏ thứ gì đang xanh.
110
+ push(path.join(ROOT, 'skills'), f => f.endsWith('.md'));
106
111
  return out;
107
112
  }
113
+
114
+ /**
115
+ * Glob tối giản cho `forbidden_patterns[].scope`. Hỗ trợ `*` (không qua `/`) và `**`
116
+ * (qua mọi cấp) — đủ cho ba dạng đang dùng và cố ý KHÔNG hơn: một glob engine đầy đủ ở
117
+ * đây là thứ không ai đọc lại, và scope sai thì rule im lặng chứ không kêu lên.
118
+ */
119
+ function globMatch(glob, rel) {
120
+ const re = glob.split('/').map(seg =>
121
+ seg === '**' ? '.*'
122
+ : seg.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^/]*')
123
+ ).join('/').replace(/\/\.\*$/, '(?:/.*)?');
124
+ return new RegExp(`^${re}$`).test(rel);
125
+ }
108
126
  const sources = allSourceFiles().map(p => ({
109
127
  rel: path.relative(ROOT, p).replace(/\\/g, '/'),
110
128
  text: fs.readFileSync(p, 'utf8'),
@@ -281,16 +299,43 @@ for (const fp of schema.forbidden_patterns) {
281
299
  // `except` = file được phép chứa pattern vì nó đang TRÍCH DẪN pattern trong một cảnh
282
300
  // báo ("đừng glob X"). Mỗi entry phải kèm lý do trong schema — không phải ignore mù.
283
301
  const except = new Set(Object.keys(fp.except || {}));
284
- const hits = sources.filter(s => s.text.includes(fp.pattern) && !except.has(s.rel));
302
+ // `scope` (thêm ở Bước S · S0) = mảng glob giới hạn vùng file rule soi tới. KHÔNG khai
303
+ // scope = toàn scan set, nên mọi entry có từ trước giữ nguyên hành vi. Vì sao cần: `pytest`
304
+ // bị cấm trong phạm vi QC nhưng HỢP LỆ ở lane DEV — modules/context-engineering là module
305
+ // Python thật, dev-gen-test mặc định sinh test Python. Cấm toàn cục là 4 dương tính giả,
306
+ // và dương tính giả đẻ ra except bừa cho tới khi R5 rỗng ruột mà vẫn xanh.
307
+ const inScope = s => !fp.scope || fp.scope.some(g => globMatch(g, s.rel));
308
+ const hits = sources.filter(s => inScope(s) && s.text.includes(fp.pattern) && !except.has(s.rel));
285
309
  if (hits.length) {
286
310
  err('R5', `Pattern bị cấm quay lại: \`${fp.pattern}\` (${fp.gap})`,
287
311
  `${fp.reason}\n Thấy ở: ${hits.map(h => h.rel).join(', ')}`);
288
312
  }
289
- // Cảnh báo nếu một except trở nên vô nghĩa — cảnh báo đã bị xoá thì except cũng nên bỏ
313
+ // Cảnh báo nếu một except trở nên vô nghĩa — cảnh báo đã bị xoá thì except cũng nên bỏ.
314
+ // Nằm ngoài `scope` cũng là vô nghĩa: file đó không bao giờ bị soi, giữ except chỉ làm
315
+ // người đọc tưởng nó đang che một thứ có thật.
290
316
  for (const f of except) {
291
317
  const src = sources.find(s => s.rel === f);
292
- if (!src || !src.text.includes(fp.pattern)) {
293
- warn('R5', `\`${fp.pattern}\`: except \`${f}\` không còn chứa pattern — bỏ except này khỏi schema`);
318
+ if (!src || !src.text.includes(fp.pattern) || !inScope(src)) {
319
+ warn('R5', `\`${fp.pattern}\`: except \`${f}\` không còn chứa pattern (hoặc ngoài scope) — bỏ except này khỏi schema`);
320
+ }
321
+ }
322
+ }
323
+
324
+ // Một `scope` glob khớp 0 file thì rule **trông như** đang canh một vùng, thực ra canh không
325
+ // khí — đúng kiểu rỗng ruột mà cảnh báo `except` chết ở trên sinh ra để chống, chỉ ở đầu kia.
326
+ // Đã suýt xảy ra thật ở S0: scope trỏ `qa-runner/**` (thư mục S2 sắp XOÁ) và không trỏ
327
+ // `qa-script-designer/**` (thư mục S2 sắp TẠO) → sau S2 đèn xanh vì RỖNG, không vì SẠCH.
328
+ // Chỉ WARN, không ERROR: trỏ vào thư mục chưa tạo là hợp lệ trong lúc đang chuyển stack.
329
+ // Gộp theo glob, không theo entry — 6 entry dùng chung một scope thì cảnh báo một lần.
330
+ {
331
+ const seen = new Set();
332
+ for (const fp of schema.forbidden_patterns) {
333
+ for (const g of (fp.scope || [])) {
334
+ if (seen.has(g)) continue;
335
+ seen.add(g);
336
+ if (!sources.some(s => globMatch(g, s.rel))) {
337
+ warn('R5', `scope \`${g}\` khớp 0 file — thư mục chưa tồn tại, hoặc đã bị xoá mà glob còn ở lại`);
338
+ }
294
339
  }
295
340
  }
296
341
  }