@educa-corp/sdd-framework 0.9.6 → 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 (147) hide show
  1. package/bin/lint-trace.js +4 -4
  2. package/bin/qc-base-map.json +13 -11
  3. package/bin/self-check.js +497 -16
  4. package/bin/trace-schema.json +3226 -2656
  5. package/core/FRAMEWORK_VERSION +1 -1
  6. package/core/commands/amend-prd.md +7 -1
  7. package/core/commands/debug.md +8 -2
  8. package/core/commands/define-product.md +38 -1
  9. package/core/commands/dev-gen-test.md +9 -3
  10. package/core/commands/dev-run-test.md +8 -2
  11. package/core/commands/dev-smoke-test.md +7 -1
  12. package/core/commands/extend-prd.md +7 -1
  13. package/core/commands/fix-bug.md +11 -5
  14. package/core/commands/generate-architecture.md +9 -1
  15. package/core/commands/generate-bdd.md +45 -5
  16. package/core/commands/generate-code.md +43 -4
  17. package/core/commands/generate-design-spec.md +7 -1
  18. package/core/commands/generate-prd.md +9 -1
  19. package/core/commands/generate-spec-manifest.md +7 -1
  20. package/core/commands/generate-tech-docs.md +41 -1
  21. package/core/commands/learn.md +7 -1
  22. package/core/commands/map-testids.md +11 -5
  23. package/core/commands/propose-scenario.md +7 -1
  24. package/core/commands/qc-analyze.md +12 -6
  25. package/core/commands/qc-automation-assess.md +356 -0
  26. package/core/commands/qc-design-script.md +430 -0
  27. package/core/commands/qc-design-test.md +98 -20
  28. package/core/commands/qc-plan.md +9 -3
  29. package/core/commands/qc-report.md +92 -77
  30. package/core/commands/qc-review-script.md +342 -0
  31. package/core/commands/{qc-review.md → qc-review-testcase.md} +86 -54
  32. package/core/commands/qc-run-manualtest.md +401 -0
  33. package/core/commands/qc-run-script.md +421 -0
  34. package/core/commands/refine-prd.md +7 -1
  35. package/core/commands/report-bug.md +9 -3
  36. package/core/commands/review-code.md +9 -3
  37. package/core/commands/review-context.md +11 -3
  38. package/core/commands/review-tech-docs.md +11 -3
  39. package/core/commands/setup-ai-first.md +7 -1
  40. package/core/commands/validate-traces.md +10 -4
  41. package/core/modules/qc-playwright-ts/module.yaml +13 -0
  42. package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
  43. package/core/modules/qc-wdio-appium/module.yaml +20 -0
  44. package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
  45. package/core/rules/workflow.md +2 -2
  46. package/core/skills/qc/_shared/self-review-principles.md +2 -2
  47. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +1 -1
  48. package/core/skills/qc/qa-analyst/data-flow.md +1 -1
  49. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +1 -1
  50. package/core/skills/qc/qa-automation-assess/matrix.md +123 -0
  51. package/core/skills/qc/qa-designer/e2e/journey.md +1 -1
  52. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  53. package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
  54. package/core/skills/qc/qa-designer/functional/api.md +2 -2
  55. package/core/skills/qc/qa-designer/functional/gui-feature.md +1 -1
  56. package/core/skills/qc/qa-designer/functional/gui-screen.md +1 -1
  57. package/core/skills/qc/qa-designer/functional/job.md +128 -0
  58. package/core/skills/qc/qa-designer/integration/api.md +2 -2
  59. package/core/skills/qc/qa-designer/integration/db.md +2 -2
  60. package/core/skills/qc/qa-designer/integration/gui.md +1 -1
  61. package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +21 -5
  62. package/core/skills/qc/qa-designer/non-functional.md +1 -1
  63. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
  64. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +28 -6
  65. package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
  66. package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
  67. package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
  68. package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
  69. package/core/skills/qc/qa-reviewer/script/exploratory.md +3 -3
  70. package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
  71. package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
  72. package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
  73. package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
  74. package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
  75. package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
  76. package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
  77. package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
  78. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
  79. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +29 -10
  80. package/core/skills/qc/qa-reviewer/test-case/e2e.md +2 -2
  81. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  82. package/core/skills/qc/qa-reviewer/test-case/functional.md +2 -2
  83. package/core/skills/qc/qa-reviewer/test-case/integration.md +2 -2
  84. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +2 -2
  85. package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
  86. package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
  87. package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
  88. package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
  89. package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
  90. package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
  91. package/core/skills/qc/qa-script-designer/api/security.md +41 -0
  92. package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
  93. package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
  94. package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
  95. package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
  96. package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
  97. package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
  98. package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
  99. package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
  100. package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
  101. package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
  102. package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
  103. package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
  104. package/core/skills/qc/qa-script-runner/report.md +41 -0
  105. package/core/skills/qc/qa-script-runner/web/run.md +48 -0
  106. package/core/steps/context-loader.md +1 -1
  107. package/core/steps/gate.md +7 -1
  108. package/core/steps/qc-scope.md +45 -2
  109. package/core/steps/qc-stamp.md +4 -4
  110. package/core/steps/report-footer.md +10 -9
  111. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  112. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +13 -12
  113. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +3 -3
  114. package/docs/02-concepts/traceability.md +1 -1
  115. package/docs/03-guides/developer.md +1 -1
  116. package/docs/03-guides/tester-qa.md +40 -11
  117. package/docs/04-reference/commands.md +4 -2
  118. package/docs/04-reference/modules.md +2 -1
  119. package/docs/04-reference/trace-schema.md +4 -4
  120. package/docs/explain/17-qc-design-test.md +5 -5
  121. package/docs/explain/18-qc-review.md +42 -20
  122. package/docs/explain/19-qc-run-test.md +13 -10
  123. package/docs/explain/20-qc-report.md +3 -3
  124. package/docs/explain/23-fix-bug.md +2 -2
  125. package/docs/explain/README.md +2 -2
  126. package/docs/plans/qc-surgery/01-checklist.md +86 -21
  127. package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
  128. package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
  129. package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
  130. package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
  131. package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
  132. package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
  133. package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
  134. package/package.json +1 -1
  135. package/core/commands/qc-run-test.md +0 -561
  136. package/core/modules/qc-playwright/stack-profile.yaml +0 -66
  137. package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
  138. package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
  139. package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
  140. package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
  141. package/core/skills/qc/qa-runner/e2e.md +0 -49
  142. package/core/skills/qc/qa-runner/functional/api.md +0 -35
  143. package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
  144. package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
  145. package/core/skills/qc/qa-runner/integration.md +0 -47
  146. package/core/skills/qc/qa-runner/non-functional.md +0 -49
  147. package/core/skills/qc/qa-runner/report/report.md +0 -37
@@ -6,11 +6,11 @@ ported_from: ai-automation-qc-base
6
6
 
7
7
  # /qc-design-test — QC Test-Case Design
8
8
 
9
- > Stage 3 của QC automation pipeline native (qc-analyze → qc-plan → qc-design-test → qc-review → qc-run-test → qc-report). Port từ qa-designer của team QC. Sinh test case Markdown (`.Test.md`) — Python đến sau ở /qc-run-test.
9
+ > Trạm 3/9 của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ qa-designer của team QC. Sinh test case Markdown (`.Test.md`) — script tự động đến sau ở /qc-design-script.
10
10
 
11
11
  ## Gate
12
12
 
13
- *Checkpoint: **chặn CỨNG** — ghi đè `*.Test.md` đã qua cổng HITL `/qc-review` → mất `Status` đã duyệt, `Expected Result` đã sửa theo finding, dấu 🚫 Block vừa gỡ; và ĐÁNH SỐ LẠI `TC_<FEATURE>_NNN` mà `REVIEW_<FEATURE>.md` đang trỏ vào. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
13
+ *Checkpoint: **chặn CỨNG** — ghi đè `*.Test.md` đã qua cổng HITL `/qc-review-testcase` → mất `Status` đã duyệt, `Expected Result` đã sửa theo finding, dấu 🚫 Block vừa gỡ; và ĐÁNH SỐ LẠI `TC_<FEATURE>_NNN` mà `REVIEW_<FEATURE>.md` đang trỏ vào. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
14
14
 
15
15
  *Mức cứng chỉ áp khi file `.Test.md` **đã tồn tại**. Lần thiết kế đầu không ghi đè gì, đi thẳng. Xem §Chạy lại.*
16
16
 
@@ -93,7 +93,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
93
93
 
94
94
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
95
95
  |---|---|:---:|
96
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
96
+ | **Không chặn** | `/review-code` · `/validate-traces` · `/debug` **KHÔNG phải vì read-only**: cả ba đều CÓ ghi file. Chúng không chặn vì thao tác ghi của chúng hoặc nằm sau một câu hỏi `(Y/N)`, hoặc nằm sau một cờ, hoặc là `append`/dựng-lại-được | — (vốn không có) |
97
97
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
98
98
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
99
99
 
@@ -101,6 +101,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
101
101
  `--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
102
102
  headless: `claude -p "/generate-code UC1 --yes"`.
103
103
 
104
+ > **Tên lệnh trong bảng trên có máy canh — `R19`.** Mỗi hàng bảng vừa nêu một mức vừa nêu
105
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
106
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
107
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
108
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
109
+
104
110
  > **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
105
111
  > ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
106
112
  > **nghĩa là gì**.
@@ -228,9 +234,26 @@ Kiểm sự tồn tại của cả ba file dưới `{qc_artifact_dir}`:
228
234
  rồi: /qc-plan {TICKET-ID} {active_platform}
229
235
  ```
230
236
 
231
- **Đủ cả ba → im lặng, đi tiếp.** Guard này **điều kiện vào cửa**, không phải phép đo: "đủ file"
232
- không phải một phát hiện, nên không in dòng nào. *(Khác `Guard BR-tag` và `Guard SC coverage` —
233
- hai cái đó là phép ĐẾM, con số của chúng có giá trị ngay cả khi sạch, nên chúng luôn in.)*
237
+ **Đủ cả ba → IN MỘT DÒNG BẰNG CHỨNG rồi đi tiếp:**
238
+
239
+ ```
240
+ ✅ Đầu vào trạm 3: 3/3 — {qc_artifact_dir}{REQUIREMENT_ANALYSIS,DOC_GAP,TEST_PLAN}.md
241
+ ```
242
+
243
+ > **Vì sao cổng vào cửa PHẢI in, dù "đủ file" không phải một phát hiện** *(sửa 2026-09-17, sau một
244
+ > ca thật)*. Bản trước ghi *"đủ cả ba → im lặng, đi tiếp"* với lý do nghe hợp lý: cổng là điều kiện,
245
+ > không phải phép đo. Cái giá không ai tính: **cổng đạt trong im lặng KHÔNG phân biệt được với cổng
246
+ > chưa bao giờ chạy** — cả hai đều không in gì.
247
+ >
248
+ > **Ca thật:** lệnh chạy trên một PRD mà `{qc_artifact_dir}` **chưa tồn tại**, tự tường thuật
249
+ > *"đủ ba file đầu vào"*, rồi đi tiếp. Không dấu vết nào để đối chiếu, và người dùng chỉ phát hiện
250
+ > vì lệnh sau đó hỏi một câu vô lý.
251
+ >
252
+ > Một dòng in ra làm hai việc mà im lặng không làm được: **bỏ qua thì thấy ngay** *(thiếu dòng)*,
253
+ > và **tường thuật sai thì đối chiếu được** *(đường dẫn in ra, mở là biết)*. Đây không phải nới
254
+ > lỏng luật *"đừng in cái không phải phát hiện"* — mà là phân biệt hai loại: **phép đo** in con số,
255
+ > **cổng vào cửa** in bằng chứng nó đã chạy. Cổng không có bằng chứng thì nó không phải cổng, nó
256
+ > là một lời đề nghị.
234
257
 
235
258
  > **Vì sao DỪNG chứ không cảnh báo rồi chạy.** Guard duy nhất còn lại của trạm này —
236
259
  > `Guard SC coverage` — đối chiếu TC với `.feature`, mà `.feature` ở spec repo thì **luôn có mặt**,
@@ -238,7 +261,7 @@ hai cái đó là phép ĐẾM, con số của chúng có giá trị ngay cả k
238
261
  > **không phân biệt được** với một lần chạy đúng.
239
262
  >
240
263
  > Thiếu `DOC_GAP.md` là ca đắt nhất: TC bị gap chặn **trông y hệt** TC bình thường (không có dấu
241
- > `🚫 Block` nào), nên `/qc-run-test` chạy nó, thấy đỏ, và `/qc-report` phân loại thành *product-gap*
264
+ > `🚫 Block` nào), nên `/qc-run-script` chạy nó, thấy đỏ, và `/qc-report` phân loại thành *product-gap*
242
265
  > rồi in một `/report-bug` sẵn-chạy. Lỗi đi **ra khỏi đội QC** thành bug gửi PO — cho một hành vi
243
266
  > mà spec chưa bao giờ định nghĩa. Đây là **báo cáo sai**, cùng loại với việc giữ một `pass` đã hết
244
267
  > hiệu lực (`rules/workflow.md` §*"Làm mất hiệu lực ≠ ghi đè"*).
@@ -268,11 +291,65 @@ hai cái đó là phép ĐẾM, con số của chúng có giá trị ngay cả k
268
291
  | `--api` | `TC_<FEATURE>_API.Test.md` | 1 Endpoint · 2 Integration API/DB/Kafka |
269
292
  | `--all` | **cả hai file** | như trên, hai file riêng biệt |
270
293
  | `--atomic-max` | — | bật chế độ tách tối đa (xem dưới) |
294
+ | `--shape=api\|job\|queue` | — | nêu tường minh hình dạng nền `system` — **bắt buộc khi chạy `--yes`** trên UC không suy được |
271
295
 
272
296
  **Câu hỏi phân file:** *"TC này verify được mà **không cần UI** không?"* → **có** = file API ·
273
297
  **không** = file giao diện. Đây đúng là Bước 2 của
274
298
  `{paths.qc_skills_dir}/qa-designer/shared/skill-decision-tree.md`.
275
299
 
300
+ ### Nền `system` — hỏi hình dạng khi không suy được
301
+
302
+ > **Chỉ hỏi khi HAI vế cùng đúng.** Hỏi mọi lần nền là `system` là kiểu hỏng **Ồn**: phần lớn UC
303
+ > `system` **là** API thật và BDD nói rõ; hỏi cả những lần đã rõ thì sau vài lần người ta bấm
304
+ > số 1 cho xong, và cổng đó chết trong khi không ai biết.
305
+
306
+ | Vế | Đo thế nào |
307
+ |---|---|
308
+ | **1** | `active_platform = system` |
309
+ | **2** | **0 dấu hiệu endpoint** — không tìm thấy method/path HTTP trong `.feature` của UC **lẫn** trong tech-doc |
310
+
311
+ Một trong hai vế sai → **đi tiếp, không hỏi**.
312
+
313
+ **Cả hai đúng → in bằng chứng rồi mới hỏi.** Hỏi khơi khơi thì người trả lời cũng đang đoán:
314
+
315
+ ```
316
+ {UC-ID} — nền system, không tìm thấy endpoint nào.
317
+
318
+ BDD nói : "{trích nguyên văn dòng When}"
319
+ Tech-doc : {đã có, không khai endpoint | chưa có}
320
+ Tìm thấy : {n} dòng có method/path HTTP
321
+
322
+ Hình dạng nào?
323
+ 1 API — có endpoint; chưa có trong tech-doc thì chờ tech-doc
324
+ 2 Job chạy ngầm — tự chạy theo lịch/điều kiện, không ai gọi
325
+ 3 Consumer hàng đợi — nằm chờ, có message tới thì xử lý
326
+ ```
327
+
328
+ **Có `--yes`:** không hỏi — **DỪNG** với lỗi rõ ràng. Cùng luật với phân giải nền
329
+ *(`steps/qc-scope.md` §2)*, và cùng lý do: đoán hình dạng là viết test case kiểm sai thứ, mà
330
+ nó vẫn ra một file trông hợp lệ.
331
+
332
+ ```
333
+ ❌ {UC-ID} nền system, không suy được hình dạng (0 dấu hiệu endpoint).
334
+ Chạy headless thì phải nêu tường minh: /qc-design-test {UC-ID} --shape=job --yes
335
+ ```
336
+
337
+ **Ghi câu trả lời vào `Tags` của MỌI TC sinh ra ở lượt này** — ô `<lane>` đã có sẵn trong khuôn
338
+ metadata:
339
+
340
+ | Trả lời | `<lane>` | Skill nạp |
341
+ |---|---|---|
342
+ | 1 API | `api` | `functional/api.md` · `integration/api.md` |
343
+ | 2 Job chạy ngầm | `job` | `functional/job.md` |
344
+ | 3 Consumer hàng đợi | `queue` | `integration/queue.md` |
345
+
346
+ > **Vì sao ghi vào từng TC chứ không một chỗ cho cả PRD.** Một PRD có UC là API và UC là job là
347
+ > chuyện thường. Ghi ở cấp PRD là ép cả PRD thành một kiểu.
348
+ >
349
+ > **Vì sao phải ghi, không chỉ dùng rồi thôi.** Trạm 5 và trạm 6 cũng cần biết hình dạng. Không
350
+ > ghi thì chúng **hỏi lại**, và có thể nhận câu trả lời khác — lúc đó test case và script kiểm
351
+ > hai thứ khác nhau, cả hai đều chạy được, và **không gì bắt được**.
352
+
276
353
  > **Vì sao hai file riêng chứ không một file rồi ghi từng nhóm** *(B12)*. `--api` chạy sau khi
277
354
  > file giao diện đã tồn tại là chuyện thường. Nếu chung một file, lần chạy `--api` phải **giữ
278
355
  > nguyên** năm nhóm kia — mà viết-lại-cả-file là đúng thứ agent hay làm. Hai file thì hai chế
@@ -316,8 +393,8 @@ vế nói về **cùng một** kết cục — ví dụ *"form hiển thị đ
316
393
  ## Role
317
394
 
318
395
  Bạn là **QC Designer** — stage 3. Sinh/bảo trì các file test-case Markdown
319
- (`.Test.md`) từ requirement đã phân tích + plan. Output feed vào qc-run-test (Python) và
320
- qc-review. Bạn **không** viết Python.
396
+ (`.Test.md`) từ requirement đã phân tích + plan. Output feed vào qc-review-testcase rồi
397
+ qc-automation-assess. Bạn **không** viết script tự động.
321
398
 
322
399
  ## Skills (`{paths.qc_skills_dir}/qa-designer/`)
323
400
 
@@ -342,7 +419,8 @@ qc-review. Bạn **không** viết Python.
342
419
  | Feature đa-màn | `functional/gui-feature.md` | file giao diện |
343
420
  | API endpoint | `functional/api.md` | **file API** |
344
421
  | Integration qua UI | `integration/gui.md` | file giao diện |
345
- | Integration API/DB/Kafka | `integration/{api,db,kafka}.md` | **file API** |
422
+ | Integration API/DB/hàng đợi | `integration/{api,db,queue}.md` | **file API** |
423
+ | Job chạy ngầm *(lane `job`)* | `functional/job.md` | **file API** |
346
424
  | End-to-end journey | `e2e/journey.md` | file giao diện |
347
425
  | Non-functional | `non-functional.md` | theo câu hỏi phân file |
348
426
  | Exploratory | `exploratory/{charter,explore-to-functional}.md` | file giao diện |
@@ -353,11 +431,11 @@ qc-review. Bạn **không** viết Python.
353
431
  đều ở `shared/tc-metadata-format.md`. **Đừng lặp lại ở đây.** Dưới đây chỉ là thứ riêng của trạm:*
354
432
 
355
433
  - Markdown-first; đừng design khi requirement chưa rõ — đẩy ngược về qc-plan/qc-analyze.
356
- - **Tham chiếu test-id, không phải gợi ý hình ảnh.** Với mỗi step GUI tác động lên một element, trích test-id ổn định từ bảng §4.5.6 của tech-doc gộp (vd "click `ft001-login-submit-btn`") để qc-run-test dựng locator từ contract. Nếu một element có action không có test-id trong §4.5.6, ghi chú lại (qc-run-test sẽ fallback về locator role/text chậm hơn).
434
+ - **Tham chiếu test-id, không phải gợi ý hình ảnh.** Với mỗi step GUI tác động lên một element, trích test-id ổn định từ bảng §4.5.6 của tech-doc gộp (vd "click `ft001-login-submit-btn`") để qc-design-script dựng locator từ contract. Nếu một element có action không có test-id trong §4.5.6, ghi chú lại (qc-design-script sẽ fallback về locator role/text chậm hơn).
357
435
  - **Đọc `@trace.testid_attr` từ header tech-doc gộp** (do `/map-testids` ghi) và ghi lại một
358
436
  dòng `Test-ID attribute: {attr}` ở metadata đầu file `.Test.md`. §4.5.6 chỉ cho **giá trị**
359
- test-id; `@trace.testid_attr` là **tên thuộc tính** chứa chúng — `/qc-run-test` cần nó để cấu
360
- hình locator, `/qc-review` cần nó để biết selector trong script có đúng contract không.
437
+ test-id; `@trace.testid_attr` là **tên thuộc tính** chứa chúng — `/qc-design-script` cần nó để cấu
438
+ hình locator, `/qc-review-script` cần nó để biết selector trong script có đúng contract không.
361
439
  Không đọc được `@trace.testid_attr` → ghi
362
440
  `Test-ID attribute: — (thiếu @trace.testid_attr, chạy /map-testids)`; **đừng bỏ trống, đừng
363
441
  tự đoán theo platform** — đoán sai thì mọi locator trượt 100%, vì một lý do không liên quan
@@ -375,7 +453,7 @@ không phải cột bảng** (file TC không có ký tự `|`):
375
453
  ```
376
454
 
377
455
  Lấy từ `@trace.scenario` của `.feature`. Một SC map được nhiều TC. Đây là **join key** cho phép
378
- qc-run-test ghi `qc_status` theo từng scenario vào sổ trace — **thiếu nó thì test vẫn chạy,
456
+ qc-run-script ghi `qc_status` theo từng scenario vào sổ trace — **thiếu nó thì test vẫn chạy,
379
457
  vẫn pass/fail, nhưng kết quả không vào được sổ và không ai biết nó phủ kịch bản nào.**
380
458
 
381
459
  Cuối file: **Trace matrix** (BR ↔ TC ↔ SC) + **danh sách TC bị block** — cả hai dạng danh sách.
@@ -450,7 +528,7 @@ Hỏi từng SC chưa phủ: *"TC cho SC này verify được mà **không cần
450
528
  > — đúng Bước 2 của `shared/skill-decision-tree.md`), không phải một nhận định tự do. Ghi *"SC này
451
529
  > phức tạp"*, *"tương tự SC2"* thì **không** rơi vào ô nào của bảng trên.
452
530
  >
453
- > **Vì sao không cứ bù vào file đang mở cho gọn.** File API được `/qc-run-test` đọc bằng lane API.
531
+ > **Vì sao không cứ bù vào file đang mở cho gọn.** File API được `/qc-design-script` đọc bằng lane API.
454
532
  > Một TC cần UI nằm ở đó **không chạy nổi** — và nó sẽ đỏ dưới dạng *script-bug* hoặc *product-gap*,
455
533
  > không ai truy ngược về một quyết định ghi file ở phase thiết kế.
456
534
 
@@ -492,7 +570,7 @@ nó tồn tại, và không ai phát hiện được khi nó chết.
492
570
 
493
571
  ## Chạy lại — `.Test.md` đã tồn tại *(GIỮ, không sinh lại từ trắng)*
494
572
 
495
- File `.Test.md` đi qua **cổng HITL `/qc-review`**. Bốn thứ trong đó **không sinh lại được**:
573
+ File `.Test.md` đi qua **cổng HITL `/qc-review-testcase`**. Bốn thứ trong đó **không sinh lại được**:
496
574
 
497
575
  | Mất gì | Vì sao |
498
576
  |---|---|
@@ -506,7 +584,7 @@ File `.Test.md` đi qua **cổng HITL `/qc-review`**. Bốn thứ trong đó **k
506
584
  | Tình huống | Xử lý |
507
585
  |---|---|
508
586
  | TC cũ, spec **không đổi** | **Giữ nguyên** — số · `Status` · `Expected Result` đã sửa |
509
- | TC cũ, spec **đổi** | Cập nhật **nội dung**; giữ **số** và `Status`, thêm ⚠️ để `/qc-review` soát lại |
587
+ | TC cũ, spec **đổi** | Cập nhật **nội dung**; giữ **số** và `Status`, thêm ⚠️ để `/qc-review-testcase` soát lại |
510
588
  | TC **mới** | Cấp số **tiếp theo** — không dồn, không tái dùng |
511
589
  | TC không còn ứng với SC nào | **KHÔNG xoá** → `Status: Obsolete`, ghi lý do |
512
590
 
@@ -534,7 +612,7 @@ sẵn ở `{paths.qc_skills_dir}/qa-designer/shared/tc-metadata-format.md` §*Qu
534
612
  quyết (Answered)*. Bước đóng đó **chưa lệnh nào gọi** — nên dấu chặn chỉ dán vào, không bao giờ gỡ ra.
535
613
 
536
614
  Một TC mang `🚫 Block` là một TC có **Expected Result dựa trên giả định chưa ai xác nhận**. Nó nằm
537
- trong thư mục dùng chung, được `Guard SC coverage` đếm là **đã phủ**, và `/qc-run-test` sẽ nhặt lên.
615
+ trong thư mục dùng chung, được `Guard SC coverage` đếm là **đã phủ**, và `/qc-design-script` sẽ nhặt lên.
538
616
 
539
617
  > **Vì sao stamp phiên bản (§Stamp phiên bản nguồn) KHÔNG phủ ca này.** Gap chuyển `Open → Answered`
540
618
  > là một **ô trong `DOC_GAP.md`** — nó **không bump version nào cả**. Mọi drift detector của framework
@@ -590,7 +668,7 @@ Ghi dưới `{qc_artifact_dir}test-cases/`
590
668
  PRD**. Tên file mang `<FEATURE>` nên các UC không đâm nhau; `@trace.verifies` là chỗ phân biệt
591
669
  TC thuộc UC nào.
592
670
 
593
- **Đuôi bắt buộc là `.Test.md`.** `/qc-run-test` và `/qc-review` tìm `*.Test.md`; ghi ra
671
+ **Đuôi bắt buộc là `.Test.md`.** `/qc-design-script` và `/qc-review-testcase` tìm `*.Test.md`; ghi ra
594
672
  `TC_<FEATURE>.md` là ghi ra thứ **không trạm nào tìm thấy**, và **không có gì báo lỗi**.
595
673
 
596
674
  `🚫 Block` trỏ `../DOC_GAP.md` — lên một cấp, vì file gap ở thư mục cha của `test-cases/`.
@@ -633,5 +711,5 @@ Guard SC coverage: {khớp {K}/{K} | ⚠️ {K}/{total} — đã bù {m} SC: {da
633
711
  {nếu có SC cần UI mà đang chạy --api: "⚠️ {n} SC cần UI chưa có TC ở file giao diện —
634
712
  KHÔNG bù vào file API. Chạy: /qc-design-test {UC-ID} (không cờ). SC: {danh sách}"}
635
713
  Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
636
- Next : /qc-review {UC-ID} ← review test case trước khi sinh script
714
+ Next : /qc-review-testcase {UC-ID} ← review test case trước khi sinh script
637
715
  ```
@@ -6,7 +6,7 @@ ported_from: ai-automation-qc-base
6
6
 
7
7
  # /qc-plan — QC Test Plan & Risk Analysis
8
8
 
9
- > Stage 2 của QC automation pipeline native (qc-analyze → qc-plan → qc-design-test → qc-review → qc-run-test → qc-report). Port từ qa-planner của team QC.
9
+ > Trạm 2/9 của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ qa-planner của team QC.
10
10
 
11
11
  ## Gate
12
12
  # Gate — Quy trình vào chuẩn cho mọi lệnh
@@ -88,7 +88,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
88
 
89
89
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
90
90
  |---|---|:---:|
91
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
91
+ | **Không chặn** | `/review-code` · `/validate-traces` · `/debug` **KHÔNG phải vì read-only**: cả ba đều CÓ ghi file. Chúng không chặn vì thao tác ghi của chúng hoặc nằm sau một câu hỏi `(Y/N)`, hoặc nằm sau một cờ, hoặc là `append`/dựng-lại-được | — (vốn không có) |
92
92
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
93
93
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
94
94
 
@@ -96,6 +96,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
96
96
  `--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
97
97
  headless: `claude -p "/generate-code UC1 --yes"`.
98
98
 
99
+ > **Tên lệnh trong bảng trên có máy canh — `R19`.** Mỗi hàng bảng vừa nêu một mức vừa nêu
100
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
101
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
102
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
103
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
104
+
99
105
  > **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
100
106
  > ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
101
107
  > **nghĩa là gì**.
@@ -240,7 +246,7 @@ Bắt buộc:
240
246
 
241
247
  ### Chạy lại — ghi đè ở đây AN TOÀN, và đây là lý do
242
248
 
243
- *(Ba trạm QC khác — `/qc-analyze` · `/qc-design-test` · `/qc-run-test` — đều ở mức **chặn CỨNG** kèm
249
+ *(Ba trạm QC khác — `/qc-analyze` · `/qc-design-test` · `/qc-design-script` — đều ở mức **chặn CỨNG** kèm
244
250
  §Chạy lại. Trạm này **không**, và đó là kết luận có chủ ý, không phải chỗ sót.)*
245
251
 
246
252
  `TEST_PLAN.md` **không có ô nào người nhập tay**: `questions-for-dev` là danh sách **gửi đi** — câu
@@ -1,14 +1,14 @@
1
- ---
2
- version: 1.0
3
- updated: 2026-06-11
4
- ported_from: ai-automation-qc-base
5
- ---
6
-
7
- # /qc-report — QC Test Report & Evidence
8
-
9
- > Stage 6 (cuối) của QC automation pipeline native (qc-analyze → qc-plan → qc-design-test → qc-review → qc-run-test → qc-report). Port từ bước report của qa-runner team QC.
10
-
11
- ## Gate
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-06-11
4
+ ported_from: ai-automation-qc-base
5
+ ---
6
+
7
+ # /qc-report — QC Test Report & Evidence
8
+
9
+ > Trạm 9/9 (cuối) của dây chuyền QC automation (qc-analyze → qc-plan → qc-design-test → qc-review-testcase → qc-automation-assess → qc-design-script → qc-review-script → qc-run-script ∥ qc-run-manualtest → qc-report). Port từ bước report của kho QC gốc (xem `bin/qc-base-map.json`).
10
+
11
+ ## Gate
12
12
  # Gate — Quy trình vào chuẩn cho mọi lệnh
13
13
 
14
14
  Mọi lệnh PHẢI chạy gate này trước khi thực thi phần logic riêng của nó.
@@ -88,7 +88,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
88
 
89
89
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
90
90
  |---|---|:---:|
91
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
91
+ | **Không chặn** | `/review-code` · `/validate-traces` · `/debug` **KHÔNG phải vì read-only**: cả ba đều CÓ ghi file. Chúng không chặn vì thao tác ghi của chúng hoặc nằm sau một câu hỏi `(Y/N)`, hoặc nằm sau một cờ, hoặc là `append`/dựng-lại-được | — (vốn không có) |
92
92
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
93
93
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
94
94
 
@@ -96,6 +96,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
96
96
  `--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
97
97
  headless: `claude -p "/generate-code UC1 --yes"`.
98
98
 
99
+ > **Tên lệnh trong bảng trên có máy canh — `R19`.** Mỗi hàng bảng vừa nêu một mức vừa nêu
100
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
101
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
102
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
103
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
104
+
99
105
  > **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
100
106
  > ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
101
107
  > **nghĩa là gì**.
@@ -160,74 +166,83 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
160
166
  - "N" → dừng, hỏi người dùng muốn thay đổi gì.
161
167
  - Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
162
168
  🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
163
-
164
-
165
- *Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Sinh report từ lần chạy `/qc-run-test` gần nhất. Dùng module **qc-playwright** (pytest-html + Playwright Trace không Allure, không dashboard viết tay).*
166
-
167
- ## Context
169
+
170
+
171
+ *Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Sinh report từ lần chạy `/qc-run-script` gần nhất. **Reporter theo nền** — đọc `§reporting` của module đã phân giải ở `steps/qc-scope.md` §2b: `web`·`system` → **Playwright HTML Report + Trace**; `app` **Allure Report v2.x**. Không dashboard viết tay.*
172
+
173
+ > ⚠️ **Hai nền KHÁC NHAU ở chỗ này — đừng "thống nhất" lại.** Luật `No Allure` cũ nay chỉ còn
174
+ > đúng cho web *(`Automation-Standards` §1 + `OQ-01` đóng 2026-06-02: Playwright HTML đủ Phase 1,
175
+ > Allure defer Phase 2)*. Nền mobile thì Allure là **bắt buộc** *(`Mobile-Automation-Standards` §1)*.
176
+ > Đó là quyết định của chuẩn, không phải chỗ sót.
177
+
178
+ ## Context
168
179
  **BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
169
180
  rồi mới tiếp tục phần bên dưới.
170
181
 
171
182
  Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, guardrail từ
172
183
  `project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
173
- placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
174
-
175
- ---
176
-
177
- ## Role
178
-
179
- Bạn là stage **QC Report** — biến lần chạy gần nhất thành report + evidence chia sẻ được.
180
-
181
- ## Skill (`{paths.qc_skills_dir}/qa-runner/report/`)
182
-
183
- - `report.md` — tự đủ: pytest-html (`--html=reports/<feature>/report.html
184
- --self-contained-html`) + Playwright Trace (`test-results/<nodeid>/trace.zip`, xem qua
185
- `python3 -m playwright show-trace <file>`), kèm screenshot/evidence đính trên FAIL/SKIP.
186
-
187
- ## Procedure
188
-
189
- 1. Định vị artifact của lần chạy gần nhất cho `{UC-ID}` (report pytest-html + trace).
190
- 2. Sinh/làm mới `reports/<feature>/report.html` (self-contained) và đảm bảo mỗi
191
- FAIL/SKIP có trace + screenshot đính kèm.
192
- 3. Tóm tắt TOTAL / PASS / FAIL / SKIP; với mỗi FAIL gồm lệnh `show-trace`
193
- phân loại script-bug hay product-gap.
194
- 4. **Bàn giao product-gap về spec (nhắc).** Với mỗi FAIL phân loại **product-gap**
195
- (defect thật, impl spec không phải script-bug), in một
196
- `/report-bug {UC-ID} {one-line expected-vs-actual}` sẵn-chạy để QC file nó vào spec repo dùng chung.
197
- BUG_FLOW của `/report-bug` rồi định tuyến root cause (Code / BDD / PRD / Design / Env). Không bao giờ
198
- fake-pass một product-gap giữ FAIL trong `qc_status` cho tới khi fix + chạy lại. **script-bug
199
- KHÔNG được file** (QC fix script và chạy lại). Liệt các lệnh; đừng tự tạo report.
200
-
201
- ## Self-Review *(trước khi in Report)*
202
-
203
- Theo 3 nhóm ở `{paths.qc_skills_dir}/_shared/self-review-principles.md` — **không chép lại ở đây**.
204
-
205
- - **Bịa:** mọi con số trong báo cáo trích được về **một dòng cụ thể** của sổ trace / output
206
- runner / bug report — không nội suy khi thiếu mẫu?
207
- - **Nhảy bước:** đã tổng hợp trên **toàn bộ** SC trong phạm vi, không chỉ những SC có kết quả
208
- đẹp? Đã liệt cả SC `not_run` `flaky`, không im lặng bỏ khỏi bảng?
209
- - **Số liệu:** mọi `%` phép chia thật **và nói rõ mẫu số**? Chỗ thiếu dữ liệu ghi **"chưa đủ
210
- dữ liệu"** thay điền một số cho đủ bảng?
211
-
212
- > **Trạm này nơi số liệu đi ra khỏi đội QC.** Một con số sai các trạm trước còn người trong
213
- > đội nhìn thấy; sai đây là đi vào báo cáo cho Lead/PM. Nhóm 3 vì vậy là nhóm nặng nhất ở đây:
214
- > *"một bảng đầy số sai tệ hơn một bảng có ô trống ghi rõ lý do"*.
215
-
216
- ## Report
217
-
184
+ placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
185
+
186
+ ---
187
+
188
+ ## Role
189
+
190
+ Bạn là stage **QC Report** — biến lần chạy gần nhất thành report + evidence chia sẻ được.
191
+
192
+ ## Skill (`{paths.qc_skills_dir}/qa-script-runner/`)
193
+
194
+ - `report.md` — tự đủ, **theo nền**:
195
+ - `web` · `system` — Playwright HTML Report (`npx playwright show-report`) + Trace
196
+ (`test-results/<test>/trace.zip`, xem qua `npx playwright show-trace <file>`)
197
+ - `app` — Allure Report v2.x (`npx allure generate reports/allure-results --clean && npx allure open`)
198
+
199
+ kèm screenshot/evidence đính trên FAIL/SKIP.
200
+
201
+ ## Procedure
202
+
203
+ 1. Định vị artifact của lần chạy gần nhất cho `{UC-ID}` (HTML report + trace, theo nền).
204
+ 2. Sinh/làm mới `reports/<feature>/report.html` (self-contained) đảm bảo mỗi
205
+ FAIL/SKIPtrace + screenshot đính kèm.
206
+ 3. Tóm tắt TOTAL / PASS / FAIL / SKIP; với mỗi FAIL gồm lệnh `show-trace`
207
+ phân loại script-bug hay product-gap.
208
+ 4. **Bàn giao product-gap về spec ( nhắc).** Với mỗi FAIL phân loại **product-gap**
209
+ (defect thật, impl spec không phải script-bug), in một
210
+ `/report-bug {UC-ID} {one-line expected-vs-actual}` sẵn-chạy để QC file vào spec repo dùng chung.
211
+ BUG_FLOW của `/report-bug` rồi định tuyến root cause (Code / BDD / PRD / Design / Env). Không bao giờ
212
+ fake-pass một product-gap nó giữ FAIL trong `qc_status` cho tới khi fix + chạy lại. **script-bug
213
+ KHÔNG được file** (QC fix script và chạy lại). Liệt kê các lệnh; đừng tự tạo report.
214
+
215
+ ## Self-Review *(trước khi in Report)*
216
+
217
+ Theo 3 nhóm `{paths.qc_skills_dir}/_shared/self-review-principles.md` **không chép lại đây**.
218
+
219
+ - **Bịa:** mọi con số trong báo cáo trích được về **một dòng cụ thể** của sổ trace / output
220
+ runner / bug report không nội suy khi thiếu mẫu?
221
+ - **Nhảy bước:** đã tổng hợp trên **toàn bộ** SC trong phạm vi, không chỉ những SC có kết quả
222
+ đẹp? Đã liệt kê cả SC `not_run` và `flaky`, không im lặng bỏ khỏi bảng?
223
+ - **Số liệu:** mọi `%` phép chia thật **và nói mẫu số**? Chỗ thiếu dữ liệu ghi **"chưa đủ
224
+ dữ liệu"** thay điền một số cho đủ bảng?
225
+
226
+ > **Trạm này là nơi số liệu đi ra khỏi đội QC.** Một con số sai ở các trạm trước còn người trong
227
+ > đội nhìn thấy; sai ở đây là đi vào báo cáo cho Lead/PM. Nhóm 3 vì vậy là nhóm nặng nhất ở đây:
228
+ > *"một bảng đầy số sai tệ hơn một bảng có ô trống ghi rõ lý do"*.
229
+
230
+ ## Report
231
+
218
232
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
219
- Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
220
-
221
- ```
222
- /qc-report Hoàn tất — {UC-ID}
223
- Report: reports/<feature>/report.html (TOTAL {N} · PASS {p} · FAIL {f} · SKIP {s})
224
- Trace : test-results/<nodeid>/trace.zip (python3 -m playwright show-trace <file>)
225
-
226
- Product-gap cần file ({g}): ← chạy các lệnh này để PO/Dev thấy trên /sync (script-bug bị loại)
227
- /report-bug {UC-ID} {gap 1 expected vs actual}
228
- /report-bug {UC-ID} {gap 2 }
229
- (không skip)
230
-
231
- Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
232
- Next: /validate-traces {UC-ID} làm mới Living Docs (qc_status), rồi tạo PR
233
- ```
233
+ Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
234
+
235
+ ```
236
+ /qc-report Hoàn tất — {UC-ID}
237
+ Report: reports/<feature>/report.html (TOTAL {N} · PASS {p} · FAIL {f} · SKIP {s})
238
+ Trace : test-results/<test>/trace.zip (npx playwright show-trace <file>) ← web·system
239
+ Report: reports/allure-results (npx allure open) ← app
240
+
241
+ Product-gap cần file ({g}): ← chạy các lệnh này để PO/Dev thấy trên /sync (script-bug bị loại)
242
+ /report-bug {UC-ID} {gap 1 — expected vs actual}
243
+ /report-bug {UC-ID} {gap 2 …}
244
+ (không có → skip)
245
+
246
+ Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý liệt kê}
247
+ Next: /validate-traces {UC-ID} ← làm mới Living Docs (qc_status), rồi tạo PR
248
+ ```