@educa-corp/sdd-framework 0.4.2 → 0.5.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 (116) hide show
  1. package/bin/self-check.js +124 -6
  2. package/bin/trace-schema.json +1199 -692
  3. package/commands/debug.md +3 -2
  4. package/commands/define-product.md +3 -2
  5. package/commands/dev-gen-test.md +37 -9
  6. package/commands/dev-run-test.md +37 -9
  7. package/commands/dev-smoke-test.md +3 -2
  8. package/commands/extend-prd.md +907 -0
  9. package/commands/extend-prd.tmpl +270 -0
  10. package/commands/fix-bug.md +37 -9
  11. package/commands/generate-architecture.md +3 -2
  12. package/commands/generate-bdd.md +56 -13
  13. package/commands/generate-bdd.tmpl +18 -3
  14. package/commands/generate-code.md +73 -16
  15. package/commands/generate-code.tmpl +36 -7
  16. package/commands/generate-design-spec.md +3 -2
  17. package/commands/generate-prd.md +28 -2
  18. package/commands/generate-prd.tmpl +25 -0
  19. package/commands/generate-spec-manifest.md +3 -2
  20. package/commands/generate-tech-docs.md +3 -2
  21. package/commands/learn.md +3 -2
  22. package/commands/map-testids.md +3 -2
  23. package/commands/propose-scenario.md +55 -3
  24. package/commands/propose-scenario.tmpl +52 -1
  25. package/commands/qc-analyze.md +3 -2
  26. package/commands/qc-design-test.md +4 -2
  27. package/commands/qc-design-test.tmpl +1 -0
  28. package/commands/qc-plan.md +3 -2
  29. package/commands/qc-report.md +3 -2
  30. package/commands/qc-review.md +3 -2
  31. package/commands/qc-run-test.md +50 -10
  32. package/commands/qc-run-test.tmpl +13 -1
  33. package/commands/refine-prd.md +3 -2
  34. package/commands/report-bug.md +3 -2
  35. package/commands/review-code.md +7 -5
  36. package/commands/review-code.tmpl +4 -3
  37. package/commands/review-context.md +6 -4
  38. package/commands/review-context.tmpl +3 -2
  39. package/commands/review-tech-docs.md +3 -2
  40. package/commands/setup-ai-first.md +3 -2
  41. package/commands/sync.md +40 -16
  42. package/commands/sync.tmpl +37 -14
  43. package/commands/update-framework.md +3 -2
  44. package/commands/validate-traces.md +318 -33
  45. package/commands/validate-traces.tmpl +315 -31
  46. package/core/FRAMEWORK_VERSION +1 -1
  47. package/core/commands/debug.md +3 -2
  48. package/core/commands/define-product.md +3 -2
  49. package/core/commands/dev-gen-test.md +37 -9
  50. package/core/commands/dev-run-test.md +37 -9
  51. package/core/commands/dev-smoke-test.md +3 -2
  52. package/core/commands/extend-prd.md +907 -0
  53. package/core/commands/fix-bug.md +37 -9
  54. package/core/commands/generate-architecture.md +3 -2
  55. package/core/commands/generate-bdd.md +56 -13
  56. package/core/commands/generate-code.md +73 -16
  57. package/core/commands/generate-design-spec.md +3 -2
  58. package/core/commands/generate-prd.md +28 -2
  59. package/core/commands/generate-spec-manifest.md +3 -2
  60. package/core/commands/generate-tech-docs.md +3 -2
  61. package/core/commands/learn.md +3 -2
  62. package/core/commands/map-testids.md +3 -2
  63. package/core/commands/propose-scenario.md +55 -3
  64. package/core/commands/qc-analyze.md +3 -2
  65. package/core/commands/qc-design-test.md +4 -2
  66. package/core/commands/qc-plan.md +3 -2
  67. package/core/commands/qc-report.md +3 -2
  68. package/core/commands/qc-review.md +3 -2
  69. package/core/commands/qc-run-test.md +50 -10
  70. package/core/commands/refine-prd.md +3 -2
  71. package/core/commands/report-bug.md +3 -2
  72. package/core/commands/review-code.md +7 -5
  73. package/core/commands/review-context.md +6 -4
  74. package/core/commands/review-tech-docs.md +3 -2
  75. package/core/commands/setup-ai-first.md +3 -2
  76. package/core/commands/sync.md +40 -16
  77. package/core/commands/update-framework.md +3 -2
  78. package/core/commands/validate-traces.md +318 -33
  79. package/core/rules/workflow.md +18 -0
  80. package/core/steps/report-footer.md +3 -2
  81. package/core/steps/trace-mirror.md +34 -7
  82. package/core/templates/feature.template +1 -1
  83. package/docs/01-getting-started/installation.md +18 -1
  84. package/docs/01-getting-started/what-is-sdd.md +4 -2
  85. package/docs/02-concepts/architecture.md +27 -3
  86. package/docs/02-concepts/pipeline-steps/02-specification.md +39 -3
  87. package/docs/02-concepts/pipeline-steps/04-bdd.md +24 -2
  88. package/docs/02-concepts/pipeline-steps/05-tech-docs.md +18 -1
  89. package/docs/02-concepts/pipeline-steps/06-code.md +35 -4
  90. package/docs/02-concepts/pipeline-steps/09-validate-traces.md +137 -12
  91. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +59 -3
  92. package/docs/02-concepts/roles-and-hitl.md +1 -1
  93. package/docs/02-concepts/traceability.md +126 -117
  94. package/docs/03-guides/developer.md +20 -4
  95. package/docs/03-guides/product-owner.md +72 -68
  96. package/docs/03-guides/tester-qa.md +81 -70
  97. package/docs/04-reference/commands.md +134 -105
  98. package/docs/04-reference/configuration.md +146 -94
  99. package/docs/04-reference/trace-schema.md +26 -9
  100. package/docs/explain/02-generate-prd.md +80 -78
  101. package/docs/explain/02b-extend-prd.md +125 -0
  102. package/docs/explain/03-refine-prd.md +86 -86
  103. package/docs/explain/04-review-context.md +18 -1
  104. package/docs/explain/06-generate-bdd.md +23 -0
  105. package/docs/explain/08-review-tech-docs.md +20 -5
  106. package/docs/explain/10-review-code.md +36 -2
  107. package/docs/explain/19-qc-run-test.md +87 -67
  108. package/docs/explain/21-validate-traces.md +74 -68
  109. package/docs/explain/23-fix-bug.md +19 -3
  110. package/docs/explain/26-propose-scenario.md +70 -63
  111. package/docs/explain/README.md +135 -134
  112. package/package.json +50 -50
  113. package/rules/workflow.md +18 -0
  114. package/steps/report-footer.md +3 -2
  115. package/steps/trace-mirror.md +34 -7
  116. package/templates/feature.template +1 -1
@@ -1,86 +1,86 @@
1
- [← /generate-prd](02-generate-prd.md) · [Explain Home](README.md) · [Next: /review-context →](04-review-context.md)
2
-
3
- # 03 · `/refine-prd` — Tinh chỉnh PRD qua 3 lăng kính
4
-
5
- > **Một câu.** Fan-out review PRD qua **3 lăng kính DEV / SA / PO**, chạy **vòng lặp completeness-critic** để hội tụ đầy đủ trong một lần, rồi sinh file findings cho PO accept/reject ở Review Board.
6
-
7
- ---
8
-
9
- ## Vấn đề giải quyết
10
-
11
- Một lượt review đơn không bao giờ liệt kê hết vấn đề — model dừng ở mức "đủ", nên mỗi vòng sau lại lòi lỗi mới (**đập chuột chũi**). `/refine-prd` ép review **hội tụ trong một lần chạy**, bắt lỗi nghiệp vụ *trước* khi truyền xuống BDD, giữ altitude & ngôn ngữ nghiệp vụ.
12
-
13
- ---
14
-
15
- ## Vị trí & tiền đề
16
-
17
- - **Vị trí:** Phase Specification (sau `/generate-prd`).
18
- - **Tiền đề:** có PRD draft.
19
- - **Đặc biệt:** có **Resume Mode** (`--resume`) áp findings đã accept và bump version PRD.
20
-
21
- ---
22
-
23
- ## Input / Output
24
-
25
- **Input:** PRD + core-entities + business-dictionary.
26
-
27
- **Output:** `{refinement_dir}/{prd-slug}-findings.yaml` — findings với `lens` (DEV/SA/PO), severity, `quote`+`uc_id` (để Review Board jump-to-source), `suggestion`, `resolution_edge_cases`, `status`.
28
-
29
- ---
30
-
31
- ## Các bước xử lý (chi tiết)
32
-
33
- Chạy qua step **review-fanout** với tham số `GRANULARITY = per-uc`:
34
-
35
- ### Phase 1 — Fan-out song song theo dimension
36
- - **DIMENSIONS = 3 lăng kính** (mỗi lăng kính một sub-agent, context window mới, quét toàn PRD chỉ qua lăng kính đó):
37
- | Lăng kính | Soi gì |
38
- |-----------|--------|
39
- | **DEV** (cơ chế nghiệp vụ) | BR + Business Logic đã đủ & không mơ hồ để build không phải đoán chưa? Nhánh nghiệp vụ thiếu, điều kiện biên, đường lỗi bỏ ngỏ |
40
- | **SA** (thông suốt & nhất quán) | Luồng nghiệp vụ thông suốt trên cả feature/domain? Tương tác UC, quan hệ entity, vòng đời trạng thái, ai-làm-gì |
41
- | **PO** | Scope khoanh vùng? Priority? Success metric? Rủi ro scope creep? |
42
- - ⚠️ **Nguyên tắc DEV & SA: đọc bằng mắt kỹ thuật, VIẾT bằng lời nghiệp vụ** — chỉ nêu *cái nghiệp vụ còn thiếu/mơ hồ* + đặt câu hỏi làm rõ; KHÔNG đề xuất cơ chế kỹ thuật.
43
- - `GRANULARITY = per-uc` → luôn fan-out `DIMENSION × UC` (+ phạm vi PRD-global), bỏ ngưỡng cả-file → **lần đầu quét sâu**. Agent cap = 12/wave, gom batch UC nếu vượt.
44
-
45
- ### Phase 2 — Vòng lặp completeness-critic
46
- - Spawn một critic đọc **toàn PRD** + danh sách findings đã có (slim) → liệt kê **chỉ vấn đề mới** (gap, mâu thuẫn, edge/negative path thiếu, **vi phạm altitude/role-boundary**: cơ chế nằm trong AC, AC lặp lại BR…).
47
- - Lặp tới khi **2 vòng liên tiếp 0 finding mới** hoặc cap **3 vòng**. Ghi `convergence_rounds`.
48
-
49
- ### Phase 3 — Dedup / xung đột / merge
50
- - Khử trùng (giữ suggestion phong phú hơn, severity cao hơn); merge được thì merge, loại trừ nhau → một finding `needs_discussion`; sắp theo severity; gán ID `F001…`; map dimension → `lens`; ghi **một** file findings.
51
-
52
- ### Full vs Delta
53
- - Lần đầu (chưa có findings file) → **FULL**. Lần sau so `prd_version`: chưa đổi → DỪNG; đổi do chính resume này (`applied_to_version` khớp) → **DELTA** (chỉ UC đã đổi + UC mới); đổi bởi actor khác → **FULL** + cảnh báo.
54
-
55
- ### Resume Mode (`--resume`)
56
- - Áp finding theo `status` (`accepted`/`modified`), bump version PRD, ghi `applied_to_version`. `needs_discussion` chặn resume tới khi người quyết.
57
-
58
- ---
59
-
60
- ## Checkpoint & Gate
61
-
62
- - 🛑 **Review Board** — PO accept/reject/modify **từng** finding (không auto-apply). Finding lifecycle: `pending → accepted|modified|rejected|needs_discussion|deferred → applied`.
63
- - `recommendation`: critical≥1 → `BLOCKED`; major≥1 → `NEEDS_REVISION`; else `APPROVED_WITH_MINOR_CHANGES`.
64
-
65
- ---
66
-
67
- ## Cơ chế đặc biệt
68
-
69
- - **Không có `--fix` mode** (khác `/review-context`) — finding 3 lăng kính là phán đoán DEV/SA/PO, **bắt buộc qua người** ở Board; `auto_fixable` chỉ là gợi ý quick-accept.
70
- - **`resolution_edge_cases`** — phân tích bậc-hai (chỉ critical/major): "nếu chốt phương án này thì đẻ ra edge case gì?" → PO thấy trước khi accept (advisory, không chặn).
71
- - **QA lens đang DISABLED** (comment trong file) — có hướng dẫn bật lại nếu cần.
72
-
73
- ---
74
-
75
- ## 👓 Góc nhìn tối ưu
76
-
77
- - **Đây là command tốn agent/token nhất phía thượng nguồn** — `per-uc` × 3 lăng kính × (UC+1) + tới 3 vòng critic. `AGENT_CAP=12` là núm chỉnh chính. Với PRD lớn, đây là điểm cần cân đối chi phí ↔ độ đầy đủ.
78
- - **Completeness-critic tới 3 vòng** — điểm đáng đo: thực tế hội tụ ở vòng mấy? Nếu thường 1–2 vòng thì cap 3 hợp lý.
79
- - **Full/delta logic phức tạp** (`applied_to_version` tracking) — mạnh nhưng nhiều nhánh; dễ rơi về FULL khi có actor khác sửa PRD (vd `/review-context` xen giữa).
80
- - **Ranh giới với `/review-context`** — cả hai đều review PRD, dùng chung review-fanout. `/refine-prd` = phán đoán chất lượng nghiệp vụ (3 lăng kính); `/review-context` = check có mã P0–P5 + auto-fix. Chồng lấn có chủ đích hay có thể gộp?
81
-
82
- ---
83
-
84
- ## Kết nối
85
-
86
- **Trước:** [`/generate-prd`](02-generate-prd.md) · **Sau:** mở Review Board → cập nhật PRD → [`/review-context`](04-review-context.md).
1
+ [← /extend-prd](02b-extend-prd.md) · [Explain Home](README.md) · [Next: /review-context →](04-review-context.md)
2
+
3
+ # 03 · `/refine-prd` — Tinh chỉnh PRD qua 3 lăng kính
4
+
5
+ > **Một câu.** Fan-out review PRD qua **3 lăng kính DEV / SA / PO**, chạy **vòng lặp completeness-critic** để hội tụ đầy đủ trong một lần, rồi sinh file findings cho PO accept/reject ở Review Board.
6
+
7
+ ---
8
+
9
+ ## Vấn đề giải quyết
10
+
11
+ Một lượt review đơn không bao giờ liệt kê hết vấn đề — model dừng ở mức "đủ", nên mỗi vòng sau lại lòi lỗi mới (**đập chuột chũi**). `/refine-prd` ép review **hội tụ trong một lần chạy**, bắt lỗi nghiệp vụ *trước* khi truyền xuống BDD, giữ altitude & ngôn ngữ nghiệp vụ.
12
+
13
+ ---
14
+
15
+ ## Vị trí & tiền đề
16
+
17
+ - **Vị trí:** Phase Specification (sau `/generate-prd`).
18
+ - **Tiền đề:** có PRD draft.
19
+ - **Đặc biệt:** có **Resume Mode** (`--resume`) áp findings đã accept và bump version PRD.
20
+
21
+ ---
22
+
23
+ ## Input / Output
24
+
25
+ **Input:** PRD + core-entities + business-dictionary.
26
+
27
+ **Output:** `{refinement_dir}/{prd-slug}-findings.yaml` — findings với `lens` (DEV/SA/PO), severity, `quote`+`uc_id` (để Review Board jump-to-source), `suggestion`, `resolution_edge_cases`, `status`.
28
+
29
+ ---
30
+
31
+ ## Các bước xử lý (chi tiết)
32
+
33
+ Chạy qua step **review-fanout** với tham số `GRANULARITY = per-uc`:
34
+
35
+ ### Phase 1 — Fan-out song song theo dimension
36
+ - **DIMENSIONS = 3 lăng kính** (mỗi lăng kính một sub-agent, context window mới, quét toàn PRD chỉ qua lăng kính đó):
37
+ | Lăng kính | Soi gì |
38
+ |-----------|--------|
39
+ | **DEV** (cơ chế nghiệp vụ) | BR + Business Logic đã đủ & không mơ hồ để build không phải đoán chưa? Nhánh nghiệp vụ thiếu, điều kiện biên, đường lỗi bỏ ngỏ |
40
+ | **SA** (thông suốt & nhất quán) | Luồng nghiệp vụ thông suốt trên cả feature/domain? Tương tác UC, quan hệ entity, vòng đời trạng thái, ai-làm-gì |
41
+ | **PO** | Scope khoanh vùng? Priority? Success metric? Rủi ro scope creep? |
42
+ - ⚠️ **Nguyên tắc DEV & SA: đọc bằng mắt kỹ thuật, VIẾT bằng lời nghiệp vụ** — chỉ nêu *cái nghiệp vụ còn thiếu/mơ hồ* + đặt câu hỏi làm rõ; KHÔNG đề xuất cơ chế kỹ thuật.
43
+ - `GRANULARITY = per-uc` → luôn fan-out `DIMENSION × UC` (+ phạm vi PRD-global), bỏ ngưỡng cả-file → **lần đầu quét sâu**. Agent cap = 12/wave, gom batch UC nếu vượt.
44
+
45
+ ### Phase 2 — Vòng lặp completeness-critic
46
+ - Spawn một critic đọc **toàn PRD** + danh sách findings đã có (slim) → liệt kê **chỉ vấn đề mới** (gap, mâu thuẫn, edge/negative path thiếu, **vi phạm altitude/role-boundary**: cơ chế nằm trong AC, AC lặp lại BR…).
47
+ - Lặp tới khi **2 vòng liên tiếp 0 finding mới** hoặc cap **3 vòng**. Ghi `convergence_rounds`.
48
+
49
+ ### Phase 3 — Dedup / xung đột / merge
50
+ - Khử trùng (giữ suggestion phong phú hơn, severity cao hơn); merge được thì merge, loại trừ nhau → một finding `needs_discussion`; sắp theo severity; gán ID `F001…`; map dimension → `lens`; ghi **một** file findings.
51
+
52
+ ### Full vs Delta
53
+ - Lần đầu (chưa có findings file) → **FULL**. Lần sau so `prd_version`: chưa đổi → DỪNG; đổi do chính resume này (`applied_to_version` khớp) → **DELTA** (chỉ UC đã đổi + UC mới); đổi bởi actor khác → **FULL** + cảnh báo.
54
+
55
+ ### Resume Mode (`--resume`)
56
+ - Áp finding theo `status` (`accepted`/`modified`), bump version PRD, ghi `applied_to_version`. `needs_discussion` chặn resume tới khi người quyết.
57
+
58
+ ---
59
+
60
+ ## Checkpoint & Gate
61
+
62
+ - 🛑 **Review Board** — PO accept/reject/modify **từng** finding (không auto-apply). Finding lifecycle: `pending → accepted|modified|rejected|needs_discussion|deferred → applied`.
63
+ - `recommendation`: critical≥1 → `BLOCKED`; major≥1 → `NEEDS_REVISION`; else `APPROVED_WITH_MINOR_CHANGES`.
64
+
65
+ ---
66
+
67
+ ## Cơ chế đặc biệt
68
+
69
+ - **Không có `--fix` mode** (khác `/review-context`) — finding 3 lăng kính là phán đoán DEV/SA/PO, **bắt buộc qua người** ở Board; `auto_fixable` chỉ là gợi ý quick-accept.
70
+ - **`resolution_edge_cases`** — phân tích bậc-hai (chỉ critical/major): "nếu chốt phương án này thì đẻ ra edge case gì?" → PO thấy trước khi accept (advisory, không chặn).
71
+ - **QA lens đang DISABLED** (comment trong file) — có hướng dẫn bật lại nếu cần.
72
+
73
+ ---
74
+
75
+ ## 👓 Góc nhìn tối ưu
76
+
77
+ - **Đây là command tốn agent/token nhất phía thượng nguồn** — `per-uc` × 3 lăng kính × (UC+1) + tới 3 vòng critic. `AGENT_CAP=12` là núm chỉnh chính. Với PRD lớn, đây là điểm cần cân đối chi phí ↔ độ đầy đủ.
78
+ - **Completeness-critic tới 3 vòng** — điểm đáng đo: thực tế hội tụ ở vòng mấy? Nếu thường 1–2 vòng thì cap 3 hợp lý.
79
+ - **Full/delta logic phức tạp** (`applied_to_version` tracking) — mạnh nhưng nhiều nhánh; dễ rơi về FULL khi có actor khác sửa PRD (vd `/review-context` xen giữa).
80
+ - **Ranh giới với `/review-context`** — cả hai đều review PRD, dùng chung review-fanout. `/refine-prd` = phán đoán chất lượng nghiệp vụ (3 lăng kính); `/review-context` = check có mã P0–P5 + auto-fix. Chồng lấn có chủ đích hay có thể gộp?
81
+
82
+ ---
83
+
84
+ ## Kết nối
85
+
86
+ **Trước:** [`/generate-prd`](02-generate-prd.md) hoặc [`/extend-prd`](02b-extend-prd.md) · **Sau:** mở Review Board → cập nhật PRD → [`/review-context`](04-review-context.md).
@@ -56,15 +56,32 @@ Giống `/refine-prd` (fan-out song song → completeness-critic → dedup/merge
56
56
  | **B2** | Terminology & entity |
57
57
  | **B3** | Gherkin rules (R1–R10) |
58
58
  | **B4** | Compliance (C.1–C.5) |
59
- | **B5** | Metadata & structural (@trace header, Coverage Matrix) |
59
+ | **B5** | Metadata & structural (@trace header, Coverage Matrix) — xem 3 nhóm dưới |
60
60
  | **B6** | Side-effect completeness |
61
61
 
62
+ **B5 — field `@trace.*` chia 3 nhóm theo mức thiệt hại, không phải một danh sách phẳng:**
63
+
64
+ | Nhóm | Mức | Field |
65
+ |---|:---:|---|
66
+ | **A — chặn** | `major`, auto-fixable | `id` · **`platform`** · `domain` · `prd` · `prd_version` · `bdd_version` · `status` |
67
+ | **B — thông tin** | `minor` | `title` · `revision` · `author` · `created_at` · `business_rules` · `dataset` |
68
+ | **C — có điều kiện** | chỉ flag khi đúng điều kiện | `service`·`module` (chỉ **umbrella**) · `api_source` (chỉ `platform = system` + PRD brownfield) |
69
+
70
+ - **`@trace.platform` là major chứ không minor** — thiếu nó thì `/generate-code` không quyết được BE/FE (và **cấm** fallback sang `platform_type`), không định vị được sổ trace, không tìm được design-spec. Auto-fix suy từ segment `bdd/{platform}/` của chính path file, **không đoán**.
71
+ - **`@trace.sc_version` của scenario cũng là major** (ngoại lệ trong nhóm scenario-tag vốn minor): thiếu nó thì SC đó **vĩnh viễn hiện `OK`** dù scenario đổi bao nhiêu lần.
72
+ - **Nhóm C không được flag khi sai điều kiện.** Trước đây B5 đòi `service`/`module` vô điều kiện → mọi `.feature` **đúng-theo-template** ở spec repo mode ăn 2 finding minor, và `--fix` **thêm field bịa** vào header.
73
+ - B5 cũng bắt **tag lạc** rò vào BDD canonical: `@trace.uc=` / `@trace.ac=` (vocabulary proposal cũ) và `@proposed` / `@from-test`.
74
+
62
75
  ### 3 · Ghi file findings + Post-Analysis Routing
63
76
  Sạch critical → nhắc người đặt `approved`; còn critical → giữ draft, sửa.
64
77
 
65
78
  ### Chế độ `--fix` (auto-apply)
66
79
  Chạy full phân tích rồi **áp ngay** các finding `auto_fixable: true` (không qua Board): PRD (P1 banned term, P1 tech-term reframe, P4 skeleton) · BDD (B2 terminology, B3 R3/R7/R9/R10, B4 C4/C5, B5 header/matrix, B6 side-effect). Finding cần người vẫn để `pending`.
67
80
  - **Version bump + reset draft:** ≥1 fix áp → PRD bump minor + **reset `Status: draft`** + Changelog; BDD tăng `@trace.bdd_version` 0.1 + **reset `@trace.status: draft`**. Ghi `applied_to_version`.
81
+ - **Bump `@trace.sc_version` theo TỪNG scenario** — không phải cả file. Finding **đổi thân scenario** (R3 diễn đạt lại step · R7 thay giá trị · R9 thêm cột data table · R10 thêm Note · B6 thêm side-effect · B2 đổi tên entity/field trong step) → bump `+0.1` cho **đúng SC đó**. Finding chỉ sửa header / Coverage Matrix / gom NHÓM (B4, B5) → **không** bump.
82
+ - Đây là tín hiệu **duy nhất** cho `/validate-traces` biết code của SC đó lỗi thời (`spec_ver != gen_ver` → `DRIFT`). `bdd_version` ở cấp file **không đủ phân giải** để biết SC nào cần regen.
83
+ - Bump vô cớ thì ngược lại: mọi SC hiện `DRIFT` giả và cờ mất giá trị.
84
+ - `--resume` còn cập nhật `spec_ver` trong `.tsv` cho SC vừa bump (giữ `gen_ver` → row hiện `DRIFT` đúng như mong đợi), và **append row** cho SC mới do B1 sinh.
68
85
 
69
86
  ### Chế độ `--resume`
70
87
  Áp các finding `accepted`/`modified` từ Board; bỏ `rejected`/`deferred`; `needs_discussion` → cảnh báo, bỏ lần này.
@@ -54,6 +54,29 @@ BDD là **anchor cứng** của traceability — mọi code/test link về scena
54
54
 
55
55
  ---
56
56
 
57
+ ## Gen lại: hai thứ dễ mất nếu làm sai
58
+
59
+ **1 · Bump `@trace.sc_version` cho SC có thân đổi.** So bản mới với bản trên disk theo **4 thành phần**: tên `Scenario:` · chuỗi step · data table · `# Side-effects:`.
60
+
61
+ | Kết quả so | Hành động |
62
+ |---|---|
63
+ | khác ở bất kỳ thành phần nào | `+0.1` |
64
+ | giống hoàn toàn | **giữ nguyên** — bump vô cớ tạo `DRIFT` giả |
65
+ | SC mới | `1.0` |
66
+
67
+ Thay đổi **ngoài** 4 thành phần đó (`@trace.business_rules`, tag `@happy`/`@edge`, comment) **không** bump — chúng không đổi hành vi mà code phải implement. Report in danh sách SC được bump + cảnh báo chúng sẽ hiện `DRIFT`.
68
+
69
+ **2 · SC biến mất khỏi `.feature` — đừng xoá row `.tsv` nếu đã có code.**
70
+
71
+ | `implemented_by` | Hành động |
72
+ |---|---|
73
+ | `—` (chưa có code) | **xoá row** — không có gì mồ côi |
74
+ | có giá trị (**đã có code**) | **GIỮ row**, `status = ORPHANED`, giữ nguyên `implemented_by`/`test_*` |
75
+
76
+ Xoá row của một SC đã có code sẽ làm method đó **vô hình**: không `UNTRACKED`, không `GAP`, không `DRIFT`, không xuất hiện ở report nào — mà vẫn nằm trong code và vẫn được caller gọi. Coverage còn *đẹp hơn* thực tế vì mẫu số nhỏ đi. `ORPHANED` **không tự hết**: người phải chọn xoá code+test, hay đưa scenario trở lại.
77
+
78
+ ---
79
+
57
80
  ## Cơ chế đặc biệt
58
81
 
59
82
  - **System BDD là tổng hợp**, không viết tay — suy từ BDD web+app, giải conflict contract trước khi có tech-docs.
@@ -1,8 +1,8 @@
1
1
  [← /generate-tech-docs](07-generate-tech-docs.md) · [Explain Home](README.md) · [Next: /generate-code →](09-generate-code.md)
2
2
 
3
- # 08 · `/review-tech-docs` — Review Technical Design (7 dimension + ký T7)
3
+ # 08 · `/review-tech-docs` — Review Technical Design (8 dimension + ký T7)
4
4
 
5
- > **Một câu.** Review tech-design qua **7 dimension T1–T7** (kiến trúc, entity, BDD trace, cross-PRD conflict, nội bộ, cấu trúc, và cổng ký liên team), sinh findings + `--resume`.
5
+ > **Một câu.** Review tech-design qua **8 dimension T1–T7 + T3b** (kiến trúc, entity, BDD trace, cross-PRD conflict, nội bộ, cấu trúc, và cổng ký liên team), sinh findings + `--resume`.
6
6
 
7
7
  ---
8
8
 
@@ -29,18 +29,32 @@ Chốt sai contract kỹ thuật = rework tốn kém cho nhiều team. `/review-
29
29
 
30
30
  ## Các bước xử lý (chi tiết)
31
31
 
32
- Chạy 7 dimension (mỗi cái phân loại severity + auto-fixable):
32
+ Chạy 8 dimension (mỗi cái phân loại severity + auto-fixable):
33
33
 
34
34
  | Dim | Tên | Soi gì | Auto-fix |
35
35
  |-----|-----|--------|----------|
36
36
  | **T1** | Architecture Alignment | Vi phạm CLAUDE.md §2 (controller gọi repo, logic trong controller, pattern cấm) — **luôn critical** | ❌ người quyết |
37
37
  | **T2** | Entity Consistency | Đối chiếu core-entities (entity thiếu, tên field lệch, quan hệ khác) | một phần (field → canonical) |
38
38
  | **T3** | BDD Traceability | 2 chiều design ↔ scenario, **theo đúng lane platform** (system/web/app SC không so chéo) | một phần |
39
+ | **T3b** | **BDD Freshness** | Doc dựng từ BDD **version nào**, BDD giờ ở version nào — so từng entry của map `@trace.bdd_versions` với `.feature` tương ứng | 2 ca (thêm/xoá entry) |
39
40
  | **T4** | Cross-PRD Endpoint Conflict | grep endpoint/entity ở doc PRD khác, **load-on-hit**; va chạm shape/behavior → critical | ❌ |
40
41
  | **T5** | Internal Consistency | Sequence vs mô tả, API spec vs code sketch, ref không định nghĩa | một phần |
41
42
  | **T6** | Structural Completeness | Section chuẩn có mặt & không rỗng | ✅ thêm skeleton |
42
43
  | **T7** | Cross-Team API Contract | **Cổng ký liên team** — chỉ khi doc có backend (system) + không phải `api_source: existing` | sign-off block auto-fix |
43
44
 
45
+ **T3b chi tiết** — T3 kiểm *nội dung* khớp, T3b kiểm *độ tươi*:
46
+
47
+ | Điều kiện | Severity | Auto-fix |
48
+ |---|---|---|
49
+ | `.feature` **mới hơn** map | **Major** | ❌ cần người review lại §4/§4.5 rồi bump `@trace.revision` |
50
+ | Platform có `.feature` nhưng **vắng** trong map | Major | ✅ thêm entry sau khi xác nhận §4 đã phủ |
51
+ | Map có platform mà không còn `.feature` | Minor | ✅ xoá entry |
52
+
53
+ - **Major chứ không Minor:** `/generate-code` DS3 thấy doc `approved` + 0 blocker-GAP sẽ lấy shape §4 **nguyên văn** làm contract "đã chốt" → contract dựng từ BDD cũ lan **thẳng** vào code. Tệ hơn drift-về-code vì sai từ nguồn.
54
+ - **Chặn `approved` — nhưng MỀM** (CHECKPOINT `Y/N`), khác GATE §12 blocker-GAP chặn cứng: BDD hay bump vì lý do **không chạm contract** (sửa từ ngữ step, thêm side-effect assertion), người review là người biết.
55
+ - Khi `--resume` áp fix: **cấm chỉ sửa số trong map** cho ca "`.feature` mới hơn" — làm thế là dán nhãn "đã đồng bộ" lên contract chưa ai review. Platform còn finding `open` → **giữ số cũ** để cờ `TECHDOC_STALE_VS_BDD` của `/validate-traces` còn sáng.
56
+ - Tên key là `@trace.bdd_versions` (**số nhiều**, map theo platform) — cố ý khác `@trace.bdd_version` (scalar) của `.feature`, vì cùng một tên cho hai kiểu dữ liệu sẽ làm vỡ parser generic.
57
+
44
58
  **T7 chi tiết:**
45
59
  - Đọc block `@trace.sign_off` (be_team / fe_team / app_team / sa); vắng → thêm skeleton.
46
60
  - Cross-check contract §4 vs web & app BDD → đảm bảo mọi team đồng thuận trước khi implement.
@@ -52,6 +66,7 @@ Sau phân tích → ghi findings; **Resume Mode** áp finding `accepted`/`modifi
52
66
  ## Checkpoint & Gate
53
67
 
54
68
  - 🔒 **T7 sign-off** — contract liên team chưa ký đủ (be/fe/app/sa) → chưa mở khoá code phía tiêu thụ.
69
+ - 🟡 **T3b (chặn mềm)** — còn finding T3b Major `open` → CHECKPOINT `Y/N` trước khi đặt `approved`.
55
70
  - Read-only — không tự sửa; findings qua Board → `--resume`.
56
71
 
57
72
  ---
@@ -67,10 +82,10 @@ Sau phân tích → ghi findings; **Resume Mode** áp finding `accepted`/`modifi
67
82
 
68
83
  ## 👓 Góc nhìn tối ưu
69
84
 
70
- - **7 dimension trong một lệnh** — nặng; T4 (cross-PRD) và T7 (sign-off) là hai phần đắt nhất. T4 dùng grep khéo để rẻ; T7 phụ thuộc con người ký.
85
+ - **8 dimension trong một lệnh** — nặng; T4 (cross-PRD) và T7 (sign-off) là hai phần đắt nhất. T4 dùng grep khéo để rẻ; T7 phụ thuộc con người ký.
71
86
  - **T7 sign-off là quy trình đa người** — dễ nghẽn nếu một team chậm ký. Đáng có cơ chế nhắc/timeout.
72
87
  - **Chồng lấn với conflict resolution ở generate-bdd (system)** — cả hai lo contract cross-platform. Ranh giới: BDD-system chốt *hành vi contract*, T7 chốt *shape API + đồng thuận team*.
73
- - **Không dùng review-fanout** (khác `/review-context`/`/refine-prd`) — 7 dimension chạy tuần tự trong một session. Với doc lớn có thể lost-in-the-middle; cân nhắc fan-out.
88
+ - **Không dùng review-fanout** (khác `/review-context`/`/refine-prd`) — 8 dimension chạy tuần tự trong một session. Với doc lớn có thể lost-in-the-middle; cân nhắc fan-out.
74
89
 
75
90
  ---
76
91
 
@@ -29,14 +29,47 @@
29
29
 
30
30
  ## Các bước xử lý (chi tiết)
31
31
 
32
- Chạy checklist 4 dimension:
32
+ Chạy checklist **5 dimension**:
33
33
 
34
34
  | # | Dimension | Kiểm gì |
35
35
  |---|-----------|---------|
36
- | 1 | **Traceability** | Mỗi controller endpoint `@trace.implements`? Test `@trace.verifies`? Tag đúng layer? `.tsv` cập nhật chưa (stale → chạy `/validate-traces` trước)? |
36
+ | 1 | **Traceability** | 9 mục xem bảng riêng dưới |
37
37
  | 2 | **Layer Architecture** (CLAUDE.md §2) | Class đúng layer? Phụ thuộc đúng chiều? Không bypass layer? |
38
38
  | 3 | **Coding Standards** (CLAUDE.md §3) | Naming? Response wrapper nhất quán? Exception không bị nuốt? Không magic number / log dữ liệu nhạy cảm? Transaction đúng? |
39
39
  | 4 | **Spec Compliance** | Mỗi scenario có implementation? Không endpoint không tài liệu (code không có spec backing)? |
40
+ | 5 | **Seam & Stub** | Mồ côi khi ghép luồng — xem bảng riêng dưới |
41
+
42
+ ### Dimension 1 — vì sao không chỉ là "có `@trace.implements` chưa"
43
+
44
+ `/generate-code` ghi **5 tag** trên mỗi entry-point. 4 tag ngoài `implements` là nguồn của drift detection, và thiếu chúng thì `/validate-traces` **mù ở file đó — im lặng**:
45
+
46
+ | Tag thiếu | `/validate-traces` mù cái gì |
47
+ |---|---|
48
+ | `@trace.prd_version` | Step 4 — `PRD_DRIFT` |
49
+ | `@trace.bdd_version` | Step 5c — `BDD_DRIFT` |
50
+ | `@trace.tech_doc_revision` | Step 5 — `TECHDOC_DRIFT` *(bỏ được nếu UC không có tech-doc)* |
51
+ | `@trace.source` | mất con trỏ ngược về spec |
52
+
53
+ → thiếu bất kỳ tag nào = **major**, không phải minor.
54
+
55
+ Cộng thêm 3 mục cấu trúc:
56
+ - `@trace.source` trỏ file `.feature` **có thật**, đúng platform (`bdd/{platform}/…`) → sai path = major
57
+ - **File đa-UC**: mỗi UC một block 5 tag riêng trên method của nó. Gộp header, hoặc trỏ `@trace.source` vào **thư mục** = major *(3 tag version là scalar theo từng UC; và các lệnh tra tag bằng khớp chuỗi chính xác nên trỏ folder ra 0 kết quả)*
58
+ - **Tag mồ côi** — `@trace.implements`/`@trace.verifies` trỏ SC **không tồn tại** trong `.feature` = **critical** (`TRACE_ORPHAN`)
59
+
60
+ ### Dimension 5 — lớp lỗi mà build xanh không thấy
61
+
62
+ `/generate-code` vừa sinh sổ `_seams.tsv` ở bước trước. Đây là chỗ **luồng ghép chạy vào no-op** hoặc **hàm thật không ai gọi** — build xanh, test từng-UC xanh, vẫn hỏng:
63
+
64
+ - sổ `_seams.tsv` còn dòng `status = READY` (= cờ 🔴) → critical
65
+ - class `*Stub*` còn là binding đang dùng trong khi hàng thật đã tồn tại → `SEAM_UNWIRED`, critical
66
+ - method còn `@trace.stub` rỗng trong khi `@trace.stub_owner` **đã gen** → `STUB_UNRESOLVED`, critical
67
+ - **method thật mồ côi** — logic thật bị đẻ **song song** thay vì lấp vào stub cũ (Fill-before-create trượt) → critical
68
+ - stub/seam **mới** thiếu tag hoặc thiếu dòng `PENDING` trong sổ → major *(nợ không ghi sổ = nợ tàng hình)*
69
+
70
+ > `SEAM_PENDING` / `STUB_PENDING` (owner UC chưa gen) là **bình thường** — chỉ nhắc.
71
+ >
72
+ > Trùng với `/validate-traces` Step 5b là **có chủ đích**: `/review-code` chạy sớm hơn (ngay sau codegen, trước khi có test), bắt sớm rẻ hơn.
40
73
 
41
74
  Sau review → **Đề xuất ghi Lessons** (tuỳ chọn) qua step `capture-lesson`: nếu phát hiện lỗi lặp lại → đề xuất ghi guardrail vào `project-lessons.md` (L1 phân giải file → L2 dựng lesson → L3 dedup → L4 ghi → L5 xác nhận).
42
75
 
@@ -45,6 +78,7 @@ Sau review → **Đề xuất ghi Lessons** (tuỳ chọn) qua step `capture-les
45
78
  ## Checkpoint & Gate
46
79
 
47
80
  - Không gate chặn — báo cáo tư vấn. Dev tự sửa (không phải AI auto-fix).
81
+ - **Verdict:** bất kỳ finding critical ở dimension 5 → `NEEDS_FIX`, **kể cả khi build xanh và test từng-UC xanh** — đó chính là loại lỗi hai thứ đó không bắt được.
48
82
 
49
83
  ---
50
84
 
@@ -1,67 +1,87 @@
1
- [← /qc-review](18-qc-review.md) · [Explain Home](README.md) · [Next: /qc-report →](20-qc-report.md)
2
-
3
- # 19 · `/qc-run-test` — Trạm 5: Sinh & chạy Playwright, ghi `qc_status`
4
-
5
- > **Một câu.** Biến `.Test.md` đã review thành **Python pytest-playwright**, chạy thật, rồi ghi **`qc_status` chính thức** (có evidence) vào trace TSV.
6
-
7
- ---
8
-
9
- ## Vấn đề giải quyết
10
-
11
- Đây là nơi QC trở thành **chính thức**: chạy test thật trên Playwright, phân loại FAIL (script-bug vs product-gap, **không fake-pass**), và đóng dấu `qc_status` — trạng thái QC authoritative.
12
-
13
- ---
14
-
15
- ## Vị trí & tiền đề
16
-
17
- - **Vị trí:** Phase QC (trạm 5), sau `/qc-review` (case APPROVED).
18
- - **Stack:** module `qc-playwright` (Python + pytest-playwright + Page Object) — **độc lập** module dev.
19
-
20
- ---
21
-
22
- ## Input / Output
23
-
24
- **Input:** `.Test.md` đã review + skill `qa-runner` + selector (từ `/map-testids`).
25
-
26
- **Output:** script Python + kết quả + cột `qc_status` trong `.trace/…/{UC-ID}-{platform}.tsv` + Panel Mirror.
27
-
28
- ---
29
-
30
- ## Các bước xử (chi tiết)
31
-
32
- 1. **Role & stack** — qc-playwright (`stack-profile.yaml`): Python, pytest-playwright fixture, Page Object; mỗi test độc lập; gom theo (role, account) để auth không xen kẽ.
33
- 2. **Skills** — nạp một file skill `qa-runner` theo layer.
34
- 3. **Sinh script** từ `.Test.md`; tag `@trace.verifies={UC-ID}-SC{N}`.
35
- 4. **Chạy** — phân loại mỗi FAIL: **script-bug** (fix selector/logic) vs **product-gap** (giữ FAIL + evidence, **không bao giờ fake-pass**).
36
- 5. **Write Trace State — `qc_status`** (kết quả QC chính thức).
37
- 6. **Refresh Panel Mirror** — Living Docs local.
38
-
39
- ---
40
-
41
- ## Checkpoint & Gate
42
-
43
- - Tiền đề: case đã APPROVED ở `/qc-review`. Script sinh ra → review lại ở `/qc-review` (script) trước PR.
44
-
45
- ---
46
-
47
- ## Cơ chế đặc biệt
48
-
49
- - **`qc_status` là trục authoritative** — khác `dev_selftest`; có evidence.
50
- - **Không fake-pass** — product-gap giữ nguyên FAIL, đẩy về PO/Dev.
51
- - **Stack QC tách hẳn dev** — `@trace.verifies` nối script ↔ SC.
52
- - **`active_platform` khoá sổ trace** — `qc_status` ghi đúng `{UC-ID}-{platform}.tsv`.
53
-
54
- ---
55
-
56
- ## 👓 Góc nhìn tối ưu
57
-
58
- - **Trạm nặng nhất của QC** sinh + chạy + phân loại + ghi trace. Chạy thật phụ thuộc môi trường (browser, data, service lên).
59
- - **Phân loại script-bug vs product-gap phụ thuộc AI/reviewer** — sai loại → hoặc giấu lỗi sản phẩm hoặc báo nhầm. Đáng có tiêu chí rõ.
60
- - **Selector phụ thuộc `/map-testids`** nếu chưa map, script giòn.
61
- - **Chạy lại tốn tài nguyên** — cân nhắc scoped run như dev-run-test.
62
-
63
- ---
64
-
65
- ## Kết nối
66
-
67
- **Trước:** [`/qc-review`](18-qc-review.md) (case) · **Sau:** [`/qc-report`](20-qc-report.md) rồi [`/qc-review`](18-qc-review.md) (script).
1
+ [← /qc-review](18-qc-review.md) · [Explain Home](README.md) · [Next: /qc-report →](20-qc-report.md)
2
+
3
+ # 19 · `/qc-run-test` — Trạm 5: Sinh & chạy Playwright, ghi `qc_status`
4
+
5
+ > **Một câu.** Biến `.Test.md` đã review thành **Python pytest-playwright**, chạy thật, rồi ghi **`qc_status` chính thức** (có evidence) vào trace TSV.
6
+
7
+ ---
8
+
9
+ ## Vấn đề giải quyết
10
+
11
+ Đây là nơi QC trở thành **chính thức**: chạy test thật trên Playwright, phân loại FAIL (script-bug vs product-gap, **không fake-pass**), và đóng dấu `qc_status` — trạng thái QC authoritative.
12
+
13
+ ---
14
+
15
+ ## Vị trí & tiền đề
16
+
17
+ - **Vị trí:** Phase QC (trạm 5), sau `/qc-review` (case APPROVED).
18
+ - **Stack:** module `qc-playwright` (Python + pytest-playwright + Page Object) — **độc lập** module dev.
19
+
20
+ ---
21
+
22
+ ## Input / Output
23
+
24
+ **Input:** `.Test.md` đã review + skill `qa-runner` + bảng Test Selectors §4.5.6 (**giá trị** test-id, từ `/map-testids`) + **`@trace.testid_attr`** ở header tech-doc (**tên thuộc tính** chứa chúng).
25
+
26
+ **Output:** script Python + kết quả + cột `qc_status` trong `.trace/…/{UC-ID}-{platform}.tsv` + panel mirror (`.trace-mirror/`).
27
+
28
+ > **`@trace.testid_attr` — đọc, KHÔNG suy từ platform.** §4.5.6 cho **giá trị** test-id; field này cho **tên thuộc tính** chứa chúng. `get_by_test_id()` của Playwright mặc định dò `data-testid` **nhưng cấu hình được** — dự án dùng `data-test`/`data-qa` thì phải `set_test_id_attribute("{attr}")` trước, không thì **trượt 100% locator**.
29
+ >
30
+ > Suy từ platform **phát biểu lại một sự thật đã ghi ở nơi khác** (`/map-testids` đã phân giải một lần cho cả feature, `/generate-code` đọc chính field đó để emit). Và nó hỏng **im lặng theo kiểu tệ nhất**: test fail `element not found` — trông y hệt một bug sản phẩm, nên QC đi mở bug thay vì sửa selector. Thiếu field → **cảnh báo mềm nêu rõ rủi ro** rồi mới fallback.
31
+
32
+ ---
33
+
34
+ ## Các bước xử (chi tiết)
35
+
36
+ 1. **Role & stack**qc-playwright (`stack-profile.yaml`): Python, pytest-playwright fixture, Page Object; mỗi test độc lập; gom theo (role, account) để auth không xen kẽ.
37
+ 2. **Skills** — nạp một file skill `qa-runner` theo layer.
38
+ 3. **Sinh script** từ `.Test.md`; tag `@trace.verifies={UC-ID}-SC{N}`.
39
+ 4. **Chạy** — phân loại mỗi FAIL: **script-bug** (fix selector/logic) vs **product-gap** (giữ FAIL + evidence, **không bao giờ fake-pass**).
40
+ 5. **Write Trace State — `qc_status`** (kết quả QC chính thức) + `qc_run_at`, `qc_owner`, `qc_blocked_by`, `last_updated`.
41
+ 6. **Đóng bug đã verify** — chạy **TRƯỚC** bước clear cột (xem dưới).
42
+ 7. **Refresh Panel Mirror** — Living Docs local.
43
+
44
+ ---
45
+
46
+ ## Checkpoint & Gate
47
+
48
+ - Tiền đề: case đã APPROVED ở `/qc-review`. Script sinh ra → review lại ở `/qc-review` (script) trước PR.
49
+
50
+ ---
51
+
52
+ ## chế đặc biệt
53
+
54
+ - **`qc_status` là trục authoritative** — khác `dev_selftest`; có evidence.
55
+ - **Không fake-pass** — product-gap giữ nguyên FAIL, đẩy về PO/Dev.
56
+ - **Stack QC tách hẳn dev** — `@trace.verifies` nối script ↔ SC.
57
+ - **`active_platform` khoá sổ trace** — `qc_status` ghi đúng `{UC-ID}-{platform}.tsv`.
58
+ - **Chủ sở hữu bước `🟡 Fixed 🟢 Closed`.** `/report-bug` mở bug (`🟢 Open`), `/fix-bug` đặt `🟡 Fixed`, **chỉ QC re-verify mới đóng được** — dev không tự đóng bug của mình.
59
+
60
+ ### sao đóng bug phải chạy TRƯỚC khi clear cột
61
+
62
+ Khi `qc_status` flip `pass`, lệnh clear `qc_owner`/`qc_blocked_by` về `—`. Nhưng `qc_blocked_by` **chính là con trỏ tới `{BUG-ID}`** — clear xong là mất đường về, và đối chiếu tay cũng không làm được. Nên thứ tự bắt buộc: **đọc `qc_blocked_by` → đóng bug → rồi mới clear**.
63
+
64
+ | `State` của bug | SC vừa `pass` → làm gì |
65
+ |---|---|
66
+ | `🟡 Fixed` | → `🟢 Closed` + dòng `Verified: /qc-run-test {today} — {UC-ID}-SC{N} pass` |
67
+ | `🟢 Open` (chưa ai fix) | **KHÔNG đóng.** Giữ `Open` + ghi chú kiểm tra lại test |
68
+ | `GAP-*` thay vì `BUG-*` | không đụng — spec-gap thuộc PO, không phải QC |
69
+
70
+ > Ca `Open` là ngoại lệ **có chủ đích**: test pass trên một bug chưa ai fix là dấu hiệu **test sai**, không phải bug hết. Tự đóng ở đây sẽ **chôn một defect thật**.
71
+
72
+ Bug report đã đổi phải **commit + push** vào spec repo — file local là dead drop, PO/Dev chỉ thấy sau khi push.
73
+
74
+ ---
75
+
76
+ ## 👓 Góc nhìn tối ưu
77
+
78
+ - **Trạm nặng nhất của QC** — sinh + chạy + phân loại + ghi trace. Chạy thật phụ thuộc môi trường (browser, data, service lên).
79
+ - **Phân loại script-bug vs product-gap phụ thuộc AI/reviewer** — sai loại → hoặc giấu lỗi sản phẩm hoặc báo nhầm. Đáng có tiêu chí rõ.
80
+ - **Selector phụ thuộc `/map-testids`** — nếu chưa map, script giòn.
81
+ - **Chạy lại tốn tài nguyên** — cân nhắc scoped run như dev-run-test.
82
+
83
+ ---
84
+
85
+ ## Kết nối
86
+
87
+ **Trước:** [`/qc-review`](18-qc-review.md) (case) · **Sau:** [`/qc-report`](20-qc-report.md) rồi [`/qc-review`](18-qc-review.md) (script).