@educa-corp/sdd-framework 0.8.1 → 0.9.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 (66) hide show
  1. package/bin/lint-trace.js +156 -1
  2. package/bin/self-check.js +0 -146
  3. package/bin/trace-schema.json +7 -3
  4. package/core/FRAMEWORK_VERSION +1 -1
  5. package/core/commands/generate-code.md +42 -0
  6. package/core/commands/propose-scenario.md +1 -1
  7. package/core/commands/qc-analyze.md +22 -260
  8. package/core/commands/qc-design-test.md +1 -1
  9. package/core/commands/qc-plan.md +4 -7
  10. package/core/commands/qc-run-test.md +1 -1
  11. package/core/commands/refine-prd.md +20 -47
  12. package/core/commands/report-bug.md +1 -1
  13. package/core/commands/review-context.md +1 -27
  14. package/core/commands/validate-traces.md +154 -3
  15. package/core/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
  16. package/core/skills/qc/qa-analyst/acceptance-criteria.md +2 -4
  17. package/core/skills/qc/qa-analyst/business-rules.md +4 -38
  18. package/core/skills/qc/qa-analyst/data-flow.md +3 -5
  19. package/core/skills/qc/qa-analyst/spec-breakdown.md +7 -9
  20. package/core/skills/qc/qa-designer/e2e/journey.md +2 -2
  21. package/core/skills/qc/qa-designer/exploratory/charter.md +1 -1
  22. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  23. package/core/skills/qc/qa-designer/functional/api.md +2 -2
  24. package/core/skills/qc/qa-designer/functional/gui-feature.md +2 -2
  25. package/core/skills/qc/qa-designer/functional/gui-screen.md +2 -2
  26. package/core/skills/qc/qa-designer/integration/api.md +2 -2
  27. package/core/skills/qc/qa-designer/integration/db.md +2 -2
  28. package/core/skills/qc/qa-designer/integration/gui.md +2 -2
  29. package/core/skills/qc/qa-designer/integration/kafka.md +2 -2
  30. package/core/skills/qc/qa-designer/non-functional.md +2 -2
  31. package/core/skills/qc/qa-planner/test-plan.md +10 -13
  32. package/core/skills/qc/qa-reviewer/script/e2e.md +1 -1
  33. package/core/skills/qc/qa-reviewer/script/exploratory.md +1 -1
  34. package/core/skills/qc/qa-reviewer/script/functional.md +1 -1
  35. package/core/skills/qc/qa-reviewer/script/integration.md +1 -1
  36. package/core/skills/qc/qa-reviewer/script/non-functional.md +1 -1
  37. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  38. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  39. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  40. package/core/skills/qc/qa-reviewer/test-case/integration.md +2 -2
  41. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  42. package/core/skills/qc/qa-runner/e2e.md +1 -1
  43. package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
  44. package/core/skills/qc/qa-runner/functional/api.md +1 -1
  45. package/core/skills/qc/qa-runner/functional/gui-feature.md +1 -1
  46. package/core/skills/qc/qa-runner/functional/gui-screen.md +1 -1
  47. package/core/skills/qc/qa-runner/integration.md +1 -1
  48. package/core/skills/qc/qa-runner/non-functional.md +1 -1
  49. package/core/skills/qc/qa-runner/report/report.md +1 -1
  50. package/core/steps/review-fanout.md +1 -27
  51. package/core/templates/project-context.yaml +2 -2
  52. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +2 -2
  53. package/docs/04-reference/commands.md +1 -1
  54. package/docs/explain/03-refine-prd.md +6 -8
  55. package/docs/explain/15-qc-analyze.md +7 -10
  56. package/docs/explain/16-qc-plan.md +2 -2
  57. package/package.json +3 -2
  58. package/bin/qc-base-map.json +0 -595
  59. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +0 -117
  60. package/core/skills/qc/qa-analyst/exhaustive-gap-scanner.md +0 -174
  61. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +0 -100
  62. package/core/skills/qc/qa-planner/risk-model.md +0 -106
  63. package/core/steps/gap-verify.md +0 -231
  64. package/docs/plans/qc-implementation-log.md +0 -1446
  65. package/docs/plans/qc-merge-plan.md +0 -502
  66. package/docs/plans/qc-sync-command.md +0 -358
@@ -1,117 +0,0 @@
1
- ---
2
- version: 1.0
3
- updated: 2026-08-25
4
- ported_from: ui-automation-testing
5
- upstream_path: skills/qa-tc-analyst/spec-issue-reporter/DOC_GAPS.template.md
6
- upstream_sha: c7ca6cfb798c609f18ffe20a38f64f95c76e1919
7
- ---
8
-
9
- > **Template DUY NHẤT cho file gap của `/qc-analyze`** *(B9 — hợp nhất 2026-08-25)*.
10
- > Bản 9 cột cũ đã bỏ: nó thiếu đúng hai thứ PO cần — cột *Giao cho đội* và ô câu hỏi 4 phần.
11
- > Giữ một bản kém hơn làm mặc định là để người không biết có cờ nhận bản kém.
12
- >
13
- > **Một chỗ CỐ Ý khác upstream:** mức nặng nhất dùng từ **`Blocker`**, không phải `Critical`.
14
- > Lý do: `/qc-run-test` đọc `🔴 Blocker` để đặt *"scenario đang chờ PO"* vào sổ kết quả trace.
15
- > Đổi từ là đứt liên kết đó. Ba mức còn lại giữ nguyên upstream.
16
-
17
- # DOC GAP -- <UC>: <Tên UC>
18
-
19
- | Trường | Giá trị |
20
- |---|---|
21
- | Feature | `<FEATURE>` |
22
- | UC | `<UC> — <Tên UC>` |
23
- | Tài liệu nguồn | `<đường dẫn PRD>` · `<đường dẫn BDD nếu có>` · `<các file inputs/ liên quan>` |
24
- | Ngày phân tích | `<YYYY-MM-DD>` |
25
- | Tổng số gap | `<N>` (Blocker: x · High: y · Medium: z · Low: w) |
26
- | Trạng thái chung | 🔴 Blocked / 🟠 Cần làm rõ / 🟢 Đủ rõ để thiết kế TC |
27
-
28
- ---
29
-
30
- ## Tài liệu đầu vào đã đọc để phân tích
31
-
32
- > Liệt kê **đầy đủ** mọi file đã đọc để dựng phân tích gap (spec chính + mọi ref-link + transitive 1-hop). Đây là căn cứ độ phủ — mọi file đã mở đều phải có mặt, KHÔNG bỏ sót. Đường dẫn tính từ `{paths.specs_dir}`.
33
-
34
- | # | Đường dẫn (từ `{paths.specs_dir}`) | Vai trò | Phiên bản |
35
- |---|---|---|---|
36
- | 1 | `<đường dẫn spec chính>` | **Spec chính** | `<vX.Y>` |
37
- | 2 | `<đường dẫn ref>` | Ref bắt buộc — `<lý do>` | `—` |
38
- | ... | ... | Transitive 1-hop — `<feature liền kề / dịch vụ tiêu thụ>` | `—` |
39
-
40
- **Tổng: `<N>` tài liệu.** Lane API: `<có → liệt kê openapi.yaml/*.dbml/tdd | không có → SKIP, không đọc, không bịa endpoint>` *(chỉ áp khi framework đã nhận trục lane — xem B5)*. Không dùng làm evidence: Change log · Appendix · mục Giả định AI.
41
-
42
- ---
43
-
44
- | 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 |
45
- |---|---|---|---|---|---|---|---|---|---|
46
- | GAP-<UC>-001 | MISSING / AMBIGUOUS / CONTRADICTORY / ASSUMPTION | Tiêu đề ngắn mô tả vấn đề | **Bối cảnh:** Ngữ cảnh dẫn đến gap này.<br/>**Vấn đề:** Điều gì chưa được spec hoặc mâu thuẫn.<br/>**Tại sao quan trọng:** Hậu quả nếu không làm rõ.<br/>**Gợi ý:** Ai cần làm gì để giải quyết. | `<đường dẫn file spec>` `<TÊN-BR hoặc AC gốc trong PRD, ví dụ FEAT-01-2-UC4-BR11>`: trích nguyên văn | Dev / PO / BA / Design | 🔴 Blocker | | Open | |
47
-
48
- ---
49
-
50
- ## Ưu tiên xử lý
51
-
52
- | Mức độ | Gap ID |
53
- |---|---|
54
- | 🔴 Blocker | GAP-<UC>-00x · ... |
55
- | 🟠 High | GAP-<UC>-00x · ... |
56
- | 🟡 Medium | GAP-<UC>-00x · ... |
57
- | ⚪ Low | GAP-<UC>-00x · ... |
58
-
59
- **Cần chốt trước khi viết test case:**
60
- - GAP-<UC>-00x: <lý do block>
61
-
62
- ---
63
-
64
- ## Chú thích (Legend)
65
-
66
- ### Loại Gap
67
-
68
- | Loại | Mô tả |
69
- |---|---|
70
- | MISSING | Thông tin, chức năng, quy tắc, hoặc kịch bản chưa được mô tả trong bất kỳ tài liệu nào trong `{paths.specs_dir}`. |
71
- | AMBIGUOUS | Mô tả mơ hồ, có thể hiểu theo nhiều cách, hoặc thiếu chi tiết để viết kịch bản kiểm thử. |
72
- | CONTRADICTORY | Hai hoặc nhiều tài liệu trong `{paths.specs_dir}` mô tả cùng một hành vi nhưng mâu thuẫn nhau. |
73
- | ASSUMPTION | Giả định do nhóm QA tự suy luận từ tài liệu trong `{paths.specs_dir}`, chưa được PO/Dev xác nhận tường minh. |
74
-
75
- ### Mức độ
76
-
77
- | Mức | Ý nghĩa |
78
- |---|---|
79
- | 🔴 Blocker | Chặn viết kịch bản kiểm thử hoặc lập trình — không thể tiến hành nếu chưa có câu trả lời. |
80
- | 🟠 High | Ảnh hưởng đến nhiều kịch bản kiểm thử hoặc logic nghiệp vụ chính — cần giải quyết trước khi viết test case. |
81
- | 🟡 Medium | Ảnh hưởng đến một số kịch bản cụ thể — cần giải quyết trước sprint kiểm thử. |
82
- | ⚪ Low | Ít ảnh hưởng — có thể ghi giả định tạm thời và xử lý trong sprint review. |
83
-
84
- ### Giao cho đội
85
-
86
- | Ký hiệu | Đội |
87
- |---|---|
88
- | Dev | Đội phát triển (Frontend + Backend) |
89
- | Architect | Kiến trúc sư hệ thống |
90
- | PO | Product Owner |
91
- | BA | Business Analyst |
92
- | Design | Đội thiết kế UX/UI |
93
- | Analytics | Nhóm dữ liệu / phân tích |
94
-
95
- ---
96
-
97
- ## ⚠️ Checklist bắt buộc trước khi lưu file
98
-
99
- Trước khi lưu file gap, kiểm tra **từng hàng** trong bảng gap:
100
-
101
- - [ ] **Có section `Tài liệu đầu vào đã đọc để phân tích`** – bảng liệt kê **đầy đủ** mọi file đã đọc (spec chính + ref-link + transitive 1-hop), có đường dẫn `{paths.specs_dir}`, vai trò, phiên bản; ghi tổng số + trạng thái lane API. KHÔNG bỏ sót file nào đã mở.
102
- - [ ] **10 cột đủ** – đúng thứ tự: `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`
103
- - [ ] **Cột 3 = `Vấn đề cần confirm`** – KHÔNG viết tắt thành `Vấn đề`
104
- - [ ] **Cột 4 = `Câu hỏi / Lý do cần confirm & Gợi ý`** – bắt buộc có đủ 4 phần, tách bằng `<br/>`:
105
- ```
106
- **Bối cảnh:** ...<br/>**Vấn đề:** ...<br/>**Tại sao quan trọng:** ...<br/>**Gợi ý:** ...
107
- ```
108
- Không viết 4 mục liên tiếp trên cùng một dòng.
109
- - [ ] **Cột 5 = `Trích đoạn tài liệu (Evidence)`** – KHÔNG viết tắt thành `Evidence`; dẫn nguyên văn + đường dẫn file `{paths.specs_dir}`; **dùng PRD source ID** (ví dụ `FEAT-01-2-UC4-BR11`), KHÔNG dùng internal analysis ID (ví dụ `BR-UC4-12`)
110
- - [ ] **Cột Mức độ** (cột 7) – bắt buộc dùng emoji: `🔴 Blocker` / `🟠 High` / `🟡 Medium` / `⚪ Low`. Không được ghi text thuần.
111
- - [ ] **Cột Giao cho đội** (cột 6) – dùng: `Dev` / `PO` / `BA` / `Design` / `Architect` / `Analytics` hoặc kết hợp. Nếu thấy "Open" ở đây → đang bị lệch cột.
112
- - [ ] **Cột Người trả lời = vai trò** (PO / BA / Dev / Design / ...). Nếu thấy "Open" ở đây → đang bị lệch cột.
113
- - [ ] **Cột Trạng thái** = `Open` / `Resolved` / `Out of Scope` / `Re-scoped → Covered`
114
- - [ ] **Trạng thái chung** trong metadata có emoji: `🔴 Blocked` / `🟠 Cần làm rõ` / `🟢 Đủ rõ để thiết kế TC`
115
- - [ ] **Có đủ 3 section cuối**: Ưu tiên xử lý · Chú thích (Legend) với bảng đầy đủ
116
- - [ ] **KHÔNG có section "Change log"** và **KHÔNG có section "AI Assumptions"**
117
- - [ ] **Evidence chỉ từ `{paths.specs_dir}`** – không dùng file trong `{paths.qc_dir}` nội bộ (TC_*.md, REQUIREMENT_ANALYSIS*.md, DOC_GAP*.md khác)
@@ -1,174 +0,0 @@
1
- ---
2
- version: 1.0
3
- updated: 2026-08-25
4
- ported_from: ui-automation-testing
5
- upstream_path: skills/qa-tc-analyst/exhaustive-gap-scanner.md
6
- upstream_sha: b3f5aa112ec2fb93100d8945a3fa3d5fe904eb26
7
- port_completeness: partial
8
- ---
9
-
10
- # Exhaustive Gap Scanner — 5 chiều quét gap
11
-
12
- Năm **lăng kính** để quét gap tài liệu. Mỗi lăng kính chỉ lo phần mình và **mù với các
13
- lăng kính khác** — đó là điều làm độ phủ cao hơn một lượt đọc tuần tự, nơi phần cuối tài liệu
14
- luôn bị lướt.
15
-
16
- > **Bốn trong năm chiều đang BẬT** ở `/qc-analyze`: `D2` · `D3` · `D4` · `D5`*(thu hẹp)*.
17
- > Chỉ `D1` tắt. File này khai *nội dung* các chiều; việc *chạy* chúng thuộc
18
- > `steps/review-fanout.md`.
19
-
20
- ## Chiều nào đang bật
21
-
22
- | Chiều | Trạng thái | Bằng chứng *(kiểm từng câu hỏi — xem `docs/plans/qc-implementation-log.md` §Kiểm chứng 31 câu hỏi)* |
23
- |---|---|---|
24
- | `D1` Luật nghiệp vụ | ⏸️ **tắt** | **4/5 câu đã có chỗ hỏi, và hỏi cụ thể hơn** — `business-rules.md` hỏi *"min/max · ký tự cho phép · trim · định dạng"* thay vì *"ngưỡng đã chốt chưa"* |
25
- | `D2` Xử lý lỗi | ✅ **bật** | **4/6 câu KHÔNG AI HỎI** — không kỹ năng nào chuyên về *"hết số lần thử lại thì đi đâu"* |
26
- | `D3` Giao diện | ✅ **bật** | **1/8 phủ tốt, 3 hở hẳn** — không ai đối chiếu chữ trên nút giữa các tài liệu |
27
- | `D4` Dữ liệu & cấu hình | ✅ **bật** | **6/6 câu KHÔNG AI HỎI** — chiều đáng giá nhất |
28
- | `D5` Đối chiếu chéo | ✅ **bật, THU HẸP** | **2/4 cặp đang hở** — cả hai dính `design-spec/`. Hai cặp còn lại đã có người làm → bỏ. Xem §Phạm vi ở D5 |
29
-
30
- > **`D5` từng bị tắt, và đó là quyết định SAI.** Lý do tắt ban đầu — *"trùng nhiều"* — đúng một
31
- > nửa: nó phủ **bốn** cặp tài liệu, và chỉ **hai** cặp đã có người làm. Hai cặp còn lại
32
- > (`PRD ↔ design-spec/` và `bdd/ ↔ design-spec/`) **không ai đối chiếu nội dung**.
33
- >
34
- > Sai vì suy từ ấn tượng thay vì đếm danh sách. Bảng kiểm chứng 31 câu hỏi trong nhật ký là thứ
35
- > đáng lẽ phải làm **trước** khi quyết.
36
-
37
- > **Chi phí:** bật cả 5 (không thu hẹp) tốn ~5–6 lần token so với không bật. Cấu hình hiện tại —
38
- > 3 chiều đầy đủ + `D5` thu hẹp — vào khoảng **~3,5 lần**. `D5` rẻ hơn một chiều thường vì nó chỉ
39
- > so 2 cặp, và `design-spec/` thì trạm QC **đã đọc từ trước**.
40
-
41
- ## Cố ý KHÔNG port nửa còn lại
42
-
43
- Bản upstream tự cài lại toàn bộ cơ chế fan-out bằng tay: một Coordinator kiểm kê tài liệu,
44
- dựng SPAWN PLAN, gọi song song 5 agent, rồi consolidate + dedup + đánh ID.
45
-
46
- Framework **đã có đúng cơ chế đó** ở `steps/review-fanout.md` — và bản của framework còn có
47
- thêm hai thứ upstream không có: vòng **completeness-critic** lặp tới khi hai vòng liền không
48
- sinh gì mới, và **agent cap** gom batch khi fan-out quá rộng.
49
-
50
- Port cả phần điều phối = nuôi hai bản cài đặt của cùng một thứ, rồi chúng trôi khỏi nhau.
51
- Nên file này **chỉ giữ phần nội dung** (5 mandate), phần điều phối để `review-fanout` lo.
52
-
53
- *Ghi vào `port_completeness: partial` ở frontmatter — khi đồng bộ ngược sau này, đừng hiểu
54
- phần thiếu là "ta cố ý xoá nội dung".*
55
-
56
- ---
57
-
58
- ## Ràng buộc nguồn *(áp cho cả 5 chiều)*
59
-
60
- - Chỉ dùng **spec repo** (`{paths.specs_dir}`) làm evidence. KHÔNG dùng artifact nội bộ do
61
- chính pipeline sinh ra (`{paths.qc_dir}/**` — test-case, test-plan, file gap khác).
62
- - **Bỏ qua** section **Change Log** · **Appendix** · **Giả định AI / AI Assumptions** trong mọi
63
- tài liệu. Evidence CHỈ lấy từ thân bài: AC · BR · UC · Wireframe · Screen Spec · Scenario.
64
- - **KHÔNG bịa** endpoint, bảng, field, hay tài liệu không tồn tại.
65
-
66
- ---
67
-
68
- ## Năm chiều
69
-
70
- Truyền vào `steps/review-fanout.md` làm `DIMENSIONS`. Chiều nào không có tài liệu đầu vào
71
- tương ứng thì **bỏ hẳn** — không tạo gap rỗng, không nhắc tới nó trong output.
72
-
73
- ### D1 · Luật nghiệp vụ *(⏸️ TẮT ở `/qc-analyze` — xem bảng trên)*
74
- - Logic rẽ nhánh: điều kiện đã đủ chưa? Thiếu nhánh nào?
75
- - Ngưỡng / ràng buộc: đã chốt số cụ thể hay còn để ngỏ?
76
- - Ngoại lệ: trường hợp biên nào chưa được xử lý trong spec?
77
- - Rule mâu thuẫn giữa các tài liệu?
78
- - Chỗ nào người viết test **buộc phải giả định** vì spec không rõ?
79
-
80
- ### D2 · Xử lý lỗi *(✅ bật)*
81
- - Quá hạn (timeout) → hành vi là gì?
82
- - Số lần thử lại đã spec chưa? Khoảng cách giữa các lần?
83
- - Thử lại hết số lần → hệ thống làm gì?
84
- - Hàng đợi lỗi: ai xử lý? Có cảnh báo cho người vận hành không?
85
- - Với **từng loại lỗi**: màn nào hiện, người dùng làm được gì tiếp?
86
- - Khôi phục: người dùng thử lại được không? Luồng đi tiếp hay bị chặn?
87
-
88
- ### D3 · Giao diện *(✅ bật — bỏ hẳn nếu không có BDD / design-spec / wireframe)*
89
- - **Trạng thái màn**: thiếu state nào? (đang tải · rỗng · lỗi · thành công · một phần · vô hiệu)
90
- - **Chữ & nhãn**: text nút/tiêu đề/thông báo/gợi ý có nhất quán trong cùng tài liệu và **giữa**
91
- các tài liệu không?
92
- - **Điều hướng**: từ mỗi màn, đi tiếp được đâu và quay lại được đâu? Đã spec đủ mọi đường chưa?
93
- - **Kiểm tra & phản hồi**: rule validate đã spec? Thông báo lỗi/thành công đã có **nội dung
94
- cụ thể** chưa?
95
- - **Trạng thái biên**: màn trống, danh sách rỗng, quá hạn, kết quả 0 — trải nghiệm thế nào?
96
- - **UI đã bị gỡ**: component/popup/màn còn trong design-spec nhưng PRD/BDD đã bỏ?
97
- - **Đa nền** *(nếu có)*: hành vi trên các nền/breakpoint có nhất quán không?
98
- - **Tài nguyên hiển thị**: loại asset (animation/ảnh/video) và tiêu chí hiển thị đã xác định chưa?
99
-
100
- ### D4 · Dữ liệu & cấu hình *(✅ bật — bỏ hẳn nếu không có bảng tính điểm / dữ liệu mẫu / cờ tính năng / spec môi trường)*
101
- - Bảng điểm / rule tính toán / bảng ánh xạ: có **đủ dữ liệu để tự kiểm chứng kết quả tính** không?
102
- - Dữ liệu mẫu: có ví dụ đủ để dựng môi trường test không?
103
- - Cấu hình đổi **giữa lúc đang chạy** thì hành vi là gì? Chốt giá trị tại thời điểm nào?
104
- - Phụ thuộc môi trường: service, hàng đợi, DB cần thiết đã được spec cho môi trường test chưa?
105
- - Việc dựng dữ liệu có phụ thuộc thứ còn để ngỏ hoặc chưa làm không?
106
- - Cờ tính năng: cờ nào ảnh hưởng hành vi cần test? Giá trị mặc định ở môi trường test là gì?
107
-
108
- ### D5 · Đối chiếu chéo tài liệu *(✅ bật — THU HẸP còn 2 cặp, xem dưới)*
109
-
110
- > **Nhiệm vụ của chiều này là PHÁT HIỆN cặp lệch + gắn HƯỚNG thô. KHÔNG tự chốt loại cuối** —
111
- > việc phân loại và lọc báo-oan do `steps/gap-verify.md` làm (T5 xác định hướng, T3b xác định
112
- > mâu thuẫn thật). Chiều này chỉ đưa bằng chứng *"X nói khác/thiếu/thừa so với Y"*.
113
-
114
- #### PHẠM VI — chỉ hai cặp, không phải bốn
115
-
116
- Bản upstream so **mọi cặp** tài liệu trong feature package. Ở framework, hai cặp đã có chỗ khác
117
- làm — so lại là nhân đôi công việc và PO nhận hai câu hỏi cho một vấn đề.
118
-
119
- | Cặp | Ở framework | |
120
- |---|---|---|
121
- | **PRD ↔ `design-spec/`** | **không ai so nội dung** — `/generate-bdd` chỉ kiểm `Built from PRD` (số phiên bản). Cùng phiên bản mà nội dung lệch thì lọt | ✅ **SO** |
122
- | **`bdd/{platform}/` ↔ `design-spec/`** | không ai | ✅ **SO** |
123
- | PRD ↔ `bdd/` | `/review-context` **B1** đã làm (AC/BR nào chưa có scenario) | ❌ bỏ |
124
- | PRD · `bdd/` ↔ `tech-docs/` | `/qc-analyze` §Đối chiếu tài liệu kỹ thuật đã làm (6 mục) | ❌ bỏ |
125
-
126
- > **Cả hai cặp SO đều dính `design-spec/`** — tức phần **Designer vẽ**. Đây là artifact duy nhất
127
- > trong feature package mà **không tài liệu nào đối chiếu nội dung với nó**.
128
- >
129
- > `design-spec/` ≠ `tech-docs/`: cái đầu là *giao diện người dùng thấy*, cái sau là *hợp đồng hệ
130
- > thống*. `tech-docs/` đã được phủ ở §Đối chiếu tài liệu kỹ thuật của `/qc-analyze`.
131
-
132
- Trạm QC **đã đọc `design-spec/`** từ trước (nó nằm trong danh sách nguồn). Nên chiều này không
133
- nạp thêm file nào — chỉ bắt nó **so** thay vì chỉ **đọc**.
134
-
135
- #### Bốn hướng lệch
136
-
137
- Lấy **PRD làm gốc**, đối chiếu **thân bài** (KHÔNG đọc Change Log):
138
-
139
- | Hướng | Nghĩa | Ai xử lý |
140
- |---|---|---|
141
- | **THIẾU** *(design-spec < PRD)* | PRD có màn / trạng thái / hành vi mà `design-spec/` **không** mô tả | Designer bổ sung |
142
- | **THỪA** *(design-spec > PRD)* | `design-spec/` **tự thêm** màn/nút/hành vi mà PRD không định nghĩa | **PO chốt**: giữ (rồi định nghĩa hệ quả vào PRD) hay gỡ |
143
- | **MÂU THUẪN** | cùng một hành vi/giá trị/chữ nhưng hai tài liệu nói khác nhau | PO + Designer |
144
- | **LỆCH-REF** | `design-spec/` trích số/tên BR·AC đã đổi nghĩa — mở đúng BR/AC đó trong PRD **hiện tại**: ref không còn, hoặc mang nghĩa khác | PO |
145
-
146
- > **THIẾU vs THỪA phải phân biệt đúng** — đây là lỗi framing hay gặp nhất, và hai hướng xử lý
147
- > **ngược nhau**. Gọi *"thiết kế thiếu"* trong khi thiết kế **thừa** là đặt sai đề bài cho cả PO
148
- > lẫn Designer: một bên tưởng phải vẽ thêm, một bên đáng lẽ phải quyết giữ hay gỡ.
149
-
150
- #### Với cặp `bdd/` ↔ `design-spec/` — soi gì
151
-
152
- - Kịch bản test đi qua một **trạng thái màn** mà `design-spec/` không có (`loading`/`error`/`empty`)?
153
- - Kịch bản test tác động lên một **thành phần giao diện** không có trong Component Inventory?
154
- - `design-spec/` mô tả một **đường điều hướng** mà không kịch bản nào đi qua?
155
-
156
- *(Chiều này chỉ chạy khi feature có `design-spec/`. Feature `system` không có → bỏ hẳn cặp này.)*
157
-
158
- ---
159
-
160
- ## Sau khi quét — BẮT BUỘC thẩm định
161
-
162
- Fan-out càng rộng thì gap bịa càng nhiều: đây là cơ chế **đẩy recall**, tự nó không có gì
163
- kéo precision. Chạy `steps/gap-verify.md` trên tập gap trước khi bàn giao — đó là nửa còn lại.
164
-
165
- **Hai cách gọi, tuỳ lệnh:**
166
-
167
- | Lệnh gọi có | Thẩm định chạy ở đâu |
168
- |---|---|
169
- | `VERIFY = on` | tự động ở `review-fanout` Phase 2.5 — dùng khi fan-out là **nguồn gap duy nhất** |
170
- | `VERIFY = off` | lệnh gọi tự chạy `gap-verify` **sau khi gộp** — dùng khi còn nguồn gap khác |
171
-
172
- `/qc-analyze` dùng cách thứ hai: gap đến từ **cả** 4 kỹ năng phân tích **và** fan-out, nên phải
173
- gộp trước rồi mới thẩm định một lần. Thẩm định hai tập rời thì phép kiểm `T6` (*"hai gap cùng gốc
174
- thì gộp lại"*) không bắt được trùng lặp chéo nguồn.
@@ -1,100 +0,0 @@
1
- ---
2
- version: 1.0
3
- updated: 2026-08-25
4
- ported_from: ui-automation-testing
5
- upstream_path: skills/qa-tc-analyst/spec-issue-reporter.md
6
- upstream_sha: 5b5c0c886e92b474e0a5a8157ba58a7c3ce4b3f8
7
- ---
8
-
9
- # Spec Issue Reporter — gom mọi điểm mơ hồ thành báo cáo gửi PO/BA/Dev
10
-
11
- Gom mọi điểm mơ hồ / thiếu / mâu thuẫn phát hiện được trong lúc phân tích thành **một** báo cáo
12
- có cấu trúc, đủ thông tin để người nhận trả lời được ngay.
13
-
14
- > **`/qc-analyze` nạp file này** *(B9 — hợp nhất 2026-08-25)*. Nó là luật viết cho
15
- > `DOC_GAP.template.md` — template **duy nhất** của file gap. Bản 9 cột cũ đã bỏ.
16
- >
17
- > **Một chỗ cố ý khác upstream:** mức nặng nhất dùng `🔴 Blocker`, không phải `Critical` —
18
- > `/qc-run-test` đọc đúng từ đó để đặt *"scenario đang chờ PO"* vào sổ trace.
19
-
20
- ## Đầu vào
21
-
22
- Mọi dấu `?`, chỗ thiếu mapping, chỗ mâu thuẫn mà các skill phân tích khác đã ghi nhận.
23
-
24
- ## Đầu ra
25
-
26
- > ⛔ **BẮT BUỘC theo template — tự-validate trước khi lưu.** Đây là skill hay xuất **sai
27
- > template** nhất: tự chế cột, gộp `Trạng thái` với `Câu trả lời`, thiếu `Giao cho đội` /
28
- > `Người trả lời`, dùng Loại phi chuẩn (`SYNC` / `Drift` / `FEASIBILITY`), quên section
29
- > *Ưu tiên xử lý* + *Chú thích*.
30
- >
31
- > TRƯỚC khi lưu: mở `{paths.qc_skills_dir}/qa-analyst/DOC_GAP.template.md`, chạy hết
32
- > **"⚠️ Checklist bắt buộc trước khi lưu file"** ở cuối template, sửa cho khớp 100%.
33
-
34
- Một file gap gồm:
35
-
36
- 1. **Section `Tài liệu đầu vào đã đọc để phân tích`** — BẮT BUỘC, đặt ngay sau metadata,
37
- **trước** bảng gap. Bảng liệt kê **đầy đủ** mọi file đã đọc (spec chính + mọi ref-link +
38
- transitive 1-hop): `# | Đường dẫn | Vai trò | Phiên bản`, kèm tổng số.
39
- 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
- đượ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`
43
-
44
- ## Quy tắc
45
-
46
- - **Evidence bắt buộc** — dẫn **nguyên văn** in nghiêng + tham chiếu vị trí cụ thể
47
- (`〔file §section〕`). Dùng ✕ khi mâu thuẫn giữa hai chỗ. Không phán đoán chủ quan.
48
- - **Cột 4 phải đủ bốn mục**, tách bằng `<br/>` thành từng dòng riêng trong cell:
49
- ```
50
- **Bối cảnh:** …<br/>**Vấn đề:** …<br/>**Tại sao quan trọng:** …<br/>**Gợi ý:** …
51
- ```
52
- Không viết bốn mục liên tiếp trên một dòng. Ngôn ngữ dễ hiểu cho PO/Design/Dev.
53
- *"Tại sao quan trọng"* là thứ cho phép người nhận **xếp ưu tiên**; *"Gợi ý"* là thứ cho phép
54
- họ **trả lời nhanh** thay vì nghĩ lại từ đầu.
55
- - **Tham chiếu BR/AC dùng ID GỐC trong PRD** (vd `FT-001-UC4-BR11`), **không** dùng ID nội bộ
56
- 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
- đọc không tra ngược được về PRD.
58
- - **Mức độ bắt buộc có emoji**: `🔴 Blocker` · `🟠 High` · `🟡 Medium` · `⚪ Low`.
59
- - **Pipe trong cell**: escape thành `\|` (vd `{a\|b\|c}`), nếu không sẽ vỡ bảng.
60
- - **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
- 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
62
- **không render** trong bảng chính. Thêm xong cập nhật luôn *Tổng số gap* ở header và bảng
63
- *Ưu tiên xử lý*.
64
- - **KHÔNG thêm section "Change log"** và **KHÔNG thêm section "AI Assumptions"** — mọi giả định
65
- AI tự suy là gap loại `ASSUMPTION` trong bảng, không tách thành section riêng.
66
-
67
- ## Trạng thái hợp lệ
68
-
69
- `Open` · `Resolved` · `Out of Scope` · `Re-scoped → Covered`
70
-
71
- **Khi một trường hợp đã đánh dấu `Out of Scope` được yêu cầu viết test:**
72
-
73
- 1. Kiểm PRD xem có ghi chú thay đổi phạm vi không — một change request có thể **dời trách
74
- nhiệm kiểm tra** từ UC này sang UC khác.
75
- 2. Có ghi chú rõ ràng → đổi trạng thái `Out of Scope` → `Re-scoped → Covered`, ghi test-case
76
- mới vào cột *Câu trả lời*.
77
- 3. Không tìm thấy ghi chú nhưng QC vẫn yêu cầu → **vẫn viết test** (QC chốt phạm vi), đồng
78
- thời ghi chú lại để truy vết.
79
-
80
- ## Xác định IN-SCOPE vs NGOÀI PHẠM VI — căn cứ SPEC, không dùng artifact tự sinh
81
-
82
- > ⚠️ **Nguồn quyết định phạm vi là SPEC, không phải tài liệu do chính pipeline QC sinh ra.**
83
-
84
- - Khi phán một hạng mục là in-scope hay ngoài phạm vi, phải trích **spec authority**: mục
85
- *Scope/Phạm vi* của PRD, `@trace.platform` của file `.feature`, hoặc design-spec nêu rõ nền
86
- tảng áp dụng.
87
- **TUYỆT ĐỐI KHÔNG** lấy `TEST_PLAN.md` / `*.Test.md` dưới `{paths.qc_dir}` làm căn cứ — chúng
88
- do chính pipeline này sinh ra, nên dùng chúng là **vòng lặp**: lấy *hệ quả* của phạm vi làm
89
- *nguồn* của phạm vi.
90
- - **Bố cục file gap:** chỉ gap **in-scope** nằm trong bảng chính và tính vào *Ưu tiên xử lý*
91
- (đây là gap sẽ chặn hoặc đẻ ra test). Gap **thật nhưng ngoài phạm vi** (thuộc feature khác)
92
- và gap **lệch đồng bộ tài liệu** → gom vào section **"Ghi chú ngoài phạm vi"** riêng, không
93
- trộn vào bảng chính, không tính ưu tiên. **Giữ audit trail, đừng xoá.**
94
- - Phân vân in hay out → mặc định **giữ in-scope + hỏi lại**. Loại nhầm ra ngoài phạm vi làm
95
- **mất coverage trong im lặng** — nguy hiểm hơn hẳn việc thừa một gap ngoài lề.
96
-
97
- ## Sau khi sinh file gap — BẮT BUỘC thẩm định
98
-
99
- Chạy `steps/gap-verify.md` trên tập gap vừa sinh trước khi bàn giao. Skill này **tìm** gap;
100
- nó không có cơ chế nào tự phát hiện gap mình vừa bịa ra. Xem `gap-verify` §"Nguyên tắc tối thượng".
@@ -1,106 +0,0 @@
1
- ---
2
- version: 1.0
3
- updated: 2026-08-25
4
- ported_from: ui-automation-testing
5
- upstream_path: skills/qa-tc-analyst/risk-acceptance-analyzer.md
6
- upstream_sha: 5eca5091acd30e063d20b63f12b04e2d1c78ac83
7
- port_completeness: partial
8
- ---
9
-
10
- # Risk Model — cách tính mức rủi ro và dùng nó để chia độ sâu test
11
-
12
- `test-plan.md` có **khung** bảng rủi ro (`§6`) nhưng không có **cách điền**. File này là cách điền.
13
-
14
- Nạp cùng `test-plan.md` khi lập plan. Đầu ra không phải file riêng — nó điền vào `§6 Rủi ro`
15
- và `§5 Tiêu chí Vào/Ra` của `TEST_PLAN.md`.
16
-
17
- ## Cố ý chỉ port một phần
18
-
19
- Bản upstream (`risk-acceptance-analyzer`) có 5 phase. Ba phase bị **cố ý bỏ** vì trạm 1 đã làm rồi:
20
-
21
- | Phase upstream | Vì sao không port |
22
- |---|---|
23
- | Test Conditions | trùng vai với `qa-analyst/spec-breakdown` + `business-rules` (trạm 1) |
24
- | Ambiguity & Gap | trùng vai với `DOC_GAP` + `steps/gap-verify.md` (trạm 1) |
25
- | Acceptance Criteria | trùng vai với `qa-analyst/acceptance-criteria` (trạm 1) |
26
-
27
- Chỉ port **Phase 3 (Risk Register)** và **Phase 5 (Ưu tiên + Entry/Exit)** — hai phần trạm 2 sở hữu.
28
-
29
- *Ghi `port_completeness: partial` ở frontmatter — lần đồng bộ sau đừng hiểu phần thiếu là
30
- "ta cố ý xoá nội dung".*
31
-
32
- ---
33
-
34
- ## Bước 1 — Liệt kê rủi ro sản phẩm
35
-
36
- Bảy nguồn rủi ro. Quét từng cái, không bỏ nguồn nào chỉ vì "feature này chắc không có":
37
-
38
- | # | Nguồn | Dấu hiệu trong PRD/BR |
39
- |---|---|---|
40
- | 1 | **Logic phức tạp** | nhiều điều kiện AND/OR lồng nhau, bảng định tuyến, công thức tính |
41
- | 2 | **Tiền / thanh toán** | giao dịch, hoàn tiền, mã giảm giá, hạn mức |
42
- | 3 | **Dữ liệu nhạy cảm** | thông tin cá nhân, số điện thoại, thông tin định danh |
43
- | 4 | **Tích hợp nhiều phần** | gọi dịch vụ khác, hàng đợi sự kiện, đồng bộ dữ liệu |
44
- | 5 | **Code mới hoặc sửa nhiều** | feature xây mới, hoặc vùng vừa refactor |
45
- | 6 | **Lịch sử lỗi cao** | vùng đã từng có bug — tra `{paths.bug_reports_dir}` cho UC/feature này |
46
- | 7 | **Ảnh hưởng nhiều người dùng** | luồng chính mọi người đều đi qua, màn đăng nhập, trang chủ |
47
-
48
- > Nguồn 6 là nguồn duy nhất **tra được bằng dữ liệu thật** trong framework — sổ bug nằm ở
49
- > `{paths.bug_reports_dir}`. Đừng đoán "vùng này chắc ổn"; mở ra đếm.
50
-
51
- ## Bước 2 — Chấm mức cho từng rủi ro
52
-
53
- Hai chiều, mỗi chiều ba mức:
54
-
55
- - **Khả năng xảy ra** — Cao / Trung bình / Thấp
56
- - **Mức thiệt hại nếu xảy ra** — Cao / Trung bình / Thấp
57
-
58
- Nhân lại ra **P0 → P3**:
59
-
60
- | Khả năng \ Thiệt hại | Cao | Trung bình | Thấp |
61
- |---|:---:|:---:|:---:|
62
- | **Cao** | **P0** | **P1** | P2 |
63
- | **Trung bình** | **P1** | P2 | P3 |
64
- | **Thấp** | P2 | P3 | P3 |
65
-
66
- > **Chấm hai chiều riêng rồi mới nhân** — đừng chấm thẳng ra P0/P1 theo cảm tính. Hai chiều
67
- > tách nhau là chỗ tranh luận trở nên cụ thể: *"cái này thiệt hại cao nhưng khả năng thấp"*
68
- > là một câu nói được, còn *"cái này P1"* thì không cãi được, chỉ tin hoặc không tin.
69
-
70
- ## Bước 3 — Dùng mức rủi ro để chia **độ sâu** test
71
-
72
- Đây là chỗ bảng rủi ro trả lại giá trị. Không có bước này thì nó chỉ là một bảng trang trí.
73
-
74
- | Mức | Test sâu tới đâu | Tự động hoá |
75
- |---|---|---|
76
- | **P0** | nhiều kỹ thuật cùng lúc: phân lớp tương đương + giá trị biên + bảng quyết định + chuyển trạng thái | ✅ ưu tiên — cả kiểm thử hồi quy |
77
- | **P1** | hai kỹ thuật trở lên, phủ đủ nhánh chính + nhánh lỗi | ✅ nếu ổn định |
78
- | **P2** | một kỹ thuật, phủ luồng thuận + một nhánh lỗi tiêu biểu | tuỳ |
79
- | **P3** | danh sách kiểm tay, không cần test case đầy đủ | ❌ |
80
-
81
- **Thứ tự chạy:** rủi ro cao **và** phụ thuộc thấp làm trước — không phải "P0 làm hết rồi mới tới P1".
82
- Một P0 đang chờ gap chặn thì không chạy được; làm P1 sẵn sàng trước là đúng.
83
-
84
- **Tháp test:** end-to-end tự động **chỉ** cho luồng P0/P1 trọng yếu. E2E cho P2/P3 là đắt và giòn —
85
- tiền không đáng.
86
-
87
- ## Bước 4 — Điền Entry / Exit theo rủi ro
88
-
89
- `test-plan.md §5` đã có khung. Rủi ro làm nó cụ thể hơn:
90
-
91
- - **Entry** — mọi gap 🔴 chặn đã `Answered`; **và** mọi rủi ro P0 đã có ít nhất một cách giảm thiểu ghi rõ.
92
- - **Exit** — phủ 100% vùng P0 · không còn defect mở ở vùng P0/P1 · tỉ lệ pass đạt ngưỡng đã khai.
93
-
94
- > **Rủi ro P0 không có cách giảm thiểu = chưa đủ điều kiện bắt đầu.** Ghi ra một rủi ro rồi
95
- > không nói làm gì với nó là ghi cho có.
96
-
97
- ---
98
-
99
- ## Điền vào `TEST_PLAN.md §6`
100
-
101
- | Rủi ro | Nguồn (1–7) | Khả năng | Thiệt hại | Mức | Giảm thiểu (loại test + kỹ thuật) |
102
- |---|---|---|---|---|---|
103
- | … | 2 · tiền | Cao | Cao | **P0** | functional/api + giá trị biên; e2e luồng thanh toán |
104
-
105
- Mỗi dòng rủi ro phải **trỏ được về BR-xx hoặc GAP-xx** đã có ở `REQUIREMENT_ANALYSIS.md` /
106
- `DOC_GAP.md` — rủi ro không neo vào yêu cầu nào là rủi ro tự nghĩ ra.