@educa-corp/sdd-framework 0.9.5 → 0.9.6

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 (55) hide show
  1. package/bin/build.js +11 -1
  2. package/bin/lint-trace.js +397 -28
  3. package/bin/self-check.js +183 -12
  4. package/bin/trace-schema.json +2656 -1981
  5. package/core/FRAMEWORK_VERSION +1 -1
  6. package/core/commands/dev-gen-test.md +62 -0
  7. package/core/commands/generate-code.md +1 -1
  8. package/core/commands/generate-tech-docs.md +3 -3
  9. package/core/commands/map-testids.md +88 -11
  10. package/core/commands/qc-analyze.md +509 -425
  11. package/core/commands/qc-design-test.md +475 -247
  12. package/core/commands/qc-plan.md +134 -93
  13. package/core/commands/qc-review.md +216 -131
  14. package/core/commands/qc-run-test.md +346 -231
  15. package/core/commands/validate-traces.md +17 -2
  16. package/core/rules/workflow.md +40 -0
  17. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +9 -1
  18. package/core/skills/qc/qa-designer/shared/duplicate-check-procedure.md +33 -5
  19. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +24 -0
  20. package/core/skills/qc/qa-planner/test-plan.md +7 -0
  21. package/core/skills/qc/qa-runner/functional/gui-feature.md +1 -1
  22. package/core/skills/qc/qa-runner/functional/gui-screen.md +1 -1
  23. package/core/steps/qc-scope.md +67 -11
  24. package/core/steps/qc-stamp.md +142 -0
  25. package/core/steps/report-footer.md +13 -5
  26. package/core/templates/tech-design.template.md +3 -3
  27. package/docs/01-getting-started/quickstart.md +4 -3
  28. package/docs/02-concepts/architecture.md +14 -0
  29. package/docs/02-concepts/glossary.md +8 -0
  30. package/docs/02-concepts/overview.md +3 -2
  31. package/docs/02-concepts/pipeline-steps/04-bdd.md +1 -1
  32. package/docs/02-concepts/pipeline-steps/05-tech-docs.md +21 -5
  33. package/docs/02-concepts/pipeline-steps/06-code.md +12 -2
  34. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +60 -12
  35. package/docs/02-concepts/pipeline-steps/README.md +4 -3
  36. package/docs/02-concepts/traceability.md +2 -2
  37. package/docs/03-guides/architect.md +2 -2
  38. package/docs/03-guides/developer.md +5 -2
  39. package/docs/03-guides/tester-qa.md +17 -5
  40. package/docs/04-reference/commands.md +6 -3
  41. package/docs/04-reference/trace-schema.md +1 -1
  42. package/docs/explain/07-generate-tech-docs.md +5 -3
  43. package/docs/explain/08-review-tech-docs.md +15 -3
  44. package/docs/explain/09-generate-code.md +30 -4
  45. package/docs/explain/10-review-code.md +1 -1
  46. package/docs/explain/11-map-testids.md +72 -70
  47. package/docs/explain/12-dev-gen-test.md +1 -1
  48. package/docs/explain/15-qc-analyze.md +14 -2
  49. package/docs/explain/16-qc-plan.md +5 -1
  50. package/docs/explain/17-qc-design-test.md +26 -3
  51. package/docs/explain/18-qc-review.md +6 -2
  52. package/docs/explain/19-qc-run-test.md +29 -6
  53. package/docs/explain/20-qc-report.md +5 -2
  54. package/docs/explain/README.md +4 -1
  55. package/package.json +1 -1
@@ -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-plan — QC Test Plan & Risk Analysis
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.
10
-
11
- ## Gate
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-06-11
4
+ ported_from: ai-automation-qc-base
5
+ ---
6
+
7
+ # /qc-plan — QC Test Plan & Risk Analysis
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.
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ó.
@@ -160,96 +160,137 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
160
160
  - "N" → dừng, hỏi người dùng muốn thay đổi gì.
161
161
  - 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
162
  🔴/⚠️ (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 **TICKET-ID** (mã PRD) — hoặc UC-ID / file feature, cả hai quy về TICKET-ID ở §Phạm vi QC. Đọc output của qc-analyze (`REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`) từ `{qc_artifact_dir}` và file `.feature` của đúng nền đó.*
166
-
167
- ## Context
163
+
164
+
165
+ *Lưu ý: Với lệnh này, target ở Bước 1 là một **TICKET-ID** (mã PRD) — hoặc UC-ID / file feature, cả hai quy về TICKET-ID ở §Phạm vi QC. Đọc output của qc-analyze (`REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`) từ `{qc_artifact_dir}` và file `.feature` của đúng nền đó.*
166
+
167
+ ## Context
168
168
  **BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
169
169
  rồi mới tiếp tục phần bên dưới.
170
170
 
171
171
  Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, guardrail từ
172
172
  `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
- ## Phạm vi QC
178
-
173
+ placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
174
+
175
+ ---
176
+
177
+ ## Phạm vi QC
178
+
179
179
  **BẮT BUỘC — đọc `.agent/steps/qc-scope.md` và thực thi TOÀN BỘ quy trình trong đó**,
180
180
  rồi mới tiếp tục phần bên dưới.
181
181
 
182
182
  Nó chốt bốn thứ mà mọi trạm QC đều cần: `TICKET-ID` · `active_platform` ·
183
- `qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--include-draft`).
183
+ `qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--force`).
184
184
  Bỏ qua thì artifact QC ghi vào **sai thư mục** và `qc_status` ghi vào **sai sổ trace** —
185
- cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
186
-
187
- > **Trạm này chạy CẢ PRD, đúng như trạm 1** *(B11)* — một `TEST_PLAN.md` cho mỗi (PRD × nền).
188
- > `qa-planner/test-plan.md` vốn viết *"Test Plan cho một **feature**"* và template của nó là
189
- > `# Test Plan – <Feature>` với metadata `Feature / Project / Module`: đây là quay về đúng
190
- > tầng mà skill gốc được viết cho.
191
- >
192
- > `uc_list` đây **phải khớp** bảng *Phạm vi phân tích* trong `DOC_GAP.md`. Lệch nhau nghĩa là
193
- > BDD đã đổi trạng thái sau lần chạy trạm 1 → nêu ra và khuyên chạy lại `/qc-analyze`, đừng
194
- > âm thầm lập plan cho một tập UC khác với tập đã phân tích.
195
-
196
- ---
197
-
198
- ## Role
199
-
200
- Bạn **QC Planner** stage 2. Từ output của qc-analyze, tạo TEST PLAN:
201
- phân tích rủi ro, scenario what-if, scope/strategy test theo từng layer, `questions-for-dev`
202
- cho mọi gap open/blocker. Bạn trả lời *"rủi ro ở đâu, phải hỏi gì?"* — bạn không
203
- thiết kế test case cụ thể (đó là qc-design-test).
204
-
205
- ## Skills (`{paths.qc_skills_dir}/qa-planner/`)
206
-
207
- - `test-plan.md` — khung plan: scope theo từng test layer (functional / integration /
208
- e2e / non-functional), what-if, entry/exit criteria, và danh sách questions-for-dev
209
- suy ra từ `DOC_GAP.md`.
210
- - `risk-model.md` — **cách tính** mức rủi ro: 7 nguồn rủi ro · khả năng × thiệt hại → P0–P3 ·
211
- và dùng mức đó chia **độ sâu** test. `test-plan.md` có khung bảng `§6`; file này là cách điền.
212
- Nạp cùng lúc, không phải thay thế.
213
-
214
- ## Output
215
-
216
- Ghi **đúng MỘT** test plan cho cả PRD vào `{qc_artifact_dir}TEST_PLAN.md`
217
- (= `{paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md`). Giới hạn plan trong các
218
- scenario của **các UC trong phạm vi** (`{UC-ID}-SC{N}` từ `.feature` của nền này) để
219
- qc-design-test thiết kế case theo từng scenario.
220
-
221
- Bắt buộc:
222
- - **Bảng `§3 Test items` cột `UC`** một plan giờ phủ nhiều UC, không cột đó thì không
223
- ai biết vùng test nào thuộc UC nào.
224
- - **`§2 Phạm vi`** liệt rõ UC `⏸ Chưa xét` ở phần *Out of scope*, kèm lý do (BDD chưa
225
- approved). *Không có dòng này thì một UC bị bỏ trông giống một UC không có gì để test.*
226
- - **`§5 Entry criteria` chặn theo từng UC**, không chặn cả PRD: gap 🔴 Blocker ở UC3 không
227
- dừng việc thiết kế test cho UC1. Ghi `Ready` / `Blocked` cho **mỗi** UC.
228
-
229
- ## Self-Review *(trước khi in Report)*
230
-
231
- Theo 3 nhóm ở `{paths.qc_skills_dir}/_shared/self-review-principles.md` **không chép lại đây**.
232
-
233
- - **Bịa:** mỗi dòng rủi ro neo được vào một `BR`/`AC`/`GAP` **có thật** trong
234
- `REQUIREMENT_ANALYSIS.md`/`DOC_GAP.md` — không phải rủi ro chung chung tự nghĩ ra kiểu *"hiệu
235
- năng thể chậm"*? Mỗi `questions-for-dev` suy ra từ một gap cụ thể?
236
- - **Nhảy bước:** đã đọc **cả hai** file đầu vào (`REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`) lọc
237
- theo cột `UC` không chỉ đọc file thứ nhất?
238
- - **Số liệu:** `{risks}`/`{questions}` in report = đúng số dòng thật trong `TEST_PLAN.md` vừa
239
- ghi, không phải đếm nhẩm?
240
-
241
- ## Report
242
-
185
+ cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
186
+
187
+ ---
188
+
189
+ ## Stamp phiên bản nguồn
190
+
191
+ **BẮT BUỘC — đọc `.agent/steps/qc-stamp.md` và thực thi phần áp cho lệnh này**,
192
+ rồi mới tiếp tục phần bên dưới.
193
+
194
+ **hai vế**: §1 **ghi** khối `Nguồn & phiên bản` vào artifact lệnh này sinh ra ·
195
+ §2 **so** stamp của artifact lệnh này ĐỌC với version hiện tại của spec.
196
+ Bỏ vế ghi thì trạm sau không có gì để so; bỏ vế so thì stamp thành một con số không ai
197
+ đọc — và một bộ TC lỗi thời sẽ chạy xanh rồi ghi `pass` **hợp lệ theo mọi phép kiểm**.
198
+
199
+ > **Trạm này chạy CẢ PRD, đúng như trạm 1** *(B11)* — một `TEST_PLAN.md` cho mỗi (PRD × nền).
200
+ > `qa-planner/test-plan.md` vốn viết *"Test Plan cho một **feature**"* template của
201
+ > `# Test Plan <Feature>` với metadata `Feature / Project / Module`: đây quay về đúng
202
+ > tầng skill gốc được viết cho.
203
+ >
204
+ > `uc_list` ở đây **phải khớp** bảng *Phạm vi phân tích* trong `DOC_GAP.md`. Lệch nhau nghĩa là
205
+ > BDD đã đổi trạng thái sau lần chạy trạm 1 → nêu ra và khuyên chạy lại `/qc-analyze`, đừng
206
+ > âm thầm lập plan cho một tập UC khác với tập đã phân tích.
207
+
208
+ ---
209
+
210
+ ## Role
211
+
212
+ Bạn **QC Planner** — stage 2. Từ output của qc-analyze, tạo TEST PLAN:
213
+ phân tích rủi ro, scenario what-if, scope/strategy test theo từng layer, và `questions-for-dev`
214
+ cho mọi gap open/blocker. Bạn trả lời *"rủi ro ở đâu, phải hỏi gì?"* — bạn không
215
+ thiết kế test case cụ thể (đó là qc-design-test).
216
+
217
+ ## Skills (`{paths.qc_skills_dir}/qa-planner/`)
218
+
219
+ - `test-plan.md` khung plan: scope theo từng test layer (functional / integration /
220
+ e2e / non-functional), what-if, entry/exit criteria, và danh sách questions-for-dev
221
+ suy ra từ `DOC_GAP.md`.
222
+ - `risk-model.md` **cách tính** mức rủi ro: 7 nguồn rủi ro · khả năng × thiệt hại P0–P3 ·
223
+ dùng mức đó chia **độ sâu** test. `test-plan.md` khung bảng `§6`; file này là cách điền.
224
+ Nạp cùng lúc, không phải thay thế.
225
+
226
+ ## Output
227
+
228
+ Ghi **đúng MỘT** test plan cho cả PRD vào `{qc_artifact_dir}TEST_PLAN.md`
229
+ (= `{paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md`). Giới hạn plan trong các
230
+ scenario của **các UC trong phạm vi** (`{UC-ID}-SC{N}` từ `.feature` của nền này) để
231
+ qc-design-test thiết kế case theo từng scenario.
232
+
233
+ Bắt buộc:
234
+ - **Bảng `§3 Test items` có cột `UC`**một plan giờ phủ nhiều UC, không cột đó thì không
235
+ ai biết vùng test nào thuộc UC nào.
236
+ - **`§2 Phạm vi`** liệt UC `⏸ Chưa xét` phần *Out of scope*, kèm lý do (BDD chưa
237
+ approved). *Không có dòng này thì một UC bị bỏ trông giống một UC không để test.*
238
+ - **`§5 Entry criteria` chặn theo từng UC**, không chặn cả PRD: gap 🔴 Blocker ở UC3 không
239
+ dừng việc thiết kế test cho UC1. Ghi `Ready` / `Blocked` cho **mỗi** UC.
240
+
241
+ ### Chạy lại — ghi đè ở đây AN TOÀN, và đây là lý do
242
+
243
+ *(Ba trạm QC khác — `/qc-analyze` · `/qc-design-test` · `/qc-run-test` — đều ở mức **chặn CỨNG** kèm
244
+ §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
+
246
+ `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
247
+ trả lời quay về qua `DOC_GAP.md` hoặc kênh chat, **không ai điền ngược vào file này**; stamp phiên
248
+ bản và cột `Ready`/`Blocked` đều do lệnh **tự tính** từ `DOC_GAP.md`. Nên chạy lại = lập lại, không
249
+ mất gì.
250
+
251
+ *Khai máy đọc: `bin/trace-schema.json` → `artifact_writers.enrolled.qc-plan.has_human_content = false`
252
+ — và **R18 ép khai `why`** chính vì một ngoại lệ có chủ ý trông y hệt một chỗ sót.*
253
+
254
+ > **⚠️ Khai lại nếu điều này hết đúng.** Có ai bắt đầu điền tay vào `TEST_PLAN.md` — một cột quyết
255
+ > định, một ghi chú duyệt, một câu trả lời dán vào — thì lệnh này **phải** lên `checkpoint_levels.hard`
256
+ > và có §Chạy lại như `/qc-analyze`. Đánh giá "an toàn" ở trên đúng **hôm nay**, không đúng vĩnh viễn.
257
+
258
+ > **`Blocked` là mức ƯU TIÊN, KHÔNG phải lệnh cấm** *(G66)*. Nó nghĩa *"UC này chưa sẵn sàng
259
+ > để **nghiệm thu**"*, không phải *"chưa được **thiết kế**"*. `/qc-design-test` vẫn chạy được và
260
+ > **nên** chạy — TC chạm gap mang dấu `🚫 Block` trỏ về hàng gap, và cơ chế đó chỉ có nghĩa khi
261
+ > trạm 3 thực sự chạy trên UC `Blocked`.
262
+ >
263
+ > Cái bị chặn là **chạy test**, không phải **viết test**. Chờ PO trả lời mất ngày tới tuần; cấm
264
+ > thiết kế trong lúc chờ là ném đi đúng phần song song mà `/map-testids` mở ra. Và đây là cùng
265
+ > lập luận đã dùng ngay ở gạch trên — chặn theo UC chứ không theo PRD — chỉ áp thêm một bậc:
266
+ > một blocker trong UC1 cũng không dừng việc thiết kế **phần còn lại** của UC1.
267
+
268
+ ## Self-Review *(trước khi in Report)*
269
+
270
+ Theo 3 nhóm ở `{paths.qc_skills_dir}/_shared/self-review-principles.md` — **không chép lại ở đây**.
271
+
272
+ - **Bịa:** mỗi dòng rủi ro neo được vào một `BR`/`AC`/`GAP` **có thật** trong
273
+ `REQUIREMENT_ANALYSIS.md`/`DOC_GAP.md` — không phải rủi ro chung chung tự nghĩ ra kiểu *"hiệu
274
+ năng có thể chậm"*? Mỗi `questions-for-dev` suy ra từ một gap cụ thể?
275
+ - **Nhảy bước:** đã đọc **cả hai** file đầu vào (`REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`) và lọc
276
+ theo cột `UC` — không chỉ đọc file thứ nhất?
277
+ - **Số liệu:** `{risks}`/`{questions}` in ở report = đúng số dòng thật trong `TEST_PLAN.md` vừa
278
+ ghi, không phải đếm nhẩm?
279
+
280
+ ## Report
281
+
243
282
  **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
244
- Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
245
-
246
- ```
247
- /qc-plan Hoàn tất — {TICKET-ID} ({active_platform})
248
- Phạm vi: {n} UC trong plan{nếu có: " · ⏸ {m} chưa xét"}
249
- Plan: {risks} rủi ro · {questions} câu hỏi mở cho dev · layers: {list}
250
- File: {paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md
251
- Sẵn sàng: {danh sách UC Ready} | Chặn: {danh sách UC Blocked + GAP-ID chặn nó}
252
- Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
253
- Next: /qc-design-test {UC-ID} ← thiết kế test case, chạy cho từng UC đã Ready
254
- (gửi questions-for-dev cho PO/Dev cho các UC còn Blocked)
255
- ```
283
+ Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
284
+
285
+ ```
286
+ /qc-plan Hoàn tất — {TICKET-ID} ({active_platform})
287
+ Phạm vi: {n} UC trong plan{nếu có: " · ⏸ {m} chưa xét"}
288
+ Plan: {risks} rủi ro · {questions} câu hỏi mở cho dev · layers: {list}
289
+ File: {paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md
290
+ Sẵn sàng: {danh sách UC Ready} | Chặn: {danh sách UC Blocked + GAP-ID chặn nó}
291
+ Self-review: {✅ sạch | ⚠️ {n} điểm cần chú ý — liệt kê}
292
+ Next: /qc-design-test {UC-ID} ← thiết kế test case, từng UC một
293
+ Ưu tiên UC `Ready`. UC `Blocked` VẪN thiết kế được — TC chạm gap mang dấu
294
+ 🚫 Block và chưa chạy tới khi gap Answered.
295
+ (song song: gửi questions-for-dev cho PO/Dev để gỡ blocker)
296
+ ```