177 lines
10 KiB
Markdown
177 lines
10 KiB
Markdown
---
|
||
name: sa-conformance
|
||
description: Skill xuyên suốt của quy trình Solution Architect — dựng và kiểm tra ma trận truy vết quyết định (DTM) và sổ mục lục ADR (ADL). Dùng để phát hiện yêu cầu định hình kiến trúc chưa ai quyết định gì, quyết định kiến trúc không truy được về nguồn nào, NFR chưa có bài đo hoặc bài kiểm tự động, component tồn tại mà không phục vụ yêu cầu nào, ADR mâu thuẫn hoặc lỗi thời, và tham chiếu gãy giữa các tài liệu kiến trúc. Kích hoạt khi người dùng nói "kiểm tra coverage kiến trúc", "có quyết định nào chưa ghi không", "ADR nào lỗi thời", "ma trận truy vết quyết định", "DTM", "rà soát chéo tài liệu kiến trúc", "trước khi trình gate kiến trúc", "NFR nào chưa được kiểm". Chạy được ở mọi giai đoạn và có quyền chặn Gate AG2, AG3, AG4.
|
||
---
|
||
|
||
# SA · CONFORMANCE — Truy vết quyết định & mục lục ADR
|
||
|
||
Skill này **không thiết kế gì**. Nó trả lời một câu: **"có chỗ nào đứt không?"** — và có
|
||
quyền chặn gate khi câu trả lời là có.
|
||
|
||
Output: `DTM` · `ADL` trong `sa-output/<PROJECT>/00-index/`
|
||
|
||
## Chuỗi truy vết phải liền mạch
|
||
|
||
```
|
||
DRV ──► ASR ──► ADR ──► CMP ──► FIT
|
||
│ │ │ │ │
|
||
└───────┴──► QAS ───────┴──► bài đo ──► CONF
|
||
```
|
||
|
||
Sáu chỗ đứt phải phát hiện được, và mỗi chỗ có nghĩa khác nhau:
|
||
|
||
| Chỗ đứt | Nghĩa là | Mức |
|
||
|---|---|---|
|
||
| `DRV` không có `ASR`/`QAS` nào | Áp lực kinh doanh không được kiến trúc phục vụ | 🔴 chặn AG2 |
|
||
| `ASR` không có `ADR` nào | Yêu cầu định hình kiến trúc mà không ai quyết định gì | 🔴 chặn AG2 |
|
||
| `ADR` không truy về `DRV`/`CON`/`QAS`/`ASR` | Quyết định không có nguồn — sở thích cá nhân | 🟠 |
|
||
| `QAS` không có bài đo | Cam kết không kiểm chứng được | 🔴 chặn AG3 (mức Must) |
|
||
| Ràng buộc `AGD` không có `FIT` và không có nhãn khuyến nghị | Sẽ bị vi phạm mà không ai biết | 🔴 chặn AG3 |
|
||
| `CMP` không phục vụ `ASR` nào và không có nhu cầu chức năng rõ | Thành phần thừa | 🟠 |
|
||
| `IF` không có file contract trong `CTR` (còn "dự kiến") | Dev FE/BE mỗi bên tự viết một bản | 🔴 chặn AG2 |
|
||
| Thực thể `DAT` không có bảng `PDM`, hoặc `MIG` không có down | Dev tự đặt schema; migration một chiều | 🔴 chặn AG2 |
|
||
| Sơ đồ không có spec Archify / spec chưa validate | Sơ đồ không kiểm được, không render được cho dev | 🟠 |
|
||
|
||
## Bốn nguyên tắc bất di bất dịch
|
||
|
||
1. **Không bịa liên kết** — không thấy quan hệ thì báo đứt, không suy diễn cho đẹp ma trận.
|
||
2. **Không tự sửa artifact của skill khác** — báo chỗ đứt và đề xuất, để skill giai đoạn sửa.
|
||
3. **Mọi phát hiện phải chỉ được file và mục cụ thể** — "tài liệu chưa đầy đủ" là báo cáo vô dụng.
|
||
4. **Có quyền chặn gate** — và phải dùng quyền đó, không hạ mức cho dễ chịu.
|
||
|
||
Nạp thêm: `../sa-lifecycle/references/artifact-map.md` §6 (quan hệ phụ thuộc) ·
|
||
`../sa-lifecycle/references/design-rules.md` · `../sa-lifecycle/references/decision-radar.md`.
|
||
|
||
## Bước 0 — Chốt input rồi dừng lại
|
||
|
||
**Chưa được ghi file.** Làm ba việc rồi **dừng chờ người dùng trả lời**:
|
||
|
||
1. **Quét được gì** — bảng artifact tìm thấy, kèm version và `Status`. Artifact `🟡 Draft` vẫn
|
||
quét nhưng đánh dấu riêng: chỗ đứt trong bản nháp chưa phải lỗi.
|
||
2. **Chọn phạm vi** — `--mode dtm|adl|full`. `full` là cả hai cộng báo cáo coverage.
|
||
3. **Hỏi người dùng** xác nhận.
|
||
|
||
Bỏ bước dừng khi lệnh có `go`.
|
||
|
||
## Thực hiện — 5 bước
|
||
|
||
### Bước 1 — Thu ID từ mọi artifact
|
||
|
||
Đọc và trích ID. **Đọc header trước** để biết version và `Status`:
|
||
|
||
| Nguồn | Trích ID |
|
||
|---|---|
|
||
| `CTX` | `DRV-nn`, `CON-nn`, `ASM-nn` |
|
||
| `ARISK` | `ARISK-nn`, POC |
|
||
| `QAS`/`ASR` | `QAS-nnn`, `ASR-nnn` |
|
||
| `SAD` | `CMP-nn` |
|
||
| `adr/` | `ADR-nnn` + trạng thái + `Supersedes`/`Superseded by` |
|
||
| `ICD` | `IF-nnn` + cột "Contract ở đâu" (file thật hay "dự kiến") |
|
||
| `CTR` + `contracts/**/*.yaml` | `CTR-nn`, `x-if: IF-nnn`, `operationId`, `x-error-codes` |
|
||
| `DAT` | thực thể + chủ sở hữu |
|
||
| `DOM` | aggregate/class + invariant ↔ `BR-nnn` |
|
||
| `PDM` + `schema/**/*.sql` | `TBL-nnn` ↔ thực thể `DAT` · `MIG-nnn` (có `.down.sql`?) · cột PII |
|
||
| `HANDOFF` | dòng ☐/✅ ở §2 |
|
||
| `SEC` | `THR-nn` |
|
||
| `FAIL` | `FM-nn` |
|
||
| `AGD` | ràng buộc §3 |
|
||
| `FIT` | `FIT-nn` + trạng thái |
|
||
| `TDEBT` | `TD-nn` |
|
||
| `CONF` | kết quả đo |
|
||
|
||
ID trùng nhau ở hai file ⇒ 🔴 báo ngay, đó là lỗi nghiêm trọng hơn mọi chỗ đứt.
|
||
|
||
### Bước 2 — Dựng `DTM`
|
||
|
||
Điền `templates/decision-traceability-matrix.md`. Bốn ma trận hai chiều:
|
||
|
||
| Ma trận | Đọc xuôi | Đọc ngược |
|
||
|---|---|---|
|
||
| `DRV` × `ASR`/`QAS` | Driver này được phục vụ bởi cái gì | Yêu cầu này sinh từ đâu |
|
||
| `ASR` × `ADR` | Yêu cầu này được quyết định thế nào | Quyết định này phục vụ gì |
|
||
| `ADR` × `CMP` | Quyết định này hiện ra ở đâu trong hệ thống | Component này tồn tại vì gì |
|
||
| `QAS` × bài đo × `FIT` | Cam kết này kiểm chứng bằng gì | Bài kiểm này bảo vệ cam kết nào |
|
||
| `IF` × `CTR` (file + `x-if`) | Interface này dev code theo file nào | File contract này phục vụ interface nào |
|
||
| `DAT` thực thể × `DOM` class × `PDM` `TBL` | Thực thể này là class nào, bảng nào | Bảng này tồn tại vì thực thể nào |
|
||
|
||
**Đọc ngược quan trọng hơn đọc xuôi.** Đọc xuôi tìm chỗ thiếu; đọc ngược tìm chỗ thừa — và
|
||
chỗ thừa (component không ai cần, ADR không phục vụ gì) thường không bao giờ bị phát hiện.
|
||
|
||
### Bước 3 — Dựng `ADL`
|
||
|
||
Điền `templates/adr-ledger.md`. Mục lục mọi ADR kèm trạng thái, và **năm kiểm tra**:
|
||
|
||
| Kiểm | Phát hiện |
|
||
|---|---|
|
||
| Chuỗi supersede | `ADR-A` ghi `Superseded by ADR-B` nhưng `ADR-B` không ghi `Supersedes ADR-A` ⇒ tham chiếu gãy |
|
||
| `Proposed` quá hạn | `Proposed` > 10 ngày ⇒ quyết định đang treo, ai đó đang chờ |
|
||
| Điểm radar ≥ 8 chưa POC | `Accepted` mà không có POC ⇒ vi phạm `decision-radar.md` §6 |
|
||
| Nguồn đã đổi | `ADR` dựa trên `QAS-nnn` mà `QAS` đó đã sửa/bỏ ⇒ quyết định có thể không còn đúng |
|
||
| Mâu thuẫn | Hai `ADR` `Accepted` quyết ngược nhau về cùng một chủ đề |
|
||
|
||
🔴 Kiểm tra cuối là kiểm tra khó nhất và có giá trị nhất. Rà theo chủ đề (dữ liệu, tích hợp,
|
||
bảo mật, hạ tầng), không rà theo số thứ tự.
|
||
|
||
### Bước 4 — Báo cáo coverage
|
||
|
||
In bảng, mỗi dòng có **tỉ lệ + danh sách ID bị đứt** (không chỉ tỉ lệ):
|
||
|
||
```
|
||
DRV → ASR/QAS 8/8 100% ✅
|
||
ASR → ADR 11/13 85% 🔴 đứt: ASR-004, ASR-009 → chặn AG2
|
||
ADR → nguồn 14/16 88% 🟠 không nguồn: ADR-006, ADR-012
|
||
QAS(Must) → bài đo 6/9 67% 🔴 thiếu: QAS-009, QAS-011, QAS-012 → chặn AG3
|
||
Ràng buộc AGD → FIT 12/18 67% 🔴 thiếu và không có nhãn: §3.2-2, §3.4-3
|
||
CMP → ASR 9/11 82% 🟠 không phục vụ ASR nào: CMP-07, CMP-10
|
||
IF → CTR (x-if) 14/17 82% 🔴 chưa có file: IF-007, IF-008, IF-020 → chặn AG2
|
||
DAT thực thể → PDM 12/12 100% ✅
|
||
MIG có down 3/4 75% 🔴 thiếu down: MIG-003 → chặn AG2
|
||
Sơ đồ có spec Archify 6/8 75% 🟠 thiếu spec: SAD §5, SEC §1
|
||
```
|
||
|
||
### Bước 5 — Xếp phát hiện và kết luận gate
|
||
|
||
Ba mức: 🔴 chặn gate · 🟠 nợ phải trả trước gate sau · 🟡 cải thiện.
|
||
|
||
Mỗi phát hiện ghi: **file · mục · cái đứt · hành động đề xuất · skill nào sửa**.
|
||
|
||
Kết luận đúng một dòng cho mỗi gate đang mở:
|
||
|
||
```
|
||
AG2: 🔴 CHẶN — ASR-004 và ASR-009 chưa có ADR nào. Chạy /sa-2-architecture --focus adr.
|
||
AG3: 🔴 CHẶN — 3 QAS mức Must chưa có bài đo. Chạy /sa-3-enablement --focus fit.
|
||
```
|
||
|
||
## Chế độ chạy
|
||
|
||
| `--mode` | Làm gì | Khi nào |
|
||
|---|---|---|
|
||
| `dtm` | Chỉ dựng/cập nhật `DTM` | Sau mỗi sprint |
|
||
| `adl` | Chỉ dựng/cập nhật `ADL` | Sau mỗi ADR mới |
|
||
| `full` | Cả hai + coverage + kết luận gate | Trước mỗi gate |
|
||
|
||
## Trước khi kết thúc
|
||
|
||
In ba thứ: **① bảng coverage đầy đủ** (tỉ lệ + ID đứt) · **② danh sách phát hiện xếp theo
|
||
mức, mỗi cái chỉ được file và mục** · **③ kết luận gate**.
|
||
|
||
Cập nhật `DTM` và `ADL`. **Không sửa artifact của skill khác.**
|
||
|
||
## Bẫy thường gặp
|
||
|
||
**Điền ma trận cho đủ.** Ma trận 100% mà một nửa liên kết là suy diễn thì tệ hơn ma trận 70%
|
||
trung thực — nó tạo cảm giác an toàn giả. Không thấy quan hệ thì để trống và báo đứt.
|
||
|
||
**Chỉ đọc xuôi.** Đọc ngược mới tìm ra thành phần thừa và quyết định không phục vụ gì. Đó là
|
||
chỗ chi phí ẩn nằm.
|
||
|
||
**Hạ mức để gate qua được.** Skill này tồn tại để chặn. Chặn ở đây tốn một tuần; chặn ở
|
||
production tốn nhiều hơn thế.
|
||
|
||
**Báo cáo "tài liệu chưa đầy đủ".** Vô dụng. Phải là: *"`ASR-004` (file `ASR_… §B2`) không có
|
||
`ADR` nào hiện thực hoá; đề xuất viết ADR về cơ chế hàng đợi; chạy
|
||
`/sa-2-architecture --focus adr`."*
|
||
|
||
**Quét cả bản nháp rồi báo đỏ.** Artifact `🟡 Draft` chưa cam kết gì. Tách riêng, đánh dấu
|
||
"trong bản nháp", không tính vào coverage chặn gate.
|