@educa-corp/sdd-framework 0.9.2 → 0.9.3

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 (37) hide show
  1. package/core/FRAMEWORK_VERSION +1 -1
  2. package/core/commands/qc-analyze.md +189 -66
  3. package/core/commands/qc-design-test.md +141 -2
  4. package/core/commands/qc-plan.md +153 -7
  5. package/core/commands/qc-review.md +134 -1
  6. package/core/commands/qc-run-test.md +134 -1
  7. package/core/modules/qc-playwright/stack-profile.yaml +3 -3
  8. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +47 -17
  9. package/core/skills/qc/qa-analyst/acceptance-criteria.md +1 -1
  10. package/core/skills/qc/qa-analyst/business-rules.md +2 -2
  11. package/core/skills/qc/qa-analyst/data-flow.md +2 -2
  12. package/core/skills/qc/qa-analyst/spec-breakdown.md +2 -2
  13. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +14 -2
  14. package/core/skills/qc/qa-designer/e2e/journey.md +1 -1
  15. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  16. package/core/skills/qc/qa-designer/functional/api.md +1 -1
  17. package/core/skills/qc/qa-designer/functional/gui-feature.md +1 -1
  18. package/core/skills/qc/qa-designer/functional/gui-screen.md +1 -1
  19. package/core/skills/qc/qa-designer/integration/api.md +1 -1
  20. package/core/skills/qc/qa-designer/integration/db.md +1 -1
  21. package/core/skills/qc/qa-designer/integration/gui.md +1 -1
  22. package/core/skills/qc/qa-designer/integration/kafka.md +1 -1
  23. package/core/skills/qc/qa-designer/non-functional.md +1 -1
  24. package/core/skills/qc/qa-planner/test-plan.md +24 -13
  25. package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
  26. package/core/steps/context-loader.md +1 -1
  27. package/core/steps/qc-scope.md +119 -0
  28. package/core/templates/project-context.yaml +3 -1
  29. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -1
  30. package/docs/04-reference/configuration.md +146 -146
  31. package/docs/explain/15-qc-analyze.md +1 -1
  32. package/docs/explain/16-qc-plan.md +1 -1
  33. package/docs/explain/17-qc-design-test.md +1 -1
  34. package/docs/plans/qc-implementation-log.md +145 -4
  35. package/docs/plans/qc-sync-command.md +2 -1
  36. package/package.json +1 -1
  37. package/scripts/migrate-qc-docs.js +261 -0
@@ -83,11 +83,11 @@ Với rule có nhiều điều kiện kết hợp → gợi ý dựng **Decision
83
83
 
84
84
  ## Output
85
85
 
86
- Ghi vào **mục Business Rules** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md`
86
+ Ghi vào **mục Business Rules** của `{qc_artifact_dir}REQUIREMENT_ANALYSIS.md`
87
87
  (KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`):
88
88
 
89
89
  - Bảng business rule có ID (BR-xx) để TC trace ngược về.
90
90
  - Gợi ý các rule cần Decision Table / BVA khi sang qa-designer.
91
91
 
92
- Rule MÂU THUẪN / KHÔNG RÕ → ghi vào `{paths.qc_dir}/{UC-ID}/DOC_GAP.md`
92
+ Rule MÂU THUẪN / KHÔNG RÕ → ghi vào `{qc_artifact_dir}DOC_GAP.md`
93
93
  (loại CONTRADICTORY / AMBIGUOUS, cột "Ảnh hưởng" trỏ BR-xx).
@@ -54,7 +54,7 @@ Thể hiện luồng dạng bước tuần tự hoặc sơ đồ text:
54
54
 
55
55
  ## Output
56
56
 
57
- Ghi vào **mục Data Flow** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md`
57
+ Ghi vào **mục Data Flow** của `{qc_artifact_dir}REQUIREMENT_ANALYSIS.md`
58
58
  (KHÔNG tạo file riêng — qc-analyze chỉ trả 2 file: `REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`):
59
59
 
60
60
  - Sơ đồ/list luồng dữ liệu cho mỗi kịch bản chính.
@@ -63,4 +63,4 @@ Ghi vào **mục Data Flow** của `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.
63
63
  - Dữ liệu/trạng thái cần chuẩn bị & cleanup → đầu vào fixture cho qa-runner.
64
64
 
65
65
  Chặng nào luồng/hành vi chưa rõ (vd lỗi xử lý ra sao, retry, partial commit) →
66
- ghi vào `{paths.qc_dir}/{UC-ID}/DOC_GAP.md` (loại MISSING / OPEN QUESTION).
66
+ ghi vào `{qc_artifact_dir}DOC_GAP.md` (loại MISSING / OPEN QUESTION).
@@ -49,7 +49,7 @@ F. GIẢ ĐỊNH & CÂU HỎI MỞ: điều suy ra được vs điều cần dev
49
49
  ## Output
50
50
 
51
51
  ⚠️ `/qc-analyze` chỉ ghi **ĐÚNG 2 FILE** cho mỗi UC, đặt trong thư mục QC **lộ ra ngoài**
52
- `{paths.qc_dir}/{UC-ID}/` (mặc định `docs/{UC-ID}/` — KHÔNG để trong `.agent/` ẩn):
52
+ `{qc_artifact_dir}` (mặc định `docs/{TICKET-ID}/{platform}/` — gom theo **PRD**, KHÔNG để trong `.agent/` ẩn):
53
53
  `REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`. KHÔNG tách mỗi bước phân tích thành file riêng.
54
54
 
55
55
  Phần spec-breakdown là **mục đầu tiên** của `REQUIREMENT_ANALYSIS.md`:
@@ -57,7 +57,7 @@ Phần spec-breakdown là **mục đầu tiên** của `REQUIREMENT_ANALYSIS.md`
57
57
  - Sơ đồ/list luồng chính & phụ
58
58
  - Danh sách giả định và câu hỏi mở (đánh dấu rõ điều CHƯA chắc)
59
59
 
60
- Đồng thời ghi mọi khoảng trống phát hiện vào `{paths.qc_dir}/{UC-ID}/DOC_GAP.md`
60
+ Đồng thời ghi mọi khoảng trống phát hiện vào `{qc_artifact_dir}DOC_GAP.md`
61
61
  (theo `{paths.qc_skills_dir}/qa-analyst/DOC_GAP.template.md`), mỗi gap có ID `GAP-xx`.
62
62
 
63
63
  Kết thúc bằng gợi ý: feature đã đủ rõ để chuyển sang `qa-planner` (phân tích rủi ro) chưa.
@@ -14,6 +14,9 @@ có cấu trúc, đủ thông tin để người nhận trả lời được nga
14
14
  > **`/qc-analyze` nạp file này** *(B9 — hợp nhất 2026-08-25)*. Nó là luật viết cho
15
15
  > `DOC_GAP.template.md` — template **duy nhất** của file gap. Bản 9 cột cũ đã bỏ.
16
16
  >
17
+ > **Một file gap phủ CẢ PRD** *(B11)* — `{paths.qc_dir}/{TICKET-ID}/{platform}/DOC_GAP.md`,
18
+ > mỗi UC là các hàng phân biệt bằng cột `UC`. Không còn một-file-mỗi-UC.
19
+ >
17
20
  > **Một chỗ cố ý khác upstream:** mức nặng nhất dùng `🔴 Blocker`, không phải `Critical` —
18
21
  > `/qc-run-test` đọc đúng từ đó để đặt *"scenario đang chờ PO"* vào sổ trace.
19
22
 
@@ -38,8 +41,11 @@ Một file gap gồm:
38
41
  transitive 1-hop): `# | Đường dẫn | Vai trò | Phiên bản`, kèm tổng số.
39
42
  KHÔNG bỏ sót file nào đã mở — đây là **căn cứ độ phủ**: không có nó thì không ai phân biệt
40
43
  được *"đã đọc và không thấy"* với *"chưa đọc"*.
41
- 2. **Bảng gap 10 cột**, đúng thứ tự:
42
- `ID | Loại | Vấn đề cần confirm | Câu hỏi / Lý do cần confirm & Gợi ý | Trích đoạn tài liệu (Evidence) | Giao cho đội | Mức độ | Người trả lời | Trạng thái | Câu trả lời`
44
+ 2. **Bảng gap 11 cột**, đúng thứ tự:
45
+ `ID | UC | Loại | Vấn đề cần confirm | Câu hỏi / Lý do cần confirm & Gợi ý | Trích đoạn tài liệu (Evidence) | Giao cho đội | Mức độ | Người trả lời | Trạng thái | Câu trả lời`
46
+ 3. **Section `Phạm vi phân tích`** — BẮT BUỘC, giữa metadata và section trên. Mỗi UC của
47
+ (PRD × nền) một hàng, kèm `@trace.status` + đã phân tích chưa + số gap. UC có BDD chưa
48
+ `approved` **vẫn có hàng**, ghi `⏸ Chưa xét`.
43
49
 
44
50
  ## Quy tắc
45
51
 
@@ -56,6 +62,12 @@ Một file gap gồm:
56
62
  do bước phân tích tự đánh số lại (vd `BR-UC4-12`). Hai hệ ID khác nhau; trộn vào là người
57
63
  đọc không tra ngược được về PRD.
58
64
  - **Mức độ bắt buộc có emoji**: `🔴 Blocker` · `🟠 High` · `🟡 Medium` · `⚪ Low`.
65
+ - **ID gap mang UC**: `GAP-UC{N}-{nnn}` (vd `GAP-UC1-001`); gap thuộc cả PRD → `GAP-GEN-{nnn}`.
66
+ Đánh số **độc lập trong từng UC** — phân tích lại UC1 KHÔNG được làm đổi số gap của UC2,
67
+ vì test case đã có đang trỏ `🚫 Block: [GAP-UC2-003]` và đổi số là đứt liên kết trong im lặng.
68
+ **Không dùng `GAP-01` phẳng.**
69
+ - **Cột `UC`** ghi mã UC đầy đủ (`{TICKET-ID}-UC{N}`), hoặc `— (toàn PRD)` cho `GAP-GEN-`.
70
+ Mọi UC xuất hiện ở đây phải khớp một hàng `✅` trong bảng *Phạm vi phân tích*.
59
71
  - **Pipe trong cell**: escape thành `\|` (vd `{a\|b\|c}`), nếu không sẽ vỡ bảng.
60
72
  - **Thêm hàng vào bảng đã có**: nối **ngay liền sau hàng cuối**, TUYỆT ĐỐI không chèn dòng
61
73
  trắng giữa các hàng — dòng trắng làm Markdown tách thành hai bảng riêng và các gap mới
@@ -37,5 +37,5 @@ Mỗi journey → 1 TC bám Format; Expected = chuỗi verify point; chuẩn b
37
37
  **Journey phụ thuộc gap vẫn viết + 🚫 Block: GAP-xx**, định tuyến ghi "dự kiến theo BR". Trace BR.
38
38
 
39
39
  ## Output
40
- File TC e2e (hoặc nhóm E2E trong file feature) trong `{paths.qc_dir}/{UC-ID}/test-cases/`.
40
+ File TC e2e (hoặc nhóm E2E trong file feature) trong `{qc_artifact_dir}test-cases/`.
41
41
  In bảng `E2E-ID | Journey | Pri | Trace | Block` + bảng TC block. Bàn giao `qa-reviewer`.
@@ -37,7 +37,7 @@ Chuyển draft → TC chính thức bám **format file `TC_<FEATURE>.md`**:
37
37
  **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có BR → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx]` nếu chặn.
38
38
  - **Test Data** dạng list · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet cụ thể.
39
39
  - Phân nhóm GUI/Functional · cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
40
- - Đặt file `{paths.qc_dir}/{UC-ID}/test-cases/TC_<FEATURE>.md`.
40
+ - Đặt file `{qc_artifact_dir}test-cases/TC_<FEATURE>.md`.
41
41
 
42
42
  ## Output
43
43
  File TC functional + bảng `TC_ID | Title | Priority | Technique | Trace`. Bàn giao `qa-reviewer`.
@@ -41,5 +41,5 @@ response (schema thành công + các mã lỗi 4xx/5xx + body lỗi) · side-eff
41
41
  - Mỗi TC bám khối Format; Expected ghi status code + phần body verify; trace BR; gap chặn → 🚫 Block.
42
42
 
43
43
  ## Output
44
- File TC (`TC_<FEATURE>_API.md` hoặc gộp trong file feature) trong `{paths.qc_dir}/{UC-ID}/test-cases/`.
44
+ File TC (`TC_<FEATURE>_API.md` hoặc gộp trong file feature) trong `{qc_artifact_dir}test-cases/`.
45
45
  In bảng TC + Trace matrix. Bàn giao `qa-reviewer`.
@@ -42,5 +42,5 @@ Liệt kê các màn/route + thứ tự điều hướng · state/dữ liệu tr
42
42
  - Mỗi TC bám khối Format; trace BR; gap chặn → 🚫 Block.
43
43
 
44
44
  ## Output
45
- File `TC_<FEATURE>.md` trong `{paths.qc_dir}/{UC-ID}/test-cases/`. In bảng TC + Trace matrix + bảng TC block.
45
+ File `TC_<FEATURE>.md` trong `{qc_artifact_dir}test-cases/`. In bảng TC + Trace matrix + bảng TC block.
46
46
  Bàn giao `qa-reviewer` (test-case).
@@ -48,5 +48,5 @@ chức năng (input/action/display/nav) · constraint (required/min-max/format/e
48
48
  - Mỗi TC bám khối Format trên; trace BR; TC chặn bởi gap → 🚫 Block.
49
49
 
50
50
  ## Output
51
- File `TC_<FEATURE>.md` trong `{paths.qc_dir}/{UC-ID}/test-cases/`. In bảng `TC_ID | Title | Priority | Tags | Trace`
51
+ File `TC_<FEATURE>.md` trong `{qc_artifact_dir}test-cases/`. In bảng `TC_ID | Title | Priority | Tags | Trace`
52
52
  + Trace matrix + bảng TC block. Bàn giao `qa-reviewer` (test-case).
@@ -39,4 +39,4 @@ Nhóm TC: happy (dữ liệu đúng đầu→cuối) → contract negative (inpu
39
39
  → concurrency → điều kiện đồng bộ (đổ/không đổ). Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
40
40
 
41
41
  ## Output
42
- File TC integration trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Ưu tiên P0 cho định tuyến & tiền-dữ liệu. Bàn giao `qa-reviewer`.
42
+ File TC integration trong `{qc_artifact_dir}test-cases/`. Ưu tiên P0 cho định tuyến & tiền-dữ liệu. Bàn giao `qa-reviewer`.
@@ -35,5 +35,5 @@ Nhóm TC: ghi đúng giá trị (happy) → default/null đúng → update khôn
35
35
  → audit log → ràng buộc/unique (negative). Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
36
36
 
37
37
  ## Output
38
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Ghi rõ query kiểm tra DB + yêu cầu cleanup;
38
+ File TC trong `{qc_artifact_dir}test-cases/`. Ghi rõ query kiểm tra DB + yêu cầu cleanup;
39
39
  không hardcode ID, chuẩn bị/dọn data qua fixture. Bàn giao `qa-reviewer`.
@@ -37,4 +37,4 @@ Nhóm TC: UI render đúng dữ liệu backend (happy) → empty state → lỗi
37
37
  Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
38
38
 
39
39
  ## Output
40
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC nêu API liên quan + biểu hiện UI. Bàn giao `qa-reviewer`.
40
+ File TC trong `{qc_artifact_dir}test-cases/`. Mỗi TC nêu API liên quan + biểu hiện UI. Bàn giao `qa-reviewer`.
@@ -37,4 +37,4 @@ Nhóm TC: phát đúng topic+payload (happy) → điều kiện không phát →
37
37
  Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
38
38
 
39
39
  ## Output
40
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC ghi topic, key, payload cần verify + hành vi consumer. Bàn giao `qa-reviewer`.
40
+ File TC trong `{qc_artifact_dir}test-cases/`. Mỗi TC ghi topic, key, payload cần verify + hành vi consumer. Bàn giao `qa-reviewer`.
@@ -37,4 +37,4 @@ Mỗi TC bám Format; **Expected có ngưỡng pass + công cụ đo**; đánh d
37
37
  Trace BR; gap chặn → 🚫 Block.
38
38
 
39
39
  ## Output
40
- File TC non-functional trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC ghi tiêu chí đo + ngưỡng + công cụ. Bàn giao `qa-reviewer`.
40
+ File TC non-functional trong `{qc_artifact_dir}test-cases/`. Mỗi TC ghi tiêu chí đo + ngưỡng + công cụ. Bàn giao `qa-reviewer`.
@@ -8,11 +8,14 @@ upstream_sha: f259b4d123c565a42ba6c6ec96980a8e4c66284f
8
8
 
9
9
  # Lập Test Plan
10
10
 
11
- Tổng hợp **output của qa-analyst** thành **Test Plan** cho một feature.
11
+ Tổng hợp **output của qa-analyst** thành **Test Plan** cho một feature — tức **một plan cho cả
12
+ (PRD × nền)**, các UC là các hàng bên trong.
12
13
 
13
14
  **Đầu vào (bắt buộc, chỉ 2 nguồn — đúng 2 file qa-analyst trả ra):**
14
- 1. `{paths.qc_dir}/{UC-ID}/REQUIREMENT_ANALYSIS.md` — chức năng, BR-xx, AC-xx, data flow (qa-analyst).
15
- 2. `{paths.qc_dir}/{UC-ID}/DOC_GAP.md` bảng gap GAP-xx, mức độ, gap Blocker (qa-analyst).
15
+ 1. `{qc_artifact_dir}REQUIREMENT_ANALYSIS.md` — chức năng, BR-xx, AC-xx, data flow của **mọi UC
16
+ trong phạm vi**, kèm mục *Mâu thuẫn chéo UC* (qa-analyst).
17
+ 2. `{qc_artifact_dir}DOC_GAP.md` — bảng gap 11 cột `GAP-UC{N}-{nnn}`, mức độ, gap Blocker, và
18
+ bảng *Phạm vi phân tích* (qa-analyst). **Lọc cột `UC`** khi cần phần của một UC cụ thể.
16
19
 
17
20
  ## Khi nào trigger
18
21
  - "lập test plan cho [Feature]" / "viết test plan"
@@ -56,14 +59,16 @@ Tổng hợp **output của qa-analyst** thành **Test Plan** cho một feature.
56
59
 
57
60
  ## Output — Template `TEST_PLAN.md`
58
61
 
59
- Đặt tại `{paths.qc_dir}/{UC-ID}/TEST_PLAN.md`:
62
+ Đặt tại `{qc_artifact_dir}TEST_PLAN.md`:
60
63
 
61
64
  ```markdown
62
- # Test Plan – <Feature>
65
+ # Test Plan – <TICKET-ID> <Tên feature> / <nền>
63
66
 
64
67
  | Trường | Giá trị |
65
68
  |---|---|
66
- | Feature / Project / Module | … |
69
+ | Feature / Project / Module | `<TICKET-ID>` — … |
70
+ | Nền (platform) | `<web \| app \| system>` |
71
+ | UC trong phạm vi | `<UC-ID>` · `<UC-ID>` … (`⏸ chưa xét`: `<UC-ID>`) |
67
72
  | Người lập | qa-planner |
68
73
  | Ngày / Phiên bản | … |
69
74
  | Nguồn | REQUIREMENT_ANALYSIS · DOC_GAP |
@@ -72,16 +77,20 @@ Tổng hợp **output của qa-analyst** thành **Test Plan** cho một feature.
72
77
  Mục tiêu test của feature (1–3 câu).
73
78
 
74
79
  ## 2. Phạm vi
75
- - **In scope:** chức năng/BR được test.
76
- - **Out of scope:** phần để tài liệu/feature khác; nội dung gạch ngang đã loại.
80
+ - **In scope:** chức năng/BR được test, **theo từng UC** (`<UC-ID>`: …).
81
+ - **Out of scope:** phần để tài liệu/feature khác; nội dung gạch ngang đã loại; và **UC
82
+ `⏸ Chưa xét`** (BDD chưa `approved`) — liệt kê rõ mã UC + lý do. *Không ghi ra thì một UC bị
83
+ bỏ trông giống một UC không có gì để test.*
77
84
 
78
85
  ## 3. Test items theo vùng & độ ưu tiên
79
86
  Bảng — mỗi vùng kèm rule chi tiết + metadata:
80
87
 
81
- | # | Vùng test | Rule chi tiết | Layer (qa-designer) | Loại test | Pri | Ước lượng |
82
- |---|---|---|---|---|---|---|
83
- | ① | <vùng> | **BR-xx:** … <br>**BR-yy:** … | functional/gui-screen | Functional/Negative | P0 | n |
84
- | … | … | … | … | … | … | … |
88
+ | # | UC | Vùng test | Rule chi tiết | Layer (qa-designer) | Loại test | Pri | Ước lượng |
89
+ |---|---|---|---|---|---|---|---|
90
+ | ① | `<UC-ID>` | <vùng> | **BR-xx:** … <br>**BR-yy:** … | functional/gui-screen | Functional/Negative | P0 | n |
91
+ | … | … | … | … | … | … | … | … |
92
+
93
+ *Cột `UC` bắt buộc — một plan phủ nhiều UC, không có nó thì không ai biết vùng test nào của UC nào.*
85
94
 
86
95
  > Tổng ước lượng sơ bộ: ~N test case (+ E2E).
87
96
 
@@ -98,7 +107,9 @@ Kỹ thuật áp dụng: EP+BVA, Decision Table (cho logic điều kiện), stat
98
107
  integration, negative/exploratory; tự động hoá theo `CLAUDE.md` (Playwright + pytest-playwright + Trace + pytest-html).
99
108
 
100
109
  ## 5. Tiêu chí Vào / Ra
101
- - **Entry:** gap Blocker (trong DOC_GAP) đã Answered; doc phụ thuộc sẵn sàng; môi trường + tài khoản role.
110
+ - **Entry (chấm theo TỪNG UC, không chấm cả PRD):** gap 🔴 Blocker của **UC đó** (lọc cột `UC`
111
+ trong DOC_GAP) đã Answered; doc phụ thuộc sẵn sàng; môi trường + tài khoản role.
112
+ Ghi `Ready`/`Blocked` cho mỗi UC — blocker ở UC3 không dừng thiết kế test UC1.
102
113
  - **Exit:** pass P0=100%, P1≥95%; không còn defect Blocker/Critical; mọi BR/AC được trace; báo cáo pytest-html + Playwright Trace.
103
114
 
104
115
  ## 6. Rủi ro (risk-based)
@@ -33,4 +33,4 @@ Input: session note (#BUG + #IDEA).
33
33
  - **Weekly summary** (nếu yêu cầu): overview, top findings, coverage gap, recommendations.
34
34
 
35
35
  ## Output
36
- Mode 1: file session note. Mode 2: bug reports + file TC trong `{paths.qc_dir}/{UC-ID}/test-cases/` + summary.
36
+ Mode 1: file session note. Mode 2: bug reports + file TC trong `{qc_artifact_dir}test-cases/` + summary.
@@ -35,7 +35,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
35
35
  **Paths (nếu có):**
36
36
  - `paths.specs_dir` → gốc của spec artifact — PRD, BDD, tech-docs, design-spec. Cấu trúc: `{specs_dir}/{domain}/{prd-slug}/{ {TICKET-ID}-{prd-slug}.md | bdd/ | tech-docs/ | design-spec/}` (file PRD đặt tên `{TICKET-ID}-{prd-slug}.md`, là file `.md` duy nhất ở gốc feature folder)
37
37
  - `paths.refinement_dir` → thư mục output cho findings/review
38
- - `paths.qc_dir` → gốc artifact QC automation (hiện ở top-level, mỗi UC một thư mục con: `{qc_dir}/{UC-ID}/`)
38
+ - `paths.qc_dir` → gốc artifact QC automation (ở top-level, gom theo **PRD**: `{qc_dir}/{TICKET-ID}/{platform}/` — một `DOC_GAP.md` / `TEST_PLAN.md` / `REQUIREMENT_ANALYSIS.md` cho cả PRD, các UC là mục bên trong. Xem `steps/qc-scope.md`)
39
39
  - `paths.qc_skills_dir` → nơi các lệnh qc-* nạp QC skill (mặc định bundled `.agent/skills/qc`; override sang repo/submodule riêng của team QC để bản nâng cấp framework không ghi đè)
40
40
  - `paths.product_definitions_dir` → gốc product definition
41
41
  - `paths.domain_knowledge_dir` → gốc domain knowledge
@@ -0,0 +1,119 @@
1
+ # QC Scope — phân giải phạm vi cho mọi lệnh `qc-*`
2
+
3
+ **Chạy TRƯỚC phần logic riêng của lệnh, và SAU `steps/gate.md`.** Bước này chốt bốn thứ mà
4
+ cả 6 trạm QC đều cần, để chúng không tự suy mỗi trạm một kiểu:
5
+
6
+ | Biến | Là gì |
7
+ |---|---|
8
+ | `TICKET-ID` | mã PRD — **thư mục artifact QC mang tên này** |
9
+ | `active_platform` | `web` \| `app` \| `system` \| … — một QC pass khoá đúng MỘT nền |
10
+ | `qc_artifact_dir` | `{paths.qc_dir}/{TICKET-ID}/{active_platform}/` |
11
+ | `uc_list` | các UC của (PRD × nền) này, kèm trạng thái BDD từng UC |
12
+
13
+ > **Vì sao gom về một chỗ.** Luật phân giải nền từng được copy-paste ở 5 lệnh và câu chữ đã
14
+ > lệch nhau. Năm bản của một luật là nơi drift sống: sửa bốn, quên một, và trạm bị quên ghi
15
+ > artifact vào sai thư mục **trong im lặng**.
16
+
17
+ ---
18
+
19
+ ## 1 — `TICKET-ID`
20
+
21
+ Artifact QC gom theo **PRD**, không theo UC. Nên mọi trạm phải quy được về `TICKET-ID`:
22
+
23
+ | `$ARGUMENTS` là | Cách lấy |
24
+ |---|---|
25
+ | **UC-ID** (`{TICKET-ID}-UC{N}`) | phần **trước** `-UC` — đúng luật `steps/gate.md` Bước 1 dùng để tìm tech-doc gộp |
26
+ | **TICKET-ID** | dùng trực tiếp |
27
+ | một **path file** (`.feature` / PRD / design-spec) | phân giải `{domain}` + `{prd-slug}` theo luật `context-loader` Bước 1, rồi lấy `TICKET-ID` từ tên file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder |
28
+
29
+ Đối chiếu: `TICKET-ID` suy ra phải khớp tên file PRD thật. Lệch → **DỪNG**, in cả hai giá
30
+ trị. (Suy sai `TICKET-ID` là ghi cả một PRD vào sai thư mục — không có bước nào phía sau bắt được.)
31
+
32
+ ---
33
+
34
+ ## 2 — `active_platform`
35
+
36
+ > **PHẢI phân giải TRƯỚC mọi phép đọc `.feature`.** `{UC-ID}-SC{N}` chỉ độc nhất trong
37
+ > (UC × nền), nên một UC đa nền có **nhiều file `.feature`** — `bdd/web/`, `bdd/app/`,
38
+ > `bdd/system/` — và mỗi file mang `@trace.status` **riêng**: bản web có thể `approved`
39
+ > trong khi bản app còn `draft`. Đọc "file `.feature` của UC" khi chưa biết nền là đọc một
40
+ > file **bất kỳ trong ba**: báo `approved` trong khi bản đang dùng còn nháp, hoặc chặn oan
41
+ > một bản đã duyệt.
42
+
43
+ Theo thứ tự, dừng ở cái đầu tiên khớp:
44
+
45
+ 1. `$ARGUMENTS` nêu nền (`web`/`app`/`system`/…) → dùng.
46
+ 2. Target là một file `.feature` → đọc `# @trace.platform` của nó.
47
+ 3. Glob `{paths.specs_dir}/{domain}/{prd-slug}/bdd/*/` — **đúng một** thư mục nền → dùng nó.
48
+ 4. Glob `{paths.qc_dir}/{TICKET-ID}/*/` — **đúng một** thư mục nền đã có artifact → dùng nó.
49
+ *(chỉ dùng cho trạm 2–6; trạm `/qc-analyze` là trạm tạo ra thư mục đó nên không có gì để soi.)*
50
+ 5. Nhiều nền mà không suy được → hỏi *"QC pass này cho nền nào? (web/app/system)"*.
51
+ **Có `--yes`:** không hỏi — DỪNG với lỗi rõ ràng, vì đoán bừa nền là ghi artifact vào sai
52
+ thư mục và ghi `qc_status` vào sai sổ trace:
53
+ ```
54
+ ❌ {TICKET-ID} có {n} nền ({list}) — không suy được nền nào cho QC pass này.
55
+ Chạy headless thì phải nêu tường minh: /{lệnh} {TICKET-ID} web --yes
56
+ ```
57
+
58
+ Lưu `active_platform`. Từ đây, **mọi** phép đọc `.feature` chỉ đọc thư mục
59
+ `bdd/{active_platform}/` — không trộn SC chéo nền.
60
+
61
+ ---
62
+
63
+ ## 3 — `qc_artifact_dir`
64
+
65
+ ```
66
+ qc_artifact_dir = {paths.qc_dir}/{TICKET-ID}/{active_platform}/
67
+ ```
68
+
69
+ Chứa: `REQUIREMENT_ANALYSIS.md` · `DOC_GAP.md` · `TEST_PLAN.md` · `test-cases/*.Test.md`
70
+ — **mỗi loại đúng MỘT file cho cả PRD**, các UC là mục/hàng bên trong.
71
+
72
+ `{paths.qc_dir}` là folder top-level **nhìn thấy** trong repo QC (mặc định `docs/`, **không**
73
+ phải `.agent/` ẩn) để đội QC mở và xử lý output dễ dàng. Spec chính thức ở lại spec submodule
74
+ của PO — đừng ghi artifact QC vào đó.
75
+
76
+ > **Sổ trace KHÔNG theo layout này.** Nó vẫn là `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{active_platform}.tsv`
77
+ > — một sổ cho mỗi (UC × nền), vì mỗi hàng là một scenario. Liên kết giữa hai bên đi qua
78
+ > **cột `UC`** của bảng gap, không qua đường dẫn file.
79
+
80
+ ---
81
+
82
+ ## 4 — `uc_list`
83
+
84
+ Glob `{paths.specs_dir}/{domain}/{prd-slug}/bdd/{active_platform}/*.feature`. Mỗi file → một
85
+ UC: đọc `# @trace.id` (mã UC) và `# @trace.status` từ header.
86
+
87
+ Chia hai nhóm:
88
+
89
+ | Nhóm | Điều kiện | Xử lý |
90
+ |---|---|---|
91
+ | **Trong phạm vi** | `@trace.status: approved` | phân tích / thiết kế / chạy bình thường |
92
+ | **Chưa xét** | khác `approved` | **KHÔNG** phân tích; vẫn ghi một hàng vào bảng phạm vi kèm trạng thái thật |
93
+
94
+ In bảng phạm vi ra trước khi làm gì:
95
+ ```
96
+ Phạm vi QC — {TICKET-ID} / {active_platform}
97
+ ✅ {UC-ID} {tên UC} approved
98
+ ⏸ {UC-ID} {tên UC} draft → chưa xét
99
+ → {n} UC trong phạm vi · {m} chưa xét
100
+ ```
101
+
102
+ **Cờ `--include-draft`:** phân tích cả UC chưa duyệt, nhưng **vẫn in bảng trên** và đánh dấu
103
+ trong artifact là dựa trên BDD nháp.
104
+
105
+ **Không UC nào `approved` và không có `--include-draft` → DỪNG:**
106
+ ```
107
+ ❌ {TICKET-ID} ({active_platform}): 0/{n} UC có BDD approved — không có gì để chạy.
108
+ Cách đúng: người duyệt đặt `# @trace.status: approved` rồi chạy lại.
109
+ Muốn chạy sớm trên BDD nháp (prototype): thêm --include-draft
110
+ ```
111
+
112
+ > **Vì sao có `--include-draft` chứ không chặn cứng.** QC sớm trên BDD nháp là một cách dùng
113
+ > **cố ý được cho phép** từ trước (guard cũ là cảnh báo mềm, không phải chặn). Bỏ hẳn nó là
114
+ > lấy đi một năng lực đang có mà không ai khai. Còn để mặc định `approved`-only thì cái
115
+ > thường gặp là cái an toàn, và cái sớm phải nói ra.
116
+
117
+ > **Vì sao `--yes` không thay được `--include-draft`.** `--yes` nghĩa *"tôi không ngồi đây để
118
+ > trả lời"*; `--include-draft` nghĩa *"tôi biết BDD còn nháp và vẫn muốn chạy"*. Gộp hai cái
119
+ > là để một lần chạy headless âm thầm phân tích spec chưa chốt rồi bàn giao như thể đã chốt.
@@ -64,7 +64,9 @@ paths:
64
64
 
65
65
  # QC's OWN analysis/design working docs (qc-analyze/plan/design-test outputs:
66
66
  # REQUIREMENT_ANALYSIS.md, DOC_GAP.md, TEST_PLAN.md, test-cases/*.Test.md).
67
- # One subfolder per UC: {qc_dir}/{UC-ID}/. Default "docs" (the QC team's own
67
+ # Grouped by PRD: {qc_dir}/{TICKET-ID}/{platform}/ ONE DOC_GAP.md / TEST_PLAN.md /
68
+ # REQUIREMENT_ANALYSIS.md per (PRD x platform), with the UCs as rows/sections inside
69
+ # (see steps/qc-scope.md). Default "docs" (the QC team's own
68
70
  # convention), VISIBLE — not hidden under .agent/. NOTE: specs (PRD / .feature /
69
71
  # design-spec) are NOT here — they come from the PO spec submodule (spec_source).
70
72
  qc_dir: "docs"
@@ -38,7 +38,7 @@
38
38
 
39
39
  | Artifact | Nội dung |
40
40
  |----------|----------|
41
- | `docs/{UC-ID}/…` | `REQUIREMENT_ANALYSIS.md`, `DOC_GAP.md`, `TEST_PLAN.md`, `test-cases/*.Test.md` |
41
+ | `docs/{TICKET-ID}/{platform}/…` | `REQUIREMENT_ANALYSIS.md`, `DOC_GAP.md`, `TEST_PLAN.md`, `test-cases/*.Test.md` — **mỗi loại đúng một file cho cả (PRD × nền)**, các UC là hàng/mục bên trong (cột `UC`) |
42
42
  | Script Python pytest-playwright | Sinh từ `.Test.md` đã review |
43
43
  | Cột `qc_status` trong `.trace/…/{UC-ID}-{platform}.tsv` | Trạng thái QC **chính thức** |
44
44
  | Evidence + report | `/qc-report` — kèm product-gap đẩy về PO/Dev |