@educa-corp/sdd-framework 0.6.0 → 0.7.0
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.
- package/bin/gate-trace.js +25 -2
- package/bin/index.js +32 -5
- package/bin/lint-trace.js +41 -0
- package/bin/self-check.js +430 -3
- package/bin/trace-schema.json +391 -30
- package/core/FRAMEWORK_VERSION +1 -1
- package/{commands/extend-prd.md → core/commands/amend-prd.md} +205 -173
- package/core/commands/dev-run-test.md +47 -9
- package/core/commands/extend-prd.md +39 -12
- package/core/commands/generate-bdd.md +43 -4
- package/core/commands/generate-code.md +33 -0
- package/core/commands/generate-tech-docs.md +34 -2
- package/core/commands/qc-run-test.md +29 -3
- package/core/commands/refine-prd.md +13 -2
- package/core/commands/review-context.md +43 -8
- package/core/commands/sync.md +105 -1
- package/core/commands/validate-traces.md +284 -11
- package/core/rules/workflow.md +34 -0
- package/core/steps/context-loader.md +26 -5
- package/core/templates/feature.template +1 -1
- package/docs/02-concepts/architecture.md +36 -0
- package/docs/04-reference/commands.md +148 -134
- package/docs/04-reference/trace-schema.md +39 -0
- package/docs/explain/02b-extend-prd.md +1 -1
- package/docs/explain/02c-amend-prd.md +152 -0
- package/docs/explain/28-sync.md +25 -0
- package/docs/explain/README.md +136 -135
- package/package.json +1 -8
- package/commands/debug.md +0 -529
- package/commands/debug.tmpl +0 -260
- package/commands/define-product.md +0 -438
- package/commands/define-product.tmpl +0 -225
- package/commands/dev-gen-test.md +0 -700
- package/commands/dev-gen-test.tmpl +0 -490
- package/commands/dev-run-test.md +0 -435
- package/commands/dev-run-test.tmpl +0 -225
- package/commands/dev-smoke-test.md +0 -374
- package/commands/dev-smoke-test.tmpl +0 -217
- package/commands/extend-prd.tmpl +0 -273
- package/commands/fix-bug.md +0 -519
- package/commands/fix-bug.tmpl +0 -197
- package/commands/generate-architecture.md +0 -354
- package/commands/generate-architecture.tmpl +0 -197
- package/commands/generate-bdd.md +0 -923
- package/commands/generate-bdd.tmpl +0 -590
- package/commands/generate-code.md +0 -859
- package/commands/generate-code.tmpl +0 -649
- package/commands/generate-design-spec.md +0 -737
- package/commands/generate-design-spec.tmpl +0 -524
- package/commands/generate-prd.md +0 -722
- package/commands/generate-prd.tmpl +0 -226
- package/commands/generate-spec-manifest.md +0 -321
- package/commands/generate-spec-manifest.tmpl +0 -164
- package/commands/generate-tech-docs.md +0 -920
- package/commands/generate-tech-docs.tmpl +0 -273
- package/commands/learn.md +0 -399
- package/commands/learn.tmpl +0 -130
- package/commands/map-testids.md +0 -238
- package/commands/map-testids.tmpl +0 -81
- package/commands/propose-scenario.md +0 -359
- package/commands/propose-scenario.tmpl +0 -202
- package/commands/qc-analyze.md +0 -269
- package/commands/qc-analyze.tmpl +0 -112
- package/commands/qc-design-test.md +0 -226
- package/commands/qc-design-test.tmpl +0 -69
- package/commands/qc-plan.md +0 -206
- package/commands/qc-plan.tmpl +0 -49
- package/commands/qc-report.md +0 -217
- package/commands/qc-report.tmpl +0 -60
- package/commands/qc-review.md +0 -210
- package/commands/qc-review.tmpl +0 -53
- package/commands/qc-run-test.md +0 -326
- package/commands/qc-run-test.tmpl +0 -116
- package/commands/refine-prd.md +0 -653
- package/commands/refine-prd.tmpl +0 -281
- package/commands/report-bug.md +0 -305
- package/commands/report-bug.tmpl +0 -148
- package/commands/review-code.md +0 -415
- package/commands/review-code.tmpl +0 -146
- package/commands/review-context.md +0 -902
- package/commands/review-context.tmpl +0 -530
- package/commands/review-tech-docs.md +0 -561
- package/commands/review-tech-docs.tmpl +0 -404
- package/commands/setup-ai-first.md +0 -602
- package/commands/setup-ai-first.tmpl +0 -450
- package/commands/sync.md +0 -430
- package/commands/sync.tmpl +0 -429
- package/commands/update-framework.md +0 -203
- package/commands/update-framework.tmpl +0 -202
- package/commands/validate-traces.md +0 -1077
- package/commands/validate-traces.tmpl +0 -920
- package/hooks/data-guard.js +0 -232
- package/hooks/settings.json +0 -19
- package/modules/android-compose/module.yaml +0 -13
- package/modules/android-compose/stack-profile.yaml +0 -57
- package/modules/angular/architecture-snippets/component-patterns.md +0 -187
- package/modules/angular/module.yaml +0 -6
- package/modules/angular/stack-profile.yaml +0 -38
- package/modules/context-engineering/architecture-snippets/context-design.md +0 -119
- package/modules/context-engineering/module.yaml +0 -9
- package/modules/context-engineering/stack-profile.yaml +0 -61
- package/modules/dotnet/architecture-snippets/clean-arch.md +0 -160
- package/modules/dotnet/module.yaml +0 -6
- package/modules/dotnet/stack-profile.yaml +0 -50
- package/modules/flutter/module.yaml +0 -14
- package/modules/flutter/stack-profile.yaml +0 -59
- package/modules/golang/architecture-snippets/domain-layout.md +0 -283
- package/modules/golang/module.yaml +0 -6
- package/modules/golang/stack-profile.yaml +0 -40
- package/modules/ios-swiftui/module.yaml +0 -13
- package/modules/ios-swiftui/stack-profile.yaml +0 -55
- package/modules/java-spring/architecture-snippets/layered-arch.md +0 -201
- package/modules/java-spring/module.yaml +0 -15
- package/modules/java-spring/stack-profile.yaml +0 -28
- package/modules/nextjs/architecture-snippets/app-router-patterns.md +0 -269
- package/modules/nextjs/module.yaml +0 -14
- package/modules/nextjs/stack-profile.yaml +0 -74
- package/modules/nuxt/module.yaml +0 -14
- package/modules/nuxt/stack-profile.yaml +0 -58
- package/modules/phaser-game/architecture-snippets/phaser-scene-patterns.md +0 -646
- package/modules/phaser-game/module.yaml +0 -15
- package/modules/phaser-game/stack-profile.yaml +0 -90
- package/modules/php-laravel/architecture-snippets/service-repository.md +0 -302
- package/modules/php-laravel/module.yaml +0 -15
- package/modules/php-laravel/stack-profile.yaml +0 -56
- package/modules/qc-playwright/stack-profile.yaml +0 -66
- package/modules/react/architecture-snippets/hooks-query-patterns.md +0 -254
- package/modules/react/module.yaml +0 -14
- package/modules/react/stack-profile.yaml +0 -63
- package/modules/react-native/module.yaml +0 -14
- package/modules/react-native/stack-profile.yaml +0 -56
- package/modules/vue/module.yaml +0 -14
- package/modules/vue/stack-profile.yaml +0 -65
- package/rules/data-protection.md +0 -80
- package/rules/workflow.md +0 -99
- package/skills/code/SKILL.md +0 -19
- package/skills/code/SKILL.tmpl +0 -19
- package/skills/debug/SKILL.md +0 -19
- package/skills/debug/SKILL.tmpl +0 -19
- package/skills/design-spec/SKILL.md +0 -11
- package/skills/design-spec/SKILL.tmpl +0 -11
- package/skills/discovery/SKILL.md +0 -14
- package/skills/discovery/SKILL.tmpl +0 -14
- package/skills/prd/SKILL.md +0 -19
- package/skills/prd/SKILL.tmpl +0 -19
- package/skills/qc/qa-analyst/DOC_GAPS.template.md +0 -63
- package/skills/qc/qa-analyst/acceptance-criteria.md +0 -60
- package/skills/qc/qa-analyst/business-rules.md +0 -59
- package/skills/qc/qa-analyst/data-flow.md +0 -64
- package/skills/qc/qa-analyst/spec-breakdown.md +0 -61
- package/skills/qc/qa-designer/e2e/journey.md +0 -41
- package/skills/qc/qa-designer/exploratory/charter.md +0 -68
- package/skills/qc/qa-designer/exploratory/explore-to-functional.md +0 -43
- package/skills/qc/qa-designer/functional/api.md +0 -45
- package/skills/qc/qa-designer/functional/gui-feature.md +0 -46
- package/skills/qc/qa-designer/functional/gui-screen.md +0 -52
- package/skills/qc/qa-designer/integration/api.md +0 -42
- package/skills/qc/qa-designer/integration/db.md +0 -39
- package/skills/qc/qa-designer/integration/gui.md +0 -40
- package/skills/qc/qa-designer/integration/kafka.md +0 -40
- package/skills/qc/qa-designer/non-functional.md +0 -40
- package/skills/qc/qa-planner/test-plan.md +0 -120
- package/skills/qc/qa-reviewer/script/e2e.md +0 -87
- package/skills/qc/qa-reviewer/script/exploratory.md +0 -45
- package/skills/qc/qa-reviewer/script/functional.md +0 -101
- package/skills/qc/qa-reviewer/script/integration.md +0 -91
- package/skills/qc/qa-reviewer/script/non-functional.md +0 -126
- package/skills/qc/qa-reviewer/test-case/e2e.md +0 -73
- package/skills/qc/qa-reviewer/test-case/exploratory.md +0 -43
- package/skills/qc/qa-reviewer/test-case/functional.md +0 -76
- package/skills/qc/qa-reviewer/test-case/integration.md +0 -69
- package/skills/qc/qa-reviewer/test-case/non-functional.md +0 -73
- package/skills/qc/qa-runner/e2e.md +0 -49
- package/skills/qc/qa-runner/exploratory/session.md +0 -36
- package/skills/qc/qa-runner/functional/api.md +0 -35
- package/skills/qc/qa-runner/functional/gui-feature.md +0 -51
- package/skills/qc/qa-runner/functional/gui-screen.md +0 -55
- package/skills/qc/qa-runner/integration.md +0 -47
- package/skills/qc/qa-runner/non-functional.md +0 -49
- package/skills/qc/qa-runner/report/report.md +0 -37
- package/skills/setup-ai-first/SKILL.md +0 -19
- package/skills/setup-ai-first/SKILL.tmpl +0 -19
- package/skills/spec/SKILL.md +0 -19
- package/skills/spec/SKILL.tmpl +0 -19
- package/skills/test/SKILL.md +0 -18
- package/skills/test/SKILL.tmpl +0 -18
- package/steps/business-language.md +0 -56
- package/steps/capture-lesson.md +0 -112
- package/steps/context-loader.md +0 -406
- package/steps/gate.md +0 -151
- package/steps/report-footer.md +0 -125
- package/steps/review-fanout.md +0 -159
- package/steps/spawn-agent.md +0 -129
- package/steps/trace-mirror.md +0 -53
- package/templates/README.md +0 -70
- package/templates/architecture.template.md +0 -394
- package/templates/ci/trace-gate.yml +0 -146
- package/templates/design-spec.template.md +0 -217
- package/templates/feature.template +0 -123
- package/templates/hooks/pre-push +0 -61
- package/templates/platform-guide.template.md +0 -145
- package/templates/prd.template.md +0 -283
- package/templates/product-definition.template.md +0 -188
- package/templates/project-context.yaml +0 -212
- package/templates/tech-design.template.md +0 -490
|
@@ -1,561 +0,0 @@
|
|
|
1
|
-
# /review-tech-docs — Review Technical Design Document
|
|
2
|
-
|
|
3
|
-
**Chế độ phân tích READ-ONLY — ghi file findings, KHÔNG sửa target.**
|
|
4
|
-
**Dùng `--resume` để áp dụng các finding được chấp nhận.**
|
|
5
|
-
|
|
6
|
-
## Gate
|
|
7
|
-
|
|
8
|
-
*Checkpoint: **không chặn** — read-only (ghi findings vào .agent/review/). Gate Bước 3 bỏ qua CHECKPOINT (Bước 3a).*
|
|
9
|
-
|
|
10
|
-
# Gate — Quy trình vào chuẩn cho mọi lệnh
|
|
11
|
-
|
|
12
|
-
Mọi lệnh PHẢI chạy gate này trước khi thực thi phần logic riêng của nó.
|
|
13
|
-
|
|
14
|
-
## Bước 0 — Kiểm tra chế độ Sub-Agent
|
|
15
|
-
|
|
16
|
-
Trước tiên, kiểm tra xem `$ARGUMENTS` có phải là payload JSON từ một orchestrator hay không:
|
|
17
|
-
|
|
18
|
-
1. Thử parse `$ARGUMENTS` dưới dạng JSON.
|
|
19
|
-
2. Nếu parse thành công **và** chứa `"_agent_mode": true`:
|
|
20
|
-
- **Bỏ qua hoàn toàn Bước 1, 2 và 3 của Gate này.**
|
|
21
|
-
- Đặt target file = `payload.target_file`
|
|
22
|
-
- Đặt loaded context = `payload.context` (KHÔNG chạy context-loader.md)
|
|
23
|
-
- Đặt phạm vi UC = `payload.uc_id` (chỉ xử lý UC này)
|
|
24
|
-
- Đặt line range = `payload.uc_section` (chỉ đọc đúng section đó của PRD)
|
|
25
|
-
- Đặt dimension = `payload.dimension` nếu có (lệnh review per-UC: chỉ review đúng lăng kính này)
|
|
26
|
-
- Đi thẳng tới phần logic riêng của lệnh.
|
|
27
|
-
3. Nếu `$ARGUMENTS` không phải JSON hoặc không có `_agent_mode` → tiếp tục sang Bước 1 (chế độ thường).
|
|
28
|
-
|
|
29
|
-
## Bước 0-B — Ghi nhận Model *(KHÔNG chặn)*
|
|
30
|
-
|
|
31
|
-
*Bỏ qua nếu `_agent_mode: true` (sub-agent — orchestrator đã ghi nhận rồi).*
|
|
32
|
-
|
|
33
|
-
Ghi lại **model mà bạn — agent đang chạy lệnh này — thực sự đang dùng**, rồi mang nó vào
|
|
34
|
-
dòng `Model:` của report cuối (xem `report-footer`). Nếu bạn biết mình **không** phải một
|
|
35
|
-
model Opus, gắn thêm cảnh báo ngay ở dòng đó.
|
|
36
|
-
|
|
37
|
-
**KHÔNG hỏi người dùng. KHÔNG chờ. KHÔNG dừng.**
|
|
38
|
-
|
|
39
|
-
> **Vì sao bước này từng là prompt chặn, và vì sao bỏ (GAPS-v3 G41):** bản cũ hiện khối
|
|
40
|
-
> `⚙️ MODEL CHECK` rồi chờ `Y/S/N`. Ba vấn đề cùng chỉ một hướng:
|
|
41
|
-
> **(1)** nó hỏi người dùng thứ mà **agent đã biết chính xác**;
|
|
42
|
-
> **(2)** câu trả lời **không kiểm chứng được** — gõ `Y` xong vẫn đang chạy Haiku thì không
|
|
43
|
-
> gì phát hiện;
|
|
44
|
-
> **(3)** **cả `Y` lẫn `S` đều đi tiếp** — cách duy nhất để nó dừng là tự nguyện gõ `N`.
|
|
45
|
-
> Tức nó **không chặn được ai**, mà tốn một lần chặn ở **mọi** lệnh. Một feature đi hết
|
|
46
|
-
> pipeline dùng 20 lệnh; 30/32 lệnh chạy gate. Hai mươi lần bấm cho một tín hiệu tự-khai
|
|
47
|
-
> không kiểm chứng được — và chính cái giá đó làm mòn CHECKPOINT ở Bước 3, cổng có giá trị thật.
|
|
48
|
-
>
|
|
49
|
-
> Khai báo trong report **mạnh hơn** hỏi: đúng nguồn (agent, không phải người), và nằm
|
|
50
|
-
> **cạnh kết quả** để cân nhắc, thay vì nằm trước khi có kết quả để bấm cho xong.
|
|
51
|
-
|
|
52
|
-
**Vẫn khuyến nghị Opus:** phân tích spec, review kiến trúc và sinh code đòi hỏi suy luận sâu;
|
|
53
|
-
model nhỏ hơn dễ bỏ sót edge case và vi phạm kiến trúc. Đổi: `/model` → chọn Opus.
|
|
54
|
-
|
|
55
|
-
## Bước 1 — Xác định Target File
|
|
56
|
-
|
|
57
|
-
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
58
|
-
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
59
|
-
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
60
|
-
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
61
|
-
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
62
|
-
- **Lệnh tech-docs** — target là tech-doc **gộp cấp PRD** `{TICKET-ID}-tech-design.md` (MỘT doc phủ nhiều UC; danh sách UC nằm ở `@trace.ucs`). Vì tên file mang `{TICKET-ID}` chứ **không** mang `{UC-ID}`, phải tách trước khi glob:
|
|
63
|
-
- `$ARGUMENTS` là **UC-ID** (`{TICKET-ID}-UC{N}`) → lấy `{TICKET-ID}` = phần **trước** `-UC`, rồi glob `{specs_dir}/{domain}/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
64
|
-
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
65
|
-
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
66
|
-
- Vẫn không khớp → glob rộng `{specs_dir}/*/*/tech-docs/*tech-design*.md` rồi liệt kê để người dùng chọn.
|
|
67
|
-
*(Đừng glob `{UC-ID}*-tech-design*.md` — nó nở thành `FT-001-UC1*-tech-design*.md` và **không bao giờ** khớp `FT-001-tech-design.md`.)*
|
|
68
|
-
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
69
|
-
|
|
70
|
-
Khi một file khớp: đặt nó làm target **và** ghi lại `domain` + `prd_slug` từ path của nó (theo quy tắc trích xuất trong `context-loader.md` Bước 1 — `prd_slug` = segment đầu tiên sau `{specs_dir}/{domain}/`). Mọi path mà lệnh đọc/ghi về sau (BDD/tech-docs/design-spec/trace cùng cấp) đều dùng **`prd_slug` đã phân giải đó**, nên tất cả artifact nằm chung một feature package. Nếu nhiều file khớp (vd: nhiều platform), chọn theo platform/scope của lệnh hoặc liệt kê ra và hỏi.
|
|
71
|
-
3. Nếu `$ARGUMENTS` rỗng hoặc không tìm thấy file khớp:
|
|
72
|
-
- Liệt kê các file trong thư mục liên quan của lệnh này (vd: `specs/*/*/*.md` — file PRD ở gốc mỗi feature folder — cho lệnh PRD, `specs/*/*/bdd/**/*.feature` cho lệnh BDD).
|
|
73
|
-
- Hiển thị danh sách cho người dùng và hỏi: "Bạn muốn làm việc với file nào? (Nhập số thứ tự hoặc tên file)"
|
|
74
|
-
- Chờ người dùng chọn rồi mới tiếp tục.
|
|
75
|
-
|
|
76
|
-
## Bước 2 — Chạy Context Loader
|
|
77
|
-
|
|
78
|
-
Nạp toàn bộ context của dự án bằng cách làm theo quy trình trong `steps/context-loader.md`.
|
|
79
|
-
Lưu toàn bộ context đã nạp vào bộ nhớ để dùng xuyên suốt phiên làm việc của lệnh.
|
|
80
|
-
|
|
81
|
-
## Bước 3 — CHECKPOINT
|
|
82
|
-
|
|
83
|
-
*Bỏ qua nếu `_agent_mode: true`.*
|
|
84
|
-
|
|
85
|
-
### 3a — Lệnh này có phải chặn không?
|
|
86
|
-
|
|
87
|
-
| Mức | Lệnh nào | `--yes` bỏ qua được? |
|
|
88
|
-
|---|---|:---:|
|
|
89
|
-
| **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
|
|
90
|
-
| **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
|
|
91
|
-
| **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
|
|
92
|
-
|
|
93
|
-
`--yes` trong `$ARGUMENTS` → bỏ qua CHECKPOINT mức *chặn thường*. (Bước 1 đã tách mọi token
|
|
94
|
-
`--` khỏi phần resolve target, nên cờ này không ảnh hưởng việc tìm file.) Mở đường chạy
|
|
95
|
-
headless: `claude -p "/generate-code UC1 --yes"`.
|
|
96
|
-
|
|
97
|
-
> **KHÔNG tự suy mức từ bảng này.** Mỗi lệnh **tự khai** mức của nó ở một dòng `*Checkpoint: …*`
|
|
98
|
-
> ngay dưới `## Gate` của chính nó — đọc dòng đó, đừng suy diễn. Bảng trên chỉ giải thích ba mức
|
|
99
|
-
> **nghĩa là gì**.
|
|
100
|
-
> Nguồn máy đọc: `bin/trace-schema.json` → `gate.checkpoint_levels`; `self-check` **R11** fail
|
|
101
|
-
> build nếu nhãn trong file lệnh lệch với schema, hoặc nếu một lệnh `hard`/`none` thiếu nhãn.
|
|
102
|
-
> *(Lệnh không có dòng nào = mức **chặn thường**, mặc định.)*
|
|
103
|
-
|
|
104
|
-
> **Mức *không chặn* là thực thi đúng miễn trừ mà `rules/workflow.md` đã cấp từ trước** —
|
|
105
|
-
> trước G41 file đó viết *"read-only commands may skip CHECKPOINT"* còn gate thì luôn đòi.
|
|
106
|
-
> Hai file cùng được nạp vào mọi lệnh mà nói ngược nhau; agent theo cái nào là tuỳ lúc.
|
|
107
|
-
|
|
108
|
-
### 3b — In gì
|
|
109
|
-
|
|
110
|
-
**KHÔNG lặp lại những gì `[CTX LOADED]` vừa in.** Recap của context-loader (Bước 7) đã hiện
|
|
111
|
-
Stack · Platform · Layers · CLAUDE.md · Dict · Entities · Lessons · Service · Status ngay phía
|
|
112
|
-
trên. CHECKPOINT chỉ thêm **một** thông tin mới là `Target`.
|
|
113
|
-
|
|
114
|
-
**Mọi thứ sạch** — recap báo `Status: FULL`, không cờ nào bật → in đúng hai dòng:
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
CHECKPOINT — Target: {resolved file path}
|
|
118
|
-
Tiếp tục? (Y/N)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Có bất thường** → thêm một dòng cho **mỗi** trạng thái, nặng nhất lên đầu:
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
CHECKPOINT
|
|
125
|
-
🔴 Service : unresolved — {lý do context-loader đã ghi}
|
|
126
|
-
⚠️ CLAUDE.md: service overlay THIẾU — dùng root (code sinh ra có thể sai stack)
|
|
127
|
-
⚠️ Target : resolve bằng wildcard — {n} file khớp, chọn {file}
|
|
128
|
-
⚠️ Module : not configured — code sinh ra sẽ dùng default
|
|
129
|
-
Status : PARTIAL — thiếu: {danh sách}
|
|
130
|
-
Target : {resolved file path}
|
|
131
|
-
Tiếp tục? (Y/N)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 3c — Cờ nào bật, cờ nào KHÔNG
|
|
135
|
-
|
|
136
|
-
Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader đã tính rồi** — không phát minh
|
|
137
|
-
điều kiện mới, chỉ mang thứ đang bị giấu lên chỗ người dùng phải quyết định:
|
|
138
|
-
|
|
139
|
-
| Bật cờ khi | Nguồn | Mức |
|
|
140
|
-
|---|---|:---:|
|
|
141
|
-
| `active_service = unresolved` | context-loader Bước 2b/2c/Fallback | 🔴 |
|
|
142
|
-
| `Status = MINIMAL` | recap Bước 7 | 🔴 |
|
|
143
|
-
| `Status = PARTIAL` | recap Bước 7 | ⚠️ |
|
|
144
|
-
| CLAUDE.md thiếu, hoặc service overlay thiếu | context-loader Bước 3 | ⚠️ |
|
|
145
|
-
| Target resolve qua wildcard, hoặc nhiều file khớp mà lệnh tự chọn | Bước 1 ở trên | ⚠️ |
|
|
146
|
-
| `module` không cấu hình | recap Bước 7 | ⚠️ |
|
|
147
|
-
|
|
148
|
-
**KHÔNG bật cờ cho:** `Lessons: chưa có` · `Dict: missing` · `Entities: missing`. Đó là
|
|
149
|
-
*"dự án chưa điền"*, không phải *"có gì đó sai"* — chúng ở lại trong recap.
|
|
150
|
-
|
|
151
|
-
> **Nguyên tắc một câu:** cờ dành cho thứ **framework không chắc chắn hoặc đã phải đoán**,
|
|
152
|
-
> không dành cho thứ **người dùng chưa làm**. Đẩy hết mọi thứ lên thì CHECKPOINT lại đầy như
|
|
153
|
-
> cũ, và ta quay về đúng chỗ xuất phát: một cổng luôn giống nhau thì bị lướt qua.
|
|
154
|
-
|
|
155
|
-
### 3d — Chờ trả lời
|
|
156
|
-
|
|
157
|
-
- "Y" → tiếp tục sang các bước riêng của lệnh.
|
|
158
|
-
- "N" → dừng, hỏi người dùng muốn thay đổi gì.
|
|
159
|
-
- Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
|
|
160
|
-
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là **file tech-design gộp của PRD** `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` — MỘT doc full-stack phủ mọi UC của PRD (không còn per-UC / per-platform). Review chạy trên cả doc; findings gom theo từng UC (đọc §10 UC Coverage để biết finding thuộc UC nào).
|
|
164
|
-
Nếu `$ARGUMENTS` chứa `--resume` → bỏ qua sang Resume Mode bên dưới.*
|
|
165
|
-
|
|
166
|
-
## Context
|
|
167
|
-
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
168
|
-
rồi mới tiếp tục phần bên dưới.
|
|
169
|
-
|
|
170
|
-
Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, guardrail từ
|
|
171
|
-
`project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
|
|
172
|
-
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Nạp tài liệu Review
|
|
177
|
-
|
|
178
|
-
Sau khi nạp context nền, đọc các thứ sau theo thứ tự:
|
|
179
|
-
|
|
180
|
-
1. **Tech-doc target** — đọc đầy đủ. Trích từ header:
|
|
181
|
-
- `@trace.ucs` → danh sách UC mà doc phủ (đối chiếu §10 UC Coverage)
|
|
182
|
-
- `@trace.domain` → domain
|
|
183
|
-
- `@trace.prd` → TICKET-ID của PRD nguồn
|
|
184
|
-
- `@trace.platforms` → các platform có mặt (system / web / app)
|
|
185
|
-
- `@trace.status` → status hiện tại (draft / in-review / approved)
|
|
186
|
-
|
|
187
|
-
2. **Các file BDD nguồn** — nạp **mọi** feature của PRD này: `{paths.specs_dir}/{domain}/{prd-slug}/bdd/**/*.feature` (system/web/app). Đây là nguồn đối chiếu cho T3/T7 — mỗi UC trong doc phải trace về scenario BDD tương ứng.
|
|
188
|
-
|
|
189
|
-
3. **Index endpoint cho T4 (KHÔNG nạp full doc khác)** — trích danh sách endpoint (§4.1) + entity chính của doc target. T4 sẽ `grep` các path đó trong `{paths.tech_docs_dir}/{domain}/*/tech-docs/*-tech-design.md` (các PRD khác) và chỉ nạp đoạn liên quan **khi có va chạm** — xem T4.
|
|
190
|
-
|
|
191
|
-
4. **Tham chiếu kiến trúc** — xác nhận lại CLAUDE.md §2: thứ tự layer, quy tắc kiến trúc.
|
|
192
|
-
|
|
193
|
-
5. **Core entities** — đã nạp trong context (Bước 6 của context-loader).
|
|
194
|
-
|
|
195
|
-
6. **PRD nguồn — §Business Rules (cho T8)** — nạp file PRD `{paths.specs_dir}/{domain}/{prd-slug}/{TICKET-ID}-{prd-slug}.md`, trích bảng Business Rule/Business Logic của các UC mà doc phủ. Đây là nguồn đối chiếu-ngược của **T8** (BR nào yêu cầu nguồn/sự kiện/generic-contract mà doc bỏ sót). Chỉ đọc §BR + §AC liên quan — KHÔNG cần toàn PRD.
|
|
196
|
-
|
|
197
|
-
Suy ra tên file findings (per-PRD):
|
|
198
|
-
`{paths.refinement_dir}/{TICKET-ID}-tech-review-findings.yaml`
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
## Review Dimensions
|
|
203
|
-
|
|
204
|
-
### T1 — Architecture Alignment *(luôn CRITICAL nếu vi phạm)*
|
|
205
|
-
|
|
206
|
-
Đối chiếu design đề xuất với quy tắc CLAUDE.md §2:
|
|
207
|
-
|
|
208
|
-
| Loại vi phạm | Severity |
|
|
209
|
-
|----------------|----------|
|
|
210
|
-
| Controller gọi Repository trực tiếp (skip layer) | Critical |
|
|
211
|
-
| Business logic trong Controller hoặc DTO | Critical |
|
|
212
|
-
| Pattern bị cấm từ §3 | Critical |
|
|
213
|
-
| Phụ thuộc đi ngược upstream (Service → Controller DTO) | Critical |
|
|
214
|
-
| Annotation transaction sai layer | Major |
|
|
215
|
-
| Thiếu tách lớp (không có Facade khi kiến trúc yêu cầu) | Major |
|
|
216
|
-
|
|
217
|
-
Với mỗi finding:
|
|
218
|
-
```
|
|
219
|
-
Component: {tên class hoặc method}
|
|
220
|
-
Violates: "{rule text}" (CLAUDE.md §2)
|
|
221
|
-
Fix: {layer/component nào nên sở hữu cái này}
|
|
222
|
-
```
|
|
223
|
-
→ **Không auto-fix.** Người phải quyết định fix cấu trúc. Bắt buộc note trong Review Board.
|
|
224
|
-
|
|
225
|
-
### T2 — Entity Consistency
|
|
226
|
-
|
|
227
|
-
Dùng catalog core-entities đã nạp:
|
|
228
|
-
|
|
229
|
-
| Vấn đề | Severity | Auto-fixable? |
|
|
230
|
-
|-------|----------|---------------|
|
|
231
|
-
| Entity được nhắc nhưng không có trong core-entities.md | Major | No — người confirm là DTO hay domain entity |
|
|
232
|
-
| Tên field khác core-entities.md | Major | Yes — đổi về canonical |
|
|
233
|
-
| Quan hệ được mô tả khác đi | Major | No — người quyết định |
|
|
234
|
-
| Entity mới được đưa ra nhưng chưa có trong core-entities.md | Minor | No — thêm vào core-entities trước |
|
|
235
|
-
|
|
236
|
-
### T3 — BDD Traceability
|
|
237
|
-
|
|
238
|
-
Đối chiếu với **mọi** feature BDD của PRD (system/web/app). Với mỗi UC trong §10 UC Coverage, kiểm tra design khớp scenario **2 chiều**.
|
|
239
|
-
|
|
240
|
-
> ⚠ **SC scope theo platform:** `{UC}-SC{N}` chỉ unique trong (UC × platform) — `system UC1-SC1` và `web UC1-SC1` là **hai scenario khác nhau**. Khi đối chiếu, match SC **trong đúng lane platform** (system SC ↔ system BDD, web SC ↔ web BDD, app SC ↔ app BDD). KHÔNG so chéo platform. §5 phải để mỗi SC trong lane 5.A/5.B/5.C của nó; §10 mỗi dòng có cột Platform.
|
|
241
|
-
|
|
242
|
-
| Vấn đề | Severity | Auto-fixable? |
|
|
243
|
-
|-------|----------|---------------|
|
|
244
|
-
| Tech-doc đề xuất behavior không có trong scenario BDD nào (cùng platform) | Major | No — tạo scenario trước |
|
|
245
|
-
| Tech-doc mâu thuẫn một scenario BDD | Critical | No — giải quyết conflict trước |
|
|
246
|
-
| Scenario (platform, SC) không có design tương ứng (thiếu ở §5 lane hoặc §10) | Minor | Yes — thêm design note còn thiếu |
|
|
247
|
-
| §10 UC Coverage sót một (platform, SC) đã có BDD | Major | Yes — thêm dòng coverage + section tương ứng |
|
|
248
|
-
| SC ghi trong §5/§10 **không kèm platform** (bare `UC1-SC1`) → nhập nhằng | Major | Yes — gắn platform vào SC ref |
|
|
249
|
-
|
|
250
|
-
### T3b — BDD Freshness *(tech-doc còn khớp BDD hiện tại không)*
|
|
251
|
-
|
|
252
|
-
*T3 kiểm **nội dung** khớp không. T3b kiểm **độ tươi**: doc này dựng từ BDD version nào, BDD giờ ở version nào. Đây là lỗ hổng cũ — không lệnh nào so hai giá trị này, nên tech-doc âm thầm lỗi thời mà vẫn giữ `@trace.status: approved`.*
|
|
253
|
-
|
|
254
|
-
Header tech-doc mang `@trace.bdd_versions` (**số nhiều** — map theo platform, vd `system=1.5, web=1.9`). Với **mỗi** entry trong map, đọc `@trace.bdd_version` (**số ít**, scalar) của `.feature` tương ứng (`{paths.specs_dir}/{domain}/{prd-slug}/bdd/{platform}/{TICKET-ID}-UC*.feature`):
|
|
255
|
-
|
|
256
|
-
| Điều kiện | Severity | Auto-fixable? |
|
|
257
|
-
|---|---|---|
|
|
258
|
-
| Map khớp `.feature` | *(sạch)* | — |
|
|
259
|
-
| `.feature` **mới hơn** map | **Major** | **No** — cần người review §4/§4.5 rồi bump `@trace.revision` |
|
|
260
|
-
| Platform có `.feature` nhưng **vắng** trong map | **Major** | Yes — thêm entry sau khi xác nhận §4 đã phủ platform đó |
|
|
261
|
-
| Map có platform mà **không** có `.feature` | Minor | Yes — xoá entry (BDD đã bỏ platform đó) |
|
|
262
|
-
|
|
263
|
-
Prose của finding "`.feature` mới hơn": *"tech-doc dựng từ BDD {platform}=v{old}, BDD giờ v{new} — §4 contract có thể đã lệch so với behavior đã chốt. Review lại §4.1–4.3 (+ §4.5 nếu FE) rồi bump `@trace.revision`."*
|
|
264
|
-
|
|
265
|
-
> **Vì sao là Major chứ không phải Minor:** `/generate-code` DS3 thấy tech-doc `@trace.status: approved` + 0 blocker-GAP thì lấy shape DTO/endpoint/error ở §4 **nguyên văn** làm contract "đã chốt". Contract dựng từ BDD cũ sẽ lan **thẳng** vào code, không cảnh báo. Đây là ca tệ hơn drift-về-code vì nó sai từ nguồn.
|
|
266
|
-
|
|
267
|
-
**Cổng chặn `approved` (chặn MỀM — đồng bộ với DS3/DS4 của `/generate-code`, không chặn cứng):** còn ≥1 finding T3b Major ở trạng thái `open` → khi người dùng định đặt `@trace.status: approved`, hiện CHECKPOINT:
|
|
268
|
-
```
|
|
269
|
-
⚠️ {n} platform có BDD mới hơn bản mà tech-doc này dựng từ:
|
|
270
|
-
{platform}: doc dựng từ v{old} · .feature giờ v{new}
|
|
271
|
-
Duyệt doc bây giờ = chốt một contract có thể đã lệch behavior.
|
|
272
|
-
Vẫn đặt approved? (Y/N)
|
|
273
|
-
```
|
|
274
|
-
Chỉ tiếp khi `Y`. *(Khác GATE của §12 blocker-GAP — cái đó chặn cứng. Ở đây chặn mềm vì BDD có thể bump vì lý do không chạm contract, vd sửa từ ngữ step; người review là người biết.)*
|
|
275
|
-
|
|
276
|
-
### T4 — Cross-PRD Endpoint Conflict Check *(targeted, load-on-hit)*
|
|
277
|
-
|
|
278
|
-
Mỗi PRD giờ chỉ 1 doc → xung đột TRONG doc đã do **T5** lo. T4 chỉ soi xung đột **liên-PRD** theo cách rẻ, KHÔNG nạp full doc khác:
|
|
279
|
-
|
|
280
|
-
1. Trích danh sách endpoint (method + path, §4.1) + entity chính của doc target.
|
|
281
|
-
2. `grep` từng path/entity đó trong `{paths.tech_docs_dir}/{domain}/*/tech-docs/*-tech-design.md` (trừ target) — chỉ đọc dòng match.
|
|
282
|
-
3. **Chỉ khi có va chạm** (một path/entity xuất hiện ở doc PRD khác) → nạp đúng đoạn §4.1/§4.2 (hoặc §3) của doc đó để so shape.
|
|
283
|
-
|
|
284
|
-
| Vấn đề *(chỉ khi grep dính)* | Severity | Auto-fixable? |
|
|
285
|
-
|-------|----------|---------------|
|
|
286
|
-
| Cùng endpoint path, request/response khác shape giữa 2 PRD | Critical | No — người giải quyết |
|
|
287
|
-
| Cùng service method với behavior khác | Critical | No — người giải quyết |
|
|
288
|
-
| Status transition của cùng entity khác nhau giữa các doc PRD | Critical | No — người giải quyết |
|
|
289
|
-
| Trách nhiệm chồng lấn (2 PRD cùng nhận sở hữu 1 endpoint/logic) | Major | No — người giải quyết |
|
|
290
|
-
|
|
291
|
-
Không có va chạm grep → T4 pass, không nạp thêm gì.
|
|
292
|
-
|
|
293
|
-
### T5 — Internal Consistency
|
|
294
|
-
|
|
295
|
-
Trong nội bộ tech-doc:
|
|
296
|
-
|
|
297
|
-
| Check | Severity | Auto-fixable? |
|
|
298
|
-
|-------|----------|---------------|
|
|
299
|
-
| Sequence diagram thể hiện flow khác phần mô tả viết | Major | No |
|
|
300
|
-
| API spec return type khác code sketch | Major | Yes — căn chỉnh cái này theo cái kia |
|
|
301
|
-
| Section tham chiếu một component/concept không bao giờ được định nghĩa sau đó | Minor | Yes — thêm định nghĩa |
|
|
302
|
-
| Assumption được nêu nhưng không design nào xử lý nó | Minor | Yes — thêm note hoặc bỏ assumption |
|
|
303
|
-
|
|
304
|
-
### T6 — Structural Completeness
|
|
305
|
-
|
|
306
|
-
Kiểm tra tất cả section chuẩn có mặt và không rỗng:
|
|
307
|
-
|
|
308
|
-
| Section | Missing severity |
|
|
309
|
-
|---------|-----------------|
|
|
310
|
-
| Header (`@trace.prd`, `@trace.ucs`, `@trace.domain`, `@trace.status`) | Major |
|
|
311
|
-
| Overview / Context | Major |
|
|
312
|
-
| Architecture Decision kèm lý do | Major |
|
|
313
|
-
| Component Diagram hoặc Layer Description | Major |
|
|
314
|
-
| Sequence Diagram hoặc Flow Steps | Major |
|
|
315
|
-
| API Contract (nếu hướng HTTP) | Major |
|
|
316
|
-
| Data Model Changes (nếu entity đổi) | Major |
|
|
317
|
-
| Error Handling Strategy | Major |
|
|
318
|
-
| Open Questions / Assumptions | Minor |
|
|
319
|
-
|
|
320
|
-
→ Mọi finding section-thiếu T6 đều **auto-fixable**: AI thêm skeleton section kèm prompt.
|
|
321
|
-
|
|
322
|
-
### T7 — Cross-Team API Contract Review
|
|
323
|
-
|
|
324
|
-
*Chỉ áp dụng khi TẤT CẢ điều sau đúng:*
|
|
325
|
-
*1. Doc có phần backend/API (`@trace.platforms` gồm `system`, tức PRD có System BDD).*
|
|
326
|
-
*2. Header tech-doc KHÔNG có `@trace.api_source: existing`.*
|
|
327
|
-
|
|
328
|
-
*Nếu `@trace.api_source: existing` → **skip T7 hoàn toàn**. Contract đã được PO xác định trong PRD — không có API design mới để đồng thuận.*
|
|
329
|
-
|
|
330
|
-
Dimension này đảm bảo team FE, App, và BE đều đồng thuận API contract trước khi bắt đầu implement.
|
|
331
|
-
|
|
332
|
-
**Step 1 — Check status sign-off trong header tech-doc:**
|
|
333
|
-
|
|
334
|
-
Đọc block `@trace.sign_off` trong header tech doc. Nếu vắng → thêm như một finding (auto-fixable: thêm skeleton).
|
|
335
|
-
|
|
336
|
-
```yaml
|
|
337
|
-
# @trace.sign_off:
|
|
338
|
-
# be_team: pending # author — set "done" khi BE hài lòng với design
|
|
339
|
-
# fe_team: pending # FE/Web — phải confirm contract khớp expectation của web BDD
|
|
340
|
-
# app_team: pending # App — phải confirm contract khớp expectation của app BDD (nếu áp dụng)
|
|
341
|
-
# sa: pending # SA/Tech Lead — approval cuối
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
**Step 2 — Contract vs BDD cross-check:**
|
|
345
|
-
|
|
346
|
-
Nạp web và app BDD cho TICKET-ID này (từ `{paths.specs_dir}/{domain}/{prd-slug}/bdd/web/` và `{paths.specs_dir}/{domain}/{prd-slug}/bdd/app/` trong spec submodule hoặc spec repo).
|
|
347
|
-
|
|
348
|
-
Với mỗi platform BDD, kiểm tra API contract của tech doc có thoả các mệnh đề `Then` của BDD không:
|
|
349
|
-
|
|
350
|
-
| Check | Severity |
|
|
351
|
-
|---|---|
|
|
352
|
-
| Field response trong API contract không phủ những gì web BDD `Then` mong | Critical |
|
|
353
|
-
| Field response trong API contract không phủ những gì app BDD `Then` mong | Critical |
|
|
354
|
-
| Shape error response không khớp những gì các platform BDD mong | Major |
|
|
355
|
-
| Annotation `@system.resolution` của System BDD mâu thuẫn với design API contract | Critical |
|
|
356
|
-
|
|
357
|
-
**Step 3 — Report sign-off pending:**
|
|
358
|
-
|
|
359
|
-
Sau review, liệt kê các sign-off còn `pending`:
|
|
360
|
-
|
|
361
|
-
```
|
|
362
|
-
⏳ Sign-off pending trước khi tech docs được approve:
|
|
363
|
-
fe_team — team FE/Web phải confirm API contract khớp expectation web BDD
|
|
364
|
-
app_team — team App phải confirm API contract khớp expectation app BDD
|
|
365
|
-
sa — SA/Tech Lead approval cuối
|
|
366
|
-
|
|
367
|
-
Khi thu đủ sign-off → cập nhật @trace.sign_off trong header tech doc, rồi chạy lại /review-tech-docs.
|
|
368
|
-
Tech docs không thể set "approved" khi còn bất kỳ sign-off bắt buộc nào pending.
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
**Approval gate:**
|
|
372
|
-
- Nếu `be_team: done` VÀ `fe_team: done` VÀ `app_team: done` (hoặc N/A) VÀ `sa: done` → tech docs có thể set `approved`
|
|
373
|
-
- Ngược lại → `@trace.status` giữ `in-review` — `generate-code` bị chặn
|
|
374
|
-
|
|
375
|
-
### T8 — Reconciliation & Completeness
|
|
376
|
-
|
|
377
|
-
*Bắt lỗi "đóng kín" + "coverage ≠ completeness" — cái mà Self-Review Gate của `generate-tech-docs` (Cổng 1/4) đáng lẽ chặn. Đối chiếu doc với PRD Business Rules, core-entities, và seam UC anh em (đọc-ngược có giới hạn — không kéo toàn bộ BDD của PRD).*
|
|
378
|
-
|
|
379
|
-
> **Nguyên tắc:** "mọi SC được map" (T3) là *cần*, KHÔNG *đủ*. T8 fail một doc dù T3 pass, nếu nó thiếu/mâu thuẫn ở tầng rộng hơn lát BDD.
|
|
380
|
-
|
|
381
|
-
> **Thuật ngữ cross-service (đọc nhanh):** *dedup* = cùng event tới ≥2 lần chỉ xử lý 1 lần (idempotency key) · *ordering* = event đúng thứ tự phát ra, hoặc bên nhận chịu được lệch · *ack path* = bên nhận xong báo lại bên gửi để ngừng gửi lại (thiếu → mất event / gửi lại vô hạn) · *cross-field invariant* = ràng buộc luôn đúng giữa nhiều field (vd `paid ⇒ paid_at ≠ null`).
|
|
382
|
-
|
|
383
|
-
| Vấn đề | Severity | Auto-fixable? |
|
|
384
|
-
|---|---|---|
|
|
385
|
-
| Enum/trạng thái dùng trong doc nhưng **không có producer** (không luồng nào sinh giá trị đó) | Major | No — người xác định owner |
|
|
386
|
-
| Cột/field ghi nhưng **không có writer** (không luồng nào set) | Major | No |
|
|
387
|
-
| **PRD Business Rule** yêu cầu một nguồn/sự kiện mà doc **bỏ sót** | Critical | No — thêm design trước |
|
|
388
|
-
| PRD-BR đưa **hợp đồng chung** (generic envelope) nhưng doc tự làm **typed-per-thing** | Major | No |
|
|
389
|
-
| **Leak boundary** — kéo định danh nội bộ của service khác vào lookup của mình thay vì abstraction tầng mình | Major | No |
|
|
390
|
-
| Cross-service **không tách** bên nào own dedup/ordering, hoặc thiếu **ack path** | Major | No |
|
|
391
|
-
| **Cross-field invariant** giữa các field/entity không được nêu | Minor | Yes — thêm note |
|
|
392
|
-
|
|
393
|
-
### T9 — Gap Honesty & Constants
|
|
394
|
-
|
|
395
|
-
*Bắt "bịa lặng" + "hard-code" + "happy-only" — cái mà Self-Review Gate Cổng 2/3/4 đáng lẽ chặn.*
|
|
396
|
-
|
|
397
|
-
| Vấn đề | Severity | Auto-fixable? |
|
|
398
|
-
|---|---|---|
|
|
399
|
-
| Policy/type/giá trị nêu **như fact không nguồn** (bịa), lẽ ra phải là `[GAP]`/`[ASSUMPTION]` | Critical | No — người xác nhận nguồn hoặc giữ GAP |
|
|
400
|
-
| Chỗ đáng lẽ khai gap lại **bỏ trắng / chép hình dạng ở boundary** | Major | No |
|
|
401
|
-
| **Constant/literal inline** như luật (chưa vào catalog / chưa đặt tên) | Major | Yes — tách vào bảng constants/enum |
|
|
402
|
-
| **Happy-only** — API/flow thiếu partial + error case + rollback | Major | No — thiết kế nhánh lỗi trước |
|
|
403
|
-
| **Hàm cốt lõi** được đặt tên nhưng **không tả** điều kiện chọn / nhánh / kết quả (dừng ở tên hàm + sequence-diagram) | Major | No — cần người bổ sung impl-spec |
|
|
404
|
-
| BDD **mâu thuẫn** invariant kiến trúc mà doc **lặng chép** thay vì ghi conflict + escalate PO sửa `.feature` | Critical | No — escalate, không tự quyết |
|
|
405
|
-
| Citation/tham chiếu **không resolve** (trỏ tới thứ không được định nghĩa) / policy nêu như fact | Minor | Yes — thêm định nghĩa hoặc bỏ ref |
|
|
406
|
-
| `[GAP]`/`[ASSUMPTION]` inline **mồ côi** — không có dòng ở §12 GAP Register (hoặc dòng §12 không có marker inline) | Major | Yes — đồng bộ register ↔ marker |
|
|
407
|
-
| §12 GAP Register còn **🔴 blocker `open`** (chưa đóng) | Critical | No — chặn approve tới khi owner đóng. *(GAP đã khai đúng KHÔNG tính là "bịa" — đây là finding về gate, không phạt trung thực)* |
|
|
408
|
-
|
|
409
|
-
> **T8/T9 phản chiếu Self-Review Gate** (4 cổng) của `generate-tech-docs` và `project-lessons` **L-012** — nếu gen bỏ lọt, cổng review bắt lại. Đặt trong nguồn `.tmpl` nên bền qua `/update-framework`.
|
|
410
|
-
|
|
411
|
-
---
|
|
412
|
-
|
|
413
|
-
## Ghi File Findings
|
|
414
|
-
|
|
415
|
-
Sau khi chạy hết các check, ghi findings vào `{paths.refinement_dir}/{TICKET-ID}-tech-review-findings.yaml`:
|
|
416
|
-
|
|
417
|
-
```yaml
|
|
418
|
-
source_file: "{absolute path to tech-doc}"
|
|
419
|
-
prd_id: "{TICKET-ID}"
|
|
420
|
-
ucs: [{UC-ID list phủ bởi doc}]
|
|
421
|
-
domain: "{domain}"
|
|
422
|
-
generated_at: "{ISO datetime}"
|
|
423
|
-
review_type: "tech-design"
|
|
424
|
-
status: "pending_review"
|
|
425
|
-
is_system_bdd: {true | false} # true nếu doc có phần backend (@trace.platforms gồm system)
|
|
426
|
-
|
|
427
|
-
sign_off: # chỉ có khi is_system_bdd: true
|
|
428
|
-
be_team: pending # đọc từ @trace.sign_off trong header tech-doc
|
|
429
|
-
fe_team: pending
|
|
430
|
-
app_team: pending # "n/a" nếu dự án không có platform app
|
|
431
|
-
sa: pending
|
|
432
|
-
sign_off_gate: blocked # blocked | ready — "ready" chỉ khi tất cả bắt buộc là "done"
|
|
433
|
-
|
|
434
|
-
findings:
|
|
435
|
-
- id: "F001"
|
|
436
|
-
check_id: "T1" # T1 · T2 · T3 · T3b · T4 · T5 · T6 · T7 · T8 · T9
|
|
437
|
-
severity: "critical" # critical | major | minor
|
|
438
|
-
section: "{section heading hoặc tên component nơi tìm thấy lỗi}"
|
|
439
|
-
uc_id: "{UC-ID}" # UC mà finding này thuộc về (một trong `ucs`; đọc §10 để xác định)
|
|
440
|
-
quote: "{trích đoạn nguyên văn copy CHÍNH XÁC từ tech-doc tại vị trí lỗi, ≤120 ký tự}"
|
|
441
|
-
finding: "{mô tả rõ ràng vi phạm hoặc gap}"
|
|
442
|
-
suggestion: "{bản fix cụ thể — AI áp dụng khi --resume nếu được chấp nhận}"
|
|
443
|
-
auto_fixable: false # true = AI áp dụng được; false = người phải ghi quyết định trong note
|
|
444
|
-
status: "pending" # pending | accepted | modified | rejected | deferred
|
|
445
|
-
|
|
446
|
-
summary:
|
|
447
|
-
total_findings: {N}
|
|
448
|
-
by_severity: { critical: {N}, major: {N}, minor: {N} }
|
|
449
|
-
auto_fixable: {N}
|
|
450
|
-
requires_human_decision: {N}
|
|
451
|
-
recommendation: "APPROVED | NEEDS_REVISION | BLOCKED"
|
|
452
|
-
sign_off_gate: "{blocked — pending: fe_team, app_team, sa | ready}"
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
> **Field định vị (`quote` + `uc_id`) — bắt buộc cho source-jump của Review Board.**
|
|
456
|
-
> Với mỗi finding, copy một đoạn `quote` **nguyên văn** thẳng từ tech-doc tại đúng chỗ
|
|
457
|
-
> lỗi xảy ra — KHÔNG diễn giải lại; nó được so khớp với tài liệu để định vị dòng.
|
|
458
|
-
> Field này cho phép reviewer click một finding trong Review Board và nhảy tới đúng vị trí nguồn.
|
|
459
|
-
|
|
460
|
-
## Report
|
|
461
|
-
|
|
462
|
-
**Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
|
|
463
|
-
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
464
|
-
|
|
465
|
-
```
|
|
466
|
-
/review-tech-docs Hoàn tất — {target file}
|
|
467
|
-
PRD: {TICKET-ID} | UCs: {UC list} | Domain: {domain}
|
|
468
|
-
Findings: {total} | 🔴 Critical: {N} | 🟡 Major: {N} | 🟢 Minor: {N}
|
|
469
|
-
Auto-fixable: {N} | Needs human decision: {N}
|
|
470
|
-
|
|
471
|
-
GAP Register (§12): {open_blocker} 🔴 blocker open / {total_open} open / {total} tracked
|
|
472
|
-
{🔒 còn blocker open → chặn approve | ✅ 0 blocker open}
|
|
473
|
-
|
|
474
|
-
Sign-off gate (chỉ system BDD):
|
|
475
|
-
be_team : {done | pending}
|
|
476
|
-
fe_team : {done | pending} ← {name / "needs sign-off" }
|
|
477
|
-
app_team : {done | pending | n/a}
|
|
478
|
-
sa : {done | pending}
|
|
479
|
-
Gate : {🔒 BLOCKED — pending: fe_team, sa | ✅ READY}
|
|
480
|
-
|
|
481
|
-
File findings: {paths.refinement_dir}/{TICKET-ID}-tech-review-findings.yaml
|
|
482
|
-
Next: Mở trong Review Board → Accept/Modify/Reject từng finding
|
|
483
|
-
Rồi chạy: /review-tech-docs --resume {tech-design-file}
|
|
484
|
-
Sau khi thu đủ sign-off → cập nhật @trace.sign_off trong tech doc, chạy lại review
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
---
|
|
488
|
-
|
|
489
|
-
## Resume Mode — Áp dụng các Finding được chấp nhận
|
|
490
|
-
|
|
491
|
-
*Kích hoạt khi `$ARGUMENTS` chứa `--resume`.*
|
|
492
|
-
*Ví dụ: `/review-tech-docs --resume {paths.tech_docs_dir}/payment/{prd-slug}/tech-docs/PAY-123-tech-design.md`*
|
|
493
|
-
|
|
494
|
-
### Phase 1 — Đọc các finding được chấp nhận
|
|
495
|
-
|
|
496
|
-
1. Suy ra file findings từ target: `{paths.refinement_dir}/{TICKET-ID}-tech-review-findings.yaml`
|
|
497
|
-
2. Đọc file. Gom các finding có `status: "accepted"` hoặc `status: "modified"`.
|
|
498
|
-
3. Nếu không có → báo "No accepted findings. File unchanged." và dừng.
|
|
499
|
-
|
|
500
|
-
### Phase 2 — Áp dụng fix
|
|
501
|
-
|
|
502
|
-
Áp dụng theo thứ tự: critical → major → minor.
|
|
503
|
-
|
|
504
|
-
| check_id | Làm gì |
|
|
505
|
-
|----------|-----------|
|
|
506
|
-
| T1 (Architecture) | Áp dụng fix cấu trúc từ note finding — chuyển logic về đúng layer, cập nhật mô tả component |
|
|
507
|
-
| T2 (Tên field) | Đổi field về tên canonical từ core-entities.md xuyên suốt tài liệu |
|
|
508
|
-
| T3 (Thiếu design note) | Thêm design decision note cho scenario chưa phủ |
|
|
509
|
-
| T3b (map bdd_version) | **Chỉ 2 ca auto-fixable:** platform vắng trong map → thêm entry `{platform}={bdd_version hiện tại}`; platform không còn `.feature` → xoá entry. Ca **`.feature` mới hơn** thì KHÔNG được chỉ sửa số trong map — làm vậy là dán nhãn "đã đồng bộ" lên một contract chưa ai review. Chỉ cập nhật entry sau khi note của reviewer xác nhận §4 đã được đối chiếu lại. |
|
|
510
|
-
| T5 (Internal inconsistency) | Căn chỉnh các section mâu thuẫn theo quyết định nêu trong note |
|
|
511
|
-
| T6 (Thiếu section) | Thêm skeleton section với prompt placeholder cho tech lead điền |
|
|
512
|
-
| T8 (cross-field invariant) | Thêm note invariant còn thiếu *(chỉ mục minor auto-fixable; enum mồ côi / PRD-BR bỏ sót / leak boundary cần người)* |
|
|
513
|
-
| T9 (constant / citation) | Tách constant inline vào bảng catalog/enum; thêm định nghĩa cho citation không resolve |
|
|
514
|
-
|
|
515
|
-
**Finding T1, T2, T4 và các mục Critical/Major của T8/T9 có `auto_fixable: false`:** cần một resolution do người viết trong
|
|
516
|
-
note "Modify" của Review Board (enum mồ côi, PRD-BR bỏ sót, leak boundary, bịa-lặng, happy-only, BDD↔kiến trúc mâu thuẫn — không tự đoán). Áp dụng đúng những gì note nói. Đừng bịa fix.
|
|
517
|
-
|
|
518
|
-
### Phase 3 — Cập nhật header + TSV + Report
|
|
519
|
-
|
|
520
|
-
Sửa file tech-doc trực tiếp:
|
|
521
|
-
1. Tìm `@trace.revision:` trong header — tăng giá trị integer lên 1.
|
|
522
|
-
2. Tìm `@trace.status:` trong header. Set `approved` **chỉ khi CẢ HAI**:
|
|
523
|
-
- (a) sign_off_gate = `ready` (tất cả sign-off done; hoặc doc không có phần system → không cần sign-off), **VÀ**
|
|
524
|
-
- (b) §12 GAP Register **không còn 🔴 blocker nào ở trạng thái `open`** (đếm ở T9).
|
|
525
|
-
Thiếu (a) hoặc (b) → set `in-review` (chặn `/generate-code`); ghi rõ lý do vào report (sign-off pending / còn N blocker-GAP open).
|
|
526
|
-
**Ngoài ra — cổng T3b (chặn MỀM):** còn ≥1 finding T3b Major `open` (`.feature` mới hơn map `@trace.bdd_versions`) → hiện CHECKPOINT ở T3b và chỉ set `approved` khi người dùng chọn `Y`; chọn `N` → `in-review` + nêu lý do.
|
|
527
|
-
3. **Làm mới map `@trace.bdd_versions`** — chỉ cho các platform mà finding T3b đã được **giải quyết** (reviewer xác nhận §4 đã đối chiếu lại, hoặc là ca thêm/xoá entry auto-fixable). Platform còn finding `open` thì **giữ nguyên số cũ**: để nó lệch chính là thứ giữ cờ `TECHDOC_STALE_VS_BDD` của `/validate-traces` sáng đèn.
|
|
528
|
-
4. Nếu block `@trace.sign_off` vắng và đây là tech doc system BDD → thêm nó với tất cả giá trị `pending`.
|
|
529
|
-
|
|
530
|
-
Ghi cả hai thay đổi vào file.
|
|
531
|
-
|
|
532
|
-
Rồi cập nhật TSV cho **mọi UC mà doc phủ** (`@trace.ucs`) — doc gộp có một `@trace.revision` chung cho cả BE và client:
|
|
533
|
-
- Với mỗi UC trong `@trace.ucs`: glob **mọi sổ platform** `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-*.tsv` (system/web/app), và set `tech_doc_revision` thành integer `@trace.revision` mới cho mọi row trong từng sổ đó.
|
|
534
|
-
- **KHÔNG** đụng `fe_tech_doc_revision` ở đây — cột đó do `/generate-code --phase=integration` ghi khi FE thực sự wire adapter theo §4.5.4 (drift-detect riêng cho FE integration).
|
|
535
|
-
- Set `last_updated` thành ngày hôm nay (`YYYY-MM-DD`) cho các row vừa chạm.
|
|
536
|
-
|
|
537
|
-
In report sau khi hoàn tất mọi lần ghi file.
|
|
538
|
-
|
|
539
|
-
```
|
|
540
|
-
/review-tech-docs --resume Đã áp dụng — {target file}
|
|
541
|
-
PRD: {TICKET-ID} | UCs: {UC list}
|
|
542
|
-
|
|
543
|
-
Applied : {N} findings ({critical} critical, {major} major, {minor} minor)
|
|
544
|
-
Skipped : {N} rejected/deferred
|
|
545
|
-
|
|
546
|
-
Changes:
|
|
547
|
-
- {change 1}
|
|
548
|
-
- {change 2}
|
|
549
|
-
|
|
550
|
-
Revision : {old} → {new}
|
|
551
|
-
Status : {approved | in-review}
|
|
552
|
-
|
|
553
|
-
Sign-off : {✅ Tất cả done — status set approved
|
|
554
|
-
| 🔒 Pending: fe_team, sa — status set in-review
|
|
555
|
-
Cập nhật @trace.sign_off trong tech doc khi mỗi team confirm, rồi chạy lại /review-tech-docs}
|
|
556
|
-
|
|
557
|
-
Chạy lại /review-tech-docs {file} để xác nhận 0 finding critical còn lại.
|
|
558
|
-
Next: {/generate-code {feature-file} ← chỉ khi status = approved
|
|
559
|
-
| Thu các sign-off pending → cập nhật @trace.sign_off → chạy lại /review-tech-docs}
|
|
560
|
-
→ nếu tech-doc sống trong spec repo dùng chung: commit + push lên spec submodule để FE/App `/sync` contract đã cập nhật
|
|
561
|
-
```
|