This commit is contained in:
Leonard-ThindPad-P50
2026-09-08 10:26:21 +07:00
commit c81f249920
169 changed files with 38726 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
# Bản đồ artifact SA
## 1. Toàn bộ artifact, ai sinh, ai tiêu thụ
| Mã | Tên đầy đủ | Thư mục | Sinh bởi | Tiêu thụ bởi |
|---|---|---|---|---|
| `CTX` | Solution Context & Drivers | `01-context/` | sa-1 | PO, Tech Lead, toàn team |
| `OPT` | Solution Options & Trade-off | `01-context/` | sa-1 | PO, Tech Lead, PM |
| `TCO` | Cost Model / TCO | `01-context/` | sa-1 | PO, PM, tài chính |
| `ARISK` | Architecture Risk Register & POC plan | `01-context/` | sa-1 | PM, Tech Lead |
| `ASR` | Architecturally Significant Requirements | `02-architecture/` | sa-2 | sa-2, Tech Lead |
| `QAS` | Quality Attribute Scenarios (NFR lượng hoá) | `02-architecture/` | sa-2 | QA, SRE, Dev |
| `SAD` | Solution Architecture Document | `02-architecture/` | sa-2 | Toàn team, khách hàng |
| `ADR` | Architecture Decision Record | `02-architecture/adr/` | sa-2, mọi giai đoạn | Team hiện tại + người 2 năm sau |
| `ICD` | Integration & Interface Catalog | `02-architecture/` | sa-2 | Dev BE/FE, đối tác, BA |
| `DAT` | Data Architecture | `02-architecture/` | sa-2 | Dev, DBA, DPO |
| `SEC` | Security Architecture & Threat Model | `02-architecture/` | sa-2 | Security, kiểm toán |
| `INF` | Infrastructure & Deployment Design | `02-architecture/` | sa-2 | DevOps/SRE |
| `FAIL` | Failure Mode & Resilience Design | `02-architecture/` | sa-2 | Dev, SRE, QA |
| `AGD` | Architecture Guidelines & Reference Impl | `03-enablement/` | sa-3 | Dev |
| `FIT` | Fitness Functions | `03-enablement/` | sa-3 | Dev, CI |
| `DREV` | Design Review Log | `03-enablement/` | sa-3 | Tech Lead, Dev |
| `TDEBT` | Technical Debt Register | `03-enablement/` | sa-3 | PM, PO, Tech Lead |
| `CONF` | Architecture Conformance Report | `04-evolution/` | sa-4 | PO, SRE, EA |
| `TRM` | Technical Roadmap / Migration Plan | `04-evolution/` | sa-4 | PM, PO |
| `PMR` | Architecture Review / Post-mortem | `04-evolution/` | sa-4 | Tech Lead, EA |
| `DTM` | Decision Traceability Matrix | `00-index/` | sa-conformance | Mọi vai trò |
| `ADL` | ADR Ledger (mục lục quyết định) | `00-index/` | sa-conformance | Mọi vai trò |
| `GLOSSARY` | Từ điển thuật ngữ kỹ thuật | `00-index/` | sa-1, bồi đắp dần | Mọi vai trò |
| `DEC` | Sổ quyết định không đủ tầm ADR (`DEC-nn`) | `00-index/` | mọi skill | Mọi vai trò |
| `OQ` | Sổ open question (`OQ-nnn`) | `00-index/` | mọi skill | Mọi vai trò |
| `INDEX` | Mục lục dự án | `00-index/` | sa-lifecycle | Mọi vai trò |
## 2. Cây thư mục
```
sa-output/<PROJECT>/
├── 00-index/
│ ├── INDEX_<PROJECT>.md
│ ├── ADL_<PROJECT>.md
│ ├── DTM_<PROJECT>.md
│ ├── GLOSSARY_<PROJECT>.md
│ ├── DEC_<PROJECT>.md
│ └── OQ_<PROJECT>.md
├── 01-context/ CTX · OPT · TCO · ARISK
├── 02-architecture/
│ ├── ASR · QAS · SAD · ICD · DAT · SEC · INF · FAIL
│ └── adr/
│ ├── ADR-001_<slug>.md
│ └── archive/
├── 03-enablement/ AGD · FIT · DREV · TDEBT
└── 04-evolution/ CONF · TRM · PMR
```
## 3. Header bắt buộc của mọi artifact
Mọi file `.md` sinh ra phải mở đầu bằng khối này. Thiếu một dòng ⇒ gate không chấm được.
```markdown
# <LOẠI> — <Tên phạm vi>
| | |
|---|---|
| **Version** | 1.0 |
| **Date** | 2026-08-30 |
| **Author** | <tên SA> (qua skill sa-2-architecture) |
| **Status** | 🟡 Draft / 🟠 In Review / 🔵 Approved / ✅ Baselined / 📦 Archived |
| **Approved by** | — *(điền tên + vai trò + ngày khi được ký)* |
| **Source** | <danh sách file input đã dùng, mỗi cái một dòng> |
| **Scope** | <hệ thống / module / phạm vi kiến trúc> |
| **Confidence** | 🟢 Đã kiểm chứng / 🟡 Ước lượng có cơ sở / 🔴 Giả định chưa xác minh |
## Change Log
| Version | Date | Người sửa | Thay đổi | ADR/DEC |
|---|---|---|---|---|
| 1.0 | 2026-08-30 | … | Bản đầu | — |
```
🔴 **Dòng `Confidence` là thứ bộ SA có mà bộ BA không có.** Tài liệu kiến trúc luôn chứa cả
sự thật lẫn ước lượng; không phân biệt hai thứ đó thì người đọc coi ước lượng là cam kết.
Một tài liệu có nhiều mức thì ghi mức **thấp nhất** ở header và đánh dấu từng mục bên trong.
**Ý nghĩa `Status`** — đây là thứ gate đọc, không phải tên file:
| Status | Nghĩa | Ai được sửa file |
|---|---|---|
| 🟡 Draft | SA đang viết | SA tự do |
| 🟠 In Review | Đã gửi duyệt | SA sửa theo comment |
| 🔵 Approved | Người duyệt đã đồng ý nội dung | SA sửa, ghi Change Log |
| ✅ Baselined | Đã qua gate, là nguồn sự thật | **Chỉ sửa qua `ADR` mới hoặc `DEC-nn`** |
| 📦 Archived | Đã bị thay bằng version mới | Không sửa |
## 4. ADR — quy ước riêng
ADR không dùng version như artifact khác. ADR **bất biến sau khi Accepted**: muốn đổi quyết
định thì viết ADR mới thay thế nó.
**Tên file:** `ADR-<nnn>_<slug-ngắn>.md` — ví dụ `ADR-007_chon-postgres-thay-mongo.md`.
Số tăng dần toàn dự án, **không bao giờ tái sử dụng**.
**Vòng đời trạng thái:**
| Status | Nghĩa | Chuyển tiếp hợp lệ |
|---|---|---|
| `Proposed` | Đang đề xuất, chưa ai ký | → Accepted · Rejected |
| `Accepted` | Đã chốt, là ràng buộc | → Superseded · Deprecated |
| `Rejected` | Đã cân nhắc và loại | *(cuối)* — **giữ file, không xoá** |
| `Superseded by ADR-nnn` | Bị thay bởi quyết định mới | *(cuối)* |
| `Deprecated` | Không còn áp dụng, chưa có bản thay | → Superseded |
🔴 **ADR bị loại vẫn phải giữ.** Giá trị lớn nhất của ADR là ghi lại *phương án đã cân nhắc và
vì sao loại*. Xoá đi thì sáu tháng sau có người đề xuất lại đúng phương án đó và cả team tranh
luận lại từ đầu.
## 5. Quy tắc version *(cho artifact không phải ADR)*
| Thay đổi | Tăng |
|---|---|
| Sửa lỗi chính tả, làm rõ câu chữ, không đổi ràng buộc | `+0.1` |
| Thêm/sửa nội dung kỹ thuật không đổi quyết định kiến trúc | `+0.1` |
| Đổi một quyết định kiến trúc, đổi phạm vi, tái cấu trúc tài liệu | `+1.0` **và phải có ADR đi kèm** |
| Qua gate lần đầu | đặt `1.0`, Status `✅ Baselined` |
File đạt `✅ Baselined` mà cần sửa: tạo version mới, **chuyển bản cũ vào `archive/`** cùng thư
mục, Status bản cũ đổi thành `📦 Archived`. Không xoá file.
## 6. Quan hệ phụ thuộc
Mũi tên = "cần cái kia mới viết đúng được". Thiếu input ⇒ vẫn làm, nhưng phải ghi `OQ` và
hạ `Confidence` xuống 🔴.
```
BRIEF/BACKLOG (BA) ──► CTX ──► OPT ──► TCO
│ │
│ └──► ARISK ──► POC
│
└──► ASR ──┬──► QAS ──────────────┬──► FIT ──► CONF
│ │
└──► SAD ──┬──► ICD ────┤
│ ├──► DAT ├──► AGD ──► DREV
│ ├──► SEC │
│ ├──► INF └──► TDEBT ──► TRM
│ └──► FAIL
└──► ADR (sinh ở mọi nhánh)
DTM đọc: CTX(DRV) · ASR · QAS · ADR · SAD(CMP) · FIT · CONF
ADL đọc: toàn bộ adr/
```
Đọc xuôi mũi tên để biết **sửa cái này thì phải sửa tiếp cái nào**. Ví dụ đổi một `QAS` ⇒ rà
lại `SAD` (còn đáp ứng không), `FIT` (bài kiểm thử còn đúng không), `CONF` (bài đo còn đúng
không), và mọi `ADR` có `QAS` đó trong mục Context.
## 7. Ánh xạ sang artifact của bộ BA
Hai bộ dùng chung `OQ` và `DEC`. Những chỗ còn lại phải khớp nhau, không sao chép:
| Artifact BA | Artifact SA tương ứng | Quan hệ |
|---|---|---|
| `BRIEF` · `GOAL-nn` | `CTX` · `DRV-nn` | SA đọc GOAL để suy ra driver kiến trúc |
| `NFR` (BA đề xuất) | `QAS` (SA lượng hoá) | **`QAS` thắng.** BA ghi nhu cầu, SA chốt con số và cách đo |
| `API` (BA đề xuất) | `ICD` (SA chốt) | **`ICD` thắng.** BA đánh dấu "chờ xác nhận", SA là người xác nhận |
| `RBAC` | `SEC` §authz | `SEC` map ma trận RBAC nghiệp vụ xuống cơ chế kỹ thuật |
| `IMPACT` | `SAD` + `DAT` | BA nêu module nghiệp vụ bị ảnh hưởng, SA nêu component và dữ liệu |
| `BR-nnn` | `ADR` khi rule ép ràng buộc kiến trúc | Ví dụ rule "không được mất giao dịch" ⇒ ADR về consistency |
| `CR-nnn` | `ADR` mới nếu CR chạm kiến trúc | CR không chạm kiến trúc thì không cần ADR |
🔴 **Không copy nội dung giữa hai bộ.** Tham chiếu bằng đường dẫn + ID. Copy là cách chắc chắn
nhất để hai tài liệu lệch nhau sau ba lần sửa.
## 8. Mẫu `INDEX_<PROJECT>.md`
```markdown
# INDEX — <PROJECT> (kiến trúc)
| | |
|---|---|
| **Cập nhật** | 2026-08-30 |
| **Giai đoạn hiện tại** | GĐ2 · Architecture |
| **Gate gần nhất đã qua** | AG1 (2026-08-25, ký bởi …) |
| **ADR đang Proposed** | ADR-011, ADR-012 |
## Artifact
| Loại | File mới nhất | Version | Status | Confidence | Cập nhật |
|---|---|---|---|---|---|
| CTX | `01-context/CTX_<...>_v1.0.md` | 1.0 | ✅ | 🟢 | 2026-08-25 |
## Open Question đang mở
| ID | Nội dung | Hỏi ai | Từ ngày | Chặn gì |
|---|---|---|---|---|
## Rủi ro kiến trúc mức cao đang mở
| ID | Rủi ro | Chủ | Cách hạ | Hạn |
|---|---|---|---|---|
```
`INDEX` do `sa-lifecycle` cập nhật mỗi lần chạy. Các skill giai đoạn **không sửa INDEX** —
chúng chỉ ghi artifact của mình rồi báo người dùng chạy `/sa-lifecycle` để đồng bộ.

View File

@@ -0,0 +1,129 @@
# Radar quyết định — cái gì cần ADR, cái gì không
Câu hỏi khó nhất của nghề SA không phải "quyết thế nào" mà "cái này có phải việc của tôi
không". Tài liệu này chốt ngưỡng đó, để skill và người dùng không tranh cãi mỗi lần.
## 1. Phép thử một câu
> Quyết định sai, sửa mất **≤ 2 ngày** → không phải việc của SA. Ghi `DEC-nn` là đủ.
> Sai mà sửa mất **≥ 4 tuần**, hoặc phải **migrate dữ liệu**, hoặc phải **đổi contract công
> khai** → bắt buộc `ADR`.
> Ở giữa → dùng bảng chấm điểm §2.
## 2. Bảng chấm điểm
Chấm 5 tiêu chí, mỗi tiêu chí 0–2 điểm.
| # | Tiêu chí | 0 điểm | 1 điểm | 2 điểm |
|---|---|---|---|---|
| 1 | **Chi phí đảo ngược** | < 2 ngày | 1–3 tuần | > 4 tuần hoặc phải migrate dữ liệu |
| 2 | **Bán kính ảnh hưởng** | Trong một module | Nhiều module cùng team | Nhiều team / hệ thống ngoài / khách hàng |
| 3 | **Chạm thuộc tính chất lượng** | Không | Ảnh hưởng gián tiếp | Quyết định trực tiếp một `QAS` mức Must |
| 4 | **Ràng buộc dài hạn** | Đổi lúc nào cũng được | Ràng trong một release | Ràng buộc ≥ 1 năm (license, vendor, mô hình dữ liệu) |
| 5 | **Tranh cãi** | Cả team đồng ý ngay | Có ý kiến khác | Đã tranh luận ≥ 2 lần hoặc có bên phản đối |
| Tổng | Xử lý |
|---|---|
| **0–2** | Không ghi gì. Là quyết định thi công, thuộc Tech Lead/Dev |
| **3–4** | Ghi `DEC-nn` trong `00-index/` — một dòng, không cần ADR |
| **5–7** | **`ADR` bắt buộc** |
| **8–10** | `ADR` + phải có POC hoặc bài đo trước khi chuyển `Accepted` |
🔴 Tiêu chí 5 hay bị coi thường. Một quyết định team đã cãi nhau hai lần mà không ai ghi lại
sẽ được cãi lại lần thứ ba, thứ tư — chi phí thật nằm ở đó, không nằm ở kỹ thuật.
## 3. Danh mục quyết định thường đạt ngưỡng ADR
Dùng làm checklist rà soát: dự án nào cũng nên trả lời được từng dòng, hoặc bằng một ADR,
hoặc bằng câu "không áp dụng vì …".
### Cấu trúc hệ thống
- Kiểu kiến trúc tổng thể (modular monolith / microservices / serverless / hybrid)
- Ranh giới service — cắt theo đâu, vì sao (thường là quyết định đắt nhất cả dự án)
- Đồng bộ hay bất đồng bộ giữa các thành phần lõi
- Có event bus / message broker không, loại nào
- Chiến lược multi-tenant (chung DB / chung schema / tách schema / tách DB)
### Dữ liệu
- Loại CSDL chính và vì sao (quan hệ / tài liệu / khoá-giá trị / cột / đồ thị)
- Ai là single source of truth cho từng thực thể lõi
- Consistency model: mạnh hay eventual, eventual thì trễ tối đa bao nhiêu
- Cơ chế giao dịch xuyên service (saga / outbox / 2PC / không có)
- Chiến lược migration dữ liệu legacy, cách rollback
- Sharding / partitioning, khoá phân mảnh
- Retention và xoá dữ liệu cá nhân (ràng buộc pháp lý)
### Tích hợp
- Kiểu contract công khai (REST / GraphQL / gRPC / event)
- Chính sách versioning và thời gian hỗ trợ phiên bản cũ
- Idempotency: khoá là gì, giữ bao lâu
- Cách xử lý khi hệ thống ngoài hỏng (degrade / hàng đợi / từ chối)
### Bảo mật
- Mô hình xác thực (session / JWT / OAuth2 / mTLS) và nơi giữ trạng thái
- Mô hình phân quyền (RBAC / ABAC / kết hợp) và **chỗ ra quyết định** (gateway hay service)
- Quản lý secret và xoay khoá
- Phân loại dữ liệu nhạy cảm và ranh giới mã hoá
- Mô hình audit log: ghi gì, giữ bao lâu, ai đọc được
### Hạ tầng & vận hành
- Cloud/vùng, và có ràng buộc dữ liệu phải nằm trong lãnh thổ không
- Mô hình chạy (VM / container / K8s / PaaS / serverless)
- Chiến lược HA và DR kèm RTO/RPO
- Chiến lược release (blue-green / canary / rolling) và cách rollback
- Bộ observability và nơi giữ log, chi phí kèm theo
### Frontend *(khi giải pháp có giao diện)*
- SPA / SSR / hybrid và lý do gắn với `QAS` (SEO, thời gian hiển thị đầu, thiết bị yếu)
- Chiến lược trạng thái và cache phía client
- Cách xử lý số lớn (`id`/số tiền vượt `2^53`) xuyên suốt tầng giao diện
- Chiến lược đa ngôn ngữ và nơi giữ chuỗi hiển thị
## 4. Cái KHÔNG nên viết ADR
Viết ADR cho những thứ này làm loãng sổ quyết định, và người đọc sẽ ngừng đọc:
| Không ADR | Vì sao | Ghi ở đâu |
|---|---|---|
| Chọn thư viện tiện ích (date, lodash…) | Thay được trong một buổi chiều | Không ghi, hoặc `AGD` |
| Quy ước đặt tên, format code | Không phải quyết định kiến trúc | `AGD` |
| Cấu trúc thư mục trong một module | Bán kính hẹp | `AGD` |
| Chọn màu, spacing, component UI | Thuộc design system | Tài liệu thiết kế |
| "Dùng interface hay abstract class" | Quyết định thi công | Code review |
| Bug fix, tối ưu cục bộ | Không ràng buộc gì về sau | Commit message |
🔴 **Ngoại lệ:** một quyết định nhỏ trở thành ADR khi nó **thiết lập tiền lệ**. "Dùng thư viện
X" là nhỏ; "mọi service từ nay dùng cùng một thư viện logging và cùng một định dạng log" là
ADR, vì nó ràng buộc mọi service tương lai.
## 5. Ai được đề xuất, ai được chốt
| Loại quyết định | Đề xuất | Chốt | Phủ quyết |
|---|---|---|---|
| Cấu trúc hệ thống, dữ liệu, tích hợp | SA | SA + Tech Lead | EA (nếu lệch chuẩn doanh nghiệp) |
| Bảo mật, quyền riêng tư | SA | **Security** | Security |
| Hạ tầng, HA/DR, chi phí vận hành | SA | SA + SRE | PO (nếu vượt ngân sách) |
| Đánh đổi nghiệp vụ (rẻ hơn nhưng chậm hơn) | SA trình bảng | **PO** | — |
| Công cụ, thư viện, quy ước code | Tech Lead | Tech Lead | SA (nếu chạm `QAS`) |
Dev và Tech Lead **được quyền đề xuất ADR**. Một tổ chức mà chỉ SA viết được ADR là tổ chức
mà kiến trúc sẽ bị vòng qua chứ không bị phản biện.
## 6. Khi nào một ADR cần POC trước
Bắt buộc POC trước khi chuyển `Proposed → Accepted` nếu có bất kỳ điều nào:
- Điểm radar ≥ 8
- Quyết định dựa trên một con số hiệu năng **chưa ai đo trong ngữ cảnh này**
- Công nghệ chưa ai trong team từng chạy production
- Phụ thuộc vào hành vi của hệ thống bên ngoài mà ta chỉ đọc tài liệu, chưa gọi thật
- Ước lượng chi phí hạ tầng dựa trên suy đoán, không có báo giá hay bài đo
POC phải có **tiêu chí pass/fail viết trước khi làm**, và kết quả (kể cả fail) ghi vào `ARISK`
rồi tham chiếu từ ADR. POC không có tiêu chí trước là POC luôn "thành công".

View File

@@ -0,0 +1,184 @@
# 12 quy tắc viết tài liệu kiến trúc
Mọi skill `sa-*` phải tuân thủ. Đây là thứ phân biệt một tài liệu kiến trúc dev đọc xong thi
công được với một bộ sơ đồ hộp và mũi tên.
Bộ này song song với `W1–W12` của bộ BA (`../../ba-lifecycle/references/writing-rules.md`).
Khi làm tài liệu chạm cả hai (ví dụ `ICD` đối chiếu `API` của BA), tuân thủ **cả hai bộ**.
## D1 — Một ADR, một quyết định
❌ `ADR-004: Chọn stack backend` — bên trong quyết cả ngôn ngữ, framework, ORM, message broker.
✅ Bốn ADR. Vì sáu tháng sau khi đổi message broker, bạn cần supersede đúng một quyết định,
không phải viết lại một tài liệu còn đúng ba phần tư.
Ngưỡng "quyết định nào cần ADR": xem `decision-radar.md`.
## D2 — Cấm NFR định tính
Danh sách cấm, kèm cách thay:
| Cấm | Thay bằng |
|---|---|
| nhanh, phản hồi tốt | `p95 ≤ 300ms cho GET /orders tại 2.000 rps` |
| chịu tải cao, mở rộng được | `20.000 đơn/giờ giờ cao điểm, tăng 3×/năm trong 2 năm` |
| ổn định, sẵn sàng cao | `99.9%/tháng ⇒ ngân sách lỗi 43 phút/tháng` |
| bảo mật | tên mối đe doạ + biện pháp + cách kiểm chứng |
| dễ bảo trì | `một dev mới onboard và sửa được một bug trong ≤ 3 ngày` |
| dữ liệu lớn | con số + đơn vị + tốc độ tăng |
Mỗi `QAS` phải trả lời đủ **bốn câu**: kịch bản gì · con số bao nhiêu · đo bằng cách nào · ai đo.
Thiếu câu thứ ba là NFR không verify được ⇒ theo `D8` nó chỉ là mong muốn.
Quét trước khi nộp: `grep -niE "nhanh|ổn định|dễ (bảo trì|dùng)|chịu tải cao|bảo mật$" <file>`
## D3 — Không có phương án bị loại thì không phải quyết định
Mọi `ADR` và mọi `OPT` phải nêu **≥ 1 phương án đã cân nhắc và loại**, kèm lý do loại nói được
bằng ràng buộc (`CON-nn`) hoặc thuộc tính chất lượng (`QAS-nnn`), không phải bằng sở thích.
❌ "Chọn PostgreSQL vì team quen."
✅ "Chọn PostgreSQL. Loại MongoDB vì `QAS-007` yêu cầu giao dịch nhiều bảng nguyên tử; loại
MySQL vì `CON-03` (đội vận hành chỉ có kinh nghiệm Postgres) và chênh lệch hiệu năng ở
`QAS-004` không đáng kể theo POC-02."
"Team quen" là một lý do **hợp lệ** — nhưng phải viết ra như một ràng buộc có tên, để sau này
biết quyết định này gắn với con người chứ không phải với kỹ thuật.
## D4 — Sơ đồ phải khai báo mức, và không trộn mức
Mỗi sơ đồ ghi rõ ở đầu: **C4 mức nào** (Context / Container / Component / Code) hoặc **loại**
(deployment, sequence, state, data flow). Một sơ đồ có cả "trình duyệt người dùng" lẫn "class
OrderValidator" là sơ đồ không ai đọc được.
Kèm mỗi sơ đồ: một **legend** giải thích hình khối và loại mũi tên (sync/async, ai gọi ai,
giao thức). Mũi tên không nhãn không mang thông tin.
**Vẽ bằng mermaid, không ASCII art** — thống nhất với quy tắc `W13` của bộ BA
(`../../ba-lifecycle/references/diagram-rules.md`). GitHub/Confluence và Artifact của Claude
Code render thẳng, và `git diff` đọc được từng cạnh.
| Sơ đồ | Loại mermaid | Sinh ở |
|---|---|---|
| C4 Context / Container / Component | `flowchart` + `subgraph` | `SAD` §3–§5 |
| Deployment view | `flowchart TB` + `subgraph` theo vùng/AZ | `SAD` §7, `INF` §3 |
| Luồng chính, có nhánh lỗi | `sequenceDiagram` | `SAD` §6 |
| Ranh giới tin cậy | `flowchart LR` | `SEC` §1 |
| Mô hình dữ liệu khái niệm | `erDiagram` | `DAT` §2 |
| Phụ thuộc giữa mục roadmap | `flowchart LR` | `TRM` §4 |
| Phương án ở mức khối | `flowchart LR` | `OPT` §3 |
🔴 **Mỗi sơ đồ phải có bảng đi kèm** (`W13`). Sơ đồ để nhìn; bảng để truy vết, để đặt con số,
và để kiểm chứng. Sơ đồ không diễn đạt được timeout, quyền, mã lỗi, hay ai sở hữu cái gì.
## D5 — Mọi interface có chủ, có contract, có chính sách phiên bản
Mỗi dòng trong `ICD` phải có: `IF-nnn` · hai đầu · giao thức · sync hay async · **ai sở hữu
contract** · nơi contract sống (đường dẫn file OpenAPI/AsyncAPI/proto) · chính sách đổi phiên
bản · hành vi khi đầu kia hỏng.
🔴 Interface không biết ai sở hữu là interface sẽ bị đổi mà không ai báo.
## D6 — Đường lỗi là bắt buộc cho mọi thứ vượt ranh giới process
Mọi lời gọi ra khỏi process (HTTP, DB, cache, queue, file, hệ thống ngoài) phải ghi:
**timeout · retry (số lần + backoff + có idempotent không) · hành vi khi hết retry · ảnh hưởng
tới người dùng**.
Bốn câu hỏi cho mỗi phụ thuộc, không được bỏ câu nào:
1. Nó chậm thì sao? *(không phải "hỏng" — chậm nguy hiểm hơn hỏng)*
2. Nó hỏng thì sao? Có degrade được không hay chết cả luồng?
3. Nó trả sai dữ liệu thì sao? Có phát hiện được không?
4. Nó hồi phục thì sao? Có retry storm không? Có cần backpressure không?
## D7 — Mỗi mảnh dữ liệu có đúng một chủ sở hữu
Trong `DAT`, mỗi thực thể ghi rõ **hệ thống nào là single source of truth**. Mọi bản sao khác
là read model, phải ghi: cập nhật bằng cơ chế gì, độ trễ tối đa bao nhiêu, và **được phép lệch
bao lâu** trước khi coi là sự cố.
❌ "Cả hai hệ thống đều lưu thông tin khách hàng và đồng bộ hai chiều."
✅ Chọn một bên làm chủ. Đồng bộ hai chiều không có chủ là cách sinh ra dữ liệu mâu thuẫn
không ai gỡ được.
## D8 — Ràng buộc không verify tự động được là khuyến nghị, không phải ràng buộc
Mỗi ràng buộc kiến trúc trong `AGD` phải có một trong hai:
- một **fitness function** trong `FIT` (ArchUnit, dependency-cruiser, lint rule, kiểm thử tải,
kiểm tra hạ tầng) chạy trên CI, **hoặc**
- ghi thẳng nhãn `⚠️ Khuyến nghị — không tự kiểm được`.
Không có nhãn và không có bài kiểm ⇒ trong sáu tháng nó sẽ bị vi phạm và không ai biết.
## D9 — Mọi con số hạ tầng phải quy được ra tiền và ra đơn vị
"Cần 8 node" ⇒ node loại gì, ở vùng nào, bao nhiêu tiền/tháng, ở mức tải nào. `TCO` và `INF`
phải khớp nhau; lệch thì `TCO` sai hoặc `INF` sai, không có khả năng thứ ba.
Mọi con số ghi kèm **nguồn**: bài đo nào, POC nào, báo giá nào, ngày nào. Con số không nguồn
là 🔴 giả định, phải hạ `Confidence` của tài liệu.
## D10 — Không quyết định thay người có thẩm quyền
SA trình phương án kèm khuyến nghị. Ba loại quyết định **không** thuộc SA:
| Loại | Chủ | SA làm gì |
|---|---|---|
| Trade-off nghiệp vụ (chậm hơn nhưng rẻ hơn) | PO | Trình bảng đánh đổi kèm con số |
| Chấp nhận rủi ro bảo mật | Security | Trình threat model + biện pháp + chi phí |
| Ngân sách, tiến độ, nhân sự | PO / PM | Trình `TCO` và effort |
Gặp chỗ chưa rõ, viết:
```markdown
> **OQ-021** — Chấp nhận eventual consistency ≤ 5 giây cho số dư ví không?
> **Hỏi:** PO (chị Lan) + Security · **Từ:** 2026-08-29 · **Chặn:** ADR-009, QAS-011
> **Phương án SA đề xuất:** Chấp nhận, vì … *(đề xuất, chưa phải quyết định)*
> **Nếu không chấp nhận:** phải dùng phân tán 2 pha ⇒ +6 tuần, +30% chi phí hạ tầng
```
Luôn ghi **hệ quả của phương án ngược lại** bằng con số — đó là thứ giúp người có thẩm quyền
quyết được trong một lần đọc.
## D11 — Ghi cả cái kiến trúc KHÔNG làm
Cuối mỗi tài liệu, hai mục bắt buộc:
- **Ngoài phạm vi** — những thứ người đọc có thể tưởng là có: *"Không hỗ trợ đa vùng
(multi-region) trong phiên bản này; DR dựa trên khôi phục từ backup, RTO 4 giờ."*
- **Giả định** — `ASM-nn`, mỗi cái có cách xác minh và hệ quả nếu sai.
Kiến trúc là tập hợp những thứ đã loại nhiều hơn là những thứ đã chọn. Không ghi ra thì người
sau tưởng bạn đã cân nhắc.
## D12 — Sơ đồ và văn bản mâu thuẫn: chia thẩm quyền rõ ràng
Ghi câu này trong mọi tài liệu có sơ đồ:
> Sơ đồ thắng về **quan hệ và luồng** (ai gọi ai, theo thứ tự nào).
> Bảng/văn bản thắng về **ràng buộc và con số** (timeout, quyền, định dạng, giới hạn).
> Mâu thuẫn ngoài hai loại trên ⇒ là lỗi tài liệu, phải sửa chứ không phải chọn bên.
---
## Checklist tự chấm trước khi nộp bất kỳ tài liệu kiến trúc nào
```
[ ] D1 Mỗi ADR chỉ chứa một quyết định
[ ] D2 grep NFR định tính trả về rỗng; mọi QAS đủ 4 câu (kịch bản/số/cách đo/ai đo)
[ ] D3 Mọi quyết định nêu ≥1 phương án đã loại + lý do gắn với CON hoặc QAS
[ ] D4 Mỗi sơ đồ khai báo mức C4 + có legend, không trộn mức
[ ] D5 Mọi interface có chủ, contract, versioning policy
[ ] D6 Mọi phụ thuộc ngoài process có timeout/retry/fallback + trả lời 4 câu hỏi
[ ] D7 Mỗi thực thể dữ liệu có đúng một single source of truth
[ ] D8 Mọi ràng buộc có FIT hoặc nhãn "⚠️ Khuyến nghị"
[ ] D9 Mọi con số hạ tầng có đơn vị, nguồn, và quy ra tiền; INF khớp TCO
[ ] D10 Mọi chỗ chưa rõ là OQ kèm hệ quả phương án ngược, không phải quyết định ngầm
[ ] D11 Có mục "Ngoài phạm vi" và mục "Giả định ASM-nn"
[ ] D12 Có câu quy định thẩm quyền sơ đồ vs văn bản
```
In checklist này dạng bảng ☐/✅ ở cuối mỗi lần chạy skill. Mục chưa đạt ⇒ nói rõ thiếu gì,
**không được đánh ✅ cho có**.

View File

@@ -0,0 +1,165 @@
# Workflow SA — 4 giai đoạn, 4 gate
## 1. Sơ đồ
```
bài toán nghiệp vụ đã phát biểu được (BRIEF/BACKLOG của BA)
│
┌──────────▼──────────┐
│ GĐ1 · CONTEXT │ driver là gì, ràng buộc gì, chọn phương án nào
│ sa-1-context │
└──────────┬──────────┘
│ AG1 — PO + Tech Lead ký: phương án & ngân sách đã chốt
┌──────────▼──────────┐
│ GĐ2 · ARCHITECTURE │ lượng hoá NFR, phân rã, contract, dữ liệu, bảo mật, hạ tầng
│ sa-2-architecture │
└──────────┬──────────┘
│ AG2 — Tech Lead + Security + Ops ký: Ready for Build
┌──────────▼──────────┐
│ GĐ3 · ENABLEMENT │ guideline, fitness function, design review, tech debt
│ sa-3-enablement │
└──────────┬──────────┘
│ AG3 — Tech Lead + QA + SRE ký: kiến trúc thi công đúng, sẵn sàng go-live
┌──────────▼──────────┐
│ GĐ4 · EVOLUTION │ đối chiếu telemetry, đánh giá drift, roadmap kỹ thuật
│ sa-4-evolution │
└──────────┬──────────┘
│ AG4 — PO + SRE + EA ký: đóng vòng hoặc mở vòng kiến trúc mới
▼
```
`sa-conformance` chạy song song, cập nhật `DTM` + `ADL` sau mỗi giai đoạn và **có quyền chặn
AG2, AG3, AG4**.
## 2. Tiêu chí pass từng gate
Gate chỉ ✅ khi **đủ artifact** *và* **đủ nội dung** *và* **có chữ ký duyệt ghi trong header
artifact** (dòng `Approved by: <tên> · <ngày>`).
Gate kiến trúc khác gate BA ở một điểm: **không ký được bằng "trông hợp lý"**. Mỗi mục dưới
đây phải chỉ ra được *bằng chứng* — một con số, một ADR, một kết quả POC, một bài đo.
### AG1 — Option sign-off · duyệt bởi **PO + Tech Lead**
- [ ] `CTX` có `DRV-nn` (driver) — mỗi driver ghi rõ **áp lực kinh doanh** đứng sau, không phải tính năng
- [ ] `CTX` có `CON-nn` (ràng buộc): ngân sách, deadline, cloud/stack bắt buộc, kỹ năng team, pháp lý
- [ ] `CTX` mô tả hiện trạng as-is: hệ thống, dữ liệu, tích hợp, hợp đồng vendor đang có
- [ ] `OPT` có **≥ 2 phương án** được chấm điểm theo cùng bộ tiêu chí, và **nêu rõ phương án bị loại + lý do**
- [ ] `TCO` có chi phí 3 năm: hạ tầng + license + vận hành + con người, theo ≥ 2 kịch bản tải
- [ ] `ARISK` có rủi ro kỹ thuật mức cao, mỗi cái có **người chịu trách nhiệm** và **cách hạ rủi ro**
- [ ] Rủi ro mức cao chưa chứng minh được ⇒ có **kế hoạch POC** kèm tiêu chí pass/fail
**Chặn:** chỉ có một phương án ("chúng ta sẽ dùng X") — đó không phải lựa chọn, đó là thói quen.
**Chặn:** ước lượng chỉ có effort dev, không có chi phí hạ tầng và vận hành.
### AG2 — Ready for Build · duyệt bởi **Tech Lead + Security + Ops/SRE**
- [ ] `ASR` liệt kê yêu cầu thực sự định hình kiến trúc, mỗi cái truy về `DRV` hoặc `QAS`
- [ ] `QAS` — mọi NFR đã lượng hoá: **kịch bản · con số · cách đo · ai đo**. Không còn NFR định tính
- [ ] `SAD` có sơ đồ C4 mức Context và Container, có deployment view, mỗi `CMP-nn` ghi rõ trách nhiệm
- [ ] `ADR-nnn` tồn tại cho **mọi quyết định đạt ngưỡng ở `decision-radar.md`**, mỗi cái nêu phương án đã loại
- [ ] `ICD` — mọi interface ra khỏi hệ thống có contract, owner, versioning policy, chế độ sync/async
- [ ] `DAT` — mỗi thực thể dữ liệu có **đúng một** chủ sở hữu; có phân loại PII và retention
- [ ] `SEC` — có threat model STRIDE cho luồng nhạy cảm; mô hình authn/authz đã chốt; Security ký
- [ ] `INF` — topology môi trường, HA/DR có **RTO/RPO bằng số**, chiến lược scale, observability
- [ ] `FAIL` — mỗi phụ thuộc ra ngoài process có failure mode, timeout, retry, fallback
- [ ] `sa-conformance` báo coverage `ASR → ADR/CMP` ≥ 100%
**Chặn:** còn `QAS` nào ghi "nhanh", "ổn định", "bảo mật" mà không có con số.
**Chặn:** còn interface nào không biết ai sở hữu.
**Đây là gate nghiêm nhất** — một quyết định sai lọt qua AG2 sẽ thành một cuộc viết lại.
### AG3 — Build conformance · duyệt bởi **Tech Lead + QA + SRE**
- [ ] `AGD` đã ban hành và có **reference implementation chạy được**, không chỉ văn bản
- [ ] `FIT` — mỗi ràng buộc kiến trúc quan trọng có một kiểm thử tự động, **đang xanh trên CI**
- [ ] `DREV` ghi mọi lần review kiến trúc, mỗi phát hiện có trạng thái đóng/mở
- [ ] Mọi `QAS` mức Must đã có **bài đo thực tế** chứng minh đạt (không phải ước lượng)
- [ ] `FAIL` đã được kiểm chứng: ít nhất các failure mode mức cao đã diễn tập (chaos/fault injection hoặc thủ công)
- [ ] `TDEBT` — mọi lệch so với kiến trúc đã ghi nhận, có chủ và có hạn, không có mục "sẽ sửa sau" trống
- [ ] `sa-conformance` báo coverage `QAS → bài đo` và `ràng buộc → FIT` ≥ 100% cho mức Must
**Chặn:** ràng buộc kiến trúc chỉ tồn tại trong văn bản, không có fitness function — theo `D8`
đó là khuyến nghị, không phải ràng buộc.
### AG4 — Operational review · duyệt bởi **PO + SRE + Enterprise Architect**
- [ ] `CONF` đối chiếu telemetry production với từng `QAS`: đạt / không đạt / chưa đo được
- [ ] Chi phí hạ tầng thực tế so với `TCO`, giải thích chênh lệch > 20%
- [ ] Mọi sự cố production trong kỳ truy được về một `ADR`, một `ASM`, hoặc ghi nhận là **điểm mù mới**
- [ ] `PMR` — đánh giá kiến trúc, liệt kê drift so với `SAD`
- [ ] `TRM` — roadmap kỹ thuật vòng sau, `TDEBT` đã xếp ưu tiên và đưa vào backlog
- [ ] `ADL` — mọi ADR có trạng thái đúng (Accepted / Superseded / Deprecated)
**Chặn:** không đo được `QAS` vì AG2 không định nghĩa cách đo — ghi nhận là bài học, không lấp liếm.
## 3. Ai làm gì
| Vai trò | Trách nhiệm trong pipeline SA |
|---|---|
| **Solution Architect** | Sở hữu toàn bộ artifact ở đây. Thiết kế, quyết định, ghi ADR, gác conformance |
| **PO / Khách hàng** | Quyết trade-off nghiệp vụ và ngân sách. Ký AG1, AG4 |
| **Tech Lead** | Ký AG1–AG3 về khả thi thi công. Phản biện thiết kế. Sở hữu chất lượng code |
| **Security** | Ký AG2. Có **quyền phủ quyết** threat model và mô hình authz |
| **Ops / SRE** | Ký AG2, AG3, AG4. Chốt HA/DR, observability, chi phí vận hành |
| **QA** | Ký AG3. Xác nhận `QAS` đo được và đã đo |
| **Enterprise Architect** | Ký AG4. Xác nhận không lệch chuẩn doanh nghiệp |
| **BA** | Cung cấp input nghiệp vụ. Không ký gate kiến trúc |
SA **không** thay PO quyết trade-off nghiệp vụ, **không** thay Security chấp nhận rủi ro,
**không** thay PM quản tiến độ — nhưng phải cung cấp đủ thông tin để cả ba ra quyết định.
## 4. Khớp với pipeline BA
Hai bộ chạy đan xen, không nối tiếp. Bảng này chốt thứ tự thật:
| Mốc | Điều kiện | Vì sao |
|---|---|---|
| SA GĐ1 bắt đầu | BA đã qua **G1** (có `BRIEF`, `GOAL`, `RQ`) | Không có driver thì không chấm được phương án |
| BA gate **G2** | SA đã qua **AG1** | Tech Lead ký G2 "khả thi kỹ thuật" dựa trên `OPT` + `ARISK` của SA |
| BA gate **G3** | SA đã qua **AG2** | `API` contract trong SRS phải khớp `ICD`; `NFR` của BA phải khớp `QAS` |
| BA gate **G4** | SA đã qua **AG3** | UAT không nên chạy trên kiến trúc chưa đo được NFR |
| BA gate **G5** | SA đã qua **AG4** | Benefit review nghiệp vụ đi cùng conformance kỹ thuật |
🔴 **Điểm giao thường bị bỏ:** BA viết `API contract đề xuất` ở GĐ3 và đánh dấu *"BA đề xuất —
chờ BE xác nhận"*. Người xác nhận đó chính là SA qua `ICD`. Không nối hai chỗ này thì SRS và
kiến trúc lệch nhau ngay từ ngày đầu.
## 5. Khi nào được bỏ giai đoạn
| Tình huống | Được bỏ | Bắt buộc giữ |
|---|---|---|
| Thêm màn hình trong module đã có, không đổi contract | GĐ1, GĐ2 | Rà `FIT` còn xanh, cập nhật `SAD` nếu thêm `CMP` |
| Thêm tính năng có endpoint mới, không đổi mô hình dữ liệu | GĐ1 | GĐ2 rút gọn: chỉ `ICD` + `QAS` liên quan |
| Đổi mô hình dữ liệu / thêm tích hợp ngoài / đổi hạ tầng | — | Đủ 4 giai đoạn |
| Hệ thống mới hoàn toàn | — | Đủ 4 giai đoạn |
| POC / thử nghiệm | GĐ3, GĐ4 | GĐ1 (để biết đang chứng minh gì), GĐ2 rút gọn |
Bỏ giai đoạn **phải ghi lý do vào `DEC-nn`** trong `00-index/`. Bỏ im lặng là nợ kiến trúc:
sáu tháng sau không ai biết hệ thống đang chạy trên giả định nào.
## 6. Vòng lặp ngược
Gate không phải một chiều. Bốn đường quay lui hợp lệ:
- **GĐ3 → GĐ2**: thi công phát hiện thiết kế không khả thi ⇒ `ADR` mới có `Supersedes: ADR-nnn`,
cập nhật `SAD`, không cần ký lại AG2 nếu không đụng `ICD`/`DAT`/`SEC`. Đụng ⇒ ký lại.
- **GĐ4 → GĐ2**: telemetry cho thấy `QAS` không đạt do thiết kế ⇒ mở `ADR` mới, đây là tín hiệu
AG2 đã ký trên ước lượng thay vì bài đo.
- **GĐ2 → GĐ1**: thiết kế chi tiết cho thấy phương án đã chọn quá đắt ⇒ quay lại `OPT`, ghi
`DEC-nn` giải thích vì sao đổi. Rẻ hơn nhiều so với phát hiện ở GĐ3.
- **Bất kỳ → GĐ1**: driver kinh doanh thay đổi ⇒ `CTX` phiên bản mới, rà lại toàn bộ `ADR`
có trạng thái `Accepted` xem còn đúng không.
## 7. Nhịp chạy đề xuất
Kiến trúc không phải một đợt làm rồi thôi. Nhịp tối thiểu cho một dự án 6 tháng:
| Việc | Tần suất |
|---|---|
| Cập nhật `ADL` + `DTM` (`sa-conformance`) | Cuối mỗi sprint |
| Design review các thay đổi chạm kiến trúc (`DREV`) | Theo yêu cầu, tối đa 2 ngày chờ |
| Rà `TDEBT`, xếp lại ưu tiên | Hai tuần một lần |
| Đo `QAS` mức Must trên môi trường gần production | Trước mỗi release |
| `CONF` đối chiếu telemetry | Hàng tháng sau go-live |
| `PMR` đánh giá kiến trúc | Mỗi quý hoặc sau mỗi sự cố nghiêm trọng |