--- name: sa-2-architecture description: Giai đoạn 2 của quy trình Solution Architect — định nghĩa kiến trúc tới mức dev thi công được. Dùng để lượng hoá NFR thành quality attribute scenario có con số và cách đo, xác định yêu cầu định hình kiến trúc (ASR), phân rã hệ thống thành component/service với sơ đồ C4, viết Architecture Decision Record, chốt contract cho mọi interface, thiết kế kiến trúc dữ liệu và ownership, dựng threat model STRIDE và mô hình phân quyền, thiết kế hạ tầng với HA/DR RTO/RPO, thiết kế đường lỗi (timeout, retry, circuit breaker, degradation), và lớp bàn giao dev - domain model/class diagram theo bounded context (DOM), contract máy đọc OpenAPI 3.1/AsyncAPI 3.0 cho mọi interface (CTR), schema vật lý đủ cột kèm DDL và migration có rollback (PDM). Mọi sơ đồ theo chuẩn Archify (spec JSON validate showcase + mermaid + bảng). Kích hoạt khi người dùng nói "thiết kế kiến trúc", "vẽ sơ đồ hệ thống", "C4", "viết ADR", "chốt NFR", "quality attribute", "thiết kế API contract", "OpenAPI", "AsyncAPI", "mô hình dữ liệu", "class diagram", "domain model", "aggregate", "thiết kế cơ sở dữ liệu", "schema vật lý", "DDL", "migration", "index", "threat model", "phân quyền kỹ thuật", "HA DR", "RTO RPO", "timeout retry", "circuit breaker", "chia service thế nào". Input là OPT đã qua AG1; output vào sa-output//02-architecture/ và phải qua Gate AG2 (Ready for Build) trước khi dev bắt đầu. --- # GĐ2 · ARCHITECTURE — Định nghĩa kiến trúc Mục tiêu duy nhất: **dev đọc xong thi công được, QA đọc xong biết đo cái gì, SRE đọc xong biết vận hành thế nào** — không ai phải quay lại hỏi "cái này để đâu, gọi ai, hỏng thì sao". Output: `ASR` · `QAS` · `SAD` · `ADR` · `DOM` · `ICD` · `CTR` · `DAT` · `PDM` · `SEC` · `INF` · `FAIL` trong `sa-output//02-architecture/` (+ `contracts/` file OpenAPI/AsyncAPI, `schema/` DDL + migration, `diagrams/` spec Archify + HTML) ## Bốn nguyên tắc bất di bất dịch 1. **Không bịa con số** — thiếu ⇒ `OQ-nnn` + `Confidence` 🔴, không điền giá trị "hợp lý". 2. **Không quyết định thay người có thẩm quyền** — trade-off nghiệp vụ là của PO, chấp nhận rủi ro bảo mật là của Security. Trình phương án kèm **hệ quả phương án ngược bằng số**. 3. **Mọi quyết định phải truy vết được** về `DRV`, `CON`, `ASR` hoặc `QAS`. Không nguồn ⇒ `ASM-nn`. 4. **Không ghi đè tài liệu đã qua gate** — sửa qua `ADR` mới có `Supersedes:`. Nạp thêm: `../sa-lifecycle/references/design-rules.md` (D1–D12) · `../sa-lifecycle/references/decision-radar.md` (ngưỡng ADR) · `../sa-lifecycle/references/artifact-map.md` §3–§4 (header, vòng đời ADR) · **`../ba-lifecycle/references/diagram-rules.md`** (chuẩn sơ đồ Archify — giai đoạn này vẽ nhiều nhất). 🔴 **Mọi sơ đồ theo chuẩn Archify** (`D4`, `W13`): spec JSON `diagrams/_..json` với `quality_profile: showcase` **+** mermaid có marker `` **+** bảng đi kèm. C4/deployment/ranh giới tin cậy → `architecture`; luồng chính → `sequence` (có nhánh lỗi); ownership dữ liệu → `dataflow`; ERD/class → `mermaid-only`. Một đường chính `emphasis`, ≤ 12 node, nhãn cạnh ghi giao thức + sync/async. Người điều phối chạy `archify validate/deliver` và `diagram-check.mjs`; không có Bash ⇒ ghi `humanInputNeeded`, không tự nhận "đã validate". ## 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ờ người dùng trả lời**: 1. **Input dùng được** — bảng `File/Nguồn | Vai trò | Độ tin cậy`. Ưu tiên: file trong hội thoại > `sa-output/…/01-context/` (`CTX`, `OPT`, `ARISK`) > `ba-output/…/02-analysis/` và `/03-specification/` (`BACKLOG`, `BR`, `RBAC`, `SRS`, `NFR`, `API`) > source code hiện có. 2. **Kiểm AG1** — `OPT` đã `✅ Baselined` và có `Approved by` chưa? Chưa ⇒ báo rõ: thiết kế trên phương án chưa chốt sẽ phải làm lại. Vẫn chạy được nếu người dùng muốn, nhưng toàn bộ `Confidence` là 🔴. 3. **Chọn phạm vi chạy** — làm cả 12 artifact hay chỉ một nhóm (`--focus`). Cả 12 là công việc nhiều tuần; hỏi rõ người dùng cần gì trước. Ba artifact **bàn giao thẳng cho dev** (`DOM`, `PDM`, `CTR`) chỉ có nghĩa khi `SAD`/`DAT`/`ICD` đã ổn định — hỏi người dùng có muốn làm ngay không. 4. **Cách hiểu bài toán** — 2–3 câu, kèm danh sách file định ghi ra. 5. **Hỏi người dùng** xác nhận bốn điểm trên. Bỏ bước dừng khi lệnh có `go`. ## Thực hiện — 12 hoạt động Thứ tự **không tuỳ ý**: 1→2→3 bắt buộc trước; 4–8 chạy song song được; 9 chạy liên tục; 10–12 (`DOM` · `CTR` · `PDM`) là **lớp bàn giao dev**, chạy sau artifact nguồn của nó (`DOM` sau `SAD`+`DAT` · `CTR` sau `ICD` · `PDM` sau `DAT`+`DOM`). Với `--focus`, vẫn phải đọc output của các bước trước, không được bỏ qua. ``` qas → asr → sad ─┬─ icd ──→ ctr ├─ dat ──→ dom ──→ pdm ├─ sec · inf · fail └─ adr (liên tục) ``` ### 1 — Lượng hoá NFR thành `QAS` *(`--focus qas`)* Điền `templates/quality-scenarios.md`. **Đây là bước quyết định chất lượng cả GĐ2.** Không có con số thì không có kiến trúc, chỉ có sơ đồ hộp. Mỗi `QAS-nnn` phải đủ **sáu phần**: ``` QAS-004 | Thông lượng đối soát Nguồn kích thích : Job đối soát nửa đêm Kích thích : 1,2 triệu bản ghi POS của một ngày Môi trường : Giờ thấp điểm, 1 node worker, DB không có tải khác Phản hồi : Đối soát xong và sinh báo cáo chênh lệch Đo lường : ≤ 45 phút (p95 trong 30 lần chạy) Đo bằng cách nào : Bài đo `perf/settlement-batch.js` trên môi trường stg với bộ dữ liệu sinh 1,2M bản ghi · chạy trước mỗi release Ai đo : QA + SRE Nguồn : DRV-02, BR-014 · Mức: Must ``` Rà đủ **bảy nhóm thuộc tính**, nhóm nào không áp dụng phải ghi "không áp dụng vì …": | Nhóm | Câu hỏi lượng hoá | Bẫy | |---|---|---| | Hiệu năng | p50/p95/p99 của thao tác nào, ở tải nào | Chỉ ghi trung bình — trung bình che giấu đuôi | | Thông lượng | Bao nhiêu đơn vị/giây, đỉnh gấp mấy lần | Không phân biệt trung bình và đỉnh | | Sẵn sàng | % uptime ⇒ **quy ra ngân sách lỗi phút/tháng** | 99.9% nghe giống 99.99% nhưng chênh 10× | | Mở rộng | Tải tăng bao nhiêu trong bao lâu, scale bằng cách nào | Thiết kế cho tải hôm nay | | Bảo mật | Mối đe doạ nào, biện pháp gì, kiểm chứng thế nào | Ghi "bảo mật" như một mục | | Bảo trì | Onboard bao lâu, sửa một bug mất bao lâu | Không đo được ⇒ bỏ, đừng ghi định tính | | Quan sát được | Sự cố phát hiện sau bao lâu, truy nguyên mất bao lâu | Quên hẳn nhóm này | 🔴 **Ngân sách lỗi là cách duy nhất làm SLA có nghĩa.** 99.9%/tháng = 43 phút; 99.99% = 4,3 phút. Hỏi PO: *"Chấp nhận hệ thống dừng 43 phút/tháng hay 4 phút/tháng?"* — câu hỏi đó quyết định kiến trúc HA và chi phí, và PO trả lời được. "Sẵn sàng cao" thì không ai trả lời được. Mỗi `QAS` gắn mức **Must / Should / Could**. `Must` là "không đạt thì không được go-live". ### 2 — Chưng cất `ASR` *(`--focus asr`)* Điền `templates/quality-scenarios.md` §ASR. `ASR` là **số ít** yêu cầu thực sự định hình kiến trúc — thường 8–15 mục cho một hệ thống trung bình, không phải 200. Một yêu cầu là `ASR` khi có ≥ 1 điều: - Ép một cấu trúc: *"phải xử lý được khi hệ thống POS ngoài mất kết nối 4 giờ"* ⇒ ép có hàng đợi - Ép một ràng buộc không đảo ngược: *"dữ liệu cá nhân phải nằm trong lãnh thổ Hàn Quốc"* - Ép một đánh đổi: *"số dư ví phải luôn chính xác"* ⇒ loại eventual consistency ở nhánh đó - Có `QAS` mức Must đứng sau Mỗi `ASR-nnn` ghi: phát biểu · nguồn (`DRV`/`CON`/`QAS`/`BR`) · **ép ra cấu trúc gì** · `ADR` nào hiện thực hoá nó. ### 3 — Phân rã hệ thống và viết `SAD` *(`--focus sad`)* Điền `templates/sad.md`. Bốn việc, theo thứ tự: **a. Chọn kiểu kiến trúc** — và viết `ADR` cho nó. Không chọn theo xu hướng; chọn theo `ASR` và `CON-04` (số người, ai vận hành). Bảng quyết định nhanh: | Tín hiệu | Nghiêng về | |---|---| | ≤ 2 team, chưa rõ ranh giới nghiệp vụ | Modular monolith *(mặc định hợp lý, đừng ngại)* | | Nhiều team release độc lập, ranh giới đã rõ và ổn định | Service tách theo bounded context | | Tải rất lệch giữa các phần, cần scale riêng | Tách đúng phần lệch, giữ phần còn lại chung | | Xử lý nền, chịu được trễ, cần chống mất việc | Thêm hàng đợi / event-driven cho nhánh đó | | Đội vận hành nhỏ, không có kinh nghiệm phân tán | **Đừng phân tán.** Chi phí vận hành là thật | **b. Vẽ C4 mức Context và Container** — bắt buộc cả hai, mỗi sơ đồ có legend và khai báo mức (quy tắc `D4`). Mức Component chỉ vẽ cho container phức tạp nhất, không vẽ cho tất cả. **c. Bảng `CMP-nn`** — mỗi container/component ghi: trách nhiệm (một câu) · **cái nó KHÔNG làm** · dữ liệu nó sở hữu · interface vào/ra · team sở hữu · `ASR` nào ép ra nó. Cột "cái nó KHÔNG làm" là cột ngăn phình chức năng. Component không có ranh giới sẽ nuốt dần mọi thứ. **d. Deployment view** — cái gì chạy ở đâu, mấy bản, ranh giới mạng, ranh giới tin cậy. ### 4 — Interface catalog `ICD` *(`--focus icd`)* Điền `templates/interface-catalog.md`. Mọi lời gọi **vượt ranh giới container** phải có một dòng `IF-nnn`. Bảy cột bắt buộc mỗi interface: hai đầu · giao thức · sync/async · **ai sở hữu contract** · đường dẫn contract thật (OpenAPI/AsyncAPI/proto) · chính sách versioning · hành vi khi đầu kia hỏng. Ba thứ phải chốt **một lần cho toàn hệ thống**, ghi thành `ADR`: | # | Vấn đề | Vì sao chốt sớm | |---|---|---| | 1 | Số lớn (id, tiền) truyền dạng gì | Vượt `2^53` thì JavaScript làm tròn sai — id 19 chữ số hỏng im lặng | | 2 | Thời gian: định dạng, múi giờ | Trộn local time và UTC là bug không ai tìm ra | | 3 | Phân trang: offset hay cursor, có `hasNext` không | Offset không có `hasNext` ⇒ nút "trang sau" hỏng | 🔴 **Đối chiếu với `API` của bộ BA.** BA viết contract đề xuất và đánh dấu *"chờ BE xác nhận"* — `ICD` chính là chỗ xác nhận. Mọi endpoint trong `API` phải có `IF-nnn`; lệch nhau ⇒ ghi `OQ`, `ICD` thắng, và **báo lại cho BA cập nhật SRS**. ### 5 — Kiến trúc dữ liệu `DAT` *(`--focus dat`)* Điền `templates/data-architecture.md`. Nguyên tắc `D7`: mỗi thực thể có **đúng một** chủ. Sáu mục bắt buộc: 1. **Bảng ownership** — thực thể × hệ thống chủ × bản sao ở đâu × độ trễ tối đa cho phép 2. **Mô hình dữ liệu mức khái niệm** — thực thể và quan hệ, chưa phải schema 3. **Consistency** — chỗ nào cần mạnh, chỗ nào chấp nhận eventual và **trễ tối đa bao lâu** 4. **Giao dịch xuyên service** — saga / outbox / 2PC / không có, kèm cách bù trừ khi lỗi 5. **Phân loại dữ liệu** — công khai / nội bộ / cá nhân (PII) / nhạy cảm, kèm retention và cách xoá theo yêu cầu pháp lý 6. **Migration** — nguồn, cách đối chiếu, **cách rollback**, cách chạy song song hai hệ thống 🔴 **Migration không có rollback là migration một chiều.** Trước khi cắt chuyển phải trả lời được: nếu sau 2 giờ phát hiện sai thì quay lại thế nào, dữ liệu phát sinh trong 2 giờ đó xử lý ra sao. ### 6 — Kiến trúc bảo mật `SEC` *(`--focus sec`)* Điền `templates/security-architecture.md`. Bốn mục: **a. Threat model STRIDE** cho mỗi luồng nhạy cảm (đăng nhập, thanh toán, dữ liệu cá nhân, thao tác quản trị). Mỗi `THR-nn`: mối đe doạ · thành phần bị nhắm · biện pháp · **cách kiểm chứng biện pháp có hiệu lực**. **b. Mô hình xác thực** — cơ chế, nơi giữ trạng thái, thời hạn, cách thu hồi, cách xoay khoá. **c. Mô hình phân quyền** — RBAC/ABAC, **chỗ ra quyết định** (gateway hay service), và bảng map `ROLE-nn` của bộ BA xuống quyền kỹ thuật. Mỗi ô ghi rõ có ràng buộc dữ liệu không (ví dụ "chỉ cửa hàng mình phụ trách"). **d. Dữ liệu nhạy cảm** — phân loại, mã hoá at-rest/in-transit, quản lý secret, audit log ghi gì. 🔴 **Security có quyền phủ quyết AG2.** Đưa họ vào từ đầu bước này, không phải lúc trình gate. Phát hiện muộn nhất và đau nhất luôn đến từ đây. ### 7 — Hạ tầng & triển khai `INF` *(`--focus inf`)* Điền `templates/infrastructure-design.md`. Năm mục: 1. **Topology môi trường** — dev/stg/prod khác nhau chỗ nào, và **chỗ khác nhau đó có làm sai lệch kết quả đo `QAS` không** 2. **HA** — chịu được mất gì (một node / một AZ / một vùng), cơ chế chuyển đổi, thời gian chuyển 3. **DR** — **RTO và RPO bằng số**, cách khôi phục, **lần diễn tập gần nhất là khi nào** 4. **Scale** — dọc/ngang, ngưỡng kích hoạt, giới hạn trên, thời gian scale mất bao lâu 5. **Observability** — log/metric/trace ghi gì, giữ bao lâu, ai đọc, **chi phí bao nhiêu** 🔴 **RTO/RPO chưa diễn tập là RTO/RPO trên giấy.** Ghi rõ ngày diễn tập gần nhất; chưa từng diễn tập ⇒ `Confidence` 🔴 và tạo `ARISK`. `INF` phải **khớp số với `TCO`** (quy tắc `D9`). Lệch ⇒ một trong hai sai. ### 8 — Đường lỗi `FAIL` *(`--focus fail`)* Điền `templates/failure-mode.md`. **Đây là phần phân biệt SA giỏi và SA vẽ sơ đồ**, và là phần bị bỏ nhiều nhất. Mỗi phụ thuộc vượt ranh giới process (HTTP, DB, cache, queue, file, hệ thống ngoài) phải trả lời **bốn câu** của quy tắc `D6`, và ghi bảng: | Phụ thuộc | Timeout | Retry | Idempotent | Hết retry thì sao | Người dùng thấy gì | `QAS` liên quan | |---|---|---|---|---|---|---| Bốn câu bắt buộc mỗi phụ thuộc: 1. **Nó chậm thì sao?** — nguy hiểm hơn hỏng, vì nó giữ tài nguyên và lan ngược lên 2. **Nó hỏng thì sao?** — 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?** — retry storm, thundering herd, cần backpressure không Cộng ba cơ chế phải quyết định cho toàn hệ thống: circuit breaker (ngưỡng mở/đóng) · backoff (kiểu, jitter) · bulkhead (tách pool tài nguyên). ### 9 — Viết `ADR` — chạy liên tục Điền `templates/adr.md`. Mỗi quyết định đạt ngưỡng ở `../sa-lifecycle/references/decision-radar.md` ⇒ một file `adr/ADR-_.md`. Quy tắc `D1`: một ADR, một quyết định. Quy tắc `D3`: bắt buộc nêu phương án đã loại. Điểm radar ≥ 8 ⇒ **không được chuyển `Accepted` khi chưa có POC hoặc bài đo**. Giữ ở `Proposed` và tạo mục trong `ARISK`. ### 10 — Domain model `DOM` *(`--focus dom`)* Điền `templates/domain-model.md`. Cần `SAD` (`CMP`), `DAT` §1 (ownership) và `BR` của BA. **Vì sao cần:** `DAT` nói ai sở hữu dữ liệu, `PDM` nói bảng trông thế nào — không có `DOM`, dev tự suy aggregate từ bảng, transaction boundary lệch nhau, invariant bị kiểm ở ba chỗ hoặc không chỗ nào. Bốn việc: 1. **Bảng bounded context × aggregate** — mỗi aggregate là một ranh giới transaction; entity thuộc đúng một aggregate; sang aggregate khác chỉ giữ **id**. 2. **Class diagram mỗi bounded context** (`classDiagram`, `mermaid-only`, ≤ 12 class) — chỉ thuộc tính nghiệp vụ và phương thức đổi trạng thái; DTO/repository thuộc `AGD`. Kèm bảng: class · invariant (`BR`) · kiểm ở phương thức nào · ai được gọi · bảng `PDM`. 3. **Snapshot hay tham chiếu sống** — giá, tên, địa chỉ lúc giao dịch là snapshot; ghi từng trường. 4. **Domain event** — tên · aggregate phát · payload tối thiểu (không PII) · người nhận · contract `CTR`. 🔴 Invariant không truy về `BR-nnn` ⇒ hoặc BA thiếu rule (báo `baSyncIssues`), hoặc SA đang bịa nghiệp vụ. Không được tự thêm rule. ### 11 — Contract máy đọc `CTR` *(`--focus ctr`)* Điền `templates/contract-index.md` **và sinh file thật** trong `02-architecture/contracts/`: `openapi/.yaml` (OpenAPI 3.1, từ `templates/contracts/openapi.template.yaml`), `asyncapi/-events.yaml` (AsyncAPI 3.0), `partners/.yaml` (mirror tài liệu đối tác, ghi nguồn). Ba ràng buộc: 1. **Mọi `IF-nnn`** trong `ICD` §2 có `x-if` ở ≥ 1 operation/channel; **mọi endpoint** trong `API` của BA có `operationId`; **mọi mã lỗi** `E-…` của SRS §4.1 có trong `x-error-codes` và schema `Error`. 2. **Ba quy ước `ICD` §1 nằm trong `components/`** và được `$ref`: số lớn `type: string`, thời gian `format: date-time`, phân trang theo `ADR`. Lỗi nghiệp vụ là 4xx. 3. Mỗi operation ≥ 1 example thành công + 1 lỗi; `operationId` duy nhất toàn dự án. Sau đó **sửa `ICD` cột "Contract ở đâu"** trỏ tới file + `operationId` thật. Còn "dự kiến" ⇒ AG2 chặn. 🔴 **Không tự viết contract thay đối tác ngoài.** Chưa có tài liệu VNPay/GHN ⇒ `ARISK` + `OQ`, file `partners/` để trống có ghi chú, không bịa schema. Người điều phối chạy `spectral lint` (nếu có) hoặc `node .claude/skills/sa-2-architecture/scripts/contract-check.mjs --dir --icd --srs --api ` và chép kết quả vào `CTR` §4. ### 12 — Schema vật lý `PDM` *(`--focus pdm`)* Điền `templates/physical-data-model.md` **và sinh DDL thật** trong `02-architecture/schema//`: `V001__init_.sql` + `V001__….down.sql` (+ `seed/R__reference_data.sql`). Cần `DAT`, `DOM`, bảng field `FLD-*` của SRS PART 2, `SEC` §5. Sáu ràng buộc: 1. **Mọi thực thể `DAT` §1 → ≥ 1 bảng `TBL-nnn`**; bảng không truy về thực thể là thừa hoặc thiếu mô hình. 2. **Mọi cột đủ bốn ô**: kiểu có độ dài/độ chính xác · Null · Default · Nguồn (`FLD`/`BR`). Độ dài `varchar` khớp bảng field của SRS theo code point — UI và DB chặn cùng một ngưỡng. 3. **Cột PII gắn cờ** và có dòng ở `SEC` §5 (mã hoá, che, retention). 4. **Index truy về truy vấn** ở `DAT` §7.1; truy vấn không có index ⇒ thiếu; index không có truy vấn ⇒ bỏ. 5. **Migration có down**, chạy được từ CSDL rỗng; công cụ migration chốt bằng `ADR`; migration đổi dữ liệu ghi thêm cách đối chiếu và ngưỡng chênh lệch. 6. Quy ước đặt tên, kiểu id, thời gian UTC, tiền, soft delete chốt **một lần** ở §1. 🔴 **Bảng field của BA và cột của SA lệch nhau là bug chắc chắn** — kiểm §7 hai chiều, lệch ⇒ `OQ` và báo BA (`baSyncIssues`), không im lặng chọn một bên. ## Trước khi kết thúc In bốn thứ: **① Bảng tự chấm Gate AG2** (`../sa-lifecycle/references/workflow.md` §2) dạng ☐/✅. **② Checklist D1–D12** dạng ☐/✅. **③ Bảng đối chiếu với bộ BA** — `NFR`↔`QAS`, `API`↔`ICD`/`CTR`, `RBAC`↔`SEC`, `BR`↔`ADR`/`DOM`, `FLD`↔`PDM`. Mọi chỗ lệch phải liệt kê kèm hành động ("BA cập nhật SRS §… theo `IF-007`"). **④ Danh sách `OQ` mở** kèm người phải trả lời và **hệ quả nếu trả lời ngược**. **⑤ Checklist sơ đồ** (`diagram-rules.md` §8) và danh sách spec `diagrams/*.json` cần validate/deliver; với `ctr`/`pdm`: danh sách file contract/DDL cần lint và chạy thử. Rồi nhắc người dùng: AG2 cần **Tech Lead + Security + Ops/SRE ký**. ## Bẫy thường gặp **Vẽ sơ đồ trước khi lượng hoá NFR.** Sơ đồ vẽ trước sẽ được bảo vệ bằng mọi giá sau đó. Làm `QAS` trước — con số sẽ tự loại phần lớn phương án và sơ đồ trở nên dễ vẽ. **Chia service theo tầng thay vì theo nghiệp vụ.** "Service API, service business, service data" là monolith bị cắt sai chỗ: mọi thay đổi nghiệp vụ đều phải sửa cả ba, deploy cả ba. Cắt theo bounded context. **Sơ đồ đẹp, mũi tên không nhãn.** Mũi tên không ghi giao thức và sync/async không mang thông tin. Kiểm tra: che phần chữ đi, sơ đồ còn nói được gì không? **Bỏ qua đường lỗi vì "sẽ xử lý lúc code".** Lúc code, mỗi dev xử lý một kiểu, và không ai biết tổng thể hệ thống hỏng thế nào. Đây là nguồn của phần lớn sự cố production. **Ghi ADR sau khi đã code xong.** ADR viết sau là biên bản hợp thức hoá, không phải quyết định. Giá trị của ADR nằm ở chỗ nó buộc phải nêu phương án đã loại **trước khi** cam kết. **Thiết kế cho tải chưa bao giờ tới.** `QAS` nói tải × 3 trong 2 năm thì thiết kế cho × 3, đừng thiết kế cho × 100. Ghi vào "Ngoài phạm vi": *"Kiến trúc này không nhắm tới tải × 100; ngưỡng phải xét lại là …"*.