@educa-corp/sdd-framework 0.9.0 → 0.9.2

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 +56 -12
  2. package/bin/qc-base-map.json +595 -0
  3. package/bin/self-check.js +146 -0
  4. package/bin/trace-schema.json +5 -0
  5. package/core/FRAMEWORK_VERSION +1 -1
  6. package/core/commands/generate-code.md +3 -2
  7. package/core/commands/propose-scenario.md +1 -1
  8. package/core/commands/qc-analyze.md +260 -22
  9. package/core/commands/qc-design-test.md +1 -1
  10. package/core/commands/qc-plan.md +7 -4
  11. package/core/commands/qc-run-test.md +1 -1
  12. package/core/commands/refine-prd.md +47 -20
  13. package/core/commands/report-bug.md +1 -1
  14. package/core/commands/review-context.md +27 -1
  15. package/core/commands/validate-traces.md +26 -2
  16. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +117 -0
  17. package/core/skills/qc/qa-analyst/acceptance-criteria.md +4 -2
  18. package/core/skills/qc/qa-analyst/business-rules.md +38 -4
  19. package/core/skills/qc/qa-analyst/data-flow.md +5 -3
  20. package/core/skills/qc/qa-analyst/exhaustive-gap-scanner.md +174 -0
  21. package/core/skills/qc/qa-analyst/spec-breakdown.md +9 -7
  22. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +100 -0
  23. package/core/skills/qc/qa-designer/e2e/journey.md +2 -2
  24. package/core/skills/qc/qa-designer/exploratory/charter.md +1 -1
  25. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +1 -1
  26. package/core/skills/qc/qa-designer/functional/api.md +2 -2
  27. package/core/skills/qc/qa-designer/functional/gui-feature.md +2 -2
  28. package/core/skills/qc/qa-designer/functional/gui-screen.md +2 -2
  29. package/core/skills/qc/qa-designer/integration/api.md +2 -2
  30. package/core/skills/qc/qa-designer/integration/db.md +2 -2
  31. package/core/skills/qc/qa-designer/integration/gui.md +2 -2
  32. package/core/skills/qc/qa-designer/integration/kafka.md +2 -2
  33. package/core/skills/qc/qa-designer/non-functional.md +2 -2
  34. package/core/skills/qc/qa-planner/risk-model.md +106 -0
  35. package/core/skills/qc/qa-planner/test-plan.md +13 -10
  36. package/core/skills/qc/qa-reviewer/script/e2e.md +1 -1
  37. package/core/skills/qc/qa-reviewer/script/exploratory.md +1 -1
  38. package/core/skills/qc/qa-reviewer/script/functional.md +1 -1
  39. package/core/skills/qc/qa-reviewer/script/integration.md +1 -1
  40. package/core/skills/qc/qa-reviewer/script/non-functional.md +1 -1
  41. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  42. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  43. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  44. package/core/skills/qc/qa-reviewer/test-case/integration.md +2 -2
  45. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  46. package/core/skills/qc/qa-runner/e2e.md +1 -1
  47. package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
  48. package/core/skills/qc/qa-runner/functional/api.md +1 -1
  49. package/core/skills/qc/qa-runner/functional/gui-feature.md +1 -1
  50. package/core/skills/qc/qa-runner/functional/gui-screen.md +1 -1
  51. package/core/skills/qc/qa-runner/integration.md +1 -1
  52. package/core/skills/qc/qa-runner/non-functional.md +1 -1
  53. package/core/skills/qc/qa-runner/report/report.md +1 -1
  54. package/core/steps/gap-verify.md +231 -0
  55. package/core/steps/review-fanout.md +27 -1
  56. package/core/templates/project-context.yaml +2 -2
  57. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +2 -2
  58. package/docs/04-reference/commands.md +1 -1
  59. package/docs/explain/03-refine-prd.md +8 -6
  60. package/docs/explain/15-qc-analyze.md +10 -7
  61. package/docs/explain/16-qc-plan.md +2 -2
  62. package/docs/plans/qc-implementation-log.md +1446 -0
  63. package/docs/plans/qc-merge-plan.md +502 -0
  64. package/docs/plans/qc-sync-command.md +358 -0
  65. package/package.json +1 -1
  66. package/core/skills/qc/qa-analyst/DOC_GAPS.template.md +0 -63
@@ -0,0 +1,1446 @@
1
+ # Nhật ký triển khai — đưa dây chuyền QC vào framework
2
+
3
+ > **Viết cho người đọc không cần biết code.** Mỗi bước ghi: giải quyết vấn đề gì, đổi cái gì,
4
+ > và trước/sau khác nhau ra sao.
5
+ >
6
+ > Hai tài liệu đi kèm: [`qc-merge-plan.md`](qc-merge-plan.md) — gộp cái gì và ba quyết định
7
+ > đang treo · [`qc-sync-command.md`](qc-sync-command.md) — về sau QC sửa skill thì đưa vào thế nào.
8
+
9
+ ---
10
+
11
+ ## Bối cảnh trong ba câu
12
+
13
+ Đội QC có một dây chuyền kiểm thử bằng AI chạy riêng bên ngoài framework, đã tích luỹ nhiều
14
+ kinh nghiệm thực chiến. Framework cũng có phần QC của mình, nhưng nó được sao chép từ một
15
+ **nhánh cũ** của đội QC và trong lúc sao chép đã **rút gọn mất** phần chi tiết nhất.
16
+
17
+ Việc đang làm: đưa bản đầy đủ về, và dựng cách để lần sau QC cải tiến thì mang sang được
18
+ mà không phải làm tay.
19
+
20
+ ---
21
+
22
+ ## Tổng quan các bước
23
+
24
+ | Bước | Tên | Trạng thái | Cần ai quyết? |
25
+ |---|---|---|---|
26
+ | **B0** | Làm cho hai bản so sánh được với nhau | ✅ xong | không |
27
+ | **B1** | Lấy lại phần kinh nghiệm đã bị rút gọn mất | ✅ xong | không |
28
+ | **B2** | Đóng dấu nguồn gốc cho từng file | ✅ xong | không |
29
+ | **B3** | Hỏi ít hơn, đúng hơn, đủ thông tin hơn | ✅ xong | không |
30
+ | **B4** | Sửa ba lỗi + lắp báo khói | ✅ xong | không |
31
+ | **B5** | Trạm QC đọc thêm tài liệu kỹ thuật | ✅ xong | đã chốt: **A** |
32
+ | **B6** | Bổ sung cách tính rủi ro cho trạm lập kế hoạch | ✅ xong | đã chốt: **a** |
33
+ | **B7** | Chốt hình dạng kết quả đầu ra | ✅ xong | `1B` · lăng kính *(`2A` bị B9 thay · **D5 tắt sai → B10 sửa**)* |
34
+ | **B8** | Bật lăng kính QC ở bước soát PRD | ✅ xong | đã chốt |
35
+ | **B9** | Bỏ chế độ `--standard`, gộp vào mặc định | ✅ xong | đã chốt |
36
+ | **B10** | Bật lại "đối chiếu chéo", thu hẹp còn 2 cặp | ✅ xong | **sửa quyết định sai ở B7** |
37
+
38
+ ---
39
+
40
+ ## ⚠️ Một chỗ rất dễ hiểu nhầm — đọc trước
41
+
42
+ **Không có tài liệu nào của đội QC bị xoá hay sửa.**
43
+
44
+ Suốt quá trình này, repo của đội QC **chỉ được ĐỌC**. Bản sao đóng băng nằm trong
45
+ `upstream/qc-base/` và còn **nguyên vẹn 82 file**.
46
+
47
+ Khi nhật ký ghi một kỹ năng là **"cố ý chưa lấy"**, nó có nghĩa:
48
+
49
+ | Nghĩa là | KHÔNG có nghĩa là |
50
+ |---|---|
51
+ | Kỹ năng đó **chưa được đưa vào** framework | ❌ bị xoá khỏi repo đội QC |
52
+ | Đã có **quyết định và lý do ghi lại** cho việc chưa đưa vào | ❌ bị đánh giá là vô dụng |
53
+ | Vẫn nằm nguyên trong bản sao — **lấy lúc nào cũng được** | ❌ mất đi |
54
+
55
+ Ngược lại với "bỏ": trước đây những kỹ năng này **vô hình** — không ai biết chúng tồn tại hay
56
+ tại sao framework không có. Giờ mỗi cái có một dòng ghi rõ tình trạng và lý do.
57
+
58
+ ---
59
+
60
+ ## 📁 Từ vựng — bốn loại tài liệu, và tên thật của chúng
61
+
62
+ Nhật ký này gọi tài liệu bằng tên tiếng Việt cho dễ đọc. Nhưng **hai trong bốn cái tên nghe rất
63
+ giống nhau** trong khi chúng là hai tài liệu hoàn toàn khác — nên tra bảng này khi thấy mơ hồ.
64
+
65
+ ```
66
+ specs/{lĩnh vực}/{tên-tính-năng}/
67
+ ├── {MÃ}-{tên-tính-năng}.md ① PRD
68
+ ├── design-spec/
69
+ │ └── {MÃ}-design-spec-web-….md ② "bản thiết kế"
70
+ ├── bdd/
71
+ │ └── web/{UC}.feature ③ "kịch bản test"
72
+ └── tech-docs/
73
+ └── {MÃ}-tech-design.md ④ "tài liệu kỹ thuật"
74
+ ```
75
+
76
+ | # | Nhật ký gọi là | Tên thật | Ai viết | Bên trong có gì |
77
+ |---|---|---|---|---|
78
+ | ① | **PRD** | `{MÃ}-{tên}.md` | PO | yêu cầu nghiệp vụ · tiêu chí chấp nhận · luật nghiệp vụ |
79
+ | ② | **bản thiết kế** | `design-spec/` | **Designer** | màn hình · thành phần giao diện · **trạng thái màn** (đang tải / lỗi / rỗng) · điều hướng · **link Figma** |
80
+ | ③ | **kịch bản test** | `bdd/{nền}/*.feature` | sinh từ PRD | Gherkin — Cho trước / Khi / Thì |
81
+ | ④ | **tài liệu kỹ thuật** | `tech-docs/…-tech-design.md` | **Kiến trúc sư** | mô hình dữ liệu · **hợp đồng hệ thống** (nhận gì, trả gì) · **danh sách mã lỗi** · luồng tuần tự · điểm nối với hệ thống khác |
82
+
83
+ > ⚠️ **② và ④ là HAI tài liệu khác nhau, đừng nhầm.**
84
+ >
85
+ > **② bản thiết kế** = *Designer vẽ gì* — người dùng nhìn thấy gì trên màn hình.
86
+ > **④ tài liệu kỹ thuật** = *hệ thống làm gì* — backend nhận vào gì, trả ra gì, lỗi có mấy loại.
87
+ >
88
+ > Cả hai tên tiếng Việt đều nghe như "kỹ thuật", nhưng một cái là **giao diện**, một cái là
89
+ > **hệ thống**. Chỗ phân biệt này quan trọng nhất ở §Kiểm chứng 31 câu hỏi (cuối nhật ký): lỗ
90
+ > tìm ra nằm ở **② bản thiết kế**, không phải ④.
91
+
92
+ ---
93
+
94
+ # ✅ B0 — Làm cho hai bản so sánh được với nhau
95
+
96
+ ## Vấn đề
97
+
98
+ Hai tài liệu **trông giống hệt nhau** với mắt người, nhưng máy báo *"toàn bộ 149 dòng đều khác"*.
99
+
100
+ Nguyên nhân: Windows và Mac/Linux đánh dấu **kết thúc dòng** bằng ký tự khác nhau. Con người
101
+ không thấy, máy thì thấy từng dòng một đều lệch.
102
+
103
+ Hậu quả: không thể trả lời câu hỏi cơ bản nhất — *"đội QC vừa sửa gì?"* Mọi phép so sánh
104
+ đều là nhiễu.
105
+
106
+ > Giống như hai bản Word nội dung y hệt nhau, nhưng một bản đặt font khác — công cụ so sánh
107
+ > tô đỏ **toàn bộ** trang, và bạn không tìm ra chỗ nào thực sự đổi.
108
+
109
+ ## Đã đổi gì
110
+
111
+ Chuẩn hoá 81 trên 82 file của bản sao đội QC về cùng một quy ước.
112
+
113
+ ## Trước / sau
114
+
115
+ | File | Máy báo "khác" trước B0 | Thực tế khác |
116
+ |---|---|---|
117
+ | Trích xuất luật nghiệp vụ | 149 dòng | **49** |
118
+ | Bóc tách yêu cầu | 119 | **19** |
119
+ | Phân tích luồng dữ liệu | 125 | **15** |
120
+ | Sinh tiêu chí chấp nhận | 117 | **13** |
121
+
122
+ ## Vì sao phải làm đầu tiên
123
+
124
+ Mọi bước sau đều dựa trên việc so sánh hai bản. Không làm B0 thì B1 mù, và công cụ đồng bộ
125
+ sau này cũng vô dụng.
126
+
127
+ ---
128
+
129
+ # ✅ B1 — Lấy lại phần kinh nghiệm đã bị rút gọn mất
130
+
131
+ ## Vấn đề
132
+
133
+ Khi framework sao chép kỹ năng của đội QC trước đây, nó giữ lại **phần tóm tắt** và bỏ đi
134
+ **phần checklist**. Mà checklist chính là chỗ chứa kinh nghiệm: *"đây là những thứ chúng ta
135
+ hay quên kiểm"*.
136
+
137
+ Bản framework chỉ còn câu chung chung: *"quét tìm điều kiện, ràng buộc field, giới hạn…"*
138
+
139
+ ## Đã lấy lại được gì
140
+
141
+ ### Checklist ràng buộc ô nhập liệu
142
+
143
+ Với **mọi** ô nhập, kiểm đủ 4 mục:
144
+
145
+ - Độ dài tối thiểu / tối đa — PRD có nêu không? Không nêu → ghi thành câu hỏi cho PO
146
+ - Ký tự nào được phép — chữ, số, **tiếng Việt có dấu**, ký tự đặc biệt, khoảng trắng?
147
+ - Có cắt khoảng trắng đầu/cuối không?
148
+ - Định dạng riêng — email, số điện thoại, ngày tháng?
149
+
150
+ Kèm một luật quan trọng:
151
+
152
+ > ⚠️ **Ô "không bắt buộc nhập" VẪN phải kiểm đủ 4 mục.**
153
+ > "Không bắt buộc" **không** đồng nghĩa "không có ràng buộc". Đây là chỗ hay bị bỏ sót nhất.
154
+
155
+ ### Checklist "hay bị bỏ sót khi đọc PRD"
156
+
157
+ | | Kiểm gì | Bug điển hình nếu bỏ qua |
158
+ |---|---|---|
159
+ | **a** | Bảng phân luồng phải đọc **cả hai chiều** — "đủ điều kiện thì bỏ qua" *và* "thiếu thì vào" | Chỉ test nhánh thuận, nhánh nghịch ra production mới lộ |
160
+ | **b** | Liệt kê **hết** biến thể (Google/Facebook, Lớp 1–6…) và hỏi: biến thể nào hành vi khác? | Test 1 biến thể, 5 cái kia không ai đụng |
161
+ | **c** | Liệt kê **mọi** sự kiện thống kê được nhắc tới; có trường nhạy cảm (SĐT) **không được** lọt vào không? | Lộ dữ liệu cá nhân qua log thống kê |
162
+ | **d** | Spec có nói "KHÔNG ghi", "KHÔNG hiển thị", "chỉ đọc" → mỗi câu là một phép kiểm riêng | Không ai test điều-không-được-xảy-ra |
163
+ | **e** | Spec viết "chuẩn hoá theo AC3", "giống màn Z" → phải mở AC3 / màn Z ra đọc | Kế thừa nửa vời, hai màn hành vi lệch nhau |
164
+ | **f** | Một tiêu chí viết "(1)…; (2)…; (3)…" → đếm ra, mỗi ý một phép kiểm | Đọc thành một ý, test một ý, sót hai |
165
+
166
+ ## Trước / sau
167
+
168
+ | | Trước | Sau |
169
+ |---|---|---|
170
+ | Kỹ năng "trích xuất luật nghiệp vụ" | 59 dòng | **91 dòng** |
171
+ | Checklist ô nhập liệu | không có | 4 mục + luật ô tuỳ chọn |
172
+ | Checklist hay-bỏ-sót | không có | 6 nhóm (a–f) |
173
+
174
+ ## Giá trị với PO
175
+
176
+ Mỗi dòng checklist tương ứng **một loại bug**. Hỏi ở lúc viết PRD thì mất 2 phút; không hỏi
177
+ thì nó thành bug ở lúc test, hoặc tệ hơn — thành tranh cãi *"spec đâu có nói"* giữa dev và QC.
178
+
179
+ ## Hai chỗ cố ý **không** lấy theo bản đội QC
180
+
181
+ | Chỗ | Bản đội QC | Quyết định |
182
+ |---|---|---|
183
+ | Câu kết phần kết quả | có lỗi lặp — viết "ghi vào file X" hai lần trong một câu | giữ bản framework (đã sạch) |
184
+ | Đường dẫn thư mục | trỏ vào thư mục riêng của dự án đội QC | giữ bản framework (đã chỉnh cho đúng cấu trúc chung) |
185
+
186
+ Hai chỗ này phải được ghi nhớ là **"khác có chủ ý"** — nếu không, mỗi lần đồng bộ sau này
187
+ sẽ lôi lại đúng lỗi lặp kia.
188
+
189
+ ## Hai file còn lại: không mất gì
190
+
191
+ "Phân tích luồng dữ liệu" và "sinh tiêu chí chấp nhận" chỉ khác cách diễn đạt.
192
+ Riêng "sinh tiêu chí chấp nhận" thì **bản framework tốt hơn** — nó có thêm phần nối tiêu chí
193
+ về đúng kịch bản kiểm thử tương ứng, thứ bản đội QC không có.
194
+
195
+ ---
196
+
197
+ # ✅ B2 — Đóng dấu nguồn gốc cho từng file
198
+
199
+ ## Vấn đề
200
+
201
+ > Bạn nhận một bản hợp đồng mẫu từ phòng pháp chế, sửa vài điều cho hợp với dự án của mình.
202
+ > Sáu tháng sau pháp chế gửi bản mẫu **mới**.
203
+ >
204
+ > Nếu lúc sửa bạn **không ghi lại** *"tôi sửa từ bản v3"*, thì bây giờ bạn không phân biệt được:
205
+ > chỗ nào là **pháp chế vừa đổi**, chỗ nào là **bạn cố ý sửa**. Ghép hai bản lại thành ra đoán.
206
+
207
+ Đây đúng tình trạng của framework: mỗi file chỉ ghi *"lấy từ đội QC"* — một cái tên, **không có
208
+ phiên bản**. Và cái tên đó còn **ghi sai** tên kho tài liệu.
209
+
210
+ ## Đã đổi gì
211
+
212
+ Mỗi file được đóng dấu ba thông tin: **lấy từ kho nào · lấy từ file nào · lấy từ phiên bản nào**
213
+ (bằng một mã kiểm tra duy nhất cho từng phiên bản).
214
+
215
+ Kết quả:
216
+
217
+ - **5 file** đóng dấu đầy đủ — đã kiểm chứng tự động là mã khớp với file gốc thật
218
+ - **30 file** sửa lại tên kho cho đúng, **chưa đóng dấu được** (lý do bên dưới)
219
+
220
+ ## Phát hiện: 30 trên 35 file **không tìm được bản gốc**
221
+
222
+ Kiểm tra đối chiếu cho thấy:
223
+
224
+ | Nhóm kỹ năng của framework | Số file | Tìm được bản gốc tương ứng |
225
+ |---|---|---|
226
+ | Phân tích yêu cầu | 5 | **5/5** ✅ |
227
+ | Thiết kế test case | 11 | **0/11** |
228
+ | Soát test case & script | 10 | không rõ — tên và cách chia đều khác |
229
+ | Chạy test & báo cáo | 8 | **0/8** — đội QC chỉ có 2 file cho phần này, framework chia thành 8 |
230
+
231
+ Nguyên nhân: framework sao chép từ một **nhánh cũ** của đội QC. Sau đó đội QC đã gộp nhiều
232
+ kỹ năng nhỏ thành kỹ năng lớn với tên khác. Nên bản gốc của 30 file kia **không còn tồn tại**
233
+ dưới dạng có thể đối chiếu.
234
+
235
+ **Hệ quả cần biết trước:** về sau đội QC cải tiến phần thiết kế test case hay phần chạy test,
236
+ sẽ **không có đường tự động** mang sang framework — vì 1 file bên họ ứng với 11 file bên mình.
237
+ Ba hướng xử lý (chưa cần quyết bây giờ):
238
+
239
+ 1. Chấp nhận 30 file đó **do framework tự sở hữu**, không đồng bộ ngược nữa
240
+ 2. Gộp lại theo cách chia của đội QC — đổi kiến trúc bốn trạm
241
+ 3. Ghép tay, công cụ chỉ báo *"bên kia vừa đổi, tự xem"*, không tự ghép
242
+
243
+ ## Phát hiện thứ hai: phần "lập kế hoạch test" cũng bị cắt
244
+
245
+ Cùng bệnh với B1, nhưng nặng hơn: **158 → 120 dòng**. Phần bị mất:
246
+
247
+ - **Phủ theo nhóm người dùng** — bảng liệt kê từng nhóm (theo vai trò / trạng thái / phân khúc),
248
+ mỗi nhóm thấy màn hình và luồng khác nhau, **kể cả nhóm "không đủ điều kiện"**
249
+ - **Ma trận đa nền** — luồng quan trọng nhất × từng cặp nền/thiết bị, ghi rõ hành vi
250
+ chỉ có ở một nền (vuốt về chỉ có ở app, bàn phím chỉ có ở web)
251
+ - **Ba chỉ số nghiệm thu có công thức đo được** — phủ chức năng 100% · phủ đa nền · phủ giá trị biên 100%
252
+ - Bảng ước lượng số test case, kèm giải thích chênh lệch giữa "tối thiểu theo yêu cầu" và "thực tế cần"
253
+ - Luật: *lỗi hạ tầng (mất mạng, quá hạn) thì kiểm **điều người dùng nhìn thấy**, không kiểm số lần thử lại*
254
+ - Ghi chú hiệu chỉnh: *tính năng đơn giản, một nền, một nhóm người dùng thì ghi "không áp dụng" —
255
+ đừng tick cho đủ ô*
256
+
257
+ **Chưa lấy lại**, vì ba lý do: nó thuộc trạm 2 chứ không phải trạm 1 · phần mất có chứa đường dẫn
258
+ nên phải chỉnh chứ không dán thẳng được · và nó tham chiếu tới cách chia UI/API/E2E — chính là
259
+ câu B5 đang chờ quyết.
260
+
261
+ ---
262
+
263
+ # ✅ B3 — Hỏi ít hơn, đúng hơn, đủ thông tin hơn
264
+
265
+ ## Vấn đề
266
+
267
+ Khi AI đọc PRD rồi báo *"chỗ này chưa rõ, PO xác nhận giúp"*, có **hai bệnh** — và bệnh thứ hai
268
+ tốn của PO nhiều hơn.
269
+
270
+ **Bệnh 1 — sót.** Chạy lần 1 ra 8 chỗ. Sửa xong chạy lại ra 6 chỗ *mới*. Lần 3 ra 4 chỗ nữa.
271
+ PO tưởng đã chốt PRD, sang viết kịch bản test hoặc code mới lòi tiếp → làm lại.
272
+
273
+ **Bệnh 2 — bịa.** Báo 22 chỗ "thiếu", nhưng phần lớn thực ra là: PRD **đã nói rồi** ở mục khác
274
+ hoặc ở tài liệu sản phẩm gốc · AI **tự nghĩ ra một yêu cầu** rồi than PRD không mô tả nó ·
275
+ hoặc là chuyện **QC tự quyết được**, không cần hỏi PO.
276
+
277
+ Bệnh 2 tệ hơn vì nó **ăn mòn lòng tin**: PO đọc 22 câu, thấy 15 câu vô nghĩa, lần sau nhận
278
+ danh sách thì lướt. Lúc đó cả những câu **thật** cũng chết theo.
279
+
280
+ > Đội QC viết thẳng điều này trong tài liệu của họ:
281
+ > *"5 gap thật tốt hơn 22 gap với 20 gap ảo."*
282
+
283
+ **Nguyên nhân gốc:** quy trình soát của framework chỉ có **một chiều lực**. Nó quét rộng, rồi
284
+ lặp một vòng phê bình hỏi *"còn thiếu gì nữa?"* cho tới khi không ra thêm. Cả hai đều đẩy
285
+ **độ phủ** lên. **Không có bước nào hỏi ngược lại: "cái vừa tìm ra có thật không?"**
286
+
287
+ ## Đã đổi gì
288
+
289
+ ### 1 · Thêm bước thẩm định độc lập — thứ framework hoàn toàn chưa có
290
+
291
+ Một bước dùng chung mới: sau khi có danh sách, nó **mở lại tài liệu gốc** và bắt từng mục tự
292
+ chứng minh. Sáu phép kiểm:
293
+
294
+ | | Kiểm gì | Loại ra cái gì |
295
+ |---|---|---|
296
+ | **T1** | Đoạn trích dẫn có thật trong tài liệu không, có đúng nghĩa không? | trích dẫn bịa hoặc chép sai nghĩa |
297
+ | **T2** | Hành vi bị bảo là "thiếu" — spec **có thật sự yêu cầu** nó không? | tự nghĩ ra yêu cầu rồi than spec không tả |
298
+ | **T3** | Câu hỏi này đã được trả lời ở tài liệu khác chưa? | cái spec đã trả lời rồi |
299
+ | **T3b** | Hai chỗ bị bảo "mâu thuẫn" — có cùng một giai đoạn không? | hai giai đoạn khác nhau của cùng luồng, không mâu thuẫn |
300
+ | **T4** | Rule đã có ở tài liệu sản phẩm gốc chưa? | đòi tài liệu con lặp lại tài liệu cha |
301
+ | **T5** | Đây có thật là chuyện nghiệp vụ không? | lệch version · làm-kỹ-test · chuyện Dev/Design tự quyết |
302
+ | **T6** | Có trùng root cause với mục khác không? | đếm hai lần một vấn đề |
303
+
304
+ Kèm hai luật cứng:
305
+
306
+ > **Cấm dùng chính phần trích dẫn trong danh sách làm bằng chứng.** Bắt buộc mở file gốc đọc lại.
307
+ > Đây là **toàn bộ lý do** bước này tồn tại — bỏ qua nó thì nó chỉ là một vòng phê bình nữa.
308
+
309
+ > **Không xoá mục nào.** Cái bị loại thì **đóng lại kèm lý do**, giữ lại để kiểm chứng.
310
+ > Xoá thì không ai kiểm được là loại đúng hay loại nhầm.
311
+
312
+ ### 2 · Hiệu chỉnh mức độ — chống thổi phồng
313
+
314
+ T1–T6 quyết định một mục **còn hay bỏ**. Nhưng còn một bệnh nữa: mục hợp lệ nhưng **bị gán mức
315
+ quá cao**. Một danh sách toàn 🔴 Critical thì **không xếp được ưu tiên** — tức cột mức độ mất
316
+ sạch giá trị.
317
+
318
+ Thêm năm nhóm được hạ mức tự động, đều là *"không phải lỗ hổng của tính năng đang xét"*: lệch
319
+ pha với tài liệu gốc · spec con đã rõ chỉ nền domain lệch · nguồn tự đánh dấu là giả định ·
320
+ nhánh phòng vệ không thể chạm tới · thiếu tài liệu kỹ thuật ở tính năng xây mới (chặn tự-động-hoá,
321
+ không phải khuyết tật nghiệp vụ).
322
+
323
+ ### 3 · Ba câu hỏi lọc — trong đó có một câu bảo vệ thời gian của PO
324
+
325
+ Mỗi mục phải vượt cả ba mới được giữ:
326
+
327
+ | | Câu hỏi |
328
+ |---|---|
329
+ | **Q1** | Chỗ này đã được spec ở thiết kế / tài liệu sản phẩm / tài liệu kỹ thuật chưa? |
330
+ | **Q2** | Chỗ này có thuộc phạm vi spec đang xét không? |
331
+ | **Q3** | **Người thực thi tự quyết được không, hay bắt buộc cần PO/BA chốt?** |
332
+
333
+ > **Q3 là câu bảo vệ thời gian của PO.** Mọi thứ QC hoặc dev tự quyết được mà vẫn đẩy lên PO
334
+ > đều là chi phí thuần — và tệ hơn, nó làm loãng những câu thật.
335
+
336
+ ### 4 · Năm góc nhìn quét song song, thay vì một lượt đọc
337
+
338
+ | Góc | Soi gì |
339
+ |---|---|
340
+ | Luật nghiệp vụ | điều kiện thiếu nhánh, ngưỡng chưa chốt số |
341
+ | Xử lý lỗi | quá hạn thì sao, thử lại mấy lần, hết lần thì đi đâu |
342
+ | Giao diện | màn thiếu trạng thái đang tải / rỗng / lỗi; chữ trên nút có nhất quán không |
343
+ | Dữ liệu & cấu hình | có đủ dữ liệu để tự kiểm chứng kết quả tính không |
344
+ | Đối chiếu chéo tài liệu | PRD nói A, thiết kế nói B — và **thiếu hay thừa** |
345
+
346
+ Riêng góc cuối có một luật đáng chú ý: phải phân biệt **THIẾU** (thiết kế bỏ sót thứ PRD yêu cầu)
347
+ với **THỪA** (thiết kế **tự thêm** thứ PRD không định nghĩa). Hai hướng xử lý ngược nhau —
348
+ THIẾU thì bổ sung vào thiết kế; THỪA thì PO chốt giữ hay gỡ. Gọi nhầm hướng là đặt sai đề bài.
349
+
350
+ ### 5 · Bảng câu hỏi đầy đủ hơn *(mới, chưa bật)*
351
+
352
+ Bảng 10 cột của đội QC được đưa vào, đặt **cạnh** bảng 9 cột hiện hành. Hai điểm hơn:
353
+
354
+ | | Bảng 9 cột hiện dùng | Bảng 10 cột mới |
355
+ |---|---|---|
356
+ | **Giao cho đội nào** | ❌ không có cột | ✅ Dev / PO / BA / Design / Kiến trúc / Dữ liệu |
357
+ | **Nội dung câu hỏi** | một ô tự do — hay chỉ ghi *"AC3 mơ hồ"* | ✅ bắt buộc đủ bốn mục: **Bối cảnh** → **Vấn đề** → **Tại sao quan trọng** → **Gợi ý** |
358
+
359
+ *"Tại sao quan trọng"* cho phép PO **xếp ưu tiên** — biết bỏ qua thì hỏng gì.
360
+ *"Gợi ý"* cho phép PO **trả lời nhanh** — duyệt hoặc sửa, thay vì nghĩ lại từ đầu.
361
+
362
+ Bảng mới **chưa được bật**; nó chờ quyết định về hình dạng đầu ra (B7).
363
+
364
+ ## Trước / sau, dưới góc nhìn PO
365
+
366
+ | | Trước | Sau |
367
+ |---|---|---|
368
+ | Bước thẩm định | **không có** | 6 phép kiểm + 3 câu lọc + hiệu chỉnh mức |
369
+ | Câu bị loại | không tồn tại khái niệm này | đóng kèm lý do — kiểm chứng được |
370
+ | Báo cáo | *"Gaps: 22 (5 blocker)"* | thêm dòng: *"22 gap thô → 7 còn mở (❌ 9 bịa/đã-trả-lời · ⚠️ 4 không phải nghiệp vụ · 🔁 2 trùng)"* |
371
+ | Chạy lại lần 2 | lòi thêm câu mới | vòng phê bình lặp tới khi hai lượt liền không ra gì mới |
372
+
373
+ ## Một quyết định port đáng ghi lại
374
+
375
+ Bản gốc của đội QC **tự cài lại toàn bộ cơ chế quét song song** bằng tay — một bộ điều phối
376
+ kiểm kê tài liệu, gọi 5 luồng, rồi gom kết quả.
377
+
378
+ Framework **đã có sẵn đúng cơ chế đó**, và bản của framework còn hơn ở hai điểm: có vòng phê
379
+ bình lặp tới khi cạn, và có giới hạn số luồng chạy đồng thời khi tài liệu quá lớn.
380
+
381
+ → Chỉ port **phần nội dung** (5 góc nhìn), bỏ phần điều phối. Nuôi hai bản cài đặt của cùng
382
+ một thứ thì chúng sẽ trôi khỏi nhau. Quyết định này được ghi vào chính file đó
383
+ (`port_completeness: partial`) để lần đồng bộ sau không hiểu nhầm phần thiếu là *"ta cố ý xoá"*.
384
+
385
+ ## Cái B3 **không** đổi
386
+
387
+ - Không đổi quy trình PO — vẫn là nhận danh sách, trả lời, duyệt
388
+ - Không đổi PRD, kịch bản test, hay tài liệu nào đang có
389
+ - Bảng 10 cột và 5 góc nhìn **chưa bật** — chờ quyết định B7
390
+ - Bước thẩm định **tắt mặc định** ở quy trình soát PRD; chỉ **bật sẵn** ở bước phân tích QC,
391
+ nơi nó không đổi hình dạng đầu ra, chỉ đổi chất lượng
392
+
393
+ ## Phần thưởng chưa dùng tới
394
+
395
+ Bước thẩm định đặt ở **tầng dùng chung**, không gắn chết vào QC. Nghĩa là quy trình soát PRD
396
+ (ba góc nhìn Dev / Kiến trúc / PO) **bật được ngay bằng một tham số** — vì nó cũng đang mắc
397
+ đúng bệnh bịa, cũng chỉ có vòng "tìm thêm" mà không có vòng "kiểm lại".
398
+
399
+ Chưa bật, để tránh đổi hành vi một lệnh đang chạy ổn. Nhưng đường đã sẵn.
400
+
401
+ ---
402
+
403
+ # ✅ B4 — Sửa ba lỗi + lắp báo khói
404
+
405
+ ## Ba lỗi lẻ
406
+
407
+ ### 1 · Kiểm nhầm bản
408
+
409
+ Một tính năng thường chạy trên **ba nền**: web, app, hệ thống. Mỗi nền có **kịch bản test riêng**,
410
+ và ba bản đó **duyệt độc lập** — bản web có thể đã duyệt trong khi bản app còn nháp.
411
+
412
+ Lệnh phân tích đang làm theo thứ tự: **kiểm "đã duyệt chưa"** → rồi mới **hỏi "nền nào"**.
413
+ Tức nó kiểm trước khi biết đang kiểm bản nào.
414
+
415
+ > Giống như ký duyệt bản hợp đồng tiếng Anh, rồi mới hỏi *"à mà mình đang triển khai bản tiếng
416
+ > Việt hay tiếng Anh nhỉ?"*
417
+
418
+ **Hậu quả:** báo "đã duyệt" trong khi bản đang dùng còn nháp — QC làm cả buổi trên tài liệu chưa
419
+ chốt. Hoặc ngược lại, chặn oan một bản đã duyệt rồi.
420
+
421
+ **Đã sửa:** đổi chỗ hai bước, hỏi nền trước. Và bổ sung một bước suy luận: nếu tính năng chỉ có
422
+ **một** nền thì tự nhận ra, không hỏi.
423
+
424
+ ### 2 · Sách hướng dẫn ghi ngược với thực tế
425
+
426
+ Tài liệu mô tả lệnh ghi *"không có bước dừng hỏi"*. Thực tế **có** — lệnh này ghi file ra nên nó
427
+ dừng xin xác nhận, đúng thiết kế.
428
+
429
+ **Vì sao lọt được:** framework có cơ chế tự động canh *"mỗi lệnh phải khai rõ mình có dừng hỏi
430
+ không"*. Nhưng nó chỉ canh **file lệnh**, **không canh** tài liệu mô tả lệnh. Hai chỗ cùng nói về
431
+ một hành vi mà không ai bắt chúng phải đồng ý với nhau.
432
+
433
+ **Đã sửa:** lệnh khai rõ mức chặn, tài liệu sửa cho khớp.
434
+
435
+ ### 3 · Chạy tự động thì bị treo
436
+
437
+ Framework hứa một đường chạy **không cần người ngồi canh**. Nhưng lệnh phân tích có **ba chỗ dừng
438
+ hỏi**, mà công tắc *"chạy tự động, đừng hỏi tôi"* chỉ tắt được **một**:
439
+
440
+ | Chỗ dừng hỏi | Trước | Sau |
441
+ |---|---|---|
442
+ | Xác nhận trước khi chạy | ✅ tắt được | ✅ |
443
+ | *"Kịch bản chưa duyệt, vẫn chạy chứ?"* | ❌ treo | ✅ tự tiếp — **nhưng vẫn in cảnh báo** |
444
+ | *"Đang làm cho nền nào?"* | ❌ treo | ✅ tự suy; không suy được thì **dừng với lỗi rõ ràng** |
445
+
446
+ Đặt chạy lúc 11 giờ đêm, 11 giờ 1 phút nó dừng hỏi, không ai trả lời, treo tới sáng.
447
+
448
+ Hai chi tiết cố ý trong bản sửa:
449
+
450
+ - Chỗ thứ hai **vẫn in cảnh báo** dù không chặn. *Không chặn ≠ không báo* — người đọc log sau này
451
+ vẫn cần thấy QC đã chạy trên tài liệu chưa chốt.
452
+ - Chỗ thứ ba **không đoán bừa**. Đoán sai nền là ghi kết quả vào sai thư mục **và** ghi trạng thái
453
+ kiểm thử vào sai sổ — hỏng im lặng. Thà dừng và nói rõ phải nêu nền.
454
+
455
+ ---
456
+
457
+ ## Việc thứ tư — lắp báo khói
458
+
459
+ Ba việc trên là lỗi lẻ. Việc này **chống tái phát**, và nó không phải phòng xa: **đã cháy hai lần**
460
+ ngay trong lúc làm.
461
+
462
+ ### Đám cháy 1 — 35 file biến mất mà mọi đèn đều xanh
463
+
464
+ | Lớp kiểm tra | Báo gì | Vì sao không bắt |
465
+ |---|---|---|
466
+ | Bộ kiểm tra tự động | ✅ sạch | canh chuyện khác, không canh *"file có tồn tại không"* |
467
+ | Bộ đóng gói | ✅ 41/41 | không có file thì đóng gói cái rỗng — vẫn thành công |
468
+ | Chạy thử tại chỗ | ✅ vẫn chạy | bản chạy thử **không tự dọn** file cũ, nên chúng vẫn nằm đó |
469
+
470
+ Và bộ cài đặt sẽ **chủ động xoá** 35 file đó ở máy người dùng khi họ nâng cấp — đúng luật, đúng
471
+ thiết kế, và im lặng hoàn toàn.
472
+
473
+ > Ba lớp che nhau. Bên trong nhà thấy bình thường; chỉ người ngoài mới bị.
474
+
475
+ ### Đám cháy 2 — mã nguồn gốc bịa
476
+
477
+ Lúc viết một file mới ở bước trước, cần ghi vào đó **mã nhận dạng phiên bản gốc** mà nó được sao
478
+ chép từ. Mã đó bị **gõ đại** thay vì tính.
479
+
480
+ Tự phát hiện và sửa. Nhưng nếu lọt, dãy số bịa nằm đó **vĩnh viễn** và mọi lần đồng bộ sau đều lấy
481
+ nó làm gốc so sánh — tức mọi lần đồng bộ về sau đều là đoán.
482
+
483
+ > Đây đúng loại việc con người **không thể** làm đáng tin bằng sự cẩn thận.
484
+
485
+ ### Báo khói kiểm bốn thứ
486
+
487
+ | | Kiểm | Bắt được |
488
+ |---|---|---|
489
+ | **a** | Mọi tài liệu của đội QC phải có mặt trong bảng theo dõi | Kỹ năng **bị bỏ quên trong im lặng**. Ghi *"cố ý không lấy"* là hợp lệ — **vắng mặt** thì không |
490
+ | **b** | Mọi mã nguồn gốc phải **khớp file thật**, ở cả bảng lẫn trong file | Đám cháy 2 |
491
+ | **c** | Mọi đích trong bảng phải tồn tại | Bảng lỗi thời sau khi đổi tên file |
492
+ | **d** | **Lệnh trỏ vào kỹ năng nào thì kỹ năng đó phải có thật** | Đám cháy 1 |
493
+
494
+ ### Đã thử cháy thật để chắc báo khói kêu
495
+
496
+ Một cái báo khói chưa bao giờ kêu thì không ai biết nó có hoạt động không. Cả bốn nhánh được thử
497
+ bằng cách **cố tình tái tạo hai đám cháy**:
498
+
499
+ | Thử | Kết quả |
500
+ |---|---|
501
+ | Xoá thư mục kỹ năng *(tái tạo đám cháy 1)* | 🔴 **9 lỗi** — nhánh (d) và (c) cùng nổ |
502
+ | Đổi một mã nguồn gốc thành số bịa *(tái tạo đám cháy 2)* | 🔴 **2 lỗi** — bắt cả ở bảng lẫn ở file, và chỉ ra hai chỗ nói khác nhau |
503
+ | Thêm một file vào tài liệu đội QC mà không khai vào bảng | 🔴 bắt đúng tên file bị bỏ quên |
504
+
505
+ Khôi phục xong, tất cả về xanh.
506
+
507
+ ---
508
+
509
+ ## Bảng theo dõi — thứ có giá trị lâu hơn cả bốn việc trên
510
+
511
+ Ba nhánh **a·b·c** cần một thứ: **bảng theo dõi 82 dòng** — mỗi tài liệu của đội QC một dòng, ghi
512
+ rõ *đã lấy / sẽ lấy / **cố ý chưa lấy** / chưa quyết*.
513
+
514
+ | Trạng thái | Số dòng | Nghĩa |
515
+ |---|---:|---|
516
+ | `ported` — đã lấy | **8** | có mã nguồn gốc, đồng bộ ngược được |
517
+ | `skipped` — **cố ý chưa lấy** | **1** | tài liệu đội QC khai đã bỏ nhánh Excel thủ công, file còn sót |
518
+ | `undecided` — **chưa quyết** | **73** | ← đây là danh sách việc thật |
519
+
520
+ > **73 việc chưa quyết hiện ra rõ ràng.** Trước đó chúng vô hình — và cảm giác là "chỉ còn vài
521
+ > việc nữa". Bảng này cũng là chỗ **ghi quyết định** cho các bước còn lại: mỗi lần chốt một câu là
522
+ > một dòng đổi trạng thái, thay vì quyết định tản mát trong hội thoại rồi quên.
523
+
524
+ Một loại ghi chú nữa được đưa vào bảng: **"lấy một phần có chủ ý"**. Ví dụ ở bước trước, năm góc
525
+ nhìn quét gap được lấy nhưng phần điều phối thì không (framework đã có sẵn). Không đánh dấu thì
526
+ lần đồng bộ sau sẽ hiểu phần thiếu là *"ta cố ý xoá nội dung"* và giữ nguyên trạng thiếu.
527
+
528
+ ## Cái B4 **không** đổi
529
+
530
+ - Không đổi quy trình PO
531
+ - Không đổi kết quả đầu ra của bất kỳ lệnh nào
532
+ - 73 dòng `chưa quyết` **không chặn gì** — chúng chỉ là danh sách hiện ra
533
+
534
+ ---
535
+
536
+ # ✅ B5 — Trạm QC đọc thêm tài liệu kỹ thuật
537
+
538
+ **Quyết định: phương án A** — không nhận cách chia UI/API/E2E của đội QC.
539
+
540
+ ## Vấn đề
541
+
542
+ Khi phân tích một tính năng, đội QC đọc **hai loại tài liệu**:
543
+
544
+ 1. **Tài liệu nghiệp vụ** — PRD, kịch bản test, bản thiết kế giao diện *(trạm QC đang đọc rồi)*
545
+ 2. **Tài liệu kỹ thuật** — hệ thống nhận vào gì, trả ra gì, dữ liệu lưu ra sao *(trạm QC **chưa** đọc)*
546
+
547
+ Vì sao phải đọc loại 2? Vì có những lỗi **chỉ lộ ra khi so hai loại với nhau** — đọc riêng bên
548
+ nào cũng thấy hợp lý.
549
+
550
+ > **Ví dụ:** PRD viết *"người dùng chọn lớp **1 đến 6**"*. Tài liệu kỹ thuật ghi hệ thống chấp
551
+ > nhận **lớp 1 đến 9**.
552
+ >
553
+ > Vênh. QC hỏi PO: *lớp 7–9 là gì — PRD thiếu, hay hệ thống làm dư?*
554
+ >
555
+ > Không ai đọc cả hai thì không ai thấy. Lỗi này thường ra tận lúc chạy thật.
556
+
557
+ ## Câu hỏi ban đầu — và vì sao nó sai
558
+
559
+ Đội QC có **11 công cụ** để đọc loại tài liệu thứ hai. Câu hỏi tưởng là: *"có lấy 11 công cụ đó
560
+ không?"*
561
+
562
+ Nhưng kiểm rồi thì framework **đã có sẵn** một tài liệu kỹ thuật hợp nhất, viết ra ở bước ngay
563
+ trước QC, gộp đủ: hệ thống nhận gì trả gì · dữ liệu lưu ra sao · lỗi xử lý thế nào · luồng chạy
564
+ qua đâu · điểm nối với hệ thống khác.
565
+
566
+ > Đội QC phải xây 11 công cụ vì ở dự án của họ, tài liệu kỹ thuật **nằm rải rác ba chỗ**, mỗi
567
+ > chỗ một định dạng.
568
+ >
569
+ > Giống như: đội thẩm định quen đọc **ba tập hồ sơ gốc** vì công ty cũ không có bản tóm tắt.
570
+ > Còn ở đây **đã có sẵn** bản tổng hợp do kỹ sư trưởng viết, gộp cả ba, luôn cập nhật.
571
+
572
+ **Đối chiếu 11 công cụ với thứ framework đã có:**
573
+
574
+ | Công cụ của đội QC | Framework đã có ở đâu | Trạm QC **đã đọc** chưa |
575
+ |---|---|---|
576
+ | Đọc đặc tả màn hình | bản thiết kế giao diện | ✅ đã đọc |
577
+ | Chụp thiết kế Figma | bản thiết kế giao diện | ✅ đã đọc |
578
+ | Đọc đặc tả tính năng | PRD + tài liệu sản phẩm gốc | ✅ đã đọc |
579
+ | Đọc hợp đồng hệ thống | **tài liệu kỹ thuật** | ❌ chưa |
580
+ | Đọc sơ đồ dữ liệu | **tài liệu kỹ thuật** | ❌ chưa |
581
+ | Rút thiết kế kỹ thuật | **tài liệu kỹ thuật** | ❌ chưa |
582
+ | Nối giao diện ↔ hệ thống | **tài liệu kỹ thuật** | ❌ chưa |
583
+ | Vẽ đường đi luồng | **tài liệu kỹ thuật** | ❌ chưa |
584
+ | Đối chiếu chéo ba nguồn | *(chính là việc đối chiếu ở trên)* | — |
585
+ | Lập kế hoạch test hệ thống | thuộc **trạm 2**, không phải trạm 1 | — |
586
+ | Điều phối ba làn | engine quét song song đã có *(B3)* | — |
587
+
588
+ **Ba công cụ đầu đã được phủ** bởi tài liệu trạm QC đang đọc rồi.
589
+ **Năm công cụ giữa** được phủ bởi **một** tài liệu mà trạm QC chưa đọc.
590
+
591
+ → Câu hỏi rút gọn còn: **"trạm QC có nên đọc thêm bản tổng hợp đã có sẵn không?"**
592
+ Không phải *"port 11 công cụ"*, mà là **sửa vài dòng trong một lệnh**.
593
+
594
+ ## Đã đổi gì
595
+
596
+ Thêm một bước vào trạm phân tích: đọc tài liệu kỹ thuật và **đối chiếu sáu mục** với PRD/kịch bản
597
+ test — mỗi chỗ vênh là một câu hỏi loại *"hai tài liệu nói khác nhau"*:
598
+
599
+ | Đối chiếu gì |
600
+ |---|
601
+ | Thực thể / trường dữ liệu PRD nhắc tới có khớp không |
602
+ | **Tập giá trị hợp lệ** · ràng buộc trường · **danh sách mã lỗi** — PRD nêu bao nhiêu nhánh lỗi, hệ thống định nghĩa bao nhiêu |
603
+ | Màn hình / thành phần giao diện có mặt đủ không |
604
+ | Thứ tự bước và nhánh rẽ có khớp kịch bản test không |
605
+ | Việc phụ PRD nêu (gửi thông báo, gọi hệ thống khác) có được định nghĩa không |
606
+ | Trường hợp biên PRD nêu có đường xử lý không — và ngược lại |
607
+
608
+ **Không có tài liệu kỹ thuật → cảnh báo, không chặn.** Dự án có thể chưa dựng nó. Nhưng phải nói
609
+ rõ hậu quả: *"lệch giữa yêu cầu nghiệp vụ và hệ thống sẽ không được phát hiện ở trạm này"* — thay
610
+ vì im lặng bỏ qua rồi để người đọc tưởng đã kiểm.
611
+
612
+ ## Chuyện thứ hai — hai sổ ghi "chỗ chưa chốt"
613
+
614
+ Tài liệu kỹ thuật **đã có sẵn một sổ** ghi những chỗ chưa chốt, do người viết nó ghi. Sổ đó có
615
+ người chịu trách nhiệm, có mức độ, **và có cổng chặn** — còn chỗ chưa chốt nghiêm trọng thì
616
+ không được sinh code.
617
+
618
+ Nên khi trạm QC bắt đầu đọc tài liệu kỹ thuật, nó gặp **một sổ khác đã tồn tại**.
619
+
620
+ **Cách xử lý đã chốt: QC ĐỌC sổ đó, KHÔNG GHI vào.**
621
+
622
+ | Thấy gì trong sổ kỹ thuật | QC làm gì |
623
+ |---|---|
624
+ | Mục chưa chốt, **đội backend tự quyết** | ghi nhận *"đang chờ"* — **không** hỏi PO |
625
+ | Mục chưa chốt, **cần đội khác** | ghi nhận *"đang chờ"* — **không** hỏi PO |
626
+ | Mục ghi rõ là **PRD/kịch bản test sai hoặc thiếu** | **đúng là việc của PO** → vẫn ghi thành câu hỏi, và trỏ ngược về mục gốc để không đếm hai lần |
627
+
628
+ > **Vì sao không ghi vào.** Một mục đã nằm trong sổ kỹ thuật nghĩa là **đã có người đang lo**.
629
+ > Mở lại nó thành câu hỏi QC là gửi PO một câu hỏi không phải việc của PO — và tạo hai sổ cùng
630
+ > theo dõi một chuyện, rồi chúng lệch nhau.
631
+
632
+ Đây thực ra là **câu hỏi lọc Q1** đã lắp ở bước trước (*"chỗ này đã được trả lời ở tài liệu khác
633
+ chưa?"*), chỉ mở rộng phạm vi *"tài liệu khác"* thêm một nguồn.
634
+
635
+ ## Điểm yếu đã biết — ghi lại để sau này không quên
636
+
637
+ Tài liệu kỹ thuật của framework **do AI viết ra từ PRD**. Nên đối chiếu chỉ bắt được *"PRD lệch
638
+ tài liệu kỹ thuật"* — **không** bắt được *"PRD lệch hệ thống thật đang chạy"*.
639
+
640
+ Điều này chỉ quan trọng với **dự án đã có hệ thống chạy sẵn từ trước**. Với dự án làm mới theo
641
+ framework thì code sinh **ra từ** tài liệu kỹ thuật, nên nó chính là nguồn.
642
+
643
+ → Đường nâng cấp đã ghi sẵn: gặp dự án cũ cần soi hệ thống thật thì lấy đúng **2–3** công cụ cần,
644
+ không phải lấy hết 11.
645
+
646
+ ## Bảng theo dõi sau B5
647
+
648
+ | | Trước | Sau |
649
+ |---|---:|---:|
650
+ | đã lấy | 8 | 8 |
651
+ | **cố ý chưa lấy, có lý do** | 1 | **11** |
652
+ | chưa quyết | 73 | **63** |
653
+
654
+ Mười công cụ chuyển từ *chưa quyết* sang *cố ý chưa lấy* — **mỗi cái ghi rõ lý do và ghi rõ framework
655
+ đã có gì thay thế**. Quyết định B5 cũng được ghi thành một mục riêng trong bảng: câu hỏi, câu trả
656
+ lời, ba lý do, và điểm yếu đã biết.
657
+
658
+ > Đây là lần đầu bảng theo dõi làm đúng việc nó sinh ra để làm: **giữ quyết định ở chỗ máy đọc
659
+ > được**, thay vì để nó tan trong hội thoại.
660
+
661
+ ## Cái B5 **không** đổi
662
+
663
+ - Không đổi quy trình PO
664
+ - Không đổi tài liệu nào đang có
665
+ - Không thêm bước dừng hỏi nào
666
+ - Dự án chưa có tài liệu kỹ thuật vẫn chạy bình thường — chỉ mất phần đối chiếu, và được báo rõ
667
+
668
+ ---
669
+
670
+ # ✅ B6 — Bổ sung cách tính rủi ro cho trạm lập kế hoạch
671
+
672
+ **Quyết định: chỉ làm (a)** — bổ sung cách tính rủi ro. Hai việc kia để dành.
673
+
674
+ ## Vấn đề tôi tưởng — và hoá ra không phải
675
+
676
+ Còn ba kỹ năng của đội QC mà tôi xếp là *"đúng vai nhưng đứng sai trạm"*, nghe như ba tranh chấp
677
+ cần phân xử. Đọc kỹ thì **hai cái tự trả lời, và cái thứ ba tôi báo sai**.
678
+
679
+ ### 1 · Phân tích rủi ro — nó tự nói ra đích đến
680
+
681
+ Câu cuối của chính kỹ năng đó ghi: *"Bổ sung vào **`TEST_PLAN.md`**"* — mà đó là sản phẩm của
682
+ **trạm 2**, không phải trạm 1. Nó tự chỉ về trạm 2. Không có gì để tranh chấp.
683
+
684
+ ### 2 · Đo độ phủ — nó tự nói ra không chạy được ở trạm 1
685
+
686
+ Phần *"khi nào KHÔNG dùng"* của chính nó ghi: *"chưa có test case nào → độ phủ sẽ = 0%, **không
687
+ có ý nghĩa**"*.
688
+
689
+ Trạm 1 là trạm **đầu tiên** — lúc đó chưa có test case nào. **Nó không thể chạy ở đó.**
690
+ Tôi xếp nhầm ngay từ đầu.
691
+
692
+ ### 3 · Kịch bản thăm dò — không trùng lặp, tôi báo sai
693
+
694
+ Tôi nói *"trùng vai, khác trạm, phải chọn một"*. Sai. Cùng một kỹ thuật, **hai mục đích khác hẳn**:
695
+
696
+ | | Framework — trạm 3 | Đội QC — trạm 1 |
697
+ |---|---|---|
698
+ | Dùng khi | *trước khi bắt đầu buổi thăm dò* | *spec mơ hồ / thiếu / **không có*** |
699
+ | Để làm gì | **thiết kế** test kiểu thăm dò | **học** xem yêu cầu là gì, khi tài liệu không đủ |
700
+ | Ví dụ | tính năng mới rủi ro cao | tiếp quản hệ thống cũ, không ai viết tài liệu |
701
+
702
+ > Giống dùng đèn pin: một bên **soi kỹ một góc đã biết**, một bên vì **mất điện cả nhà**.
703
+
704
+ Đội QC dùng nó làm **phương án dự phòng khi không có tài liệu**. Framework không có phương án đó —
705
+ trạm 1 hiện giả định luôn có PRD và kịch bản test.
706
+
707
+ → Không phải chọn một. Là câu hỏi *"framework có cần phương án dự phòng không?"* — và câu trả lời
708
+ là **chưa**: trạm 1 của framework đứng **sau** cả chuỗi PRD → kịch bản test → tài liệu kỹ thuật →
709
+ code. Đến lúc QC vào việc thì tài liệu **phải có**; nếu không có thì vấn đề nằm ở chỗ khác, không
710
+ phải ở QC.
711
+
712
+ ## Việc thật sự phải làm
713
+
714
+ Chỉ một: **framework có khung bảng rủi ro nhưng không có cách điền.**
715
+
716
+ | | Framework hiện có | Đội QC có |
717
+ |---|---|---|
718
+ | Bảng rủi ro | 4 cột trống, một dòng gợi ý *"rút từ gap chặn + logic phức tạp"* | **cách chấm**: khả năng xảy ra × mức thiệt hại → P0–P3 |
719
+ | Nguồn rủi ro | không liệt kê | **7 nguồn cụ thể** |
720
+ | Rủi ro dùng làm gì | không nói | quyết định **độ sâu** test từng vùng |
721
+
722
+ ## Đã bổ sung gì
723
+
724
+ ### Bảy nguồn rủi ro — quét từng cái, không bỏ nguồn nào
725
+
726
+ logic phức tạp · **tiền / thanh toán** · dữ liệu nhạy cảm · tích hợp nhiều phần · code mới hoặc
727
+ sửa nhiều · **lịch sử lỗi cao** · ảnh hưởng nhiều người dùng
728
+
729
+ > Nguồn *"lịch sử lỗi cao"* là nguồn duy nhất **tra được bằng dữ liệu thật** — framework có sổ bug.
730
+ > Nên luật viết vào là: **mở ra đếm, đừng đoán "vùng này chắc ổn"**.
731
+
732
+ ### Chấm hai chiều rồi mới nhân
733
+
734
+ | Khả năng \ Thiệt hại | Cao | Trung bình | Thấp |
735
+ |---|:---:|:---:|:---:|
736
+ | **Cao** | **P0** | **P1** | P2 |
737
+ | **Trung bình** | **P1** | P2 | P3 |
738
+ | **Thấp** | P2 | P3 | P3 |
739
+
740
+ > **Vì sao tách hai chiều thay vì chấm thẳng ra P0/P1.** Hai chiều tách nhau là chỗ tranh luận
741
+ > trở nên **cụ thể**: *"cái này thiệt hại cao nhưng khả năng thấp"* là một câu **nói được và cãi
742
+ > được**. Còn *"cái này P1"* thì không cãi được — chỉ tin hoặc không tin.
743
+
744
+ ### Mức rủi ro quyết định **độ sâu** test
745
+
746
+ Đây là chỗ bảng rủi ro trả lại giá trị. Không có bước này thì nó chỉ là bảng trang trí.
747
+
748
+ | Mức | Test sâu tới đâu | Tự động hoá |
749
+ |---|---|---|
750
+ | **P0** | nhiều kỹ thuật cùng lúc | ✅ ưu tiên, cả hồi quy |
751
+ | **P1** | hai kỹ thuật trở lên, đủ nhánh chính + nhánh lỗi | ✅ nếu ổn định |
752
+ | **P2** | một kỹ thuật, luồng thuận + một nhánh lỗi tiêu biểu | tuỳ |
753
+ | **P3** | danh sách kiểm tay | ❌ |
754
+
755
+ Và hai luật đi kèm:
756
+
757
+ - **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"*.
758
+ Một P0 đang bị chặn thì không chạy được; làm P1 sẵn sàng trước là đúng.
759
+ - **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 không
760
+ nói làm gì với nó là ghi cho có.
761
+
762
+ ## Một quyết định kỹ thuật nhỏ, nhưng đáng ghi
763
+
764
+ Nội dung này lẽ ra trộn thẳng vào kỹ năng lập kế hoạch đã có. **Nhưng không làm vậy** — vì kỹ năng
765
+ đó đã được **đóng dấu nguồn gốc** trỏ về một file của đội QC, còn phần rủi ro đến từ **file khác**.
766
+
767
+ Trộn vào là file có **hai nguồn gốc**, mà cơ chế đóng dấu chỉ chịu được một → báo khói lắp ở bước
768
+ trước sẽ mất tác dụng với chính file đó.
769
+
770
+ → Tách thành file riêng, đóng dấu sạch. Hai file nạp cùng lúc.
771
+
772
+ > Đây là lần đầu **cơ chế đóng dấu ảnh hưởng ngược lại cách tổ chức file** — và theo hướng đúng:
773
+ > nó ép một file = một nguồn, thay vì để nội dung trộn lẫn rồi không ai truy được về đâu.
774
+
775
+ Cũng ghi `lấy một phần có chủ ý`: bản gốc có 5 phần, chỉ lấy 2. Ba phần kia trạm 1 đã làm rồi
776
+ (bóc tách yêu cầu · tìm gap · tiêu chí chấp nhận).
777
+
778
+ ## Bảng theo dõi sau B6
779
+
780
+ | | Trước | Sau |
781
+ |---|---:|---:|
782
+ | đã lấy | 8 | **9** |
783
+ | cố ý chưa lấy, có lý do | 11 | **13** |
784
+ | chưa quyết | 63 | **60** |
785
+
786
+ ## Cái B6 **không** đổi
787
+
788
+ - Không đổi quy trình PO
789
+ - Không đổi tài liệu nào đang có — chỉ thêm cột vào một bảng vốn đã có
790
+ - Không thêm bước dừng hỏi nào
791
+
792
+ ---
793
+
794
+ # ✅ B7 — Chốt hình dạng kết quả đầu ra
795
+
796
+ **Quyết định: 1B · 2A · 3 lăng kính · núm tự-chọn-theo-kích-thước · in dòng bước tiếp.**
797
+
798
+ ## Hai phần tự giải quyết trước khi bàn
799
+
800
+ | | Kết quả | Vì sao không còn gì để cân |
801
+ |---|---|---|
802
+ | Bản phân tích yêu cầu | **giữ** | B5 vừa đổ thêm nội dung vào chính file này — danh sách *"đang chờ chốt"* từ sổ ẩn số kỹ thuật. Nó không còn chỉ là bản phân tích, mà là chỗ trạm 2 và 3 biết **cái gì đang bị chặn và bởi ai** |
803
+ | Kế hoạch test | **vẫn ở trạm 2** | B6 vừa làm trạm 2 dày lên (cách tính rủi ro, bảy nguồn). Gộp ngược vào trạm 1 bây giờ là một trạm ôm hai việc không liên quan |
804
+
805
+ ## 1 · Hai bản file gap, **một** nguồn dữ liệu
806
+
807
+ ```
808
+ {qc_dir}/{UC-ID}/{nền}/DOC_GAPS.md ← bản người đọc
809
+ {refinement_dir}/{UC-ID}-qa-findings.yaml ← bảng điều khiển đọc được
810
+ ```
811
+
812
+ Sinh bản người đọc trước rồi **render** sang bản máy đọc — không phân tích lại lần hai.
813
+
814
+ PO giờ xem gap của QC **trong cùng bảng điều khiển** đã quen dùng cho việc soát PRD, thay vì phải mở đúng file trong đúng thư mục.
815
+
816
+ ### Hai rào bắt buộc
817
+
818
+ **Không có nút "chấp nhận rồi tự sửa".** Bảng điều khiển có nút đó, và với gap của việc soát PRD thì đúng — nó chạy ở **thời điểm PRD**, sửa lúc đó là sửa đúng chỗ.
819
+
820
+ Gap của trạm QC phát hiện **sau khi code đã xong**. Tự sửa PRD ở thời điểm đó là **sửa sau lưng cả dây chuyền**: kịch bản test sinh từ PRD cũ, code sinh từ kịch bản đó, sổ kết quả kiểm thử neo vào kịch bản đó. Đổi PRD mà không đi lại đường ấy thì mọi thứ phía sau **nói dối**.
821
+
822
+ → File này để **PO đọc và quyết**, không phải để máy tự áp. Đường sửa vẫn là kênh báo lỗi và đề xuất kịch bản đã có.
823
+
824
+ **File riêng, không ghi chung.** Ghi chung với file soát PRD sẽ phá cơ chế mà nó dùng để phân biệt *"PRD đổi do chính tôi"* với *"có người lạ sửa"* — và nó sẽ **mãi mãi** tưởng có người sửa sau lưng, mỗi lần chạy đều quét lại toàn bộ kèm cảnh báo giả.
825
+
826
+ ## 2 · Chế độ `--standard` chỉ trả bảng 10 cột
827
+
828
+ > ⚠️ **Quyết định này bị B9 thay thế.** `--standard` đã bị bỏ hẳn — khuôn 10 cột trở thành
829
+ > **mặc định**. Giữ phần dưới để thấy đường suy nghĩ: chính việc viết ra bảng so sánh này làm
830
+ > lộ ra rằng mọi ô ở cột `--standard` đều **nên** là mặc định. Xem B9.
831
+
832
+ | | Mặc định | `--standard` |
833
+ |---|---|---|
834
+ | Bảng gap | 9 cột | **10 cột** — thêm *giao cho đội*; ô câu hỏi bắt buộc đủ **bối cảnh → vấn đề → tại sao quan trọng → gợi ý** |
835
+ | Bản cho bảng điều khiển | ✅ | ❌ |
836
+ | Liệt kê tài liệu đã đọc | không bắt buộc | **bắt buộc** |
837
+ | Kèm kế hoạch test | ❌ | ❌ — việc của trạm 2 |
838
+
839
+ **Bản phân tích yêu cầu vẫn ghi ra** kể cả ở chế độ này. Đội QC coi nó là giấy nháp, nhưng trạm 2 và 3 **đọc nó**.
840
+
841
+ ## 3 · Ba lăng kính bật, hai tắt
842
+
843
+ | Lăng kính | | Vì sao |
844
+ |---|:---:|---|
845
+ | Dữ liệu & cấu hình | ✅ | **không gì phủ** — thêm nhiều giá trị nhất |
846
+ | Xử lý lỗi | ✅ | không kỹ năng nào chuyên về *"hết số lần thử lại thì đi đâu"* |
847
+ | Giao diện | ✅ | bản thiết kế có trạng thái màn, nhưng **không ai đối chiếu chữ trên nút** giữa các tài liệu |
848
+ | Luật nghiệp vụ | ⏸️ | B1 vừa thu hồi 2 checklist chuyên sâu — trùng |
849
+ | Đối chiếu chéo tài liệu | ⏸️ | B5 làm spec ↔ kỹ thuật; lệnh soát PRD làm PRD ↔ kịch bản test — trùng |
850
+
851
+ > ⚠️ **Quyết định tắt "đối chiếu chéo" là SAI — đã sửa ở B10.** Lăng kính đó phủ **bốn** cặp tài
852
+ > liệu, không phải hai; **2/4 đang hở**. Lý do *"trùng"* ghi ở đây đúng một nửa.
853
+ > Xem §Kiểm chứng 31 câu hỏi và **B10**.
854
+
855
+ Bật cả 5 tốn ~5–6 lần; bật 3 còn ~3 lần. **Hai cái tắt là hai cái trùng nhiều nhất**, nên cắt chúng mất ít độ phủ nhất.
856
+
857
+ ## 4 · Núm "tự chọn theo kích thước"
858
+
859
+ Việc soát PRD **luôn** chia mịn tới từng use case. Trạm QC thì **không** — nó chọn theo kích thước.
860
+
861
+ > **Vì sao khác nhau.** Ở tầng PRD, gap bỏ sót **đi tiếp im lặng** tới tận lúc chạy thật. Ở trạm QC, gap bỏ sót còn **bốn lớp chặn phía sau**: trạm 3 bật ngược khi không viết nổi giá trị mong đợi · trạm 4 soát độ phủ · trạm 5 phân loại lỗi thật vs script sai.
862
+ >
863
+ > Ép mịn ở đây tốn gấp ~3 lần cho tính năng nhỏ, để đổi lấy một lưới an toàn **đã có ba lớp khác**.
864
+
865
+ ## 5 · In dòng bước tiếp
866
+
867
+ Đo được ở repo đội QC: **13/14 lần** một lần chạy ra **cả** file gap **và** kế hoạch test. Ở framework đó là **hai lệnh**.
868
+
869
+ Người quen dây cũ sẽ dừng lại và tưởng đã xong. Dòng `Next` là chỗ duy nhất nói cho họ biết còn một bước.
870
+
871
+ ## Một quyết định thiết kế đáng ghi
872
+
873
+ Gap đến từ **hai nguồn**, và chúng bổ sung nhau:
874
+
875
+ | Nguồn | Trả lời câu | Gap là |
876
+ |---|---|---|
877
+ | 4 kỹ năng phân tích | *"yêu cầu là gì?"* | sản phẩm phụ |
878
+ | 3 lăng kính | *"còn thiếu gì?"* | mục tiêu chính |
879
+
880
+ Nên bước thẩm định chạy **một lần, sau khi gộp** — không phải mỗi nguồn một lần.
881
+
882
+ > Lý do: phép kiểm chống trùng lặp là *"hai gap cùng gốc thì gộp lại"*, và nó chỉ chạy được khi **thấy toàn bộ** tập. Thẩm định hai tập rời thì trùng lặp chéo nguồn lọt lưới, và PO nhận **hai câu hỏi giống nhau**.
883
+
884
+ ## Hai mâu thuẫn tôi tự tạo ra rồi sửa
885
+
886
+ Trong lúc viết tôi tạo ra đúng lớp lỗi cả việc này đang chữa — **hai chỗ nói khác nhau về cùng một chuyện**:
887
+
888
+ 1. Bảng ghi *"lăng kính luật nghiệp vụ: tắt"*, nhưng ngay dưới nó vẫn dán nhãn *"(luôn chạy)"*
889
+ 2. Cuối file khai *"engine tự thẩm định"*, trong khi trạm QC lại tự thẩm định sau khi gộp
890
+
891
+ Sửa cả hai. Chỗ thứ hai thay bằng bảng **nói rõ hai cách gọi** thay vì khẳng định một cách — vì cả hai cách đều đúng, tuỳ lệnh gọi có bao nhiêu nguồn gap.
892
+
893
+ ## Ước lượng chi phí — và ba lỗi của tôi
894
+
895
+ Đo được từ **14 lần chạy thật** ở repo đội QC:
896
+
897
+ | | |
898
+ |---|---|
899
+ | Gap mỗi lần | trung vị **12**, dải **2–28** |
900
+ | Cấu hình 4 nguồn *(giống framework)* | trung bình **9,4** gap |
901
+ | Ra cả kế hoạch test | **13/14** lần |
902
+ | Đầu ra mỗi lần | file gap ~21.700 B + kế hoạch test ~21.400 B |
903
+
904
+ **Phát hiện ngược trực giác:** đọc **ít** tài liệu → tìm ra **nhiều** gap hơn.
905
+
906
+ ```
907
+ Chỉ PRD → 14,0 gap
908
+ Đủ 4 nguồn → 9,4 gap
909
+ ```
910
+
911
+ Không phải vì đọc nhiều thì lười tìm, mà vì **tài liệu bổ sung TRẢ LỜI bớt câu hỏi**. PRD viết *"hiển thị thông báo lỗi phù hợp"* → đọc riêng PRD là gap; có kịch bản test ghi rõ nội dung thông báo → hết gap.
912
+
913
+ Điều này **ủng hộ B5**: đọc thêm tài liệu kỹ thuật không chỉ **bắt thêm** lệch nghiệp vụ ↔ kỹ thuật, mà còn **loại bớt** câu hỏi thừa gửi PO. Lúc quyết B5 tôi chỉ lập luận vế đầu.
914
+
915
+ **Ba lỗi trong ước lượng của tôi**, đều cùng hướng ước thấp:
916
+
917
+ | # | Lỗi |
918
+ |---|---|
919
+ | 1 | Kích thước tài liệu nguồn — **bịa**, và vẫn chưa đo được (submodule spec chưa checkout) |
920
+ | 2 | Số gap giả định 10 → thật là 9,4 ở cấu hình framework |
921
+ | 3 | Chỉ tính đầu ra là file gap — quên kế hoạch test, thiếu ~80% ở khâu đó |
922
+
923
+ **Tỉ lệ giữa hai lựa chọn:** sinh thêm bản file gap ~**3%** của phần đội thêm; bật lăng kính ~**97%**. Chọn định dạng file gần như miễn phí; **số lăng kính là toàn bộ câu chuyện.**
924
+
925
+ ---
926
+
927
+ # ✅ B8 — Bật lăng kính QC ở bước soát PRD
928
+
929
+ **Ý này của bạn, không phải của tôi** — và nó làm tổng thể tốt hơn bản B7 vừa xong.
930
+
931
+ ## Câu hỏi
932
+
933
+ *"Bật lăng kính QC ở bước soát PRD, dùng đúng nội dung vừa xây, rồi trạm QC chỉ ra file gap — có tối ưu hơn không?"*
934
+
935
+ Trong ý đó có **ba việc**. Kiểm rồi thì **chỉ một nên làm** — nhưng làm nó thì đúng là tốt hơn.
936
+
937
+ ## Việc nên làm: bật lăng kính QC ở bước soát PRD ✅
938
+
939
+ Framework đã có sẵn một lăng kính QC ở bước soát PRD, **viết xong rồi tắt đi**, kèm công thức bật lại 5 bước.
940
+
941
+ Điểm mấu chốt khi đọc kỹ: lăng kính đó **không phải "tìm mọi gap"**. Nó hỏi đúng **hai câu về hình thức**:
942
+
943
+ > *"Tiêu chí chấp nhận này có nêu kết quả **quan sát / kiểm chứng được** không?"*
944
+ > *"Tiêu chí chấp nhận có lặp lại nội dung của luật nghiệp vụ không?"*
945
+
946
+ Và nó **tự cấm** hỏi câu thứ ba: *"KHÔNG hỏi 'tiêu chí đủ chi tiết chưa' — câu đó kéo cơ chế kỹ thuật vào tiêu chí nghiệm thu"*.
947
+
948
+ Cả hai câu nó hỏi đều **trả lời được từ PRD một mình**. Không cần bản thiết kế, không cần kịch bản test, không cần tài liệu kỹ thuật.
949
+
950
+ | | |
951
+ |---|---|
952
+ | **Rẻ** | Bước soát PRD **đã** chạy quét song song với 3 lăng kính. Thêm cái thứ tư = cộng vào một lần chạy đã có |
953
+ | **An toàn** | Chạy ở thời điểm PRD → nút *"chấp nhận rồi tự sửa PRD"* là **đúng**, vì phía sau chưa có gì để lỗi thời. Đây chính là thứ B7 phải tắt |
954
+ | **Sẵn sàng** | Công thức bật lại đã viết trong file từ trước |
955
+
956
+ ## Hai việc KHÔNG làm — và lý do
957
+
958
+ ### Không chuyển 3 lăng kính của trạm QC lên đây ❌
959
+
960
+ Không phải vì không nên, mà vì **không chạy được**. Thứ tự dây chuyền:
961
+
962
+ ```
963
+ Discovery → [PRD ◀ bước soát] → Bản thiết kế → Kịch bản test → Tài liệu kỹ thuật → Code → QC
964
+ ```
965
+
966
+ Ở thời điểm soát PRD, **chỉ có PRD**:
967
+
968
+ | Lăng kính | Cần đọc | Có ở thời điểm PRD? |
969
+ |---|---|---|
970
+ | Xử lý lỗi | nhánh lỗi nghiệp vụ — phần lớn ở PRD | ✅ phần lớn |
971
+ | Giao diện | **bản thiết kế** | ❌ chưa tồn tại |
972
+ | Dữ liệu & cấu hình | bảng tính điểm ở PRD; **cờ tính năng + môi trường ở tài liệu kỹ thuật** | ⚠️ nửa |
973
+ | Đối chiếu nghiệp vụ ↔ kỹ thuật *(B5)* | **tài liệu kỹ thuật** | ❌ chưa tồn tại |
974
+
975
+ Và có vấn đề sâu hơn cả việc thiếu file:
976
+
977
+ > Ở thời điểm PRD **không thể phân biệt** *"PRD thiếu X"* với *"PRD cố ý để X cho bản thiết kế"*.
978
+ >
979
+ > Câu hỏi lọc quan trọng nhất của bước thẩm định là *"chỗ này đã được trả lời ở tài liệu khác chưa?"* — mà ở đây **không có tài liệu khác để tra**. Bộ lọc mất tác dụng.
980
+
981
+ Số liệu 14 lần chạy thật xác nhận:
982
+
983
+ ```
984
+ Chỉ đọc PRD → 14,0 gap trung bình
985
+ Đọc đủ 4 nguồn → 9,4 gap trung bình
986
+ ```
987
+
988
+ Khoảng **5 gap chênh lệch** phần lớn là câu hỏi mà tài liệu sau **trả lời hộ**. Đưa lăng kính nội dung lên thời điểm PRD là **cố tình sinh ra 5 gap đó rồi gửi PO**.
989
+
990
+ Đây chính là lý do lăng kính gốc **tự bó hẹp vào câu hỏi hình thức**. Người viết nó đã nhìn ra chuyện này từ trước.
991
+
992
+ ### Không bỏ bản file cho bảng điều khiển ở trạm QC ❌
993
+
994
+ Có một lớp gap **chỉ tồn tại ở thời điểm QC**: kịch bản test nói khác PRD · tài liệu kỹ thuật nói khác PRD *(ca "lớp 1–6 vs 1–9")* · không có dữ liệu để tự kiểm chứng kết quả tính · ẩn số thiết kế đang chờ chốt.
995
+
996
+ Không cái nào tồn tại được ở thời điểm PRD. Bỏ bản đó là đẩy chúng về lại một file trong thư mục — đúng vấn đề mà B7 vừa giải.
997
+
998
+ ## Cái thật sự tốt hơn: **lọc hai tầng**
999
+
1000
+ Không phải thay thế, mà là **tầng rẻ chạy trước, tầng đắt chạy sau trên đầu vào đã sạch hơn**:
1001
+
1002
+ ```
1003
+ Thời điểm PRD lăng kính QC (hình thức) → tiêu chí nào không kiểm chứng được
1004
+ → sửa NGAY, chưa có gì phía sau để lỗi thời
1005
+
1006
+ Thời điểm QC 3 lăng kính + đối chiếu → gap CHỈ có ở đây
1007
+ và ÍT HƠN, vì tầng trên đã dọn
1008
+ ```
1009
+
1010
+ | | Chỉ có B7 | Thêm B8 |
1011
+ |---|---|---|
1012
+ | Tiêu chí không kiểm chứng được | phát hiện ở **thời điểm QC** → gửi PO → PO sửa PRD → kịch bản test lỗi thời → sinh lại | phát hiện ở **thời điểm PRD** → sửa luôn → chưa có gì phía sau |
1013
+ | Số gap ở trạm QC | như cũ | **ít hơn** |
1014
+ | Chi phí thẩm định ở QC | tỉ lệ số gap | **giảm theo** |
1015
+ | PO nhận gì | gap ở hai thời điểm, lẫn loại | **loại hình thức sớm, loại nội dung muộn** — mỗi loại đúng lúc sửa được |
1016
+
1017
+ ## Chi phí — con số này chắc hơn các con số trước
1018
+
1019
+ Lần này suy được từ **công thức trong engine**, không phải giả định về kích thước tài liệu.
1020
+
1021
+ Bước soát PRD chạy ba giai đoạn, chỉ **một** phụ thuộc số lăng kính:
1022
+
1023
+ | Giai đoạn | Tăng khi thêm lăng kính? |
1024
+ |---|---|
1025
+ | Quét song song | ✅ tổng lượt đọc = *lăng kính × phạm vi* → **+33%** |
1026
+ | Vòng phê bình | ❌ **0%** — mỗi lượt là **một** luồng đọc toàn bộ, không liên quan số lăng kính |
1027
+ | Gộp & khử trùng | tăng chút |
1028
+
1029
+ **Và số luồng KHÔNG tăng.** Engine chặn ở 12 luồng, chia nhóm để vừa:
1030
+
1031
+ ```
1032
+ 3 lăng kính → 4 nhóm → 3 × 4 = 12 luồng
1033
+ 4 lăng kính → 3 nhóm → 4 × 3 = 12 luồng ← Y HỆT
1034
+ ```
1035
+
1036
+ Nên chi phí cố định mỗi luồng **không tăng chút nào**; chỉ khối lượng đọc tài liệu tăng.
1037
+
1038
+ **Hệ quả ngược trực giác: PRD càng lớn thì % tăng càng NHỎ.**
1039
+
1040
+ | PRD | 3 lăng kính | 4 lăng kính | Tăng |
1041
+ |---|---|---|---|
1042
+ | ≤ 2 use case | 9 luồng | **12 luồng** | ~**+33%** — chưa chạm chặn |
1043
+ | ≥ 4 use case | 12 luồng *(đã chặn)* | 12 luồng *(đã chặn)* | ~**+13%** — chỉ đọc tăng |
1044
+
1045
+ Ba điều làm nhẹ thêm:
1046
+
1047
+ 1. **Bước soát PRD chỉ đọc MỘT tài liệu** (PRD), so với trạm QC đọc **bốn**. Cùng phần trăm nhưng cơ số nhỏ hơn nhiều.
1048
+ 2. **Chỉ lần chạy đầu là toàn bộ** — nó có chế độ chỉ quét phần đã đổi cho các lần sau.
1049
+ 3. **Có tiết kiệm ở phía đối diện** — trạm QC gặp ít gap loại đó hơn. *(Không đo được, nên không tính vào.)*
1050
+
1051
+ > So sánh cái đáng so: cùng một việc, làm ở bước soát PRD tốn **+13–33% của một lần chạy nhỏ**; để ở trạm QC thì nó là **+300% của một lần chạy lớn**.
1052
+
1053
+ ## Đã đổi gì
1054
+
1055
+ Áp đúng công thức 5 bước có sẵn trong file:
1056
+
1057
+ 1. Đưa lăng kính QC ra khỏi khối bị vô hiệu, đặt **đầu** danh sách
1058
+ 2. Đổi *3 lăng kính / cả ba* → *4 lăng kính / cả bốn* ở 4 chỗ + file engine dùng chung
1059
+ 3. Thêm `QA` vào danh sách giá trị hợp lệ + bảng tổng hợp
1060
+ 4. Thêm `QA` vào ghi chú *"phán đoán DEV/SA/PO"*
1061
+ 5. Dựng lại
1062
+
1063
+ Thêm hai thứ không có trong công thức:
1064
+
1065
+ - **Khối ghi rõ phạm vi lăng kính** — hình thức, KHÔNG phải nội dung — kèm lý do và số liệu. Để người sau **không nới nó ra** mà tưởng đang làm tốt hơn.
1066
+ - **Công thức TẮT LẠI**, đối xứng với công thức bật. Bản gốc chỉ có một chiều.
1067
+
1068
+ ## Một lỗi tôi bắt được nhờ B4
1069
+
1070
+ Sau khi sửa lệnh, `docs/explain/03-refine-prd.md` vẫn ghi *"3 lăng kính"* ở **5 chỗ**.
1071
+
1072
+ Đây **đúng lớp lỗi tôi vừa sửa ở B4** — tài liệu mô tả nói ngược với lệnh, và không cơ chế nào canh chuyện đó. Sửa cả 5 chỗ, thêm dòng giải thích phạm vi.
1073
+
1074
+ > Lần này tôi tự đi kiểm vì B4 đã dạy phải kiểm. Nhưng nó cho thấy **báo khói vẫn còn một lỗ**: nó canh *"lệnh trỏ vào kỹ năng có tồn tại"*, **không** canh *"tài liệu mô tả có khớp lệnh"*. Đáng thêm, nhưng khó — vì so văn xuôi với văn xuôi.
1075
+
1076
+ ---
1077
+
1078
+ # ✅ B9 — Bỏ chế độ `--standard`, gộp cái tốt vào mặc định
1079
+
1080
+ **Câu hỏi của bạn:** *"Nếu đã ghi 2 file, thì `--standard` để làm gì nữa?"*
1081
+
1082
+ Đi kiểm thì đúng — nó **gần như không còn lý do tồn tại**.
1083
+
1084
+ ## Ba dữ kiện đã đo
1085
+
1086
+ **1 · Không có công cụ nào đọc file gap.** Grep toàn bộ repo đội QC: file gap xuất hiện đúng
1087
+ **một** lần, và là một **dòng chú thích** trong file test (*"xem DOC_GAP"*). Không script, không
1088
+ parser, không CI. File gap là **để người đọc**.
1089
+
1090
+ **2 · Cột thứ 10 không được bước sau dùng.** Cột *"Giao cho đội"* — khác biệt chính giữa hai
1091
+ khuôn — **không** được bước thiết kế test, bước soát, hay bước tổng hợp đọc. Nó là thông tin cho
1092
+ **người**, không phải khoá liên kết giữa các bước.
1093
+
1094
+ **3 · Khác biệt còn lại là thẩm mỹ, không phải chức năng.**
1095
+
1096
+ ## Đối chiếu từng khác biệt
1097
+
1098
+ | Khác biệt | Là lý do cần một chế độ riêng? |
1099
+ |---|---|
1100
+ | Cột *Giao cho đội* | ❌ **nên có ở mặc định** — framework thiếu nó là thiếu |
1101
+ | Câu hỏi 4 phần *(bối cảnh → vấn đề → tại sao quan trọng → gợi ý)* | ❌ **nên có ở mặc định** — B3 đã ghi *"framework thiếu hai thứ PO cần"* |
1102
+ | Section *tài liệu đã đọc* | ❌ **nên có ở mặc định** — đây là căn cứ độ phủ |
1103
+ | Cách đánh số gap | ❌ đổi thẳng được |
1104
+ | Từ `Blocker` vs `Critical` | ⚠️ **cái duy nhất nối vào bước sau** |
1105
+ | Không ghi bản cho bảng điều khiển | ❓ ai lại muốn **ít** thông tin hơn? |
1106
+
1107
+ Chỉ **một** dòng thật sự vướng: `/qc-run-test` đọc `🔴 Blocker` để đặt *"scenario này đang chờ PO"*
1108
+ vào sổ kết quả.
1109
+
1110
+ ## Đã đổi gì
1111
+
1112
+ **Bỏ hẳn `--standard`.** Mặc định giờ là khuôn 10 cột của đội QC:
1113
+
1114
+ ```
1115
+ {qc_dir}/{UC-ID}/{nền}/
1116
+ ├── REQUIREMENT_ANALYSIS.md handoff nội bộ cho trạm 2 và 3
1117
+ └── DOC_GAP.md 10 cột + section "tài liệu đã đọc"
1118
+ {refinement_dir}/
1119
+ └── {UC-ID}-qa-findings.yaml bản cho bảng điều khiển
1120
+ ```
1121
+
1122
+ **Hợp nhất hai template thành một.** Bản 9 cột đã xoá.
1123
+
1124
+ **Giữ từ `Blocker`** thay vì `Critical` — đây là chỗ **cố ý khác upstream**, và lý do được ghi
1125
+ ngay trong template: đổi từ là đứt liên kết với sổ kết quả. Ba mức còn lại giữ nguyên upstream.
1126
+
1127
+ **Đổi tên file: `DOC_GAPS.md` → `DOC_GAP.md`** — 33 file trong nguồn.
1128
+
1129
+ > **Vì sao không dùng `DOC_GAP_{UC-ID}.md` như đội QC.** Họ dùng hai kiểu: 10 file có hậu tố UC,
1130
+ > 4 file không. Nhưng **cả 10 file có hậu tố đều nằm trong thư mục vốn đã mang UC** — tức chính
1131
+ > họ cũng lặp. Framework đặt file trong `{qc_dir}/{UC-ID}/{nền}/`, nên thêm hậu tố là lặp UC-ID
1132
+ > **hai lần** trong đường dẫn. Chọn `DOC_GAP.md`: khớp từ vựng đội QC (bỏ chữ `S`), và cũng là
1133
+ > một trong hai kiểu họ dùng thật.
1134
+
1135
+ ## Bốn lý do bỏ chế độ riêng
1136
+
1137
+ **1 · Không nuôi một bản kém hơn làm mặc định.** Bản 9 cột thiếu đúng hai thứ PO cần. Giữ nó làm
1138
+ mặc định rồi để bản tốt sau một cờ là **để người không biết có cờ đó nhận bản kém**.
1139
+
1140
+ **2 · Hai template = hai chỗ phải bảo trì.** Đội QC cải tiến bảng của họ thì ta phải đồng bộ
1141
+ **hai** bản, và chúng sẽ lệch. Đúng bệnh cả việc này đang chữa.
1142
+
1143
+ **3 · Chế độ mà khác biệt duy nhất là "ghi ít file hơn" thì không phải chế độ.** Nó là một cờ
1144
+ `--no-findings`, và chẳng ai cần cờ đó.
1145
+
1146
+ **4 · Kỳ vọng ban đầu vẫn được đáp — tốt hơn.** Yêu cầu gốc là *"`--standard` trả về đúng kết quả
1147
+ gốc đội QC"*. Giờ **mặc định** đã là khuôn của họ → họ nhận đúng thứ họ quen mà **không cần gõ
1148
+ cờ nào**.
1149
+
1150
+ ## Một cái bẫy bắt được ngay tại chỗ
1151
+
1152
+ Sau khi xoá hai template cũ và dựng lại, `core/` sạch — nhưng bản chạy thử tại chỗ **vẫn còn cả
1153
+ hai file cũ**.
1154
+
1155
+ Đây **đúng cơ chế đã gây sự cố 35 file** ở B4: bản chạy thử là bản copy-đè, **không tự dọn**. Nên
1156
+ nó thấy sạch trong khi bản phát hành mới là bản đúng — và lần này ngược lại: bản phát hành đúng,
1157
+ bản chạy thử còn rác.
1158
+
1159
+ Dọn tay. Ba tầng giờ khớp: **7 file mỗi tầng**.
1160
+
1161
+ > Báo khói lắp ở B4 **không bắt được cái này** — nó canh *"lệnh trỏ vào kỹ năng có tồn tại"*,
1162
+ > không canh *"bản chạy thử có file lạ không có ở bản nguồn"*. Đáng thêm một nhánh nữa.
1163
+
1164
+ ## Và một lỗi thứ hai — đã bít bằng nhánh báo khói mới
1165
+
1166
+ Script đổi tên hàng loạt `DOC_GAPS → DOC_GAP` quét **cả phần khai nguồn gốc** ở đầu file, nên nó
1167
+ sửa luôn dòng *"lấy từ file nào của đội QC"* thành một tên **không tồn tại** ở bản gốc.
1168
+
1169
+ Báo khói **vẫn báo xanh**. Vì nhánh kiểm mã nguồn gốc chỉ so **mã**, mà mã thì vẫn khớp — đường
1170
+ dẫn sai không làm mã sai. Chỉ lộ ra khi tôi kiểm tay.
1171
+
1172
+ > Mất đường dẫn nguồn gốc là **mất nửa mốc so sánh**: biết *"mã nào"* mà không biết *"của file nào"*.
1173
+ > Lần đồng bộ sau sẽ so với một file không có thật.
1174
+
1175
+ **Đã thêm nhánh mới:** đường dẫn nguồn gốc khai trong file phải **khớp bảng theo dõi** *và* phải
1176
+ **tồn tại thật** ở bản gốc. Thử lại đúng ca vừa lọt → báo khói kêu, **cả hai góc**.
1177
+
1178
+ Đây là nhánh thứ năm. Bốn nhánh trước sinh ra từ hai sự cố ở B4; nhánh này sinh ra từ một sự cố
1179
+ ở B9. **Cứ mỗi lần lọt một lỗi mới, báo khói dày thêm một tầng** — và lần nào cũng là loại lỗi
1180
+ *im lặng*, không phải loại báo ầm ĩ.
1181
+
1182
+ ## Cái B9 **không** đổi
1183
+
1184
+ - Không đổi quy trình PO — PO nhận **nhiều** thông tin hơn, không ít hơn
1185
+ - Không đổi từ `Blocker` nên sổ kết quả và các bước sau không bị đụng
1186
+ - Không đổi số file đầu ra
1187
+
1188
+ ---
1189
+
1190
+ # ✅ B10 — Bật lại "đối chiếu chéo", thu hẹp còn hai cặp
1191
+
1192
+ **Sửa quyết định sai ở B7.** Bảng kiểm chứng 31 câu hỏi (ngay dưới) là thứ chứng minh nó sai.
1193
+
1194
+ ## Đã bật gì
1195
+
1196
+ Lăng kính *"đối chiếu chéo tài liệu"* phủ **bốn cặp**. Giờ chạy **hai**:
1197
+
1198
+ | Cặp | | Vì sao |
1199
+ |---|---|---|
1200
+ | `PRD ↔ design-spec/` | ✅ **SO** | **không ai đối chiếu nội dung.** Lệnh sinh kịch bản test chỉ kiểm *số phiên bản* — cùng phiên bản mà nội dung lệch thì lọt |
1201
+ | `bdd/ ↔ design-spec/` | ✅ **SO** | không ai |
1202
+ | `PRD ↔ bdd/` | ❌ bỏ | lệnh soát tài liệu đã làm |
1203
+ | `PRD·bdd/ ↔ tech-docs/` | ❌ bỏ | B5 đã làm |
1204
+
1205
+ **Cả hai cặp bật đều dính `design-spec/`** — thứ **Designer vẽ**. Đây là artifact **duy nhất**
1206
+ trong bộ tài liệu tính năng mà không ai đối chiếu nội dung với nó.
1207
+
1208
+ > ⚠️ Đừng lẫn `design-spec/` với `tech-docs/`. Cái đầu là **giao diện người dùng thấy**; cái sau
1209
+ > là **hợp đồng hệ thống** — và `tech-docs/` đã được B5 phủ. Hai tên tiếng Việt nghe gần giống
1210
+ > nhau, đọc nhầm là hiểu ngược kết luận. Xem §Từ vựng đầu nhật ký.
1211
+
1212
+ ## Bốn hướng lệch — và vì sao phải phân biệt
1213
+
1214
+ | Hướng | Nghĩa | Ai xử lý |
1215
+ |---|---|---|
1216
+ | **THIẾU** | PRD có màn/trạng thái/hành vi mà Designer **không vẽ** | Designer bổ sung |
1217
+ | **THỪA** | Designer **tự thêm** màn/nút mà PRD không định nghĩa | **PO chốt**: giữ (rồi định nghĩa hệ quả vào PRD) hay gỡ |
1218
+ | **MÂU THUẪN** | cùng hành vi/giá trị/chữ nhưng hai tài liệu nói khác | PO + Designer |
1219
+ | **LỆCH-REF** | bản thiết kế trích số yêu cầu đã đổi nghĩa | PO |
1220
+
1221
+ > **THIẾU và THỪA xử lý ngược nhau**, nên gọi nhầm hướng là **đặt sai đề bài cho cả hai người**:
1222
+ > một bên tưởng phải vẽ thêm, một bên đáng lẽ phải quyết giữ hay gỡ.
1223
+
1224
+ ## Với cặp kịch bản test ↔ bản thiết kế — soi gì
1225
+
1226
+ - Kịch bản đi qua một **trạng thái màn** mà bản thiết kế không có (đang tải / lỗi / rỗng)?
1227
+ - Kịch bản tác động lên một **thành phần giao diện** không có trong danh sách thành phần?
1228
+ - Bản thiết kế mô tả một **đường điều hướng** mà không kịch bản nào đi qua?
1229
+
1230
+ ## Chi phí — rẻ hơn ước lượng ban đầu
1231
+
1232
+ Hai lý do:
1233
+
1234
+ 1. **Chỉ so 2 cặp**, không phải 4 — nửa khối lượng của một lăng kính đầy đủ.
1235
+ 2. **Trạm QC đã đọc bản thiết kế từ trước** — nó nằm trong danh sách nguồn từ đầu. Nên đây không
1236
+ phải *"đọc thêm tài liệu"*, mà là *"đã đọc rồi, giờ bắt nó **so** thay vì chỉ **đọc**"*.
1237
+ Không nạp thêm file nào.
1238
+
1239
+ Cấu hình hiện tại: 3 lăng kính đầy đủ + 1 thu hẹp ≈ **~3,5 lần** so với không bật lăng kính nào.
1240
+
1241
+ ## Chốt lại: 4/5 lăng kính đang bật
1242
+
1243
+ | Lăng kính | | Bằng chứng |
1244
+ |---|---|---|
1245
+ | Xử lý lỗi | ✅ | 4/6 câu không ai hỏi |
1246
+ | Giao diện | ✅ | 1/8 phủ tốt, 3 hở hẳn |
1247
+ | Dữ liệu & cấu hình | ✅ | **6/6 câu không ai hỏi** |
1248
+ | Đối chiếu chéo | ✅ thu hẹp | 2/4 cặp đang hở |
1249
+ | **Luật nghiệp vụ** | ⏸️ **duy nhất tắt** | 4/5 câu đã có chỗ hỏi, **và hỏi cụ thể hơn** |
1250
+
1251
+ ## Đã ghi chống tái phát
1252
+
1253
+ Cả hai file — lệnh và định nghĩa lăng kính — đều mang một dòng ghi **vì sao `D5` từng bị tắt** và
1254
+ kết luận rằng lý do đó **đúng một nửa**, kèm câu:
1255
+
1256
+ > *"Đừng tắt lại `D5` mà không đọc bảng kiểm chứng 31 câu hỏi."*
1257
+
1258
+ Vì lỗi ban đầu không phải lỗi kiến thức mà là **lỗi phương pháp**: suy từ ấn tượng thay vì đếm
1259
+ danh sách. Người sau đọc thấy *"nghe trùng"* rất dễ tắt lại đúng như tôi đã làm.
1260
+
1261
+ ---
1262
+
1263
+ # 🔍 Kiểm chứng — 31 câu hỏi của 5 lăng kính, từng câu một
1264
+
1265
+ > **Vì sao có phần này.** Quyết định bật/tắt lăng kính ở B7 dựa trên **ấn tượng**
1266
+ > (*"cái này nghe trùng"*), không phải trên danh sách. Phần này làm lại tử tế: đọc **đủ 31 câu
1267
+ > hỏi** của 5 lăng kính, đối chiếu từng câu với chỗ khác trong framework, và ghi bằng chứng.
1268
+ >
1269
+ > **Kết quả: 4/5 quyết định đúng, 1 SAI.** Chi tiết ở cuối.
1270
+
1271
+ ## Cách đọc bảng
1272
+
1273
+ | Ký hiệu | Nghĩa |
1274
+ |---|---|
1275
+ | ✅ **phủ tốt** / **phủ hơn** | chỗ khác đã hỏi, và hỏi **cụ thể hơn** |
1276
+ | 🟡 **một phần** | có chạm tới, nhưng không hỏi đúng câu đó |
1277
+ | 🔴 **hở** | **không ai hỏi câu này** |
1278
+
1279
+ ---
1280
+
1281
+ ## D1 · Luật nghiệp vụ — ⏸️ tắt
1282
+
1283
+ | Câu hỏi lăng kính đặt ra | Chỗ khác đã hỏi gì | |
1284
+ |---|---|---|
1285
+ | Điều kiện đủ chưa? Thiếu nhánh nào? | `business-rules` — *"bảng phân luồng đọc **cả hai chiều**; bảng N loại tài khoản × M màn → duyệt **từng ô**"* | ✅ phủ hơn |
1286
+ | Ngưỡng chốt số chưa? | `business-rules` + `spec-breakdown` — *"mọi ô nhập, **kể cả ô không bắt buộc**: min/max · ký tự cho phép · trim · định dạng"* | ✅ phủ hơn |
1287
+ | Trường hợp biên chưa xử lý? | `business-rules` *(tiêu chí có sub-case → đếm ra)* + `spec-breakdown` *(trạng thái, luồng phụ)* | 🟡 một phần — biên **đầu vào** có, biên **nghiệp vụ** chung chung |
1288
+ | Rule mâu thuẫn giữa tài liệu? | `business-rules` §Kết quả — *"rule mâu thuẫn/không rõ → ghi thành câu hỏi"* | ✅ phủ |
1289
+ | Chỗ buộc phải giả định? | `business-rules` + `spec-breakdown` §F — *"điều suy ra được vs điều cần xác nhận"* | ✅ phủ |
1290
+
1291
+ **4/5 phủ tốt hoặc tốt hơn → tắt là đúng.**
1292
+
1293
+ ---
1294
+
1295
+ ## D2 · Xử lý lỗi — ✅ bật
1296
+
1297
+ | Câu hỏi lăng kính đặt ra | Chỗ khác đã hỏi gì | |
1298
+ |---|---|---|
1299
+ | Quá hạn → hành vi là gì? | `data-flow` chỉ **liệt kê** "timeout" là một *loại* điểm thất bại, **không hỏi hành vi** | 🔴 hở |
1300
+ | Số lần thử lại? Khoảng cách? | — | 🔴 hở |
1301
+ | Hết số lần thử → đi đâu? | — | 🔴 hở |
1302
+ | Hàng đợi lỗi: ai xử lý? có cảnh báo? | `data-flow` có nhắc hàng đợi, **không hỏi ai xử lý lỗi** | 🔴 hở |
1303
+ | Từng loại lỗi: màn nào hiện, làm gì tiếp? | tài liệu kỹ thuật §8 **có bảng** — nhưng đó là **đầu ra của người viết tài liệu**, không phải câu hỏi QC đặt ra | 🟡 một phần |
1304
+ | Khôi phục: thử lại được? bị chặn? | — | 🔴 hở |
1305
+
1306
+ **4/6 hoàn toàn không ai hỏi → bật là đúng.**
1307
+
1308
+ ---
1309
+
1310
+ ## D3 · Giao diện — ✅ bật
1311
+
1312
+ | Câu hỏi lăng kính đặt ra | Chỗ khác đã hỏi gì | |
1313
+ |---|---|---|
1314
+ | Trạng thái màn thiếu gì? | bản thiết kế **bắt buộc** có `default / loading / error`, thêm `empty` nếu màn có thể rỗng | ✅ phủ tốt |
1315
+ | Chữ & nhãn nhất quán **giữa các tài liệu**? | — | 🔴 hở |
1316
+ | Điều hướng đủ mọi đường chưa? | bản thiết kế §Hành động & Điều hướng — **mô tả**, không kiểm đủ | 🟡 một phần |
1317
+ | Thông báo lỗi có **nội dung cụ thể** chưa? | `review-context` R7 đòi giá trị cụ thể — nhưng cho **kịch bản test**, không cho nội dung thông báo | 🟡 một phần |
1318
+ | Trạng thái biên: rỗng, kết quả 0? | bản thiết kế có `empty` state | 🟡 một phần |
1319
+ | UI đã gỡ ở PRD nhưng còn trong thiết kế? | — | 🔴 hở |
1320
+ | Đa nền nhất quán? | bản thiết kế mô tả **riêng từng nền**, không đối chiếu chúng với nhau | 🟡 một phần |
1321
+ | Tài nguyên hiển thị đã xác định? | — | 🔴 hở |
1322
+
1323
+ **1/8 phủ tốt, 3 hở hẳn → bật là đúng.**
1324
+
1325
+ ---
1326
+
1327
+ ## D4 · Dữ liệu & cấu hình — ✅ bật
1328
+
1329
+ | Câu hỏi lăng kính đặt ra | Chỗ khác đã hỏi gì | |
1330
+ |---|---|---|
1331
+ | Đủ dữ liệu để **tự kiểm chứng kết quả tính**? | — | 🔴 hở |
1332
+ | Dữ liệu mẫu đủ dựng môi trường test? | — | 🔴 hở |
1333
+ | Cấu hình đổi **giữa lúc đang chạy** → hành vi? | — | 🔴 hở |
1334
+ | Phụ thuộc môi trường đã spec? | `data-flow` liệt kê chặng, **không hỏi môi trường test** | 🔴 hở |
1335
+ | Dựng dữ liệu phụ thuộc thứ chưa có? | — | 🔴 hở |
1336
+ | Cờ tính năng ảnh hưởng gì? Giá trị mặc định? | — | 🔴 hở |
1337
+
1338
+ **6/6 không ai hỏi → đây là lăng kính đáng giá nhất trong cả năm.**
1339
+
1340
+ ---
1341
+
1342
+ ## D5 · Đối chiếu chéo tài liệu — ⏸️ tắt ← **quyết định SAI**
1343
+
1344
+ Lăng kính này phủ **bốn cặp** tài liệu, không phải hai.
1345
+
1346
+ *(Tra §Từ vựng đầu nhật ký nếu quên — ② **bản thiết kế** `design-spec/` là Designer vẽ gì;
1347
+ ④ **tài liệu kỹ thuật** `tech-docs/` là hệ thống nhận/trả gì. Hai file khác nhau.)*
1348
+
1349
+ | Cặp tài liệu | Tên thật | Chỗ khác đã làm gì | |
1350
+ |---|---|---|---|
1351
+ | ① PRD ↔ ③ kịch bản test | `PRD` ↔ `bdd/` | `review-context` — yêu cầu nào chưa có kịch bản | ✅ phủ |
1352
+ | ①③ ↔ ④ tài liệu kỹ thuật | `PRD·bdd/` ↔ `tech-docs/` | trạm QC §Đối chiếu *(thêm ở B5)* — 6 mục | ✅ phủ |
1353
+ | ① PRD ↔ ② **bản thiết kế** | `PRD` ↔ **`design-spec/`** | lệnh sinh kịch bản test chỉ so **số phiên bản** *("thiết kế dựng từ PRD v2, PRD giờ v3")*. **Cùng phiên bản mà nội dung lệch thì không ai thấy** | 🔴 hở nội dung |
1354
+ | ③ **kịch bản test** ↔ ② **bản thiết kế** | `bdd/` ↔ **`design-spec/`** | — | 🔴 hở hẳn |
1355
+
1356
+ **2/4 hở — và cả hai cặp hở đều dính ② `design-spec/`, tức phần Designer vẽ.**
1357
+
1358
+ > ④ `tech-docs/` **không liên quan** tới lỗ này — B5 đã phủ nó. Đây là chỗ dễ nhầm nhất, vì hai
1359
+ > cái tên tiếng Việt nghe gần giống nhau.
1360
+
1361
+ ### Lỗ đó cụ thể là gì
1362
+
1363
+ Cả hai ca đều nằm ở **② `design-spec/`** — thứ Designer vẽ:
1364
+
1365
+ | Ca | Hướng | Xử lý |
1366
+ |---|---|---|
1367
+ | Designer vẽ nút *"Bỏ qua ngay"* mà PRD **không định nghĩa** | **THỪA** *(thiết kế > PRD)* | PO chốt: giữ (rồi định nghĩa hệ quả vào PRD) hay gỡ đi |
1368
+ | PRD có màn *"chờ 5 giây"* mà Designer **không vẽ** | **THIẾU** *(thiết kế < PRD)* | bổ sung vào bản thiết kế |
1369
+ | Kịch bản test đi qua một trạng thái màn mà bản thiết kế **không có** | **THIẾU** | bổ sung, hoặc sửa kịch bản |
1370
+
1371
+ **Hai hướng xử lý ngược nhau** — gọi nhầm hướng là đặt sai đề bài cho cả PO lẫn Designer.
1372
+ Lăng kính này phân biệt được. Hiện **không ai làm**.
1373
+
1374
+ ---
1375
+
1376
+ # Tổng kết
1377
+
1378
+ | | Quyết định ở B7 | Bằng chứng | |
1379
+ |---|---|---|---|
1380
+ | **D1** Luật nghiệp vụ | tắt | 4/5 phủ tốt hơn | ✅ đúng |
1381
+ | **D2** Xử lý lỗi | bật | 4/6 không ai hỏi | ✅ đúng |
1382
+ | **D3** Giao diện | bật | 3/8 hở hẳn | ✅ đúng |
1383
+ | **D4** Dữ liệu & cấu hình | bật | **6/6 không ai hỏi** | ✅ đúng nhất |
1384
+ | **D5** Đối chiếu chéo | tắt | **2/4 hở** | ❌ **SAI** |
1385
+
1386
+ ## Vì sao sai ở D5
1387
+
1388
+ Tôi thấy **hai cặp đầu** đã có người làm nên kết luận *"trùng nhiều"* — mà **không đếm hết**
1389
+ lăng kính này phủ **bốn** cặp.
1390
+
1391
+ Đó là suy từ ấn tượng, không phải từ danh sách. **Đúng loại lỗi cả việc này đang chữa: khẳng
1392
+ định không có bằng chứng đằng sau.** Và nó lọt vì không có bảng nào như bảng trên — bảng này
1393
+ đáng lẽ phải làm **trước** khi quyết, không phải sau.
1394
+
1395
+ ## Sửa — ĐÃ LÀM ở B10
1396
+
1397
+ **Bật lại D5, thu hẹp còn đúng hai cặp đang hở:**
1398
+
1399
+ ```
1400
+ CHỈ đối chiếu: PRD ↔ design-spec/ ← ① ↔ ②
1401
+ bdd/*.feature ↔ design-spec/ ← ③ ↔ ②
1402
+
1403
+ BỎ (đã có người làm):
1404
+ PRD ↔ bdd/ ← review-context
1405
+ PRD · bdd/ ↔ tech-docs/ ← B5
1406
+ ```
1407
+
1408
+ Thu hẹp thế thì nó **không làm lại việc đã có**, chỉ bịt đúng chỗ hở.
1409
+
1410
+ **Rẻ hơn ước lượng ban đầu** (~+15–20%, có thể ít hơn): trạm QC **đã đọc `design-spec/` rồi** —
1411
+ nó nằm trong danh sách nguồn từ đầu. Nên đây không phải *"đọc thêm tài liệu"*, mà là *"đã đọc
1412
+ rồi, giờ bắt nó **so** với hai tài liệu kia"*. Không nạp thêm file nào.
1413
+
1414
+ ---
1415
+
1416
+ # Các bước còn lại
1417
+
1418
+ **Chín bước B0–B9 đã xong.** Không còn bước nào đang chờ quyết định để bắt đầu.
1419
+
1420
+ Nhưng có **một quyết định sai đã phát hiện** và **hai món nợ** — xem §Còn treo ở cuối.
1421
+ Mô tả kế hoạch gốc nằm ở [`qc-merge-plan.md`](qc-merge-plan.md).
1422
+
1423
+ > **Nhật ký này chỉ ghi bước đã hoàn thành** — mỗi bước xong mới nạp vào đây, không viết trước.
1424
+
1425
+ ---
1426
+
1427
+ ## Những gì đã kiểm chứng sau mỗi bước
1428
+
1429
+ Sau mỗi bước, toàn bộ hệ thống được dựng lại và kiểm tra tự động:
1430
+
1431
+ - 41/41 mẫu lệnh dựng thành công
1432
+ - Bộ kiểm tra nội bộ báo sạch
1433
+ - Nội dung mới đã lan đủ ba tầng: bản nguồn → bản đóng gói → bản đang chạy
1434
+ - **9** dấu nguồn gốc đều được kiểm chứng khớp với file gốc thật
1435
+ - Báo khói đã **thử cháy thật** cả 5 nhánh — không giao một cái chưa bao giờ kêu
1436
+
1437
+ ---
1438
+
1439
+ ## Còn treo
1440
+
1441
+ | # | Câu | Mức | Ai quyết |
1442
+ |---|---|---|---|
1443
+ | **1** | Chạy thử trên một tính năng thật — **chín bước, chưa một lần chạy**. Ước lượng chi phí của tôi đã sai 3 lần, đều ước thấp | 🔴 chưa validate | bạn (cần spec thật) |
1444
+ | **2** | Đưa nhật ký cho đội QC xem — họ là chủ sở hữu các kỹ năng này, và định dạng họ nhận đã đổi | 🟠 | bạn |
1445
+ | 3 | 30 file không có bản gốc — framework tự sở hữu, gộp lại, hay ghép tay? | 🟡 nợ | bạn |
1446
+ | 4 | Có lấy lại 38 dòng đã mất của phần "lập kế hoạch test" không? | 🟡 nợ | bạn |