@educa-corp/sdd-framework 0.9.5 → 0.9.7

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 (113) hide show
  1. package/bin/build.js +11 -1
  2. package/bin/lint-trace.js +397 -28
  3. package/bin/self-check.js +623 -16
  4. package/bin/trace-schema.json +3187 -1981
  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 +70 -2
  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 +44 -5
  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 +44 -4
  21. package/core/commands/learn.md +7 -1
  22. package/core/commands/map-testids.md +96 -13
  23. package/core/commands/propose-scenario.md +7 -1
  24. package/core/commands/qc-analyze.md +516 -426
  25. package/core/commands/qc-automation-assess.md +356 -0
  26. package/core/commands/qc-design-script.md +400 -0
  27. package/core/commands/qc-design-test.md +482 -248
  28. package/core/commands/qc-plan.md +141 -94
  29. package/core/commands/qc-report.md +9 -3
  30. package/core/commands/{qc-review.md → qc-review-script.md} +172 -132
  31. package/core/commands/qc-review-testcase.md +409 -0
  32. package/core/commands/qc-run-manualtest.md +401 -0
  33. package/core/commands/{qc-run-test.md → qc-run-script.md} +200 -232
  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 +27 -6
  41. package/core/modules/qc-playwright/stack-profile.yaml +1 -1
  42. package/core/rules/workflow.md +42 -2
  43. package/core/skills/qc/_shared/self-review-principles.md +2 -2
  44. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +10 -2
  45. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +1 -1
  46. package/core/skills/qc/qa-automation-assess/matrix.md +120 -0
  47. package/core/skills/qc/qa-designer/e2e/journey.md +1 -1
  48. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  49. package/core/skills/qc/qa-designer/functional/api.md +1 -1
  50. package/core/skills/qc/qa-designer/functional/gui-feature.md +1 -1
  51. package/core/skills/qc/qa-designer/functional/gui-screen.md +1 -1
  52. package/core/skills/qc/qa-designer/integration/api.md +1 -1
  53. package/core/skills/qc/qa-designer/integration/db.md +1 -1
  54. package/core/skills/qc/qa-designer/integration/gui.md +1 -1
  55. package/core/skills/qc/qa-designer/integration/kafka.md +1 -1
  56. package/core/skills/qc/qa-designer/non-functional.md +1 -1
  57. package/core/skills/qc/qa-designer/shared/duplicate-check-procedure.md +33 -5
  58. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +34 -5
  59. package/core/skills/qc/qa-planner/test-plan.md +7 -0
  60. package/core/skills/qc/qa-reviewer/script/e2e.md +1 -1
  61. package/core/skills/qc/qa-reviewer/script/exploratory.md +1 -1
  62. package/core/skills/qc/qa-reviewer/script/functional.md +1 -1
  63. package/core/skills/qc/qa-reviewer/script/integration.md +1 -1
  64. package/core/skills/qc/qa-reviewer/script/non-functional.md +1 -1
  65. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +3 -3
  66. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  67. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  68. package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
  69. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  70. package/core/skills/qc/qa-runner/e2e.md +2 -2
  71. package/core/skills/qc/qa-runner/functional/gui-feature.md +4 -4
  72. package/core/skills/qc/qa-runner/functional/gui-screen.md +4 -4
  73. package/core/skills/qc/qa-runner/integration.md +1 -1
  74. package/core/skills/qc/qa-runner/non-functional.md +1 -1
  75. package/core/steps/context-loader.md +1 -1
  76. package/core/steps/gate.md +7 -1
  77. package/core/steps/qc-scope.md +67 -11
  78. package/core/steps/qc-stamp.md +142 -0
  79. package/core/steps/report-footer.md +19 -10
  80. package/core/templates/tech-design.template.md +3 -3
  81. package/docs/01-getting-started/quickstart.md +4 -3
  82. package/docs/02-concepts/architecture.md +14 -0
  83. package/docs/02-concepts/glossary.md +8 -0
  84. package/docs/02-concepts/overview.md +3 -2
  85. package/docs/02-concepts/pipeline-steps/04-bdd.md +1 -1
  86. package/docs/02-concepts/pipeline-steps/05-tech-docs.md +21 -5
  87. package/docs/02-concepts/pipeline-steps/06-code.md +12 -2
  88. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  89. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +65 -16
  90. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +3 -3
  91. package/docs/02-concepts/pipeline-steps/README.md +4 -3
  92. package/docs/02-concepts/traceability.md +2 -2
  93. package/docs/03-guides/architect.md +2 -2
  94. package/docs/03-guides/developer.md +6 -3
  95. package/docs/03-guides/tester-qa.md +23 -10
  96. package/docs/04-reference/commands.md +9 -4
  97. package/docs/04-reference/trace-schema.md +5 -5
  98. package/docs/explain/07-generate-tech-docs.md +5 -3
  99. package/docs/explain/08-review-tech-docs.md +15 -3
  100. package/docs/explain/09-generate-code.md +30 -4
  101. package/docs/explain/10-review-code.md +1 -1
  102. package/docs/explain/11-map-testids.md +72 -70
  103. package/docs/explain/12-dev-gen-test.md +1 -1
  104. package/docs/explain/15-qc-analyze.md +14 -2
  105. package/docs/explain/16-qc-plan.md +5 -1
  106. package/docs/explain/17-qc-design-test.md +30 -7
  107. package/docs/explain/18-qc-review.md +43 -17
  108. package/docs/explain/19-qc-run-test.md +38 -12
  109. package/docs/explain/20-qc-report.md +8 -5
  110. package/docs/explain/23-fix-bug.md +2 -2
  111. package/docs/explain/README.md +6 -3
  112. package/docs/plans/qc-surgery/01-checklist.md +70 -17
  113. package/package.json +1 -1
@@ -1 +1 @@
1
- 0.9.5
1
+ 0.9.7
@@ -108,7 +108,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
108
108
 
109
109
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
110
110
  |---|---|:---:|
111
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
111
+ | **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ó) |
112
112
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
113
113
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
114
114
 
@@ -116,6 +116,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
116
116
  `--` 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
117
117
  headless: `claude -p "/generate-code UC1 --yes"`.
118
118
 
119
+ > **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
120
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
121
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
122
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
123
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
124
+
119
125
  > **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: …*`
120
126
  > 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
121
127
  > **nghĩa là gì**.
@@ -5,7 +5,7 @@ Khác `/fix-bug`: chỉ phân tích, không full workflow, không cần ticket.
5
5
 
6
6
  ## Gate
7
7
 
8
- *Checkpoint: **không chặn** — read-only. Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
8
+ *Checkpoint: **không chặn** — **không phải vì read-only**: lệnh CÓ ghi `{lessons_path}` qua §Capture Lesson (`steps/capture-lesson.md`), nhưng chỉ sau câu hỏi `(Y/N)`. Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
9
9
 
10
10
  # Gate — Quy trình vào chuẩn cho mọi lệnh
11
11
 
@@ -86,7 +86,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
86
86
 
87
87
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
88
88
  |---|---|:---:|
89
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
89
+ | **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ó) |
90
90
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
91
91
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
92
92
 
@@ -94,6 +94,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
94
94
  `--` 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
95
95
  headless: `claude -p "/generate-code UC1 --yes"`.
96
96
 
97
+ > **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
98
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
99
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
100
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
101
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
102
+
97
103
  > **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: …*`
98
104
  > 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
99
105
  > **nghĩa là gì**.
@@ -1,6 +1,11 @@
1
1
  # /define-product — Khám phá tính năng (Q&A 8 Phase)
2
2
 
3
3
  ## Gate
4
+
5
+ *Checkpoint: **chặn CỨNG** — ghi đè product-definition đã có → xoá dấu `✅ PO xác nhận` trên từng mục và đẩy `Completed Phase` về 0, tức bỏ cả vòng discovery đã chạy. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
6
+
7
+ *Mức cứng chỉ áp khi file **đã tồn tại** và có ≥1 mục mang `✅ PO xác nhận`. Buổi discovery đầu đi thẳng; resume khi chưa mục nào chốt cũng đi thẳng. Xem §Chạy lại.*
8
+
4
9
  # Gate — Quy trình vào chuẩn cho mọi lệnh
5
10
 
6
11
  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ó.
@@ -80,7 +85,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
85
 
81
86
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
82
87
  |---|---|:---:|
83
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
88
+ | **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ó) |
84
89
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
85
90
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
86
91
 
@@ -88,6 +93,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
93
  `--` 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
89
94
  headless: `claude -p "/generate-code UC1 --yes"`.
90
95
 
96
+ > **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
97
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
98
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
99
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
100
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
101
+
91
102
  > **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: …*`
92
103
  > 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
93
104
  > **nghĩa là gì**.
@@ -423,6 +434,32 @@ Ghi `{paths.product_definitions_dir}/{TICKET-ID}-{slug}.md` theo `templates/prod
423
434
  - Khi Phase 7 pass mà không còn GAP → đặt `Completed Phase: 7` và `Status: completed`.
424
435
  - Nếu discovery bị ngắt giữa chừng, file vẫn được ghi với `Completed Phase` phản ánh phase cao nhất đã xác nhận — buổi sau resume tiếp từ phase kế tiếp.
425
436
 
437
+ ## Chạy lại — product-definition đã tồn tại *(RESUME, không làm lại từ đầu)*
438
+
439
+ File này ghi lại một buổi discovery với PO, và từng mục mang dấu xác nhận của **người**:
440
+
441
+ | Phần | Ai tạo | Sinh lại được? |
442
+ |---|---|:---:|
443
+ | Nội dung AI trích (`🤖 AI trích — chờ PO chốt`) | lệnh này | ✅ |
444
+ | **Dấu `✅ PO xác nhận`** trên từng mục | **PO**, trong buổi làm việc | ❌ **không** |
445
+ | **`Completed Phase`** | lệnh này, nhưng là điểm resume | ❌ về 0 là làm lại cả buổi |
446
+
447
+ **Khi file đã có ≥1 mục `✅ PO xác nhận`, in khối này** *(mức chặn CỨNG)*:
448
+
449
+ ```
450
+ ❌ Product definition đã tồn tại: {path}
451
+ Hiện: Completed Phase {n}/7 · Status {status} · {m} mục đã ✅ PO xác nhận
452
+
453
+ Chạy lại từ đầu xoá mọi dấu ✅ PO xác nhận và đưa Completed Phase về 0,
454
+ tức phải mời PO ngồi lại từ phase 1.
455
+
456
+ Muốn đi tiếp từ chỗ dừng → tiếp tục; lệnh tự resume từ phase {n+1}
457
+ Muốn sửa một mục đã chốt → sửa thẳng trong file, giữ nguyên dấu ✅
458
+ Thật sự muốn làm lại → đổi tên file cũ rồi chạy lại (tự chịu trách nhiệm)
459
+ ```
460
+
461
+ > **Buổi discovery đầu (file chưa có) đi thẳng, không chặn.**
462
+
426
463
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
427
464
  Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
428
465
 
@@ -7,6 +7,11 @@
7
7
  > **dev self-test** để QC thấy dev đã tự chạy check của mình.
8
8
 
9
9
  ## Gate
10
+
11
+ *Checkpoint: **chặn CỨNG** — ghi đè file test đã có → XOÁ bản sửa tay của dev (mock, fixture, expectation đã chỉnh) mà chính `/dev-run-test` bảo họ làm. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
12
+
13
+ *Mức cứng chỉ áp khi file test **đã tồn tại**. Lần sinh đầu đi thẳng. Xem §Chạy lại.*
14
+
10
15
  # Gate — Quy trình vào chuẩn cho mọi lệnh
11
16
 
12
17
  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ó.
@@ -86,7 +91,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
86
91
 
87
92
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
88
93
  |---|---|:---:|
89
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
94
+ | **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ó) |
90
95
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
91
96
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
92
97
 
@@ -94,6 +99,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
94
99
  `--` 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
95
100
  headless: `claude -p "/generate-code UC1 --yes"`.
96
101
 
102
+ > **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
103
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
104
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
105
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
106
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
107
+
97
108
  > **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: …*`
98
109
  > 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
99
110
  > **nghĩa là gì**.
@@ -622,7 +633,7 @@ Sau khi sinh tất cả file test, cập nhật **sổ của platform đang test
622
633
  | `dev_selftest` | `not_run` (test giờ đã tồn tại nhưng chưa chạy — `/dev-run-test` set pass/fail) |
623
634
  | `last_updated` | hôm nay `YYYY-MM-DD` |
624
635
 
625
- Giữ nguyên mọi cột khác (gồm `dev_selftest_at`, do `/dev-run-test` sở hữu, và `qc_status`/`qc_run_at`, do `/qc-run-test` sở hữu).
636
+ Giữ nguyên mọi cột khác (gồm `dev_selftest_at`, do `/dev-run-test` sở hữu, và `qc_status`/`qc_run_at`, do `/qc-run-script` + `/qc-run-manualtest` sở hữu).
626
637
 
627
638
  ---
628
639
 
@@ -684,6 +695,63 @@ bên trong từng sub-agent.
684
695
 
685
696
  ---
686
697
 
698
+ ## Output — lệnh này ghi những gì, ở đâu
699
+
700
+ | Ghi gì | Người sửa tay? |
701
+ |---|:---:|
702
+ | File **unit / integration / E2E test** theo layout của `{active_module}` | ✅ **có** — xem §Chạy lại |
703
+ | Sổ trace: `test_count` · `test_classes` · `dev_selftest` | ❌ lệnh ghi |
704
+
705
+ > **Vì sao mục này tồn tại** *(G84)*. Trước đó §Output chỉ khai `Trace: …tsv updated` — **không
706
+ > khai file test nó ghi ra**. Một lệnh không khai mình ghi gì thì không ai nghĩ tới việc **bảo vệ
707
+ > thứ nó ghi**. Đúng lỗi gốc của G77 ở lane QC. Cột *"người sửa tay?"* là câu hỏi mà
708
+ > `bin/trace-schema.json` → `artifact_writers` ép mọi lệnh trả lời.
709
+
710
+ ## Chạy lại — file test đã tồn tại *(GIỮ phần đã có, sinh phần THIẾU)*
711
+
712
+ **Dev SỬA TAY chính các file này.** `/dev-run-test` nói thẳng:
713
+
714
+ > `:260` — *"Test fail → `/fix-bug {TICKET_ID}` (bug thật) hoặc **fix test** (sai expectation)"*
715
+ > `:137` — *"`TimeoutError` | Test gọi LLM endpoint live | **Thêm mock; kiểm tra test fixture**"*
716
+
717
+ Nên chuỗi bình thường là **sinh → chạy → đỏ → dev sửa tay → chạy lại**, và lần sinh sau **không được**
718
+ là lần xoá.
719
+
720
+ | Tình huống | Xử lý |
721
+ |---|---|
722
+ | File test đã có, `.feature` **không đổi** | **Không sinh lại.** Không hỏi gì — ca thường nhất |
723
+ | `.feature` có SC **mới** | Sinh **chỉ** test cho SC mới; giữ nguyên file/class đã có |
724
+ | File test có **thay đổi chưa commit** | **DỪNG** — xem dưới |
725
+
726
+ **Nhận diện "đã sửa tay" bằng `git status` / `git diff`** trên các đường dẫn ở §Output. Không cần ai
727
+ đánh dấu gì, và nó bắt được **mọi** lần sửa — kể cả lần người sửa quên đánh dấu.
728
+
729
+ ```
730
+ ❌ {n} file test có thay đổi chưa commit — có thể là bản sửa tay của bạn
731
+ (mock, fixture, expectation đã chỉnh). Sinh lại sẽ XOÁ chúng.
732
+ Files: {danh sách}
733
+ Cách đúng: commit bản sửa trước, rồi chạy lại.
734
+ Cố ý bỏ hết và sinh từ trắng: thêm --force
735
+ ```
736
+
737
+ **KHÔNG đoán.** Thấy thay đổi chưa commit thì lệnh **không tự phân biệt** *"dev vừa sửa"* với *"lần
738
+ sinh trước chưa commit"* — hai ca đó nhìn giống hệt nhau trên `git status`. **Dừng oan một lần rẻ
739
+ hơn xoá nhầm một lần.**
740
+
741
+ > **Vì sao mặc định là "sinh phần thiếu" chứ không phải "đừng sinh".** `/qc-design-script` (G77) có vòng
742
+ > đời **chạy nhiều / sinh ít** nên mặc định của nó là *"CHẠY, đừng sinh lại"*. Lệnh này **chỉ sinh**,
743
+ > không chạy gì — copy nguyên mặc định đó sang là **copy nhầm ngữ cảnh**. *Cùng khuôn không có nghĩa
744
+ > là cùng thuốc.*
745
+ >
746
+ > **Vì sao ca "không đổi gì" phải HOÀN TOÀN im lặng.** Sinh lại test là việc làm mỗi lần spec đổi.
747
+ > Bản vá nào làm nó hỏi mỗi lần thì người dùng sẽ thêm `--force` vào alias — và lúc đó mất sạch lớp
748
+ > bảo vệ này.
749
+
750
+ Có `--force` → report **bắt buộc** khai:
751
+ ```
752
+ ⚠️ --force: sinh lại từ trắng — đã xoá {n} file test có thay đổi chưa commit: {danh sách}
753
+ ```
754
+
687
755
  ## Output
688
756
 
689
757
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
@@ -86,7 +86,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
86
86
 
87
87
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
88
88
  |---|---|:---:|
89
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
89
+ | **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ó) |
90
90
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
91
91
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
92
92
 
@@ -94,6 +94,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
94
94
  `--` 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
95
95
  headless: `claude -p "/generate-code UC1 --yes"`.
96
96
 
97
+ > **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
98
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
99
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
100
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
101
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
102
+
97
103
  > **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: …*`
98
104
  > 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
99
105
  > **nghĩa là gì**.
@@ -388,7 +394,7 @@ Cập nhật **sổ của platform đang test** `{paths.trace_dir}/{domain}/{prd
388
394
  > tay hoặc sổ sinh bởi version framework cũ hơn.
389
395
 
390
396
  Giữ nguyên mọi cột khác — đặc biệt **không bao giờ** đụng `qc_status`/`qc_run_at`
391
- (kết quả QC automation chính thức, do `/qc-run-test` sở hữu; nó có guard riêng cùng loại).
397
+ (kết quả QC automation chính thức, do `/qc-run-script` sở hữu; nó có guard riêng cùng loại).
392
398
  `dev_selftest` (dev smoke) và `qc_status` (QC chính thức) là hai tín hiệu riêng.
393
399
 
394
400
  ## Refresh Panel Mirror
@@ -82,7 +82,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
82
82
 
83
83
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
84
84
  |---|---|:---:|
85
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
85
+ | **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ó) |
86
86
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
87
87
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
88
88
 
@@ -90,6 +90,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
90
90
  `--` 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
91
91
  headless: `claude -p "/generate-code UC1 --yes"`.
92
92
 
93
+ > **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
94
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
95
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
96
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
97
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
98
+
93
99
  > **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: …*`
94
100
  > 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
95
101
  > **nghĩa là gì**.
@@ -103,7 +103,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
103
103
 
104
104
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
105
105
  |---|---|:---:|
106
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
106
+ | **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ó) |
107
107
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
108
108
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
109
109
 
@@ -111,6 +111,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
111
111
  `--` 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
112
112
  headless: `claude -p "/generate-code UC1 --yes"`.
113
113
 
114
+ > **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
115
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
116
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
117
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
118
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
119
+
114
120
  > **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: …*`
115
121
  > 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
116
122
  > **nghĩa là gì**.
@@ -80,7 +80,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
80
 
81
81
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
82
82
  |---|---|:---:|
83
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
83
+ | **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ó) |
84
84
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
85
85
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
86
86
 
@@ -88,6 +88,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
88
  `--` 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
89
89
  headless: `claude -p "/generate-code UC1 --yes"`.
90
90
 
91
+ > **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
92
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
93
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
94
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
95
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
96
+
91
97
  > **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: …*`
92
98
  > 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
93
99
  > **nghĩa là gì**.
@@ -283,7 +289,7 @@ Với mỗi SC mà regression test phủ (theo `@trace.verifies` của test vừ
283
289
  | `last_updated` | hôm nay `YYYY-MM-DD` |
284
290
 
285
291
  Giữ nguyên mọi cột khác. Đặc biệt:
286
- - **KHÔNG** đụng `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` — QC sở hữu; `/qc-run-test` sẽ flip khi re-verify (và chính nó đóng `{BUG-ID}` → `🟢 Closed`).
292
+ - **KHÔNG** đụng `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` — QC sở hữu; `/qc-run-script` sẽ flip khi re-verify (và chính nó đóng `{BUG-ID}` → `🟢 Closed`).
287
293
  - **KHÔNG** đụng `spec_ver`/`gen_ver` — fix bug **không** đổi spec, nên không được tạo tín hiệu DRIFT giả.
288
294
 
289
295
  Rồi làm mới panel mirror:
@@ -364,7 +370,7 @@ git push -u origin fix/{TICKET_ID}-{slug} # rồi mở PR vào branch đư
364
370
 
365
371
  Sau khi fix được commit, cập nhật `{paths.bug_reports_dir}/{BUG-ID}.md`:
366
372
  - Set `State` → `🟡 Fixed` và thêm một **Resolution** ngắn (root cause + link commit/PR).
367
- - Nó **chưa** `Closed` — QC sở hữu verification: khi `/qc-run-test` chạy lại và `qc_status`
373
+ - Nó **chưa** `Closed` — QC sở hữu verification: khi `/qc-run-script` chạy lại và `qc_status`
368
374
  của SC liên kết flip thành `pass`, nó thành `🟢 Closed` (và `qc_owner`/`qc_blocked_by` clear).
369
375
  - Commit report đã cập nhật vào spec repo (cùng push 2 tầng như `/report-bug`) để view
370
376
  "waiting-on" của PO/PM phản ánh nó trên `/sync`.
@@ -511,9 +517,9 @@ Root Cause: {analysis}
511
517
  Changes: {list}
512
518
  ✅ Regression test added | ✅ Build: SUCCESS
513
519
  {Trace: {UC-ID}-{platform}.tsv updated — test_count +{n}, dev_selftest → not_run | nếu có chạm row trace}
514
- {🐞 BUG-{id} → State: Fixed (pushed) — Closed sau khi /qc-run-test re-verify pass | nếu fix một bug đã file}
520
+ {🐞 BUG-{id} → State: Fixed (pushed) — Closed sau khi /qc-run-script re-verify pass | nếu fix một bug đã file}
515
521
  {📝 Lesson L-NNN recorded (nếu đã capture)}
516
522
  Branch: fix/{TICKET_ID}-{slug}
517
523
  Next: /dev-run-test {UC-ID} ← dev_selftest vừa bị reset về not_run, chạy để lấy lại tín hiệu xanh
518
- Rồi tạo PR và link tới ticket. {QC: chạy lại /qc-run-test {UC-ID} để verify + đóng bug | nếu áp dụng}
524
+ Rồi tạo PR và link tới ticket. {QC: chạy lại /qc-run-script {UC-ID} để verify + đóng bug | nếu áp dụng}
519
525
  ```
@@ -17,6 +17,8 @@
17
17
 
18
18
  *Checkpoint: **chặn CỨNG** — ghi đè architecture.md đã verified_by một người thật. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
19
19
 
20
+ *Mức cứng chỉ áp khi `architecture.md` **đã có** VÀ `verified_by` là `AI-draft`/trống. `verified_by: {người thật}` → **KHÔNG đè**, nhảy Bước 6 refresh có kiểm soát. File chưa có: đi thẳng.*
21
+
20
22
  # Gate — Quy trình vào chuẩn cho mọi lệnh
21
23
 
22
24
  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ó.
@@ -96,7 +98,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
96
98
 
97
99
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
98
100
  |---|---|:---:|
99
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
101
+ | **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ó) |
100
102
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
101
103
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
102
104
 
@@ -104,6 +106,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
104
106
  `--` 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
105
107
  headless: `claude -p "/generate-code UC1 --yes"`.
106
108
 
109
+ > **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
110
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
111
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
112
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
113
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
114
+
107
115
  > **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: …*`
108
116
  > 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
109
117
  > **nghĩa là gì**.
@@ -1,6 +1,11 @@
1
1
  # /generate-bdd — Sinh BDD Feature Files
2
2
 
3
3
  ## Gate
4
+
5
+ *Checkpoint: **chặn CỨNG** — ghi đè `.feature` đã có → mode **F** gen lại TOÀN BỘ scenario và ĐÁNH SỐ LẠI `sc_id`, mà sổ TSV, tag `@trace.verifies` trong code, và `.Test.md` đều đang trỏ vào những id đó. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
6
+
7
+ *Mức cứng chỉ áp khi Version Check chọn **`F`** (gen lại TOÀN BỘ scenario) — nhánh duy nhất đánh số lại `sc_id`. Chọn **`Y`** (cập nhật hẹp) không mất gì, đi thẳng; lần gen đầu cũng đi thẳng. Xem §Chạy lại.*
8
+
4
9
  # Gate — Quy trình vào chuẩn cho mọi lệnh
5
10
 
6
11
  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ó.
@@ -80,7 +85,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
85
 
81
86
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
82
87
  |---|---|:---:|
83
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
88
+ | **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ó) |
84
89
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
85
90
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
86
91
 
@@ -88,6 +93,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
93
  `--` 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
89
94
  headless: `claude -p "/generate-code UC1 --yes"`.
90
95
 
96
+ > **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
97
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
98
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
99
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
100
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
101
+
91
102
  > **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: …*`
92
103
  > 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
93
104
  > **nghĩa là gì**.
@@ -846,10 +857,10 @@ sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tde
846
857
  | `test_classes` | `—` |
847
858
  | `dev_selftest` | `—` (chưa chạy test) |
848
859
  | `dev_selftest_at` | `—` |
849
- | `qc_status` | `—` (kết quả QC automation chính thức — set bởi `/qc-run-test`) |
860
+ | `qc_status` | `—` (kết quả QC automation chính thức — set bởi `/qc-run-script` + `/qc-run-manualtest`) |
850
861
  | `qc_run_at` | `—` |
851
- | `qc_owner` | `—` (SC chưa pass đang chờ ai: `dev` / `po` — set bởi `/qc-run-test` + `/report-bug`) |
852
- | `qc_blocked_by` | `—` (`BUG-{id}` / `GAP-{id}` liên kết — set bởi `/qc-run-test` + `/report-bug`) |
862
+ | `qc_owner` | `—` (SC chưa pass đang chờ ai: `dev` / `po` — set bởi `/qc-run-script` + `/report-bug`) |
863
+ | `qc_blocked_by` | `—` (`BUG-{id}` / `GAP-{id}` liên kết — set bởi `/qc-run-script` + `/report-bug`) |
853
864
  | `prd_version` | `@trace.prd_version` từ header `.feature` |
854
865
  | `bdd_version` | `@trace.bdd_version` từ header `.feature` |
855
866
  | `tech_doc_revision` | `—` (revision tech-doc gộp `{TICKET-ID}-tech-design.md` — set bởi `/generate-code` + `/review-tech-docs`) |
@@ -920,6 +931,35 @@ bên trong từng sub-agent.
920
931
 
921
932
  ## Output
922
933
 
934
+ ## Chạy lại — `.feature` đã tồn tại *(mặc định GIỮ, chỉ `F` mới thay)*
935
+
936
+ Chạy lại trạm này là chuyện bình thường: PRD đổi thì BDD phải theo. Nhưng hai chế độ của Version
937
+ Check **khác hẳn nhau**, và chỉ một chế độ phá:
938
+
939
+ | Chế độ | Làm gì | Mất gì |
940
+ |---|---|---|
941
+ | **Y** — cập nhật hẹp | chỉ đụng scenario thuộc các row changelog mới hơn `@trace.prd_version` | **không mất gì** — `sc_id` cũ giữ nguyên |
942
+ | **F** — gen lại toàn bộ | sinh lại **mọi** scenario của UC | **ĐÁNH SỐ LẠI `sc_id`** |
943
+
944
+ **Trước khi thực thi `F`, in khối này và chờ xác nhận** *(mức chặn CỨNG — `--yes` không bỏ qua)*:
945
+
946
+ ```
947
+ ❌ Sắp gen lại TOÀN BỘ scenario: {feature-path}
948
+ Hiện: {n} scenario · @trace.bdd_version {v} · prd_version {pv}
949
+
950
+ Mode F đánh số lại sc_id từ SC1. Ba chỗ đang trỏ vào số cũ sẽ hỏng:
951
+ • sổ trace {UC-ID}-{platform}.tsv — mỗi row khớp theo sc_id
952
+ • tag @trace.verifies={UC-ID}-SC{N} trong code đã sinh
953
+ • TC_<FEATURE>.Test.md của làn QC — 🚫 Block và bảng phủ đều trỏ sc_id
954
+
955
+ Chỉ đổi phần PRD vừa sửa → chọn Y (cập nhật hẹp), không mất gì
956
+ PRD đã cắt changelog quá xa → F là đúng, nhưng chạy /validate-traces ngay sau để bắt lệch
957
+ Không chắc → Y trước; F luôn làm lại được, số cũ thì không
958
+ ```
959
+
960
+ > **Chọn `Y` thì KHÔNG in khối này và KHÔNG chặn** — cập nhật hẹp không làm mất gì, và hỏi lại
961
+ > một lựa chọn người dùng vừa đưa ra là cách nhanh nhất khiến `Y` thành phản xạ.
962
+
923
963
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
924
964
  Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
925
965
 
@@ -958,7 +998,7 @@ Next (umbrella):
958
998
  🔻 Tín hiệu kiểm thử bị hạ (spec vừa đổi — nghiệm thu cũ hết hiệu lực):
959
999
  {UC-ID}-SC2 dev_selftest pass→not_run · qc_status pass→not_run
960
1000
  ⚠️ {n} test của các SC này viết cho spec CŨ — rà lại nội dung, đừng chỉ chạy lại.
961
- → sau khi /generate-code: /dev-gen-test (rà test) → /dev-run-test → QC /qc-run-test
1001
+ → sau khi /generate-code: /dev-gen-test (rà test) → /dev-run-test → QC /qc-design-script
962
1002
  ℹ️ Coverage "đã kiểm đạt" sẽ TỤT trên dashboard — đó là số đúng; số cũ mới là số sai.
963
1003
  (Tỷ lệ phủ code/test KHÔNG đổi — test_count giữ nguyên vì test vẫn nằm trên đĩa.)
964
1004
 
@@ -1,6 +1,11 @@
1
1
  # /generate-code — Sinh Implementation Code
2
2
 
3
3
  ## Gate
4
+
5
+ *Checkpoint: **chặn CỨNG** — ghi đè mã nguồn đã có → XOÁ bản sửa tay của dev. Đây là artifact đắt nhất trong framework, và tới trước 2026-09-16 lệnh này vẫn ở mức `normal` — tức `--yes` ghi đè nó trong im lặng. `--yes` KHÔNG bỏ qua được (gate Bước 3a).*
6
+
7
+ *Mức cứng chỉ áp khi trạng thái là **`drifted`** hoặc **`synced`** — Bước 1 phân biệt qua sổ TSV. Trạng thái **`new`** đi thẳng, gồm cả ca headless `claude -p "/generate-code UC1 --yes"` mà `steps/gate.md` nêu làm ví dụ. Xem §Chạy lại.*
8
+
4
9
  # Gate — Quy trình vào chuẩn cho mọi lệnh
5
10
 
6
11
  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ó.
@@ -80,7 +85,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
85
 
81
86
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
82
87
  |---|---|:---:|
83
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
88
+ | **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ó) |
84
89
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
85
90
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
86
91
 
@@ -88,6 +93,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
93
  `--` 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
89
94
  headless: `claude -p "/generate-code UC1 --yes"`.
90
95
 
96
+ > **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
97
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
98
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
99
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
100
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
101
+
91
102
  > **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: …*`
92
103
  > 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
93
104
  > **nghĩa là gì**.
@@ -657,7 +668,7 @@ DTOs → Entity/Model → Repository → Service interface → Service impl →
657
668
 
658
669
  Mỗi element **có action** (button, input, link, select, toggle, form-submit) PHẢI mang một **test-id ổn định** để QC định vị trực tiếp (không scan runtime):
659
670
 
660
- 1. **Nguồn id — bảng §4.5.6 là HỢP ĐỒNG, không phải gợi ý.** Đọc **§4.5.6 Test Selectors** cho platform này ở tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`, lọc theo cột "Phục vụ SC" khớp SC của UC này, rồi lấy id **nguyên văn**. Bảng do `/map-testids` ghi ở phase Tech Design — **trước** lệnh này.
671
+ 1. **Nguồn id — bảng §4.5.6 là HỢP ĐỒNG, không phải gợi ý.** Đọc **§4.5.6 Test Selectors** cho platform này ở tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`, lọc theo cột "Serves SC" khớp SC của UC này, rồi lấy id **nguyên văn**. Bảng do `/map-testids` ghi ở phase Tech Design — **trước** lệnh này.
661
672
 
662
673
  **Bảng rỗng hoặc không có row nào cho SC của UC này** → *không tự sinh id rồi đi tiếp*. Cảnh báo rồi **để người quyết**:
663
674
 
@@ -679,7 +690,7 @@ Mỗi element **có action** (button, input, link, select, toggle, form-submit)
679
690
  - **`--yes` (headless)** → coi như **Y**, nhưng dòng cảnh báo ở report là **bắt buộc**. Không được im lặng: `lint-trace --code` T18 là lưới bắt phía sau, và nó chỉ có nghĩa khi người ta biết có gì để tìm.
680
691
 
681
692
  > **Vì sao hỏi chứ không tự sinh như trước.** Tự sinh rồi *"đối chiếu lúc integration"* nghe hợp lý nhưng thực tế là **code quyết định hợp đồng**: QC đọc §4.5.6 thấy rỗng nên đi dò DOM, còn FE đã gắn một bộ id không ai biết. Đến lúc đối chiếu thì cả hai bên đều đã làm xong theo hai hướng khác nhau. Hỏi ở đây là đặt quyết định đó vào tay người, **đúng lúc nó còn rẻ**.
682
- 2. **TÊN THUỘC TÍNH: đọc `@trace.testid_attr` từ header tech-doc gộp — KHÔNG tự suy từ module.** Đây là **nửa FE của contract FE↔QC**: `/qc-run-test` đọc **chính field này** để cấu hình locator, và `bin/trace-schema.json` khai `artifact: tech-design.md` (`written_by: map-testids`). Hai bên phải đọc **cùng một bản** — nếu FE suy từ module còn QC đọc tech-doc thì FE gắn một kiểu, QC tìm một kiểu, và **không trùng một element nào**.
693
+ 2. **TÊN THUỘC TÍNH: đọc `@trace.testid_attr` từ header tech-doc gộp — KHÔNG tự suy từ module.** Đây là **nửa FE của contract FE↔QC**: `/qc-design-script` đọc **chính field này** để cấu hình locator, và `bin/trace-schema.json` khai `artifact: tech-design.md` (`written_by: map-testids`). Hai bên phải đọc **cùng một bản** — nếu FE suy từ module còn QC đọc tech-doc thì FE gắn một kiểu, QC tìm một kiểu, và **không trùng một element nào**.
683
694
 
684
695
  | Đọc được gì | Làm gì |
685
696
  |---|---|
@@ -687,7 +698,7 @@ Mỗi element **có action** (button, input, link, select, toggle, form-submit)
687
698
  | **Không tìm thấy field** | **Cảnh báo mềm, KHÔNG im lặng hardcode** (khối dưới), rồi mới fallback theo `active_module` |
688
699
  | Header `.feature` cũng khai và **LỆCH** với tech-doc | Ưu tiên tech-doc, nhưng **in cả hai giá trị** — không im lặng chọn một bên. `.feature` là lối cũ, chỉ còn cho stack lai |
689
700
 
690
- Cảnh báo khi thiếu field (cùng khuôn `/qc-run-test` dùng, để hai nửa của contract nói cùng một giọng):
701
+ Cảnh báo khi thiếu field (cùng khuôn `/qc-design-script` dùng, để hai nửa của contract nói cùng một giọng):
691
702
  ```
692
703
  ⚠️ Tech-doc thiếu @trace.testid_attr — fallback theo module ({attr mặc định}).
693
704
  Nếu FE dùng thuộc tính khác thì MỌI locator của QC sẽ trượt, và test sẽ đỏ với
@@ -840,7 +851,7 @@ Bất kể trường hợp nào, in khối này ở report cuối để dev khô
840
851
  🔻 Tín hiệu kiểm thử bị hạ ({spec vừa đổi | vừa lấp stub} — nghiệm thu cũ hết hiệu lực):
841
852
  {sc_id}: dev_selftest pass→not_run · qc_status pass→not_run
842
853
  ⚠️ {n} test của các SC này viết cho bản cũ — rà lại nội dung, đừng chỉ chạy lại.
843
- → /dev-run-test {UC-ID} rồi QC chạy /qc-run-test {UC-ID}
854
+ → /dev-run-test {UC-ID} rồi QC chạy /qc-run-script {UC-ID}
844
855
  ℹ️ Coverage "đã kiểm đạt" trên dashboard sẽ TỤT sau lần này — đó là số đúng;
845
856
  số cũ mới là số sai. (Tỷ lệ phủ code/test không đổi — test_count giữ nguyên.)
846
857
  ```
@@ -938,6 +949,34 @@ git commit -m "{commit_format}: {description}"
938
949
 
939
950
  ## Output
940
951
 
952
+ ## Chạy lại — code của UC đã tồn tại *(GIỮ bản sửa tay, chỉ đụng phần drift)*
953
+
954
+ Đây là artifact đắt nhất trong framework, và tới trước 2026-09-16 lệnh này vẫn ở mức `normal` —
955
+ tức `--yes` ghi đè mã nguồn dev đã sửa tay **trong im lặng**.
956
+
957
+ Khác ba lệnh `hard` cùng nhóm, lệnh này **không có điểm hỏi nào khác**: Bước 1 tự phân biệt
958
+ `new` / `drifted` / `synced` qua sổ TSV rồi đi tiếp. Nên CHECKPOINT là chỗ dừng duy nhất.
959
+
960
+ **Khi trạng thái là `drifted` hoặc `synced`, in khối này** *(mức chặn CỨNG)*:
961
+
962
+ ```
963
+ ❌ Code của {UC-ID} đã tồn tại — trạng thái: {drifted|synced}
964
+ File: {danh sách file mang @trace.implements của UC này}
965
+ Sổ trace: gen_version {gv} · spec_version {sv} · test_count {tc}
966
+
967
+ Sinh lại ghi đè cả phần dev đã sửa tay. Thường mất:
968
+ • xử lý edge-case thêm sau khi /dev-run-test báo đỏ
969
+ • mock/fixture chỉnh tay (chính /dev-run-test hướng dẫn làm)
970
+ • bản vá từ /fix-bug — kèm @trace.fixes / @trace.root_cause
971
+
972
+ Chỉ sửa một lỗi cụ thể → /fix-bug {TICKET_ID} (sửa ĐIỂM, trên nhánh riêng)
973
+ Spec đổi, muốn áp phần đổi → tiếp tục, rồi /dev-run-test ngay để bắt hồi quy
974
+ Muốn xem lệch chỗ nào trước → /validate-traces --prd {domain}/{prd-slug}
975
+ ```
976
+
977
+ > **Trạng thái `new` (chưa có code) đi thẳng, không chặn** — đây là ca headless mà
978
+ > `steps/gate.md` nêu làm ví dụ (`claude -p "/generate-code UC1 --yes"`), và nó không đổi.
979
+
941
980
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
942
981
  Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
943
982
 
@@ -80,7 +80,7 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
80
 
81
81
  | Mức | Lệnh nào | `--yes` bỏ qua được? |
82
82
  |---|---|:---:|
83
- | **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
83
+ | **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ó) |
84
84
  | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
85
85
  | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
86
86
 
@@ -88,6 +88,12 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
88
88
  `--` 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
89
89
  headless: `claude -p "/generate-code UC1 --yes"`.
90
90
 
91
+ > **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
92
+ > tên lệnh sẽ bị đối chiếu với `gate.checkpoint_levels`; lệch là build đỏ. Lý do có rule này:
93
+ > ngày 2026-09-16 hai lệnh đổi mức, schema và `commands/*.tmpl` đều sửa, **build vẫn xanh**,
94
+ > mà bảng này lẫn `rules/workflow.md` đều còn liệt chúng ở mức cũ. `R11` chỉ canh
95
+ > `commands/*.tmpl` ↔ schema — *biết có máy canh không bằng biết máy canh **đến đâu***.
96
+
91
97
  > **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: …*`
92
98
  > 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
93
99
  > **nghĩa là gì**.