@educa-corp/sdd-framework 0.4.2 → 0.6.0

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 (149) hide show
  1. package/bin/build.js +113 -19
  2. package/bin/gate-trace.js +464 -0
  3. package/bin/index.js +418 -146
  4. package/bin/lint-trace.js +602 -0
  5. package/bin/self-check.js +499 -6
  6. package/bin/trace-schema.json +1449 -692
  7. package/commands/debug.md +123 -510
  8. package/commands/debug.tmpl +3 -0
  9. package/commands/define-product.md +86 -509
  10. package/commands/dev-gen-test.md +120 -516
  11. package/commands/dev-run-test.md +120 -516
  12. package/commands/dev-smoke-test.md +86 -509
  13. package/commands/extend-prd.md +486 -0
  14. package/commands/extend-prd.tmpl +273 -0
  15. package/commands/fix-bug.md +152 -515
  16. package/commands/generate-architecture.md +94 -514
  17. package/commands/generate-architecture.tmpl +3 -0
  18. package/commands/generate-bdd.md +138 -519
  19. package/commands/generate-bdd.tmpl +18 -3
  20. package/commands/generate-code.md +156 -523
  21. package/commands/generate-code.tmpl +36 -7
  22. package/commands/generate-design-spec.md +86 -509
  23. package/commands/generate-prd.md +114 -509
  24. package/commands/generate-prd.tmpl +28 -0
  25. package/commands/generate-spec-manifest.md +86 -509
  26. package/commands/generate-tech-docs.md +86 -509
  27. package/commands/learn.md +172 -495
  28. package/commands/learn.tmpl +70 -3
  29. package/commands/map-testids.md +86 -509
  30. package/commands/propose-scenario.md +136 -508
  31. package/commands/propose-scenario.tmpl +52 -1
  32. package/commands/qc-analyze.md +86 -509
  33. package/commands/qc-design-test.md +87 -509
  34. package/commands/qc-design-test.tmpl +1 -0
  35. package/commands/qc-plan.md +86 -509
  36. package/commands/qc-report.md +86 -509
  37. package/commands/qc-review.md +86 -509
  38. package/commands/qc-run-test.md +133 -517
  39. package/commands/qc-run-test.tmpl +13 -1
  40. package/commands/refine-prd.md +99 -519
  41. package/commands/refine-prd.tmpl +3 -0
  42. package/commands/report-bug.md +86 -509
  43. package/commands/review-code.md +127 -513
  44. package/commands/review-code.tmpl +7 -3
  45. package/commands/review-context.md +96 -515
  46. package/commands/review-context.tmpl +6 -2
  47. package/commands/review-tech-docs.md +90 -510
  48. package/commands/review-tech-docs.tmpl +3 -0
  49. package/commands/setup-ai-first.md +166 -137
  50. package/commands/setup-ai-first.tmpl +72 -0
  51. package/commands/sync.md +86 -118
  52. package/commands/sync.tmpl +84 -16
  53. package/commands/update-framework.md +16 -102
  54. package/commands/update-framework.tmpl +14 -0
  55. package/commands/validate-traces.md +458 -531
  56. package/commands/validate-traces.tmpl +381 -31
  57. package/core/FRAMEWORK_VERSION +1 -1
  58. package/core/README.md +20 -0
  59. package/core/commands/debug.md +123 -510
  60. package/core/commands/define-product.md +86 -509
  61. package/core/commands/dev-gen-test.md +120 -516
  62. package/core/commands/dev-run-test.md +120 -516
  63. package/core/commands/dev-smoke-test.md +86 -509
  64. package/core/commands/extend-prd.md +486 -0
  65. package/core/commands/fix-bug.md +152 -515
  66. package/core/commands/generate-architecture.md +94 -514
  67. package/core/commands/generate-bdd.md +138 -519
  68. package/core/commands/generate-code.md +156 -523
  69. package/core/commands/generate-design-spec.md +86 -509
  70. package/core/commands/generate-prd.md +114 -509
  71. package/core/commands/generate-spec-manifest.md +86 -509
  72. package/core/commands/generate-tech-docs.md +86 -509
  73. package/core/commands/learn.md +172 -495
  74. package/core/commands/map-testids.md +86 -509
  75. package/core/commands/propose-scenario.md +136 -508
  76. package/core/commands/qc-analyze.md +86 -509
  77. package/core/commands/qc-design-test.md +87 -509
  78. package/core/commands/qc-plan.md +86 -509
  79. package/core/commands/qc-report.md +86 -509
  80. package/core/commands/qc-review.md +86 -509
  81. package/core/commands/qc-run-test.md +133 -517
  82. package/core/commands/refine-prd.md +99 -519
  83. package/core/commands/report-bug.md +86 -509
  84. package/core/commands/review-code.md +127 -513
  85. package/core/commands/review-context.md +96 -515
  86. package/core/commands/review-tech-docs.md +90 -510
  87. package/core/commands/setup-ai-first.md +166 -137
  88. package/core/commands/sync.md +86 -118
  89. package/core/commands/update-framework.md +16 -102
  90. package/core/commands/validate-traces.md +458 -531
  91. package/core/hooks/data-guard.js +174 -83
  92. package/core/hooks/settings.json +2 -1
  93. package/core/rules/workflow.md +48 -4
  94. package/core/steps/capture-lesson.md +34 -1
  95. package/core/steps/context-loader.md +24 -3
  96. package/core/steps/gate.md +92 -35
  97. package/core/steps/report-footer.md +26 -2
  98. package/core/steps/trace-mirror.md +34 -7
  99. package/core/templates/README.md +24 -1
  100. package/core/templates/ci/trace-gate.yml +146 -0
  101. package/core/templates/feature.template +1 -1
  102. package/core/templates/hooks/pre-push +61 -0
  103. package/docs/01-getting-started/installation.md +18 -1
  104. package/docs/01-getting-started/what-is-sdd.md +4 -2
  105. package/docs/02-concepts/architecture.md +48 -5
  106. package/docs/02-concepts/pipeline-steps/02-specification.md +39 -3
  107. package/docs/02-concepts/pipeline-steps/04-bdd.md +24 -2
  108. package/docs/02-concepts/pipeline-steps/05-tech-docs.md +18 -1
  109. package/docs/02-concepts/pipeline-steps/06-code.md +35 -4
  110. package/docs/02-concepts/pipeline-steps/09-validate-traces.md +137 -12
  111. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +59 -3
  112. package/docs/02-concepts/roles-and-hitl.md +1 -1
  113. package/docs/02-concepts/traceability.md +183 -117
  114. package/docs/03-guides/architect.md +63 -0
  115. package/docs/03-guides/developer.md +20 -4
  116. package/docs/03-guides/product-owner.md +72 -68
  117. package/docs/03-guides/tester-qa.md +81 -70
  118. package/docs/04-reference/commands.md +134 -105
  119. package/docs/04-reference/configuration.md +146 -94
  120. package/docs/04-reference/model-selection.md +32 -19
  121. package/docs/04-reference/trace-schema.md +26 -9
  122. package/docs/explain/02-generate-prd.md +80 -78
  123. package/docs/explain/02b-extend-prd.md +125 -0
  124. package/docs/explain/03-refine-prd.md +86 -86
  125. package/docs/explain/04-review-context.md +18 -1
  126. package/docs/explain/06-generate-bdd.md +23 -0
  127. package/docs/explain/08-review-tech-docs.md +20 -5
  128. package/docs/explain/10-review-code.md +36 -2
  129. package/docs/explain/19-qc-run-test.md +87 -67
  130. package/docs/explain/21-validate-traces.md +75 -68
  131. package/docs/explain/23-fix-bug.md +19 -3
  132. package/docs/explain/26-propose-scenario.md +70 -63
  133. package/docs/explain/27-learn.md +5 -3
  134. package/docs/explain/README.md +135 -134
  135. package/hooks/data-guard.js +174 -83
  136. package/hooks/settings.json +2 -1
  137. package/package.json +53 -50
  138. package/rules/workflow.md +48 -4
  139. package/steps/capture-lesson.md +34 -1
  140. package/steps/context-loader.md +24 -3
  141. package/steps/gate.md +92 -35
  142. package/steps/report-footer.md +26 -2
  143. package/steps/trace-mirror.md +34 -7
  144. package/templates/README.md +24 -1
  145. package/templates/ci/trace-gate.yml +146 -0
  146. package/templates/feature.template +1 -1
  147. package/templates/hooks/pre-push +61 -0
  148. package/scripts/init.sh +0 -49
  149. package/scripts/upgrade.sh +0 -94
@@ -4,6 +4,9 @@
4
4
  **Dùng `--resume` để áp dụng các finding được chấp nhận.**
5
5
 
6
6
  ## Gate
7
+
8
+ *Checkpoint: **không chặn** — read-only (ghi findings vào .agent/review/). Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
9
+
7
10
  {{include:steps/gate.md}}
8
11
 
9
12
  *Lưu ý: Với lệnh này, target ở Bước 1 là **file tech-design gộp của PRD** `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` — MỘT doc full-stack phủ mọi UC của PRD (không còn per-UC / per-platform). Review chạy trên cả doc; findings gom theo từng UC (đọc §10 UC Coverage để biết finding thuộc UC nào).
@@ -22,35 +22,31 @@ Trước tiên, kiểm tra xem `$ARGUMENTS` có phải là payload JSON từ m
22
22
  - Đi thẳng tới phần logic riêng của lệnh.
23
23
  3. Nếu `$ARGUMENTS` không phải JSON hoặc không có `_agent_mode` → tiếp tục sang Bước 1 (chế độ thường).
24
24
 
25
- ## Bước 0-B — Kiểm tra Model
25
+ ## Bước 0-B — Ghi nhận Model *(KHÔNG chặn)*
26
26
 
27
- *Bỏ qua bước này nếu `_agent_mode: true` (sub-agent — orchestrator đã kiểm tra rồi).*
27
+ *Bỏ qua nếu `_agent_mode: true` (sub-agent — orchestrator đã ghi nhận rồi).*
28
28
 
29
- Các lệnh sinh nội dung review phức tạp đòi hỏi khả năng suy luận mạnh.
30
- Dùng model nhỏ hơn sẽ rủi ro: bỏ sót edge case, phân tích spec thiếu sót, vi phạm kiến trúc.
29
+ Ghi lại **model bạn agent đang chạy lệnh này thực sự đang dùng**, rồi mang nó vào
30
+ dòng `Model:` của report cuối (xem `report-footer`). Nếu bạn biết mình **không** phải một
31
+ model Opus, gắn thêm cảnh báo ngay ở dòng đó.
31
32
 
32
- Hiển thị chờ phản hồi:
33
+ **KHÔNG hỏi người dùng. KHÔNG chờ. KHÔNG dừng.**
33
34
 
34
- ```
35
- ⚙️ MODEL CHECK
36
- ──────────────────────────────────────────────────────────────────
37
- Recommended : model Opus mới nhất
38
- Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
39
- suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
40
-
41
- Cách đổi trong Claude Code:
42
- /model chọn model Opus
43
- • hoặc: Settings → Model
44
-
45
- Đang chạy một model Opus?
46
- Y — đúng → tiếp tục
47
- S — bỏ qua kiểm tra (tôi chấp nhận rủi ro chất lượng thấp hơn với model hiện tại)
48
- ──────────────────────────────────────────────────────────────────
49
- ```
35
+ > **Vì sao bước này từng là prompt chặn, và vì sao bỏ (GAPS-v3 G41):** bản cũ hiện khối
36
+ > `⚙️ MODEL CHECK` rồi chờ `Y/S/N`. Ba vấn đề cùng chỉ một hướng:
37
+ > **(1)** nó hỏi người dùng thứ mà **agent đã biết chính xác**;
38
+ > **(2)** câu trả lời **không kiểm chứng được** — gõ `Y` xong vẫn đang chạy Haiku thì không
39
+ > phát hiện;
40
+ > **(3)** **cả `Y` lẫn `S` đều đi tiếp** cách duy nhất để nó dừng là tự nguyện gõ `N`.
41
+ > Tức nó **không chặn được ai**, mà tốn một lần chặn ở **mọi** lệnh. Một feature đi hết
42
+ > pipeline dùng 20 lệnh; 30/32 lệnh chạy gate. Hai mươi lần bấm cho một tín hiệu tự-khai
43
+ > không kiểm chứng được — và chính cái giá đó làm mòn CHECKPOINT ở Bước 3, cổng có giá trị thật.
44
+ >
45
+ > Khai báo trong report **mạnh hơn** hỏi: đúng nguồn (agent, không phải người), và nằm
46
+ > **cạnh kết quả** để cân nhắc, thay vì nằm trước khi có kết quả để bấm cho xong.
50
47
 
51
- - "Y" tiếp tục sang Bước 1.
52
- - "S" tiếp tục sang Bước 1 (người dùng chấp nhận rủi ro, thêm ⚠️ vào report cuối).
53
- - "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang một model Opus (`/model`) rồi chạy lại lệnh này."
48
+ **Vẫn khuyến nghị Opus:** phân tích spec, review kiến trúc và sinh code đòi hỏi suy luận sâu;
49
+ model nhỏ hơn dễ bỏ sót edge case vi phạm kiến trúc. Đổi: `/model` chọn Opus.
54
50
 
55
51
  ## Bước 1 — Xác định Target File
56
52
 
@@ -80,23 +76,84 @@ Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phi
80
76
 
81
77
  ## Bước 3 — CHECKPOINT
82
78
 
83
- Sau khi hoàn thành Bước 1 và 2, hiển thị bản tóm tắt và chờ xác nhận:
79
+ *Bỏ qua nếu `_agent_mode: true`.*
80
+
81
+ ### 3a — Lệnh này có phải chặn không?
82
+
83
+ | Mức | Lệnh nào | `--yes` bỏ qua được? |
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ó) |
86
+ | **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
87
+ | **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
88
+
89
+ `--yes` trong `$ARGUMENTS` → bỏ qua CHECKPOINT mức *chặn thường*. (Bước 1 đã tách mọi token
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
+ headless: `claude -p "/generate-code UC1 --yes"`.
92
+
93
+ > **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
+ > 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
+ > **nghĩa là gì**.
96
+ > Nguồn máy đọc: `bin/trace-schema.json` → `gate.checkpoint_levels`; `self-check` **R11** fail
97
+ > build nếu nhãn trong file lệnh lệch với schema, hoặc nếu một lệnh `hard`/`none` thiếu nhãn.
98
+ > *(Lệnh không có dòng nào = mức **chặn thường**, mặc định.)*
99
+
100
+ > **Mức *không chặn* là thực thi đúng miễn trừ mà `rules/workflow.md` đã cấp từ trước** —
101
+ > trước G41 file đó viết *"read-only commands may skip CHECKPOINT"* còn gate thì luôn đòi.
102
+ > Hai file cùng được nạp vào mọi lệnh mà nói ngược nhau; agent theo cái nào là tuỳ lúc.
103
+
104
+ ### 3b — In gì
105
+
106
+ **KHÔNG lặp lại những gì `[CTX LOADED]` vừa in.** Recap của context-loader (Bước 7) đã hiện
107
+ Stack · Platform · Layers · CLAUDE.md · Dict · Entities · Lessons · Service · Status ngay phía
108
+ trên. CHECKPOINT chỉ thêm **một** thông tin mới là `Target`.
109
+
110
+ **Mọi thứ sạch** — recap báo `Status: FULL`, không cờ nào bật → in đúng hai dòng:
84
111
 
85
112
  ```
86
- CHECKPOINT
87
- -----------
88
- Target : {resolved file path}
89
- Project : {project.name từ project-context.yaml}
90
- Tech stack : {language} / {framework}
91
- Module : {module nếu có, else "not configured"}
92
- Domains : {danh sách domain, ngăn cách bởi dấu phẩy}
113
+ CHECKPOINT — Target: {resolved file path}
114
+ Tiếp tục? (Y/N)
115
+ ```
93
116
 
117
+ **Có bất thường** → thêm một dòng cho **mỗi** trạng thái, nặng nhất lên đầu:
118
+
119
+ ```
120
+ CHECKPOINT
121
+ 🔴 Service : unresolved — {lý do context-loader đã ghi}
122
+ ⚠️ CLAUDE.md: service overlay THIẾU — dùng root (code sinh ra có thể sai stack)
123
+ ⚠️ Target : resolve bằng wildcard — {n} file khớp, chọn {file}
124
+ ⚠️ Module : not configured — code sinh ra sẽ dùng default
125
+ Status : PARTIAL — thiếu: {danh sách}
126
+ Target : {resolved file path}
94
127
  Tiếp tục? (Y/N)
95
128
  ```
96
129
 
97
- Chờ người dùng trả lời ràng "Y" hoặc "N" rồi mới tiếp tục.
98
- - "Y" → tiếp tục sang các bước riêng của lệnh bên dưới.
99
- - "N" dừng lại hỏi người dùng muốn thay đổi gì.
130
+ ### 3c Cờ nào bật, cờ nào KHÔNG
131
+
132
+ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader đã tính rồi** — không phát minh
133
+ điều kiện mới, chỉ mang thứ đang bị giấu lên chỗ người dùng phải quyết định:
134
+
135
+ | Bật cờ khi | Nguồn | Mức |
136
+ |---|---|:---:|
137
+ | `active_service = unresolved` | context-loader Bước 2b/2c/Fallback | 🔴 |
138
+ | `Status = MINIMAL` | recap Bước 7 | 🔴 |
139
+ | `Status = PARTIAL` | recap Bước 7 | ⚠️ |
140
+ | CLAUDE.md thiếu, hoặc service overlay thiếu | context-loader Bước 3 | ⚠️ |
141
+ | Target resolve qua wildcard, hoặc nhiều file khớp mà lệnh tự chọn | Bước 1 ở trên | ⚠️ |
142
+ | `module` không cấu hình | recap Bước 7 | ⚠️ |
143
+
144
+ **KHÔNG bật cờ cho:** `Lessons: chưa có` · `Dict: missing` · `Entities: missing`. Đó là
145
+ *"dự án chưa điền"*, không phải *"có gì đó sai"* — chúng ở lại trong recap.
146
+
147
+ > **Nguyên tắc một câu:** cờ dành cho thứ **framework không chắc chắn hoặc đã phải đoán**,
148
+ > không dành cho thứ **người dùng chưa làm**. Đẩy hết mọi thứ lên thì CHECKPOINT lại đầy như
149
+ > cũ, và ta quay về đúng chỗ xuất phát: một cổng luôn giống nhau thì bị lướt qua.
150
+
151
+ ### 3d — Chờ trả lời
152
+
153
+ - "Y" → tiếp tục sang các bước riêng của lệnh.
154
+ - "N" → dừng, hỏi người dùng muốn thay đổi gì.
155
+ - Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
156
+ 🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
100
157
 
101
158
 
102
159
  *Lưu ý: Với lệnh này — **bỏ qua Gate Step 1, 2, và 3** (chưa có file input và chưa có project context). Chỉ chạy Step 0-B (model check). Project root là **thư mục làm việc hiện tại**. Đi thẳng tới Precondition Check bên dưới.*
@@ -207,6 +264,34 @@ specs/{domain}/{prd-slug}/
207
264
  | **2 — Umbrella** | Chỉ `.trace/` + `.agent/review/` (ở umbrella root) | Mọi thứ khác — **toàn bộ spec sống trong spec submodule (`spec_source`)** dưới `specs/{domain}/{prd-slug}/`; service submodule chỉ chứa **code + `.trace/`** |
208
265
  | **3 — PO Spec repo** | `specs/product-definition/`, `specs/domain-knowledge/`, **`feedback/`**, `.agent/review/` (folder `specs/{domain}/{prd-slug}/` theo feature tạo on demand) | `.trace/` (theo service, sống cạnh code trong mỗi service submodule) |
209
266
 
267
+ ### Step 1b — Luật merge cho sổ trace *(mọi project_type có tạo `.trace/`)*
268
+
269
+ Ngay khi tạo `.trace/`, tạo luôn `.trace/.gitattributes`:
270
+
271
+ ```gitattributes
272
+ # Sổ trace — dữ liệu KHÔNG regenerate được. Hai luật, hai lý do khác nhau:
273
+ #
274
+ # merge=union — giữ row của CẢ HAI nhánh thay vì bắt người chọn một bên. Trùng sc_id sau
275
+ # union là ca ĐÚNG VÀ ĐƯỢC MONG ĐỢI: `--lint-trace` T4 bắt nó, rồi /validate-traces
276
+ # reconcile về một row. Mất row thì KHÔNG có gì bắt được. Đánh đổi có chủ ý — đừng "dọn".
277
+ # (union là driver built-in của git: không ai cần chạy git config gì thêm.)
278
+ #
279
+ # text eol=lf — BẮT BUỘC đi kèm union. Thiếu nó: một máy ghi CRLF → git thấy MỌI dòng đã
280
+ # đổi → union giữ cả hai bản → NHÂN ĐÔI CẢ FILE, gồm cả dòng header.
281
+ #
282
+ # KHÔNG thêm *.json — trace-report.json nằm cùng thư mục và union trên JSON tạo ra JSON
283
+ # không hợp lệ. Nó sinh lại được: conflict thì chạy lại /validate-traces.
284
+ *.tsv text eol=lf merge=union
285
+ *.jsonl text eol=lf merge=union
286
+ ```
287
+
288
+ **Vì sao làm ở đây, ngay lúc tạo thư mục:** sổ trace phải commit và được nhiều người ghi trên
289
+ nhiều nhánh song song. Không có luật này, lần merge song song đầu tiên sẽ conflict — và giải
290
+ conflict bằng "take mine" là **mất row của người kia, im lặng**. Đây là ca **chắc chắn xảy ra**
291
+ với team ≥3 người và không cần ai làm sai gì cả.
292
+
293
+ *Project đã cài từ trước → `/sync` Step 4c kiểm và tạo hộ.*
294
+
210
295
  ## Step 2 — Tạo CLAUDE.md
211
296
 
212
297
  *Bỏ qua hoàn toàn step này nếu `project_type = 2` (Umbrella) — umbrella không có một tech stack đơn.*
@@ -375,6 +460,50 @@ Hoặc: VS Code → `Ctrl+Shift+P` → **"Extensions: Install from Marketplace"*
375
460
  - 📋 **Review Board** — UI trực quan để review findings từ `/refine-prd`, `/review-context`, `/review-tech-docs`
376
461
  - 📊 **Living Documentation** — dashboard traceability dựa trên `.trace/*.tsv`
377
462
 
463
+ ## Step 6b — Cổng chặn bằng máy (Khuyến nghị mạnh)
464
+
465
+ *Skip nếu `project_type = 3` (PO Spec repo) — không có code thì không có PR cần chặn.*
466
+
467
+ Framework phát hiện được một lớp lỗi mà **build xanh + test từng-UC xanh KHÔNG thấy**: luồng
468
+ ghép chạy vào hàm rỗng (`SEAM_UNWIRED`, `STUB_UNRESOLVED`), hoặc code trỏ vào scenario đã bị
469
+ xoá (`ORPHANED`, `TRACE_ORPHAN`). Nhưng nếu việc phát hiện đó phụ thuộc vào **có người tự
470
+ nguyện chạy `/validate-traces` rồi đọc report bằng mắt**, thì sau sprint thứ ba không ai làm.
471
+
472
+ Hai file mẫu đã có sẵn. Hỏi user muốn cài cái nào:
473
+
474
+ ```
475
+ Cài cổng chặn bằng máy? (khuyến nghị cả hai)
476
+ 1. pre-push hook — chặn push khi sổ trace hỏng cấu trúc. Rẻ, 2 giây, offline được.
477
+ Bắt được marker conflict git trước khi nó vào nhánh chung.
478
+ 2. CI workflow — chặn PR khi có cờ 🔴. Cần GitHub Actions.
479
+ 3. Cả hai (khuyến nghị)
480
+ 4. Bỏ qua, cài sau
481
+ ```
482
+
483
+ **Chọn 1 hoặc 3** — copy hook rồi cấp quyền chạy:
484
+ ```bash
485
+ cp .agent/templates/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
486
+ ```
487
+ *Nếu `trace_dir` của project không phải `.trace` (vd `../.trace` hay `{spec_source}/.trace`) →
488
+ mở file vừa copy và sửa biến `TRACE_DIR` ở đầu file cho khớp.*
489
+
490
+ **Chọn 2 hoặc 3** — copy workflow:
491
+ ```bash
492
+ mkdir -p .github/workflows && cp .agent/templates/ci/trace-gate.yml .github/workflows/
493
+ ```
494
+ *Rồi mở nó ra: sửa `src/**` ở job `require-fresh-audit` cho khớp layout project, và bỏ comment
495
+ `submodules: recursive` nếu spec/trace nằm trong submodule.*
496
+
497
+ > **Phải COPY RA khỏi `.agent/`** — `.agent/` bị ghi đè mỗi lần `/update-framework`, và
498
+ > `.git/hooks/` thì git không chạy từ chỗ khác. Copy ra rồi thì chúng là file của project.
499
+
500
+ Kiểm ngay sau khi cài (chưa có sổ trace thì cả hai thoát sạch, không phải lỗi):
501
+ ```bash
502
+ npx @educa-corp/sdd-framework --lint-trace
503
+ ```
504
+
505
+ Chi tiết + giới hạn của cổng → `docs/03-guides/architect.md` §Cắm vào CI.
506
+
378
507
  ## Step 7 — Verify
379
508
 
380
509
  Checklist tuỳ theo `project_type`:
@@ -410,108 +539,8 @@ Checklist tuỳ theo `project_type`:
410
539
 
411
540
  ## Output
412
541
 
413
- # Report Footer Định dạng output chuẩn cho mọi lệnh
414
-
415
- Mọi report của lệnh phải kết thúc bằng section footer chuẩn này.
416
-
417
- ## Status Badge
418
-
419
- Chọn một theo kết quả:
420
- - `✅ Complete` — mọi bước thành công, không có vấn đề
421
- - `❌ Failed` — lệnh không hoàn thành được do lỗi chặn
422
- - `⚠️ Warnings` — hoàn thành nhưng có vấn đề không chặn, nên review lại
423
-
424
- ## Output Artifacts
425
-
426
- Liệt kê mọi file được tạo hoặc sửa bởi lệnh này:
427
- ```
428
- Output Artifacts:
429
- {created|updated} {file-path} ({mô tả ngắn})
430
- {created|updated} {file-path} ({mô tả ngắn})
431
- ```
432
-
433
- Nếu không ghi file nào (vd: lệnh review hoặc phân tích) → ghi `Output Artifacts: none (read-only)`.
434
-
435
- ## Pipeline Position
436
-
437
- In một sơ đồ pipeline một dòng, đánh dấu phase của lệnh HIỆN TẠI bằng `◀ bạn ở đây`,
438
- để người dùng luôn thấy lệnh này nằm ở đâu trong luồng end-to-end:
439
-
440
- ```
441
- Discovery → PRD → [Design Spec] → BDD → Tech Design → Code → Dev Self-Check → QC → Trace Audit
442
- ```
443
-
444
- Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **phase của nó** trong sơ đồ trên:
445
-
446
- | Phase | Commands |
447
- |-------|----------|
448
- | Discovery | `/define-product` |
449
- | PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
450
- | Design Spec | `/generate-design-spec` |
451
- | BDD | `/generate-bdd` · `/review-context` (BDD) |
452
- | Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
453
- | Code | `/generate-code` · `/review-code` |
454
- | Dev Self-Check | `/dev-gen-test` · `/dev-run-test` · `/dev-smoke-test` |
455
- | QC | `/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review` · `/qc-run-test` · `/qc-report` |
456
- | Trace Audit | `/validate-traces` |
457
-
458
- Với **lệnh review**, thêm vòng review 3 bước và đánh dấu bước hiện tại, vd:
459
- `Vòng review: [① phân tích ◀] → ② Review Board → ③ --resume`.
460
-
461
- **Lệnh xuyên suốt** (`/sync`, `/update-framework`, `/fix-bug`, `/debug`, `/learn`,
462
- `/report-bug`, `/propose-scenario`, `/generate-spec-manifest`) nằm ngoài pipeline tuyến tính —
463
- **bỏ hẳn dòng Pipeline** cho các lệnh này (đừng cố nhét chúng vào sơ đồ).
464
-
465
- ## Gợi ý lệnh tiếp theo
466
-
467
- Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
468
-
469
- | Lệnh hiện tại | Gợi ý lệnh tiếp theo |
470
- |-------------------------|-----------------------------------------------|
471
- | /setup-ai-first | `/define-product` để bắt đầu feature đầu tiên |
472
- | /define-product | `/generate-prd {product-definition-file}` |
473
- | /generate-prd | `/refine-prd {prd-file}` rồi `/review-context {prd-file}` |
474
- | /refine-prd | Mở Review Board → cập nhật PRD → `/review-context {prd-file}` |
475
- | /review-context (PRD) | Khi 0 critical → PO đặt `Status: approved`, rồi FE/App: `/generate-design-spec {prd-file}` (→ design sign-off → BDD); BE: `/generate-bdd {prd-file}`. Còn critical/NEEDS_FIX → sửa PRD (giữ draft) |
476
- | /generate-design-spec | Designer review → xác nhận link Figma → PO + Designer sign-off → `/generate-bdd {prd-file}` |
477
- | /generate-bdd | `/review-context {feature-file}` để kiểm tra độ phủ |
478
- | /review-context (BDD) | `/generate-tech-docs {UC-ID}` nếu APPROVED; sinh lại nếu NEEDS_FIX |
479
- | /qc-analyze | `/qc-plan {UC-ID}` (xử lý các gap blocker 🔴 trước) |
480
- | /qc-plan | `/qc-design-test {UC-ID}` |
481
- | /qc-design-test | `/qc-review {UC-ID}` (review test-case) |
482
- | /qc-review (test-case) | `/qc-run-test {UC-ID}` nếu APPROVED; sửa TC nếu NEEDS_FIX |
483
- | /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
484
- | /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
485
- | /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
486
- | /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
487
- | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
488
- | /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
489
- | /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
490
- | /dev-gen-test | `/dev-run-test {UC-ID}` |
491
- | /dev-run-test (passing) | `/review-code {UC-ID}` |
492
- | /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
493
- | /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
494
- | /dev-smoke-test | Tạo PR và link tới ticket |
495
- | /validate-traces | **Cờ 🔴 trước (chặn PR):** SEAM_UNWIRED → nối binding sang class thật, xoá/thay stub · STUB_UNRESOLVED → `/generate-code {owner_uc}` (lấp logic tại chỗ + xoá hàm song song) · ORPHANED/TRACE_ORPHAN → quyết định thủ công (xoá code+test, đưa scenario trở lại `.feature`, hoặc sửa `sc_id` của tag). **Rồi:** DRIFT/UNTRACKED → `/generate-code {UC-ID}` · BDD_DRIFT → `/generate-code {feature-file}` · tech-doc lỗi thời vs BDD → `/generate-tech-docs` → `/review-tech-docs` · PRD drift → `/generate-bdd {prd-file}` · GAP → `/dev-gen-test {UC-ID}`. **Chỉ tạo PR khi mọi cờ 🔴 = 0** |
496
- | /fix-bug | `/dev-run-test {UC-ID}` (dev_selftest vừa reset về not_run) → tạo PR; nếu fix một `{BUG-ID}` → QC chạy `/qc-run-test {UC-ID}` để verify + đóng bug |
497
- | /debug | `/fix-bug {ticket-id}` nếu cần sửa |
498
- | /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
499
- | /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
500
- | /learn | Tiếp tục làm việc — lesson áp dụng ở lệnh kế tiếp |
501
- | /sync | `/validate-traces` để xem độ phủ đầy đủ; xử lý mọi `📥 tester feedback` được nêu |
502
- | /update-framework | Review `git diff .agent/`, commit; `/sync` để đồng bộ nội dung dự án |
503
-
504
- Định dạng footer như sau:
505
- ```
506
- ---
507
- Status : {badge}
508
- {khối Output Artifacts}
509
- Pipeline : Discovery → PRD → [BDD ◀ bạn ở đây] → Tech Design → Code → Dev Self-Check → QC → Trace Audit
510
- (lệnh review) Vòng review: [① phân tích ◀] → ② Review Board → ③ --resume
511
- Next : {lệnh gợi ý kèm ví dụ tham số}
512
- ```
513
- *(Bỏ dòng `Pipeline` cho các lệnh xuyên suốt liệt kê ở trên.)*
514
-
542
+ **Đọc `.agent/steps/report-footer.md`** áp đúng khuôn footer trong đó (Status Badge ·
543
+ Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
515
544
 
516
545
  ```
517
546
  /setup-ai-first Hoàn tất ✅
@@ -113,6 +113,34 @@ specs/{domain}/{prd-slug}/
113
113
  | **2 — Umbrella** | Chỉ `.trace/` + `.agent/review/` (ở umbrella root) | Mọi thứ khác — **toàn bộ spec sống trong spec submodule (`spec_source`)** dưới `specs/{domain}/{prd-slug}/`; service submodule chỉ chứa **code + `.trace/`** |
114
114
  | **3 — PO Spec repo** | `specs/product-definition/`, `specs/domain-knowledge/`, **`feedback/`**, `.agent/review/` (folder `specs/{domain}/{prd-slug}/` theo feature tạo on demand) | `.trace/` (theo service, sống cạnh code trong mỗi service submodule) |
115
115
 
116
+ ### Step 1b — Luật merge cho sổ trace *(mọi project_type có tạo `.trace/`)*
117
+
118
+ Ngay khi tạo `.trace/`, tạo luôn `.trace/.gitattributes`:
119
+
120
+ ```gitattributes
121
+ # Sổ trace — dữ liệu KHÔNG regenerate được. Hai luật, hai lý do khác nhau:
122
+ #
123
+ # merge=union — giữ row của CẢ HAI nhánh thay vì bắt người chọn một bên. Trùng sc_id sau
124
+ # union là ca ĐÚNG VÀ ĐƯỢC MONG ĐỢI: `--lint-trace` T4 bắt nó, rồi /validate-traces
125
+ # reconcile về một row. Mất row thì KHÔNG có gì bắt được. Đánh đổi có chủ ý — đừng "dọn".
126
+ # (union là driver built-in của git: không ai cần chạy git config gì thêm.)
127
+ #
128
+ # text eol=lf — BẮT BUỘC đi kèm union. Thiếu nó: một máy ghi CRLF → git thấy MỌI dòng đã
129
+ # đổi → union giữ cả hai bản → NHÂN ĐÔI CẢ FILE, gồm cả dòng header.
130
+ #
131
+ # KHÔNG thêm *.json — trace-report.json nằm cùng thư mục và union trên JSON tạo ra JSON
132
+ # không hợp lệ. Nó sinh lại được: conflict thì chạy lại /validate-traces.
133
+ *.tsv text eol=lf merge=union
134
+ *.jsonl text eol=lf merge=union
135
+ ```
136
+
137
+ **Vì sao làm ở đây, ngay lúc tạo thư mục:** sổ trace phải commit và được nhiều người ghi trên
138
+ nhiều nhánh song song. Không có luật này, lần merge song song đầu tiên sẽ conflict — và giải
139
+ conflict bằng "take mine" là **mất row của người kia, im lặng**. Đây là ca **chắc chắn xảy ra**
140
+ với team ≥3 người và không cần ai làm sai gì cả.
141
+
142
+ *Project đã cài từ trước → `/sync` Step 4c kiểm và tạo hộ.*
143
+
116
144
  ## Step 2 — Tạo CLAUDE.md
117
145
 
118
146
  *Bỏ qua hoàn toàn step này nếu `project_type = 2` (Umbrella) — umbrella không có một tech stack đơn.*
@@ -281,6 +309,50 @@ Hoặc: VS Code → `Ctrl+Shift+P` → **"Extensions: Install from Marketplace"*
281
309
  - 📋 **Review Board** — UI trực quan để review findings từ `/refine-prd`, `/review-context`, `/review-tech-docs`
282
310
  - 📊 **Living Documentation** — dashboard traceability dựa trên `.trace/*.tsv`
283
311
 
312
+ ## Step 6b — Cổng chặn bằng máy (Khuyến nghị mạnh)
313
+
314
+ *Skip nếu `project_type = 3` (PO Spec repo) — không có code thì không có PR cần chặn.*
315
+
316
+ Framework phát hiện được một lớp lỗi mà **build xanh + test từng-UC xanh KHÔNG thấy**: luồng
317
+ ghép chạy vào hàm rỗng (`SEAM_UNWIRED`, `STUB_UNRESOLVED`), hoặc code trỏ vào scenario đã bị
318
+ xoá (`ORPHANED`, `TRACE_ORPHAN`). Nhưng nếu việc phát hiện đó phụ thuộc vào **có người tự
319
+ nguyện chạy `/validate-traces` rồi đọc report bằng mắt**, thì sau sprint thứ ba không ai làm.
320
+
321
+ Hai file mẫu đã có sẵn. Hỏi user muốn cài cái nào:
322
+
323
+ ```
324
+ Cài cổng chặn bằng máy? (khuyến nghị cả hai)
325
+ 1. pre-push hook — chặn push khi sổ trace hỏng cấu trúc. Rẻ, 2 giây, offline được.
326
+ Bắt được marker conflict git trước khi nó vào nhánh chung.
327
+ 2. CI workflow — chặn PR khi có cờ 🔴. Cần GitHub Actions.
328
+ 3. Cả hai (khuyến nghị)
329
+ 4. Bỏ qua, cài sau
330
+ ```
331
+
332
+ **Chọn 1 hoặc 3** — copy hook rồi cấp quyền chạy:
333
+ ```bash
334
+ cp .agent/templates/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
335
+ ```
336
+ *Nếu `trace_dir` của project không phải `.trace` (vd `../.trace` hay `{spec_source}/.trace`) →
337
+ mở file vừa copy và sửa biến `TRACE_DIR` ở đầu file cho khớp.*
338
+
339
+ **Chọn 2 hoặc 3** — copy workflow:
340
+ ```bash
341
+ mkdir -p .github/workflows && cp .agent/templates/ci/trace-gate.yml .github/workflows/
342
+ ```
343
+ *Rồi mở nó ra: sửa `src/**` ở job `require-fresh-audit` cho khớp layout project, và bỏ comment
344
+ `submodules: recursive` nếu spec/trace nằm trong submodule.*
345
+
346
+ > **Phải COPY RA khỏi `.agent/`** — `.agent/` bị ghi đè mỗi lần `/update-framework`, và
347
+ > `.git/hooks/` thì git không chạy từ chỗ khác. Copy ra rồi thì chúng là file của project.
348
+
349
+ Kiểm ngay sau khi cài (chưa có sổ trace thì cả hai thoát sạch, không phải lỗi):
350
+ ```bash
351
+ npx @educa-corp/sdd-framework --lint-trace
352
+ ```
353
+
354
+ Chi tiết + giới hạn của cổng → `docs/03-guides/architect.md` §Cắm vào CI.
355
+
284
356
  ## Step 7 — Verify
285
357
 
286
358
  Checklist tuỳ theo `project_type`: