@educa-corp/sdd-framework 0.6.0 → 0.7.1
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 +418 -31
- package/core/FRAMEWORK_VERSION +1 -1
- package/{commands/extend-prd.md → core/commands/amend-prd.md} +206 -173
- package/core/commands/dev-run-test.md +48 -10
- package/core/commands/extend-prd.md +39 -12
- package/core/commands/generate-bdd.md +52 -10
- package/core/commands/generate-code.md +35 -2
- package/core/commands/generate-tech-docs.md +36 -4
- package/core/commands/map-testids.md +1 -1
- 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 +289 -16
- package/core/rules/workflow.md +34 -0
- package/core/steps/context-loader.md +27 -6
- package/core/templates/feature.template +1 -1
- package/core/templates/project-context.yaml +3 -3
- package/core/templates/tech-design.template.md +2 -2
- package/docs/02-concepts/architecture.md +37 -1
- package/docs/02-concepts/overview.md +1 -1
- package/docs/02-concepts/pipeline-steps/02-specification.md +13 -7
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +2 -0
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -0
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +34 -3
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +10 -1
- package/docs/02-concepts/traceability.md +187 -183
- package/docs/03-guides/architect.md +13 -4
- package/docs/03-guides/developer.md +1 -0
- package/docs/03-guides/product-owner.md +89 -72
- package/docs/03-guides/tester-qa.md +81 -81
- package/docs/04-reference/commands.md +148 -134
- package/docs/04-reference/trace-schema.md +45 -1
- package/docs/explain/02b-extend-prd.md +1 -1
- package/docs/explain/02c-amend-prd.md +152 -0
- package/docs/explain/06-generate-bdd.md +1 -1
- package/docs/explain/13-dev-run-test.md +15 -1
- package/docs/explain/19-qc-run-test.md +91 -87
- package/docs/explain/21-validate-traces.md +79 -75
- 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,602 +0,0 @@
|
|
|
1
|
-
# /setup-ai-first — Khởi tạo SDD Framework trong một dự án
|
|
2
|
-
|
|
3
|
-
Dẫn người dùng qua một setup một-lần tạo mọi thư mục cần thiết, cài CLAUDE.md, và verify môi trường.
|
|
4
|
-
|
|
5
|
-
## Gate
|
|
6
|
-
# Gate — Quy trình vào chuẩn cho mọi lệnh
|
|
7
|
-
|
|
8
|
-
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ó.
|
|
9
|
-
|
|
10
|
-
## Bước 0 — Kiểm tra chế độ Sub-Agent
|
|
11
|
-
|
|
12
|
-
Trước tiên, kiểm tra xem `$ARGUMENTS` có phải là payload JSON từ một orchestrator hay không:
|
|
13
|
-
|
|
14
|
-
1. Thử parse `$ARGUMENTS` dưới dạng JSON.
|
|
15
|
-
2. Nếu parse thành công **và** chứa `"_agent_mode": true`:
|
|
16
|
-
- **Bỏ qua hoàn toàn Bước 1, 2 và 3 của Gate này.**
|
|
17
|
-
- Đặt target file = `payload.target_file`
|
|
18
|
-
- Đặt loaded context = `payload.context` (KHÔNG chạy context-loader.md)
|
|
19
|
-
- Đặt phạm vi UC = `payload.uc_id` (chỉ xử lý UC này)
|
|
20
|
-
- Đặt line range = `payload.uc_section` (chỉ đọc đúng section đó của PRD)
|
|
21
|
-
- Đặt dimension = `payload.dimension` nếu có (lệnh review per-UC: chỉ review đúng lăng kính này)
|
|
22
|
-
- Đi thẳng tới phần logic riêng của lệnh.
|
|
23
|
-
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).
|
|
24
|
-
|
|
25
|
-
## Bước 0-B — Ghi nhận Model *(KHÔNG chặn)*
|
|
26
|
-
|
|
27
|
-
*Bỏ qua nếu `_agent_mode: true` (sub-agent — orchestrator đã ghi nhận rồi).*
|
|
28
|
-
|
|
29
|
-
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
|
|
30
|
-
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
|
|
31
|
-
model Opus, gắn thêm cảnh báo ngay ở dòng đó.
|
|
32
|
-
|
|
33
|
-
**KHÔNG hỏi người dùng. KHÔNG chờ. KHÔNG dừng.**
|
|
34
|
-
|
|
35
|
-
> **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
|
|
36
|
-
> `⚙️ MODEL CHECK` rồi chờ `Y/S/N`. Ba vấn đề cùng chỉ một hướng:
|
|
37
|
-
> **(1)** nó hỏi người dùng thứ mà **agent đã biết chính xác**;
|
|
38
|
-
> **(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
|
|
39
|
-
> gì phát hiện;
|
|
40
|
-
> **(3)** **cả `Y` lẫn `S` đều đi tiếp** — cách duy nhất để nó dừng là tự nguyện gõ `N`.
|
|
41
|
-
> 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
|
|
42
|
-
> 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
|
|
43
|
-
> 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.
|
|
44
|
-
>
|
|
45
|
-
> Khai báo trong report **mạnh hơn** hỏi: đúng nguồn (agent, không phải người), và nằm
|
|
46
|
-
> **cạnh kết quả** để cân nhắc, thay vì nằm trước khi có kết quả để bấm cho xong.
|
|
47
|
-
|
|
48
|
-
**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;
|
|
49
|
-
model nhỏ hơn dễ bỏ sót edge case và vi phạm kiến trúc. Đổi: `/model` → chọn Opus.
|
|
50
|
-
|
|
51
|
-
## Bước 1 — Xác định Target File
|
|
52
|
-
|
|
53
|
-
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.)
|
|
54
|
-
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.
|
|
55
|
-
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/`):
|
|
56
|
-
- **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 đó.
|
|
57
|
-
- **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.)*
|
|
58
|
-
- **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:
|
|
59
|
-
- `$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`.
|
|
60
|
-
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
61
|
-
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
62
|
-
- 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.
|
|
63
|
-
*(Đừ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`.)*
|
|
64
|
-
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
65
|
-
|
|
66
|
-
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.
|
|
67
|
-
3. Nếu `$ARGUMENTS` rỗng hoặc không tìm thấy file khớp:
|
|
68
|
-
- 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).
|
|
69
|
-
- 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)"
|
|
70
|
-
- Chờ người dùng chọn rồi mới tiếp tục.
|
|
71
|
-
|
|
72
|
-
## Bước 2 — Chạy Context Loader
|
|
73
|
-
|
|
74
|
-
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`.
|
|
75
|
-
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.
|
|
76
|
-
|
|
77
|
-
## Bước 3 — CHECKPOINT
|
|
78
|
-
|
|
79
|
-
*Bỏ qua nếu `_agent_mode: true`.*
|
|
80
|
-
|
|
81
|
-
### 3a — Lệnh này có phải chặn không?
|
|
82
|
-
|
|
83
|
-
| Mức | Lệnh nào | `--yes` bỏ qua được? |
|
|
84
|
-
|---|---|:---:|
|
|
85
|
-
| **Không chặn** | Lệnh read-only: `/review-code` · `/validate-traces` · `/debug` · `/review-context` · `/review-tech-docs` | — (vốn không có) |
|
|
86
|
-
| **Chặn thường** | Mọi lệnh sinh/sửa artifact | ✅ |
|
|
87
|
-
| **Chặn CỨNG** | Ghi đè file đã tồn tại · `--resume` áp findings · migrate · prune | ❌ **không bao giờ** |
|
|
88
|
-
|
|
89
|
-
`--yes` trong `$ARGUMENTS` → bỏ qua CHECKPOINT mức *chặn thường*. (Bước 1 đã tách mọi token
|
|
90
|
-
`--` 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
|
|
91
|
-
headless: `claude -p "/generate-code UC1 --yes"`.
|
|
92
|
-
|
|
93
|
-
> **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: …*`
|
|
94
|
-
> 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
|
|
95
|
-
> **nghĩa là gì**.
|
|
96
|
-
> Nguồn máy đọc: `bin/trace-schema.json` → `gate.checkpoint_levels`; `self-check` **R11** fail
|
|
97
|
-
> 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.
|
|
98
|
-
> *(Lệnh không có dòng nào = mức **chặn thường**, mặc định.)*
|
|
99
|
-
|
|
100
|
-
> **Mức *không chặn* là thực thi đúng miễn trừ mà `rules/workflow.md` đã cấp từ trước** —
|
|
101
|
-
> trước G41 file đó viết *"read-only commands may skip CHECKPOINT"* còn gate thì luôn đòi.
|
|
102
|
-
> 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.
|
|
103
|
-
|
|
104
|
-
### 3b — In gì
|
|
105
|
-
|
|
106
|
-
**KHÔNG lặp lại những gì `[CTX LOADED]` vừa in.** Recap của context-loader (Bước 7) đã hiện
|
|
107
|
-
Stack · Platform · Layers · CLAUDE.md · Dict · Entities · Lessons · Service · Status ngay phía
|
|
108
|
-
trên. CHECKPOINT chỉ thêm **một** thông tin mới là `Target`.
|
|
109
|
-
|
|
110
|
-
**Mọi thứ sạch** — recap báo `Status: FULL`, không cờ nào bật → in đúng hai dòng:
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
CHECKPOINT — Target: {resolved file path}
|
|
114
|
-
Tiếp tục? (Y/N)
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**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:
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
CHECKPOINT
|
|
121
|
-
🔴 Service : unresolved — {lý do context-loader đã ghi}
|
|
122
|
-
⚠️ CLAUDE.md: service overlay THIẾU — dùng root (code sinh ra có thể sai stack)
|
|
123
|
-
⚠️ Target : resolve bằng wildcard — {n} file khớp, chọn {file}
|
|
124
|
-
⚠️ Module : not configured — code sinh ra sẽ dùng default
|
|
125
|
-
Status : PARTIAL — thiếu: {danh sách}
|
|
126
|
-
Target : {resolved file path}
|
|
127
|
-
Tiếp tục? (Y/N)
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### 3c — Cờ nào bật, cờ nào KHÔNG
|
|
131
|
-
|
|
132
|
-
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
|
|
133
|
-
đ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:
|
|
134
|
-
|
|
135
|
-
| Bật cờ khi | Nguồn | Mức |
|
|
136
|
-
|---|---|:---:|
|
|
137
|
-
| `active_service = unresolved` | context-loader Bước 2b/2c/Fallback | 🔴 |
|
|
138
|
-
| `Status = MINIMAL` | recap Bước 7 | 🔴 |
|
|
139
|
-
| `Status = PARTIAL` | recap Bước 7 | ⚠️ |
|
|
140
|
-
| CLAUDE.md thiếu, hoặc service overlay thiếu | context-loader Bước 3 | ⚠️ |
|
|
141
|
-
| Target resolve qua wildcard, hoặc nhiều file khớp mà lệnh tự chọn | Bước 1 ở trên | ⚠️ |
|
|
142
|
-
| `module` không cấu hình | recap Bước 7 | ⚠️ |
|
|
143
|
-
|
|
144
|
-
**KHÔNG bật cờ cho:** `Lessons: chưa có` · `Dict: missing` · `Entities: missing`. Đó là
|
|
145
|
-
*"dự án chưa điền"*, không phải *"có gì đó sai"* — chúng ở lại trong recap.
|
|
146
|
-
|
|
147
|
-
> **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**,
|
|
148
|
-
> 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ư
|
|
149
|
-
> 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.
|
|
150
|
-
|
|
151
|
-
### 3d — Chờ trả lời
|
|
152
|
-
|
|
153
|
-
- "Y" → tiếp tục sang các bước riêng của lệnh.
|
|
154
|
-
- "N" → dừng, hỏi người dùng muốn thay đổi gì.
|
|
155
|
-
- Có `--yes` và mức *chặn thường* → coi như "Y", **nhưng vẫn IN khối CHECKPOINT** nếu có cờ
|
|
156
|
-
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
*Lưu ý: Với lệnh này — **bỏ qua Gate Step 1, 2, và 3** (chưa có file input và chưa có project context). Chỉ chạy Step 0-B (model check). Project root là **thư mục làm việc hiện tại**. Đi thẳng tới Precondition Check bên dưới.*
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Precondition Check
|
|
164
|
-
|
|
165
|
-
Kiểm tra đã setup chưa:
|
|
166
|
-
- Nếu cả `CLAUDE.md` **và** `.agent/project-context.yaml` đều tồn tại → hỏi: "Dự án này đã được khởi tạo. Chạy lại setup để regenerate file config? (Y/N)"
|
|
167
|
-
- N → dừng
|
|
168
|
-
- Y → tiếp tục (file có sẵn được giữ — mỗi bước sẽ đề nghị merge/skip)
|
|
169
|
-
- Nếu chỉ có `specs/` hoặc phát hiện setup một phần → tiếp tục bình thường (an toàn chạy lại)
|
|
170
|
-
|
|
171
|
-
## Step 0.5 — Loại dự án
|
|
172
|
-
|
|
173
|
-
Hỏi người dùng:
|
|
174
|
-
|
|
175
|
-
```
|
|
176
|
-
Dự án này thuộc loại nào?
|
|
177
|
-
1. Single-service — một codebase, một platform (setup chuẩn)
|
|
178
|
-
2. Umbrella repo — repo này chứa nhiều service submodule (microservices / multi-app)
|
|
179
|
-
3. PO Spec repo — chỉ docs, không có code chạy được (chỉ PRD + design-spec)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Lưu câu trả lời thành `project_type`. Mặc định `1` nếu user không trả lời.
|
|
183
|
-
|
|
184
|
-
Dựa trên câu trả lời:
|
|
185
|
-
|
|
186
|
-
**project_type = 1 (Single-service):** Tiếp tục setup chuẩn bên dưới.
|
|
187
|
-
|
|
188
|
-
**project_type = 2 (Umbrella):** Hỏi các câu follow-up:
|
|
189
|
-
- "Path tới spec submodule (vd `free-trial-spec`)? Nhấn Enter để skip."
|
|
190
|
-
- "Một business-domain được triển khai trên NHIỀU platform (BE + Web + App) không? (Y/N)"
|
|
191
|
-
- **N → dạng phẳng (FORM A):** "Liệt kê service dạng cặp `domain:module`, ngăn cách bởi dấu phẩy
|
|
192
|
-
(vd `user:java-spring,order:java-spring`). Nhấn Enter để skip."
|
|
193
|
-
- **Y → dạng map-theo-platform (FORM B):** "Liệt kê dạng bộ ba `domain:platform:module`
|
|
194
|
-
(platform ∈ system|web|app), ngăn cách bởi dấu phẩy — lặp lại domain cho từng platform
|
|
195
|
-
(vd `onboarding:system:java-spring,onboarding:web:nextjs,onboarding:app:flutter`). Nhấn Enter để skip."
|
|
196
|
-
context-loader route theo `@trace.platform` của target `.feature` → chọn đúng submodule.
|
|
197
|
-
**Giữ `@trace.domain` là business-domain** (KHÔNG bịa `onboarding-web`).
|
|
198
|
-
- "Có ô định tuyến nào ứng với NHIỀU repo không — tức cùng một domain (và cùng platform,
|
|
199
|
-
nếu có) nhưng mỗi feature nằm ở một repo riêng? (vd mỗi mini-game webview một repo) (Y/N)"
|
|
200
|
-
- **Y → dạng map-theo-prd_slug (FORM C):** "Liệt kê dạng `domain:platform:prd-slug:module`
|
|
201
|
-
— bỏ trống đoạn platform nếu domain không chia platform (`domain::prd-slug:module`) —
|
|
202
|
-
ngăn cách bởi dấu phẩy (vd
|
|
203
|
-
`learning:webview:dap-chuot:phaser-game,learning:webview:ban-cung:phaser-game`).
|
|
204
|
-
Nhấn Enter để skip."
|
|
205
|
-
`prd-slug` là **tên thư mục feature-package** dưới `specs/{domain}/`, phải khớp chính xác.
|
|
206
|
-
context-loader tra `@trace.platform` rồi tra tiếp `prd_slug` → chọn đúng repo.
|
|
207
|
-
Không khớp slug nào thì lệnh DỪNG (`unresolved`) chứ không đoán repo gần giống.
|
|
208
|
-
|
|
209
|
-
Rồi:
|
|
210
|
-
- Skip tạo bất kỳ artifact `specs/` nào (mọi spec — PRD, BDD, tech-docs, design-spec — sống trong spec submodule theo bố cục feature-package `specs/{domain}/{prd-slug}/`)
|
|
211
|
-
- Chỉ tạo: `.trace/`, `.agent/review/` ở cấp umbrella
|
|
212
|
-
*(Trừ khi user yêu cầu rõ tạo cấu trúc đầy đủ)*
|
|
213
|
-
- Sinh `.agent/project-context.yaml` ở umbrella mode với services (FORM A, B hoặc C — trộn được trong cùng một file) và spec_source đã cung cấp.
|
|
214
|
-
**Sau khi sinh, MỞ file kiểm tra:** mỗi `services.{domain}.path` (hoặc `.{platform}.path`, hoặc `.by_prd_slug.{slug}.path`) phải trỏ **đúng tên thư mục submodule thật** — generator để placeholder `TODO-…` vì tên dir thường khác tên domain. Sửa cho khớp trước khi chạy lệnh generate.
|
|
215
|
-
- Skip tạo `CLAUDE.md` root (umbrella không có một tech stack đơn) — nhưng nhắc mỗi submodule code cần overlay `{path}/CLAUDE.md` riêng (thiếu thì code-gen fallback về default + cờ ⚠️, có thể sai coding-standards).
|
|
216
|
-
- Sau setup, nhắc: "Mở từng service submodule riêng trong Claude Code để cài framework/overlay ở đó nếu cần."
|
|
217
|
-
|
|
218
|
-
**project_type = 3 (PO Spec repo):**
|
|
219
|
-
- Tạo base dir: `specs/product-definition/`, `specs/domain-knowledge/`, `feedback/`, `.agent/review/`
|
|
220
|
-
- Artifact theo từng feature (`specs/{domain}/{prd-slug}/{ {TICKET-ID}-{prd-slug}.md, bdd/, tech-docs/, design-spec/}`) được tạo on demand bởi các lệnh generate — ĐỪNG tạo trước
|
|
221
|
-
- Skip: `.trace/` (theo service, sống cạnh code trong mỗi service submodule)
|
|
222
|
-
- Sinh `CLAUDE.md` tối thiểu chỉ với §1 (project overview) và §7 (git conventions)
|
|
223
|
-
- Hỏi người dùng: **"Liệt kê các business domain của bạn (vd auth, payment, loyalty):"** — lưu thành domain list cho `project-context.yaml` và nhắc PO các tên này phải được dùng nhất quán ở row `| **Domain** |` của bảng Metadata trong mọi PRD
|
|
224
|
-
- Thông báo:
|
|
225
|
-
- Lệnh cho PO repo: `/define-product`, `/generate-prd`, `/review-context`, `/generate-design-spec`
|
|
226
|
-
- **Quan trọng cho handoff team dev:** Mọi PRD phải có row `| **Domain** | {domain} |` trong **bảng Metadata**. Team dev dùng nó để route BDD/code sinh ra tới đúng service submodule. Tên domain không nhất quán sẽ phá routing.
|
|
227
|
-
- Bảng Metadata PRD (do `/generate-prd` điền sẵn theo template):
|
|
228
|
-
```
|
|
229
|
-
| **Domain** | {domain} | ← phải khớp một key trong services config của team dev
|
|
230
|
-
| **Ticket** | {TICKET-ID} |
|
|
231
|
-
| **Status** | draft | approved |
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Step 1 — Tạo cấu trúc thư mục
|
|
235
|
-
|
|
236
|
-
Tạo các thư mục này (skip nếu đã tồn tại):
|
|
237
|
-
|
|
238
|
-
```
|
|
239
|
-
{project-root}/
|
|
240
|
-
├── specs/
|
|
241
|
-
│ ├── product-definition/ ← Output của /define-product
|
|
242
|
-
│ └── domain-knowledge/ ← business dictionary & domain context
|
|
243
|
-
├── .trace/ ← .trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv
|
|
244
|
-
└── .agent/
|
|
245
|
-
└── review/
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Bố cục feature-package** — artifact spec theo từng feature KHÔNG được tạo trước. Mỗi lệnh generate
|
|
249
|
-
tự tạo folder của nó on demand dưới `specs/{domain}/{prd-slug}/`:
|
|
250
|
-
|
|
251
|
-
```
|
|
252
|
-
specs/{domain}/{prd-slug}/
|
|
253
|
-
├── {TICKET-ID}-{prd-slug}.md ← /generate-prd (vd SEG01-segment-scoring-service.md)
|
|
254
|
-
├── bdd/ ← /generate-bdd (file .feature)
|
|
255
|
-
├── tech-docs/ ← /generate-tech-docs
|
|
256
|
-
└── design-spec/ ← /generate-design-spec (chỉ platform FE/App)
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
*Tạo base dir nào tuỳ theo `project_type` set ở Step 0.5:*
|
|
260
|
-
|
|
261
|
-
| project_type | Tạo | Skip |
|
|
262
|
-
|---|---|---|
|
|
263
|
-
| **1 — Single-service** | Cấu trúc base ở trên (`specs/product-definition/`, `specs/domain-knowledge/`, `.trace/`, `.agent/review/`) | folder theo feature (tạo on demand) |
|
|
264
|
-
| **2 — Umbrella** | Chỉ `.trace/` + `.agent/review/` (ở umbrella root) | Mọi thứ khác — **toàn bộ spec sống trong spec submodule (`spec_source`)** dưới `specs/{domain}/{prd-slug}/`; service submodule chỉ chứa **code + `.trace/`** |
|
|
265
|
-
| **3 — PO Spec repo** | `specs/product-definition/`, `specs/domain-knowledge/`, **`feedback/`**, `.agent/review/` (folder `specs/{domain}/{prd-slug}/` theo feature tạo on demand) | `.trace/` (theo service, sống cạnh code trong mỗi service submodule) |
|
|
266
|
-
|
|
267
|
-
### Step 1b — Luật merge cho sổ trace *(mọi project_type có tạo `.trace/`)*
|
|
268
|
-
|
|
269
|
-
Ngay khi tạo `.trace/`, tạo luôn `.trace/.gitattributes`:
|
|
270
|
-
|
|
271
|
-
```gitattributes
|
|
272
|
-
# Sổ trace — dữ liệu KHÔNG regenerate được. Hai luật, hai lý do khác nhau:
|
|
273
|
-
#
|
|
274
|
-
# merge=union — giữ row của CẢ HAI nhánh thay vì bắt người chọn một bên. Trùng sc_id sau
|
|
275
|
-
# union là ca ĐÚNG VÀ ĐƯỢC MONG ĐỢI: `--lint-trace` T4 bắt nó, rồi /validate-traces
|
|
276
|
-
# reconcile về một row. Mất row thì KHÔNG có gì bắt được. Đánh đổi có chủ ý — đừng "dọn".
|
|
277
|
-
# (union là driver built-in của git: không ai cần chạy git config gì thêm.)
|
|
278
|
-
#
|
|
279
|
-
# text eol=lf — BẮT BUỘC đi kèm union. Thiếu nó: một máy ghi CRLF → git thấy MỌI dòng đã
|
|
280
|
-
# đổi → union giữ cả hai bản → NHÂN ĐÔI CẢ FILE, gồm cả dòng header.
|
|
281
|
-
#
|
|
282
|
-
# KHÔNG thêm *.json — trace-report.json nằm cùng thư mục và union trên JSON tạo ra JSON
|
|
283
|
-
# không hợp lệ. Nó sinh lại được: conflict thì chạy lại /validate-traces.
|
|
284
|
-
*.tsv text eol=lf merge=union
|
|
285
|
-
*.jsonl text eol=lf merge=union
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
**Vì sao làm ở đây, ngay lúc tạo thư mục:** sổ trace phải commit và được nhiều người ghi trên
|
|
289
|
-
nhiều nhánh song song. Không có luật này, lần merge song song đầu tiên sẽ conflict — và giải
|
|
290
|
-
conflict bằng "take mine" là **mất row của người kia, im lặng**. Đây là ca **chắc chắn xảy ra**
|
|
291
|
-
với team ≥3 người và không cần ai làm sai gì cả.
|
|
292
|
-
|
|
293
|
-
*Project đã cài từ trước → `/sync` Step 4c kiểm và tạo hộ.*
|
|
294
|
-
|
|
295
|
-
## Step 2 — Tạo CLAUDE.md
|
|
296
|
-
|
|
297
|
-
*Bỏ qua hoàn toàn step này nếu `project_type = 2` (Umbrella) — umbrella không có một tech stack đơn.*
|
|
298
|
-
*Với `project_type = 3` (PO Spec repo) — tạo CLAUDE.md tối thiểu chỉ với §1 (project overview) và §7 (git conventions). Skip §2–§6.*
|
|
299
|
-
|
|
300
|
-
Kiểm tra `CLAUDE.md` tồn tại chưa:
|
|
301
|
-
- Có → hỏi "Merge template hay skip?"
|
|
302
|
-
- Không → tạo từ template bên dưới
|
|
303
|
-
|
|
304
|
-
Sau khi tạo, hướng dẫn: "Mở CLAUDE.md và điền các giá trị `{{PLACEHOLDER}}` bằng thông tin dự án của bạn."
|
|
305
|
-
|
|
306
|
-
### CLAUDE.md Template
|
|
307
|
-
|
|
308
|
-
```
|
|
309
|
-
# §1. Project Overview
|
|
310
|
-
Project: {{PROJECT_NAME}}
|
|
311
|
-
Language: {{LANGUAGE}}
|
|
312
|
-
Framework: {{FRAMEWORK}}
|
|
313
|
-
Build: {{BUILD_COMMAND}}
|
|
314
|
-
Test: {{TEST_COMMAND}}
|
|
315
|
-
Domains: {{COMMA_SEPARATED_DOMAINS}}
|
|
316
|
-
|
|
317
|
-
# §2. Architecture
|
|
318
|
-
layers: "{{LAYER_STACK}}"
|
|
319
|
-
# Example: Controller → Facade → Service → Repository
|
|
320
|
-
rules:
|
|
321
|
-
- "Controllers must not contain business logic"
|
|
322
|
-
- "Services own transaction boundaries"
|
|
323
|
-
|
|
324
|
-
# §3. Coding Standards
|
|
325
|
-
naming:
|
|
326
|
-
classes: "{{NAMING_CONVENTION}}"
|
|
327
|
-
methods: "{{METHOD_CONVENTION}}"
|
|
328
|
-
response_wrapper: "{{WRAPPER}}"
|
|
329
|
-
forbidden:
|
|
330
|
-
- "Magic numbers"
|
|
331
|
-
- "Debug print statements"
|
|
332
|
-
|
|
333
|
-
# §4. Traceability
|
|
334
|
-
# Every entry-point method must carry the FULL block (repeat it per UC in a
|
|
335
|
-
# multi-UC file — the version tags are per-UC scalars, never merge them):
|
|
336
|
-
# @trace.implements={UC-ID}-SC{N}
|
|
337
|
-
# @trace.prd_version={PRD version} / @trace.bdd_version={BDD version} / @trace.tech_doc_revision={n}
|
|
338
|
-
# @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature
|
|
339
|
-
# ({platform} = web|app|system · adjust the root if specs_dir differs in .agent/project-context.yaml)
|
|
340
|
-
# Tests must be tagged:
|
|
341
|
-
# @trace.verifies={UC-ID}-SC{N}
|
|
342
|
-
|
|
343
|
-
# §5. Error Handling
|
|
344
|
-
not_found: "{{NOT_FOUND_EXCEPTION}}"
|
|
345
|
-
http_codes: { get: 200, create: 201, not_found: 404, validation: 400 }
|
|
346
|
-
|
|
347
|
-
# §6. Build & Test
|
|
348
|
-
build_command: "{{BUILD_COMMAND}}"
|
|
349
|
-
test_command: "{{TEST_COMMAND}}"
|
|
350
|
-
run_command: "{{RUN_COMMAND}}"
|
|
351
|
-
|
|
352
|
-
# §7. Git Conventions
|
|
353
|
-
branch_feature: "feature/{{TICKET_PREFIX}}-{N}-{slug}"
|
|
354
|
-
commit_feature: "feat({{TICKET_PREFIX}}-{N}): {description}"
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
## Step 3 — Tạo project-context.yaml
|
|
358
|
-
|
|
359
|
-
*Với `project_type = 2` (Umbrella):*
|
|
360
|
-
- *Nếu `.agent/project-context.yaml` đã được sinh bởi `--init --umbrella` → mở nó và verify/sửa section `services` (domain key, path, module). Skip copy template bên dưới.*
|
|
361
|
-
- *Nếu chưa sinh → hỏi: "Path spec submodule?" và "Services (cặp domain:module)?" rồi sinh config umbrella (xem Step 0.5 cho format).*
|
|
362
|
-
|
|
363
|
-
Tạo `.agent/project-context.yaml` dùng `.agent/templates/project-context.yaml` làm template nguồn.
|
|
364
|
-
|
|
365
|
-
Copy template và hướng dẫn: "Mở `.agent/project-context.yaml` và điền mọi giá trị `{{PLACEHOLDER}}`. Section `paths` đã được cấu hình sẵn với default hợp lý — chỉnh nếu dự án dùng tên thư mục khác."
|
|
366
|
-
|
|
367
|
-
## Step 4 — Tạo business-dictionary.md
|
|
368
|
-
|
|
369
|
-
*Skip Step 4 và 5 nếu `project_type = 2` (Umbrella) — business dictionary và core entities sống trong spec submodule và do team PO quản lý. Team dev đọc chúng từ `{spec_source}/specs/domain-knowledge/`.*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
Tạo `specs/domain-knowledge/business-dictionary.md` nếu chưa tồn tại:
|
|
373
|
-
|
|
374
|
-
```markdown
|
|
375
|
-
# Business Dictionary — {{PROJECT_NAME}}
|
|
376
|
-
|
|
377
|
-
> Thuật ngữ chuẩn cho dự án này. Mọi PRD, BDD spec, và code phải theo các thuật ngữ này.
|
|
378
|
-
> Managed by: PO / SA team.
|
|
379
|
-
|
|
380
|
-
## Canonical Terms
|
|
381
|
-
|
|
382
|
-
| Canonical Term | Description / Context |
|
|
383
|
-
|----------------|----------------------|
|
|
384
|
-
| {Term} | {Short description, usage scope} |
|
|
385
|
-
|
|
386
|
-
## Banned Terms
|
|
387
|
-
|
|
388
|
-
| ❌ Do NOT use | ✅ Use instead | Reason |
|
|
389
|
-
|---------------|-------------------|--------|
|
|
390
|
-
| {banned} | {canonical} | {why} |
|
|
391
|
-
|
|
392
|
-
## Status / Enum Registry
|
|
393
|
-
|
|
394
|
-
| Entity | Field | Allowed Values |
|
|
395
|
-
|--------|---------|--------------------|
|
|
396
|
-
| {Entity} | status | {value1, value2} |
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
Hướng dẫn: "Mở `specs/domain-knowledge/business-dictionary.md` và thêm thuật ngữ dự án của bạn. File này sẽ được mọi lệnh đọc để enforce naming nhất quán."
|
|
400
|
-
|
|
401
|
-
## Step 5 — Tạo core-entities.md
|
|
402
|
-
|
|
403
|
-
Tạo `specs/domain-knowledge/core-entities.md` nếu chưa tồn tại:
|
|
404
|
-
|
|
405
|
-
```markdown
|
|
406
|
-
# Core Entities — {{PROJECT_NAME}}
|
|
407
|
-
|
|
408
|
-
> Glossary entity máy-đọc-được cho phát triển có AI hỗ trợ.
|
|
409
|
-
> Được mọi lệnh nạp để AI biết domain model của bạn mà không cần đọc source code.
|
|
410
|
-
> Managed by: Tech Lead / Architect.
|
|
411
|
-
>
|
|
412
|
-
> HOW TO USE:
|
|
413
|
-
> - Add one `## Entity: {Name}` section per domain entity (aggregate root, value object, etc.)
|
|
414
|
-
> - Keep field descriptions concise — this is a REFERENCE, not API docs
|
|
415
|
-
> - Update this file whenever you add/rename fields or change business invariants
|
|
416
|
-
|
|
417
|
-
---
|
|
418
|
-
|
|
419
|
-
## Entity: {EntityName}
|
|
420
|
-
|
|
421
|
-
**Purpose**: {1-2 sentences — what this entity represents and why it exists in the domain}
|
|
422
|
-
**Domain**: {domain}
|
|
423
|
-
**Storage**: {e.g., `orders` table in PostgreSQL | `orders` collection in MongoDB}
|
|
424
|
-
**Owner service**: {service/module that owns this entity}
|
|
425
|
-
|
|
426
|
-
| Field | Type | Nullable | Description |
|
|
427
|
-
|--------------|---------|----------|-------------------------------------|
|
|
428
|
-
| id | UUID | No | Primary key |
|
|
429
|
-
| {field_name} | {type} | Yes/No | {short description} |
|
|
430
|
-
| status | Enum | No | See Status Registry in business-dictionary.md |
|
|
431
|
-
|
|
432
|
-
**Business invariants:**
|
|
433
|
-
- {Rule 1: e.g., "status can only transition: PENDING → ACTIVE → CLOSED"}
|
|
434
|
-
- {Rule 2: e.g., "total must equal sum of line items"}
|
|
435
|
-
|
|
436
|
-
**Relationships:**
|
|
437
|
-
- `{EntityA}` 1:N `{EntityB}` — {one sentence description}
|
|
438
|
-
- `{EntityA}` N:N `{EntityC}` via `{junction_table}` — {description}
|
|
439
|
-
|
|
440
|
-
---
|
|
441
|
-
|
|
442
|
-
## Entity: {AnotherEntity}
|
|
443
|
-
|
|
444
|
-
*(Add more entities following the same pattern above)*
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
Hướng dẫn: "Mở `specs/domain-knowledge/core-entities.md` và định nghĩa các domain entity chính. Bắt đầu với aggregate root. File này được mọi lệnh AI nạp — định nghĩa tốt ở đây tiết kiệm đáng kể qua-lại khi sinh code."
|
|
448
|
-
|
|
449
|
-
## Step 6 — Cài VS Code Extension (Khuyến nghị)
|
|
450
|
-
|
|
451
|
-
Khuyến nghị user cài extension VS Code **Spec Driven Docs Tools** — nó cung cấp panel Review Board + Living Documentation tích hợp với workflow này.
|
|
452
|
-
|
|
453
|
-
```bash
|
|
454
|
-
code --install-extension SpecDrivenDocsTools.spec-driven-docs-tool
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
Hoặc: VS Code → `Ctrl+Shift+P` → **"Extensions: Install from Marketplace"** → tìm **Spec Driven Docs Tools**.
|
|
458
|
-
|
|
459
|
-
**Nó làm gì:**
|
|
460
|
-
- 📋 **Review Board** — UI trực quan để review findings từ `/refine-prd`, `/review-context`, `/review-tech-docs`
|
|
461
|
-
- 📊 **Living Documentation** — dashboard traceability dựa trên `.trace/*.tsv`
|
|
462
|
-
|
|
463
|
-
## Step 6b — Cổng chặn bằng máy (Khuyến nghị mạnh)
|
|
464
|
-
|
|
465
|
-
*Skip nếu `project_type = 3` (PO Spec repo) — không có code thì không có PR cần chặn.*
|
|
466
|
-
|
|
467
|
-
Framework phát hiện được một lớp lỗi mà **build xanh + test từng-UC xanh KHÔNG thấy**: luồng
|
|
468
|
-
ghép chạy vào hàm rỗng (`SEAM_UNWIRED`, `STUB_UNRESOLVED`), hoặc code trỏ vào scenario đã bị
|
|
469
|
-
xoá (`ORPHANED`, `TRACE_ORPHAN`). Nhưng nếu việc phát hiện đó phụ thuộc vào **có người tự
|
|
470
|
-
nguyện chạy `/validate-traces` rồi đọc report bằng mắt**, thì sau sprint thứ ba không ai làm.
|
|
471
|
-
|
|
472
|
-
Hai file mẫu đã có sẵn. Hỏi user muốn cài cái nào:
|
|
473
|
-
|
|
474
|
-
```
|
|
475
|
-
Cài cổng chặn bằng máy? (khuyến nghị cả hai)
|
|
476
|
-
1. pre-push hook — chặn push khi sổ trace hỏng cấu trúc. Rẻ, 2 giây, offline được.
|
|
477
|
-
Bắt được marker conflict git trước khi nó vào nhánh chung.
|
|
478
|
-
2. CI workflow — chặn PR khi có cờ 🔴. Cần GitHub Actions.
|
|
479
|
-
3. Cả hai (khuyến nghị)
|
|
480
|
-
4. Bỏ qua, cài sau
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
**Chọn 1 hoặc 3** — copy hook rồi cấp quyền chạy:
|
|
484
|
-
```bash
|
|
485
|
-
cp .agent/templates/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
|
|
486
|
-
```
|
|
487
|
-
*Nếu `trace_dir` của project không phải `.trace` (vd `../.trace` hay `{spec_source}/.trace`) →
|
|
488
|
-
mở file vừa copy và sửa biến `TRACE_DIR` ở đầu file cho khớp.*
|
|
489
|
-
|
|
490
|
-
**Chọn 2 hoặc 3** — copy workflow:
|
|
491
|
-
```bash
|
|
492
|
-
mkdir -p .github/workflows && cp .agent/templates/ci/trace-gate.yml .github/workflows/
|
|
493
|
-
```
|
|
494
|
-
*Rồi mở nó ra: sửa `src/**` ở job `require-fresh-audit` cho khớp layout project, và bỏ comment
|
|
495
|
-
`submodules: recursive` nếu spec/trace nằm trong submodule.*
|
|
496
|
-
|
|
497
|
-
> **Phải COPY RA khỏi `.agent/`** — `.agent/` bị ghi đè mỗi lần `/update-framework`, và
|
|
498
|
-
> `.git/hooks/` thì git không chạy từ chỗ khác. Copy ra rồi thì chúng là file của project.
|
|
499
|
-
|
|
500
|
-
Kiểm ngay sau khi cài (chưa có sổ trace thì cả hai thoát sạch, không phải lỗi):
|
|
501
|
-
```bash
|
|
502
|
-
npx @educa-corp/sdd-framework --lint-trace
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
Chi tiết + giới hạn của cổng → `docs/03-guides/architect.md` §Cắm vào CI.
|
|
506
|
-
|
|
507
|
-
## Step 7 — Verify
|
|
508
|
-
|
|
509
|
-
Checklist tuỳ theo `project_type`:
|
|
510
|
-
|
|
511
|
-
**project_type = 1 (Single-service):**
|
|
512
|
-
- [ ] `specs/` tồn tại
|
|
513
|
-
- [ ] `specs/product-definition/` tồn tại
|
|
514
|
-
- [ ] `specs/domain-knowledge/` tồn tại
|
|
515
|
-
- [ ] `.trace/` tồn tại
|
|
516
|
-
*(folder `specs/{domain}/{prd-slug}/` theo feature tạo on demand — không check ở đây)*
|
|
517
|
-
- [ ] `.agent/project-context.yaml` tồn tại
|
|
518
|
-
- [ ] `CLAUDE.md` tồn tại
|
|
519
|
-
- [ ] `specs/domain-knowledge/business-dictionary.md` tồn tại
|
|
520
|
-
- [ ] `specs/domain-knowledge/core-entities.md` tồn tại
|
|
521
|
-
|
|
522
|
-
**project_type = 2 (Umbrella):**
|
|
523
|
-
- [ ] `.agent/project-context.yaml` tồn tại với `setup.mode: umbrella`
|
|
524
|
-
- [ ] Section `services` có ít nhất một entry với đúng domain key
|
|
525
|
-
- [ ] Path `spec_source` tồn tại (vd thư mục `my-project-specs/` có mặt)
|
|
526
|
-
- [ ] `.agent/review/` tồn tại
|
|
527
|
-
- [ ] Spec submodule đã init: `git submodule status` không hiện prefix `-`
|
|
528
|
-
|
|
529
|
-
**project_type = 3 (PO Spec repo):**
|
|
530
|
-
- [ ] `specs/product-definition/` tồn tại
|
|
531
|
-
- [ ] `specs/domain-knowledge/` tồn tại
|
|
532
|
-
- [ ] `feedback/` tồn tại
|
|
533
|
-
*(folder `specs/{domain}/{prd-slug}/` theo feature tạo on demand — không check ở đây)*
|
|
534
|
-
- [ ] `.agent/review/` tồn tại
|
|
535
|
-
- [ ] `.agent/project-context.yaml` tồn tại
|
|
536
|
-
- [ ] `CLAUDE.md` tồn tại (tối thiểu)
|
|
537
|
-
- [ ] `specs/domain-knowledge/business-dictionary.md` tồn tại
|
|
538
|
-
- [ ] `specs/domain-knowledge/core-entities.md` tồn tại
|
|
539
|
-
|
|
540
|
-
## Output
|
|
541
|
-
|
|
542
|
-
**Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
|
|
543
|
-
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
544
|
-
|
|
545
|
-
```
|
|
546
|
-
/setup-ai-first Hoàn tất ✅
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
Output tuỳ theo `project_type`:
|
|
550
|
-
|
|
551
|
-
**Single-service:**
|
|
552
|
-
```
|
|
553
|
-
Next:
|
|
554
|
-
1. Điền CLAUDE.md (thay các giá trị {{PLACEHOLDER}})
|
|
555
|
-
2. Điền .agent/project-context.yaml
|
|
556
|
-
3. Điền specs/domain-knowledge/business-dictionary.md
|
|
557
|
-
4. Điền specs/domain-knowledge/core-entities.md
|
|
558
|
-
5. git add và commit 4 file đó
|
|
559
|
-
6. Cài VS Code extension:
|
|
560
|
-
code --install-extension SpecDrivenDocsTools.spec-driven-docs-tool
|
|
561
|
-
7. /define-product để bắt đầu feature đầu tiên
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
**Umbrella:**
|
|
565
|
-
```
|
|
566
|
-
Next:
|
|
567
|
-
1. Review .agent/project-context.yaml:
|
|
568
|
-
- Cập nhật services[].path khớp tên thư mục submodule thực tế
|
|
569
|
-
- Cập nhật domain key của services khớp row `Domain` (bảng Metadata) trong các file PRD
|
|
570
|
-
- Xác nhận path spec_source đúng
|
|
571
|
-
|
|
572
|
-
2. Chạy /sync — một lệnh lo mọi thứ còn lại:
|
|
573
|
-
/sync
|
|
574
|
-
→ git pull + submodule init + spec submodule update
|
|
575
|
-
→ Tự tạo .agent/project-context.yaml cho mỗi service submodule
|
|
576
|
-
(phát hiện module từ pom.xml / go.mod / package.json / pubspec.yaml v.v.)
|
|
577
|
-
→ Sync Living Docs panel
|
|
578
|
-
→ Refresh spec-manifest.yaml
|
|
579
|
-
|
|
580
|
-
3. Bắt đầu sinh:
|
|
581
|
-
/generate-bdd {spec_source}/specs/{domain}/{prd-slug}/{TICKET-ID}-{prd-slug}.md
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
**PO Spec repo:**
|
|
585
|
-
```
|
|
586
|
-
Next:
|
|
587
|
-
1. Điền .agent/project-context.yaml:
|
|
588
|
-
- domains: [liệt kê mọi business domain — chúng thành row `Domain` (bảng Metadata) trong PRD]
|
|
589
|
-
- project.name, project.description
|
|
590
|
-
2. Điền specs/domain-knowledge/business-dictionary.md ← canonical terms
|
|
591
|
-
3. Điền specs/domain-knowledge/core-entities.md ← entity glossary
|
|
592
|
-
4. git add và commit các file đó
|
|
593
|
-
5. Cài VS Code extension:
|
|
594
|
-
code --install-extension SpecDrivenDocsTools.spec-driven-docs-tool
|
|
595
|
-
6. /define-product để bắt đầu feature đầu tiên
|
|
596
|
-
|
|
597
|
-
⚠️ Nhắc handoff team dev:
|
|
598
|
-
- Mỗi PRD phải có row `Domain` (bảng Metadata) khớp một trong domains list của bạn
|
|
599
|
-
- Khi team dev setup umbrella repo của họ, họ map các tên domain này
|
|
600
|
-
tới path service submodule trong section services của project-context.yaml
|
|
601
|
-
- Chia sẻ tên domain với team dev trước khi họ cấu hình umbrella
|
|
602
|
-
```
|