13 KiB
name, description
| name | description |
|---|---|
| ba-traceability | Skill xuyên suốt của quy trình BA — dựng và kiểm tra ma trận truy vết yêu cầu (RTM). Dùng để phát hiện yêu cầu bị bỏ quên, user story không có nguồn gốc (scope creep), AC không được test, business rule không được kiểm chứng, và tham chiếu gãy giữa các tài liệu. Kích hoạt khi người dùng nói "kiểm tra coverage", "có sót yêu cầu nào không", "ma trận truy vết", "RTM", "traceability", "rà soát chéo tài liệu BA", "trước khi trình gate", "requirement nào chưa được test". Chạy được ở mọi giai đoạn và có quyền chặn Gate G2, G3, G4. |
⊕ TRACEABILITY — Ma trận truy vết & kiểm tra coverage
Skill này không thuộc giai đoạn nào. Nó chạy sau mỗi giai đoạn và trả lời đúng một câu hỏi: "có cái gì bị rơi giữa các tài liệu không?"
Nó có quyền chặn Gate G2, G3, G4: coverage không đạt thì gate không pass.
Output: RTM_<PROJECT>.md trong ba-output/<PROJECT>/00-index/ + báo cáo coverage.
Bốn nguyên tắc bất di bất dịch
- Không bịa yêu cầu.
- Không quyết định thay PO.
- Mọi phát biểu truy vết được — đây chính là việc của skill này.
- Không ghi đè tài liệu đã qua gate.
🔴 Nguyên tắc riêng: skill này KHÔNG sửa tài liệu nghiệp vụ. Nó phát hiện và báo cáo. Sửa là việc của skill giai đoạn tương ứng. Tự sửa sẽ che mất vấn đề thay vì giải quyết nó.
Bước 0 — Chốt input rồi dừng lại
Chưa được ghi file. Làm năm việc rồi dừng chờ trả lời:
- Profile — đọc
00-index/PROFILE_<PROJECT>.md. Nó quyết định phép kiểm nào áp dụng (Bước 2) và ngưỡng nào bắt buộc (Bước 5). - Tài liệu quét được — bảng
File | Loại | Version | Status | Số ID trích được. - Tài liệu thiếu — loại nào không tìm thấy, và điều đó làm phép kiểm nào không chạy được (nói rõ, đừng lặng lẽ bỏ phép kiểm đó).
- Mục đích lần chạy — dựng RTM lần đầu, cập nhật sau một giai đoạn, hay kiểm tra trước khi trình gate?
- Hỏi xác nhận bốn điểm trên.
Bỏ qua khi lệnh có go.
Thực hiện — 4 bước
Bước 1 — Trích ID từ mọi tài liệu
Quét theo quy ước ID ở ../ba-lifecycle/README.md §4:
grep -rnoE "(RQ|US|BR|AC|NFR|OQ|DEC|CR|RISK|ASM|GOAL|STK|ROLE|FLD)-[A-Za-z0-9-]+" ba-output/<PROJECT> \
| sort -u
Với mỗi ID ghi lại: nơi định nghĩa (tài liệu nào định nghĩa nó) và nơi tham chiếu (tài liệu nào nhắc tới nó).
🔴 Phân biệt hai thứ này là điểm mấu chốt. Một ID được tham chiếu nhiều nơi nhưng không có nơi định nghĩa là tham chiếu gãy — dev đọc spec thấy "theo BR-021" rồi đi tìm không ra.
Bước 2 — Sáu phép kiểm coverage
Điền templates/rtm.md. Chạy đủ sáu phép, mỗi phép ra một danh sách:
| # | Phép kiểm | Chiều | Phát hiện | Chặn gate |
|---|---|---|---|---|
| 1 | Mỗi RQ → có ≥1 US |
xuôi | Yêu cầu bị bỏ quên | G2 |
| 2 | Mỗi US → truy về được RQ |
ngược | Scope creep | G2 |
| 3 | Mỗi US → có ≥1 AC mỗi nhóm bắt buộc |
xuôi | Đặc tả chưa xong | G3 |
| 4 | Mỗi BR → được áp dụng ở ≥1 US/field |
xuôi | Rule mồ côi | G3 |
| 5 | Mỗi AC → có ≥1 test case |
xuôi | AC không được kiểm chứng | G4 |
| 6 | Mỗi ID được tham chiếu → có nơi định nghĩa | — | Tham chiếu gãy | G2/G3/G4 |
Hai chiều đều quan trọng, và chúng bắt hai loại lỗi khác nhau:
chiều xuôi RQ → US → AC → test case bắt: BỎ SÓT
chiều ngược test case → AC → US → RQ bắt: LÀM THỪA
Chỉ chạy chiều xuôi là bỏ qua toàn bộ scope creep — thứ làm dự án trễ mà không ai giải thích được vì sao.
Phép kiểm 3 chặt hơn "có AC": mỗi US phải có AC ở đủ bốn nhóm (thành công · validation ·
lỗi hệ thống · phân quyền). US chỉ có AC nhóm 1 ⇒ tính là chưa phủ, không phải "đã phủ
một phần".
Điều chỉnh theo profile
| Trục | Ảnh hưởng tới phép kiểm |
|---|---|
PRODUCT = ml-model |
Phép kiểm 3 chỉ áp cho hệ thống bao quanh. Phần dự đoán thay bằng: mỗi GOAL chất lượng có ≥1 metric có ngưỡng, và mỗi ngưỡng truy về được một chi phí nghiệp vụ |
PRODUCT = data-pipeline |
Thêm phép kiểm: mỗi luồng có ≥1 quy tắc đối soát nguồn–đích. Thiếu ⇒ 🔴 chặn G3 |
PRODUCT = batch-job |
Thêm phép kiểm: mỗi job đã trả lời idempotency và thất bại giữa chừng. Bỏ trống ⇒ 🔴 chặn G3 |
PRODUCT = api-service |
Thêm phép kiểm: mỗi mã lỗi map về ≥1 endpoint, và mỗi endpoint có cột "người gọi nên làm gì" |
RIGOR = light |
Phép kiểm 3 chỉ đòi nhóm 1–2; nhóm 3–4 đòi nếu có ghi/xoá dữ liệu hoặc >1 vai trò |
RIGOR = strict |
Thêm phép kiểm: mỗi hành động ghi có dòng trong bảng lưu vết; mỗi mã lỗi có đủ bản dịch |
🔴 Phép kiểm bị bỏ vì profile phải được ghi ra trong báo cáo, kèm lý do — đừng lặng lẽ tính coverage trên tập nhỏ hơn rồi báo 100%.
Bước 3 — Tám phép kiểm nhất quán
Ngoài coverage, kiểm tra tài liệu có mâu thuẫn nhau không (6 phép cho mọi loại + 2 phép riêng cho design, screen):
| # | Phép kiểm | Cách kiểm | Ví dụ lỗi bắt được |
|---|---|---|---|
| 1 | Version lệch | SRS khai Source: BR_v1.0 nhưng BR đã lên v1.2 |
SRS viết theo rule cũ |
| 2 | Ràng buộc lệch | Bảng field trong SRS vs. bảng ràng buộc trong API |
UI chặn 20 ký tự, API chặn 50 |
| 3 | Mã lỗi lệch | Mã trong SRS §4.1 vs. mã trong API §4 |
Mã lỗi không endpoint nào sinh ra |
| 4 | Trạng thái lệch | Trạng thái trong BR vs. trạng thái dùng trong SRS/RBAC |
RBAC phân quyền cho trạng thái không tồn tại |
| 5 | Thành phần lệch (screen) | Tập C-id/F-id trong SRS §2.3.1/§2.3.3 vs. WF §3.x.2, data-c trong WF.html và data-c/data-f trong HIFI.html — hai chiều |
Nút có trong WF (từ prototype) mà SRS không đặc tả hành vi; hoặc SRS có nút mà WF không đặt chỗ |
| 6 | Quy ước lệch (screen) | SRS §2.3.2/§2.3.6/§4.3 định nghĩa phân trang, trạng thái, định dạng khác UICONV mà UICONV §12 không có dòng |
Hai SRS hai kiểu phân trang; múi giờ hiển thị khác nhau |
| 7 | Text lệch (screen · design) | Text của mọi data-key trong HIFI.html vs. bảng SRS §4.2 — phải nguyên văn (W5) |
Design "làm gọn" nhãn: SRS "Tạo mới", HIFI "Tạo"; message lỗi viết lại |
| 8 | Token lệch (screen · design) | Khối :root/ds-components trong HIFI vs. 00-index/ds/; mã màu thô trong markup HIFI; màu trong FIGMA/*.svg ∉ tokens.json; SCR của SRS §2.1 thiếu trong HIFI/SVG |
HIFI dùng #333 không có trong DS; SVG còn màu cũ sau khi đổi token; màn hình lỗi không có mockup |
Phép 1 chạy được bằng máy: so Source: trong header với version thật của file được trích dẫn.
Phép 5 cũng vậy:
grep -oE "\b[CF][0-9]{2}\b" SRS_<US>*.md | sort -u > /tmp/srs_ids
grep -oE "\b[CF][0-9]{2}\b|data-c=\"[CF][0-9]{2}\"" WF_<US>*.md WF_<US>*.html | grep -oE "[CF][0-9]{2}" | sort -u > /tmp/wf_ids
comm -3 /tmp/srs_ids /tmp/wf_ids # phải rỗng
Phép 5 (phần HIFI), 7 và 8 chạy bằng script của ba-design — chép kết quả nguyên văn vào RTM §4:
node .claude/skills/ba-design/scripts/design-check.mjs \
--tokens ba-output/<P>/00-index/ds/tokens.json --css ba-output/<P>/00-index/ds/tokens.css \
--components ba-output/<P>/00-index/ds/components.html \
--html ba-output/<P>/03-specification/design/HIFI_<US>_v1.0.html \
--srs ba-output/<P>/03-specification/SRS_<US>_v1.0.md --wf ba-output/<P>/03-specification/WF_<US>_v1.0.md \
--svg-dir ba-output/<P>/03-specification/design/FIGMA_<US>_v1.0
Không chạy được ⇒ ghi "chưa kiểm bằng máy" cho phép 7–8, không báo "không lệch". H3/H4 🔴 ⇒ chặn G3.
Ngoài ra với screen: đọc WF §5 — mỗi dòng loại Tồn tại/Hành vi có trạng thái ☐ là một
blocker G3, liệt kê đích danh. WF không có §5 hoặc §5 trống không ghi "đã đối chiếu" ⇒ báo
"chưa đối chiếu prototype", không phải "không lệch".
Bước 4 — OQ và CR tồn đọng
grep -rn "OQ-[0-9]" ba-output/<PROJECT> | sort -u
grep -rn "TBD\|TODO\|???" ba-output/<PROJECT>
Với mỗi OQ mở: hỏi ai · từ ngày · chặn ID nào · quá hạn bao nhiêu ngày (>5 ngày làm việc
⇒ 🔴). Với mỗi CR: trạng thái · chờ ai · bao lâu rồi.
TBD trong bảng field hoặc bảng mã lỗi ⇒ báo là blocker của G3.
Báo cáo — in đúng năm phần
① Bảng coverage tổng hợp — mở đầu bằng dòng profile và danh sách phép kiểm đã bỏ:
Profile: data-pipeline · brownfield · strict
Phép kiểm bỏ: (không có)
Phép kiểm thêm: đối soát nguồn–đích · lưu vết mọi hành động ghi
| Phép kiểm | Tổng | Đã phủ | Coverage | Ngưỡng | ☐/✅ |
|---|---|---|---|---|---|
| RQ → US | 12 | 11 | 91,7% | 100% | 🔴 |
| US → RQ | 18 | 16 | 88,9% | 100% | 🔴 |
| US → AC (đủ 4 nhóm) | 18 | 12 | 66,7% | 100% | 🔴 |
| BR → áp dụng | 24 | 24 | 100% | 100% | ✅ |
| AC → test case | 96 | — | — | 100% | ⏳ QA chưa viết |
| Tham chiếu → định nghĩa | 214 | 211 | 98,6% | 100% | 🔴 |
② Danh sách chi tiết từng lỗ hổng — mỗi dòng nêu đích danh ID, ở tài liệu nào, và skill nào cần chạy để sửa:
🔴 RQ-005 chưa có US nào phủ
Định nghĩa tại: BRIEF_Settlement_v1.0.md §6
Sửa bằng: /ba-2-analysis Settlement
🔴 BR-021 được tham chiếu ở SRS_US011 §1.3 nhưng không tìm thấy định nghĩa
Có thể đã bị đổi số hoặc BR_Settlement chưa cập nhật
Sửa bằng: /ba-2-analysis Settlement --only br
③ Bảng nhất quán — tám phép kiểm ở Bước 3, mỗi mâu thuẫn một dòng; phép 7–8 kèm dòng kết quả design-check.
④ OQ/CR tồn đọng — sắp theo số ngày quá hạn giảm dần.
⑤ Kết luận gate
G2: 🔴 CHẶN — RQ-005 chưa phủ, US-018 và US-019 không truy về RQ
G3: 🔴 CHẶN — 6/18 US thiếu AC nhóm lỗi hệ thống; 4 TBD trong bảng field
G4: ⏳ Chưa đánh giá được — QA chưa nộp test case
Nói thẳng gate nào bị chặn và vì sao. Không làm tròn lên. Coverage 99% vẫn là chặn khi ngưỡng là 100% — cái 1% đó chính là yêu cầu sẽ lọt ra sản phẩm mà không ai kiểm chứng.
Bẫy thường gặp
Chỉ chạy chiều xuôi. Bỏ qua toàn bộ scope creep. Chiều ngược mới trả lời được câu "cái này ai yêu cầu?".
Coi ID xuất hiện trong tài liệu là đã được phủ. SRS nhắc BR-021 không có nghĩa là
BR-021 đã được hiện thực hoá — phải xem nó được áp vào field/AC nào. Đếm số lần xuất hiện
là phép đo sai.
Bỏ qua tham chiếu gãy vì "chắc là do đánh nhầm số". Tham chiếu gãy nghĩa là dev đọc spec, thấy "theo BR-021", đi tìm không ra, rồi tự quyết. Đó là cách một business rule bốc hơi khỏi sản phẩm.
Tự sửa tài liệu khi phát hiện lỗ hổng. Vi phạm nguyên tắc riêng của skill này. Báo cáo và chỉ đúng skill để sửa; tự sửa sẽ che mất vấn đề, và lần sau nó lại xuất hiện.
Làm tròn coverage lên. 99% vẫn là chặn. Cái 1% đó là một yêu cầu thật, của một người thật.
Bỏ phép kiểm vì profile rồi báo 100%. RIGOR = light bỏ bớt phép kiểm là hợp lệ; không
ghi ra là đã bỏ thì con số 100% trở thành nói dối. Luôn in danh sách phép kiểm đã bỏ.
Chỉ chạy trước gate. Chạy sau mỗi giai đoạn thì lỗ hổng được phát hiện lúc còn rẻ. Chạy lần đầu vào hôm trước ngày họp duyệt thì phát hiện cũng chỉ để hoãn họp.