@educa-corp/sdd-framework 0.4.0 → 0.5.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/build.js +9 -0
- package/bin/index.js +115 -4
- package/bin/self-check.js +354 -0
- package/bin/trace-schema.json +1199 -0
- package/commands/debug.md +19 -12
- package/commands/define-product.md +19 -12
- package/commands/dev-gen-test.md +53 -19
- package/commands/dev-run-test.md +55 -20
- package/commands/dev-run-test.tmpl +2 -1
- package/commands/dev-smoke-test.md +19 -12
- package/commands/extend-prd.md +907 -0
- package/commands/extend-prd.tmpl +270 -0
- package/commands/fix-bug.md +101 -15
- package/commands/fix-bug.tmpl +29 -3
- package/commands/generate-architecture.md +19 -12
- package/commands/generate-bdd.md +174 -48
- package/commands/generate-bdd.tmpl +107 -18
- package/commands/generate-code.md +122 -29
- package/commands/generate-code.tmpl +69 -10
- package/commands/generate-design-spec.md +19 -12
- package/commands/generate-prd.md +44 -12
- package/commands/generate-prd.tmpl +25 -0
- package/commands/generate-spec-manifest.md +19 -12
- package/commands/generate-tech-docs.md +22 -15
- package/commands/generate-tech-docs.tmpl +2 -2
- package/commands/learn.md +19 -12
- package/commands/map-testids.md +19 -12
- package/commands/propose-scenario.md +91 -15
- package/commands/propose-scenario.tmpl +72 -3
- package/commands/qc-analyze.md +19 -12
- package/commands/qc-design-test.md +20 -12
- package/commands/qc-design-test.tmpl +1 -0
- package/commands/qc-plan.md +19 -12
- package/commands/qc-report.md +19 -12
- package/commands/qc-review.md +19 -12
- package/commands/qc-run-test.md +88 -22
- package/commands/qc-run-test.tmpl +35 -3
- package/commands/refine-prd.md +19 -12
- package/commands/report-bug.md +19 -12
- package/commands/review-code.md +60 -14
- package/commands/review-code.tmpl +41 -2
- package/commands/review-context.md +62 -16
- package/commands/review-context.tmpl +43 -4
- package/commands/review-tech-docs.md +50 -14
- package/commands/review-tech-docs.tmpl +31 -2
- package/commands/setup-ai-first.md +26 -16
- package/commands/setup-ai-first.tmpl +7 -4
- package/commands/sync.md +43 -18
- package/commands/sync.tmpl +37 -14
- package/commands/update-framework.md +43 -4
- package/commands/update-framework.tmpl +37 -0
- package/commands/validate-traces.md +481 -49
- package/commands/validate-traces.tmpl +462 -37
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/README.md +56 -0
- package/core/commands/debug.md +19 -12
- package/core/commands/define-product.md +19 -12
- package/core/commands/dev-gen-test.md +53 -19
- package/core/commands/dev-run-test.md +55 -20
- package/core/commands/dev-smoke-test.md +19 -12
- package/core/commands/extend-prd.md +907 -0
- package/core/commands/fix-bug.md +101 -15
- package/core/commands/generate-architecture.md +19 -12
- package/core/commands/generate-bdd.md +174 -48
- package/core/commands/generate-code.md +122 -29
- package/core/commands/generate-design-spec.md +19 -12
- package/core/commands/generate-prd.md +44 -12
- package/core/commands/generate-spec-manifest.md +19 -12
- package/core/commands/generate-tech-docs.md +22 -15
- package/core/commands/learn.md +19 -12
- package/core/commands/map-testids.md +19 -12
- package/core/commands/propose-scenario.md +91 -15
- package/core/commands/qc-analyze.md +19 -12
- package/core/commands/qc-design-test.md +20 -12
- package/core/commands/qc-plan.md +19 -12
- package/core/commands/qc-report.md +19 -12
- package/core/commands/qc-review.md +19 -12
- package/core/commands/qc-run-test.md +88 -22
- package/core/commands/refine-prd.md +19 -12
- package/core/commands/report-bug.md +19 -12
- package/core/commands/review-code.md +60 -14
- package/core/commands/review-context.md +62 -16
- package/core/commands/review-tech-docs.md +50 -14
- package/core/commands/setup-ai-first.md +26 -16
- package/core/commands/sync.md +43 -18
- package/core/commands/update-framework.md +43 -4
- package/core/commands/validate-traces.md +481 -49
- package/core/modules/android-compose/stack-profile.yaml +1 -1
- package/core/modules/flutter/stack-profile.yaml +1 -1
- package/core/modules/ios-swiftui/stack-profile.yaml +1 -1
- package/core/modules/java-spring/stack-profile.yaml +1 -1
- package/core/modules/nextjs/stack-profile.yaml +1 -1
- package/core/modules/nuxt/stack-profile.yaml +1 -1
- package/core/modules/phaser-game/stack-profile.yaml +1 -1
- package/core/modules/php-laravel/stack-profile.yaml +1 -1
- package/core/modules/qc-playwright/stack-profile.yaml +1 -1
- package/core/modules/react/stack-profile.yaml +1 -1
- package/core/modules/react-native/stack-profile.yaml +1 -1
- package/core/modules/vue/stack-profile.yaml +1 -1
- package/core/rules/workflow.md +29 -0
- package/core/steps/gate.md +13 -8
- package/core/steps/report-footer.md +6 -4
- package/core/steps/trace-mirror.md +34 -7
- package/core/templates/README.md +47 -0
- package/core/templates/feature.template +14 -11
- package/core/templates/project-context.yaml +26 -14
- package/core/templates/tech-design.template.md +1 -1
- package/docs/01-getting-started/installation.md +18 -1
- package/docs/01-getting-started/what-is-sdd.md +4 -2
- package/docs/02-concepts/architecture.md +27 -3
- package/docs/02-concepts/pipeline-steps/02-specification.md +39 -3
- package/docs/02-concepts/pipeline-steps/04-bdd.md +24 -2
- package/docs/02-concepts/pipeline-steps/05-tech-docs.md +18 -1
- package/docs/02-concepts/pipeline-steps/06-code.md +35 -4
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +137 -12
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +59 -3
- package/docs/02-concepts/roles-and-hitl.md +1 -1
- package/docs/02-concepts/traceability.md +126 -94
- package/docs/03-guides/developer.md +20 -4
- package/docs/03-guides/product-owner.md +72 -68
- package/docs/03-guides/tester-qa.md +81 -70
- package/docs/04-reference/commands.md +134 -105
- package/docs/04-reference/configuration.md +146 -94
- package/docs/04-reference/trace-schema.md +145 -37
- package/docs/explain/02-generate-prd.md +80 -78
- package/docs/explain/02b-extend-prd.md +125 -0
- package/docs/explain/03-refine-prd.md +86 -86
- package/docs/explain/04-review-context.md +18 -1
- package/docs/explain/06-generate-bdd.md +23 -0
- package/docs/explain/08-review-tech-docs.md +20 -5
- package/docs/explain/10-review-code.md +36 -2
- package/docs/explain/19-qc-run-test.md +87 -67
- package/docs/explain/21-validate-traces.md +74 -68
- package/docs/explain/23-fix-bug.md +19 -3
- package/docs/explain/26-propose-scenario.md +70 -63
- package/docs/explain/README.md +135 -134
- package/modules/android-compose/stack-profile.yaml +1 -1
- package/modules/flutter/stack-profile.yaml +1 -1
- package/modules/ios-swiftui/stack-profile.yaml +1 -1
- package/modules/java-spring/stack-profile.yaml +1 -1
- package/modules/nextjs/stack-profile.yaml +1 -1
- package/modules/nuxt/stack-profile.yaml +1 -1
- package/modules/phaser-game/stack-profile.yaml +1 -1
- package/modules/php-laravel/stack-profile.yaml +1 -1
- package/modules/qc-playwright/stack-profile.yaml +1 -1
- package/modules/react/stack-profile.yaml +1 -1
- package/modules/react-native/stack-profile.yaml +1 -1
- package/modules/vue/stack-profile.yaml +1 -1
- package/package.json +5 -4
- package/rules/workflow.md +29 -0
- package/scripts/migrate-bdd-platform.js +286 -0
- package/steps/gate.md +13 -8
- package/steps/report-footer.md +6 -4
- package/steps/trace-mirror.md +34 -7
- package/templates/README.md +47 -0
- package/templates/feature.template +14 -11
- package/templates/project-context.yaml +26 -14
- package/templates/tech-design.template.md +1 -1
package/commands/generate-bdd.md
CHANGED
|
@@ -32,23 +32,23 @@ Hiển thị và chờ phản hồi:
|
|
|
32
32
|
```
|
|
33
33
|
⚙️ MODEL CHECK
|
|
34
34
|
──────────────────────────────────────────────────────────────────
|
|
35
|
-
Recommended :
|
|
35
|
+
Recommended : model Opus mới nhất
|
|
36
36
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
37
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
37
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
38
38
|
|
|
39
39
|
Cách đổi trong Claude Code:
|
|
40
|
-
•
|
|
41
|
-
• hoặc:
|
|
40
|
+
• /model → chọn model Opus
|
|
41
|
+
• hoặc: Settings → Model
|
|
42
42
|
|
|
43
|
-
Đang chạy
|
|
44
|
-
Y — đúng
|
|
43
|
+
Đang chạy một model Opus?
|
|
44
|
+
Y — đúng → tiếp tục
|
|
45
45
|
S — bỏ qua kiểm tra (tôi chấp nhận rủi ro chất lượng thấp hơn với model hiện tại)
|
|
46
46
|
──────────────────────────────────────────────────────────────────
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
- "Y" → tiếp tục sang Bước 1.
|
|
50
50
|
- "S" → tiếp tục sang Bước 1 (người dùng chấp nhận rủi ro, thêm ⚠️ vào report cuối).
|
|
51
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
51
|
+
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang một model Opus (`/model`) rồi chạy lại lệnh này."
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
@@ -57,7 +57,12 @@ Hiển thị và chờ phản hồi:
|
|
|
57
57
|
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/`):
|
|
58
58
|
- **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 đó.
|
|
59
59
|
- **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.)*
|
|
60
|
-
- **Lệnh tech-docs
|
|
60
|
+
- **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:
|
|
61
|
+
- `$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`.
|
|
62
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
63
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
64
|
+
- 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.
|
|
65
|
+
*(Đừ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`.)*
|
|
61
66
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
62
67
|
|
|
63
68
|
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.
|
|
@@ -481,7 +486,16 @@ Tiếp tục sang bước kế tiếp của lệnh đang gọi.
|
|
|
481
486
|
|
|
482
487
|
|
|
483
488
|
> **Proposal của tester (input tuỳ chọn):** trước khi sinh, quét `{paths.bdd_proposals_dir}/` (mặc định `{spec_source}/feedback/bdd-proposals/`) tìm `{UC-ID}-*.md`. Với mỗi proposal:
|
|
484
|
-
> - `Status: accepted` (PO/Dev đã duyệt) → chèn scenario vào `.feature` của UC (
|
|
489
|
+
> - `Status: accepted` (PO/Dev đã duyệt) → chèn scenario vào `.feature` của UC, **normalize khi chèn** (xem dưới), rồi **lưu trữ**: chuyển file sang `{paths.bdd_proposals_dir}/archived/` + đặt `Status: incorporated`, và **commit + push** spec repo để gỡ khỏi feedback chung.
|
|
490
|
+
>
|
|
491
|
+
> **Normalize — bắt buộc, nếu không scenario sẽ vô hình với trace:**
|
|
492
|
+
> 1. Gán `# @trace.scenario: {UC-ID}-SC{N}` với `{N}` = số SC **kế tiếp** trong file đó (thay placeholder `SC?`).
|
|
493
|
+
> 2. Giữ `# @trace.sc_version: 1.0`. Bổ sung `# @trace.business_rules` nếu proposal để `—` (suy từ AC mà dòng `# Covers:` trỏ tới); không suy được → để `—` và nêu trong report.
|
|
494
|
+
> 3. **Strip** tag `@proposed` / `@from-test` — chúng là nhãn vòng đời proposal, không thuộc BDD canonical.
|
|
495
|
+
> 4. Đặt scenario vào **đúng NHÓM** theo business theme (C.5), không nối vào cuối file.
|
|
496
|
+
> 5. **Append row TSV** cho SC mới (như nhánh "SC mới" ở Write Trace State: `spec_ver = 1.0`, mọi cột gen/test/qc = `—`, `status = UNTRACKED`).
|
|
497
|
+
>
|
|
498
|
+
> **Backward-compat:** proposal cũ mang `@trace.uc=` / `@trace.ac=` (vocabulary trước đây, không thuộc contract `.feature`) → tự map sang canonical (`@trace.uc` bỏ — số UC đã có trong `sc_id`; `@trace.ac` → dòng `# Covers:`) và in một dòng cảnh báo khuyến nghị proposal sau viết theo format mới.
|
|
485
499
|
> - `Status: proposed`/`rejected` (hoặc thiếu `Status`) → **bỏ qua**, để nguyên cho PO/Dev xử lý (KHÔNG tự đoán, KHÔNG tự đưa vào).
|
|
486
500
|
> Bỏ qua sạch nếu folder rỗng.
|
|
487
501
|
|
|
@@ -687,9 +701,24 @@ Chỉ cần kiểm tra trạng thái đã phân giải:
|
|
|
687
701
|
| `active_service = "unresolved"` (có section `services` nhưng domain PRD không khớp entry nào) | **DỪNG**, báo: "Domain `{domain}` của PRD không khớp service nào trong `services:` của project-context.yaml — bổ sung mapping rồi chạy lại." (Không đoán/hỏi tay — domain là khoá định danh, lệch là lỗi cấu hình cần sửa ở SoT.) |
|
|
688
702
|
| Single-service (không có section `services`) | `active_module = tech_stack.module` (đã set ở Bước 6.5). Tiếp tục. |
|
|
689
703
|
|
|
690
|
-
|
|
704
|
+
### Phân giải `active_platform` (umbrella mode)
|
|
691
705
|
|
|
692
|
-
|
|
706
|
+
Umbrella mode không hỏi platform (khác spec repo mode) — nó **suy** từ module của service. Bắt buộc phải có giá trị: `active_platform` đi vào **path file**, vào **header `@trace.platform`**, và vào **tên sổ trace** `{UC-ID}-{platform}.tsv`.
|
|
707
|
+
|
|
708
|
+
| `active_module` | → `active_platform` |
|
|
709
|
+
|---|---|
|
|
710
|
+
| react · nextjs · vue · nuxt · angular | `web` |
|
|
711
|
+
| flutter · react-native · ios-swiftui · android-compose | `app` |
|
|
712
|
+
| java-spring · golang · dotnet · php-laravel | `system` |
|
|
713
|
+
| context-engineering · phaser-game | theo `platform_type` của stack-profile (`backend` → `system`, còn lại → `web`) |
|
|
714
|
+
|
|
715
|
+
- `active_service = "multi"` + `service_candidates_kind = platform` → **nhiều** `active_platform` (một cho mỗi platform trong `service_candidates`); sinh một file `.feature` cho mỗi platform, module lấy theo `service_candidates.{platform}.module`.
|
|
716
|
+
- Không suy được (module lạ, không có trong bảng và không có `platform_type`) → **DỪNG**, hỏi người dùng chọn `web`/`app`/`system`. **KHÔNG** ghi file khi chưa có `active_platform` — file thiếu platform sẽ vô hình với `/validate-traces` và va chạm tên với platform khác.
|
|
717
|
+
|
|
718
|
+
**Output path (umbrella mode):** `{paths.specs_dir}/{domain}/{prd-slug}/bdd/{active_platform}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
719
|
+
|
|
720
|
+
*(**Subfolder `{platform}/` LUÔN có — mọi mode.** `web` và `system` của cùng một UC là hai file khác nhau: nếu bỏ subfolder, chúng ra cùng filename và **ghi đè nhau**; ngoài ra trace tách theo platform (`{UC-ID}-{platform}.tsv`) nên bố cục spec phải tách tương ứng.*
|
|
721
|
+
*Cái KHÔNG thêm là subfolder theo **service**: feature-package đã domain-scoped sẵn ở `{domain}/`, mà service route 1-1 theo domain — thêm subfolder service chỉ lặp lại domain. `active_service` chỉ dùng cho `service_root`/từ vựng, KHÔNG vào path spec.)*
|
|
693
722
|
|
|
694
723
|
**Từ vựng theo platform** — điều chỉnh cách viết step BDD theo `active_module`:
|
|
695
724
|
|
|
@@ -772,9 +801,9 @@ Sau khi sinh tất cả file `.feature` và `.tsv` cho UC được giao, trả v
|
|
|
772
801
|
|
|
773
802
|
Trước khi sinh, kiểm tra các file `.feature` có sẵn cho PRD này:
|
|
774
803
|
|
|
775
|
-
1.
|
|
776
|
-
|
|
777
|
-
|
|
804
|
+
1. Search path (**giống nhau ở cả hai mode** — bố cục `bdd/{platform}/` là chuẩn duy nhất):
|
|
805
|
+
`{paths.specs_dir}/{domain}/{prd-slug}/bdd/{active_platform}/{TICKET-ID}-UC*.feature`
|
|
806
|
+
> **Legacy:** nếu không khớp gì, thử thêm một lần ở bố cục phẳng cũ `…/bdd/{TICKET-ID}-UC*.feature`. Khớp → xử lý như file có sẵn **và** in cảnh báo: `⚠️ File .feature đang ở bố cục phẳng (trước v0.4.1). Chạy: npx sdd-framework --migrate-bdd-platform để chuyển sang bdd/{platform}/.` Đừng tự di chuyển file trong lệnh này.
|
|
778
807
|
2. Đọc `| **Version** |` hiện tại của PRD từ metadata (vd: `1.2`).
|
|
779
808
|
|
|
780
809
|
**Nếu không có file feature nào** → gen mới, tiếp tục bình thường. Dùng version PRD làm `@trace.prd_version`.
|
|
@@ -823,7 +852,7 @@ Trước khi sinh, kiểm tra các file `.feature` có sẵn cho PRD này:
|
|
|
823
852
|
| Check | Rule |
|
|
824
853
|
|-------|------|
|
|
825
854
|
| C.1 Wireframe Coverage | Mỗi component/action trong Wireframe (PRD §4b) có ≥1 SC. **FE/App: mỗi Screen State (≠default) và mỗi AC-UI behavioral của design-spec (`design_coverage`) cũng phải có ≥1 SC** — dedup với AC nghiệp vụ PRD; bỏ AC-UI visual thuần. |
|
|
826
|
-
| C.2 PRD Traceability | Mỗi AC và mỗi BR
|
|
855
|
+
| C.2 PRD Traceability | Mỗi AC **thuộc UC này** (đúng tập ở `**AC liên quan:**` của UC trong PRD §3) và mỗi BR trong bảng Business Rule của UC này map tới ≥1 SC. **KHÔNG** phủ AC của UC khác — đó là việc của `.feature` UC đó. *(AC ở PRD là global cấp PRD, còn `.feature` là per-UC; enforce theo nghĩa "mọi AC của PRD" sẽ bắt AI bịa scenario ngoài scope hoặc báo MISSING giả.)* |
|
|
827
856
|
| C.3 Business Dictionary | Dùng đúng canonical term từ business-dictionary.md. |
|
|
828
857
|
| C.4 Banned Terms | 0 banned term trong file — grep trước khi gen. |
|
|
829
858
|
| C.5 NHÓM Grouping | Feature ≥3 SC → PHẢI có NHÓM grouping theo business theme. |
|
|
@@ -879,28 +908,32 @@ CHECKPOINT: "Outline này đúng chưa? Bạn muốn thêm hay bớt SC nào kh
|
|
|
879
908
|
|
|
880
909
|
## Generate
|
|
881
910
|
|
|
882
|
-
**Output path
|
|
883
|
-
|
|
884
|
-
|
|
911
|
+
**Output path — MỘT bố cục duy nhất cho cả hai mode:**
|
|
912
|
+
|
|
913
|
+
```
|
|
914
|
+
{paths.specs_dir}/{domain}/{prd-slug}/bdd/{active_platform}/{TICKET-ID}-UC{N}-{slug}.feature
|
|
915
|
+
```
|
|
885
916
|
|
|
886
|
-
|
|
917
|
+
`{active_platform}` ∈ `web` | `app` | `system` — từ Platform Selection (spec repo mode) hoặc suy từ `active_module` (umbrella mode, xem §Service Detection). **Không có `active_platform` thì không ghi file.**
|
|
918
|
+
|
|
919
|
+
Với mỗi UC, ghi vào path trên và set `# @trace.platform: {active_platform}` trong header (**bắt buộc, mọi mode** — `/generate-code` dùng nó để quyết BE/FE và để định vị sổ trace; `/generate-tech-docs` và `context-loader` cũng đọc nó). Dùng từ vựng cho active platform.
|
|
887
920
|
|
|
888
921
|
```gherkin
|
|
889
922
|
# ============================================================
|
|
890
923
|
# @trace.id: {TICKET-ID}-UC{N}
|
|
891
924
|
# @trace.title: <Feature name>
|
|
892
|
-
# @trace.revision: 1 ← field tĩnh;
|
|
925
|
+
# @trace.revision: 1 ← field tĩnh; version theo dõi bằng @trace.bdd_version
|
|
893
926
|
# @trace.domain: <domain>
|
|
894
|
-
# @trace.platform: {active_platform — web | app | system
|
|
895
|
-
# @trace.service: {active_service —
|
|
927
|
+
# @trace.platform: {active_platform — web | app | system} ← BẮT BUỘC mọi mode; phải khớp segment bdd/{platform}/ của path
|
|
928
|
+
# @trace.service: {active_service — BẮT BUỘC mọi mode. "—" ở single-service/spec repo mode; "multi" nếu chưa chốt; "unresolved" nếu routing sai. Nguồn của cột TSV `service` — trace gộp không tách theo service nên đây là chỗ DUY NHẤT mang thông tin sở hữu}
|
|
896
929
|
# @trace.module: {active_module trong umbrella mode; "unknown" trong spec repo mode}
|
|
897
930
|
# @trace.status: draft
|
|
898
931
|
# @trace.author: AI-generated
|
|
899
932
|
# @trace.created_at: {YYYY-MM-DD}
|
|
900
933
|
# @trace.prd: {TICKET-ID}
|
|
901
934
|
# @trace.prd_version: {đọc từ metadata PRD "| **Version** |"}
|
|
902
|
-
# @trace.bdd_version: {1.0 nếu gen mới; tăng 0.1 khi gen lại
|
|
903
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-
|
|
935
|
+
# @trace.bdd_version: {cấp FILE — 1.0 nếu gen mới; tăng 0.1 khi gen lại. Khác @trace.sc_version (cấp từng SC) bên dưới}
|
|
936
|
+
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}, {TICKET-ID}-UC{N}-BR{m+1} ← {m} lấy NGUYÊN từ PRD §3: BR đánh số LIÊN TỤC toàn PRD, KHÔNG reset theo UC
|
|
904
937
|
# @trace.dataset: {domain}.testdata.yaml
|
|
905
938
|
# ============================================================
|
|
906
939
|
|
|
@@ -947,8 +980,8 @@ Feature: <Feature name>
|
|
|
947
980
|
|
|
948
981
|
# Side-effects: <liệt kê ngắn các Then side-effect cần verify>
|
|
949
982
|
# @trace.scenario: {TICKET-ID}-UC{N}-SC1
|
|
950
|
-
# @trace.sc_version: 1.0
|
|
951
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-
|
|
983
|
+
# @trace.sc_version: 1.0 ← cấp SCENARIO. Sửa thân SC này (tên/step/table/side-effect) thì +0.1, nếu không code cũ mãi hiện OK
|
|
984
|
+
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}
|
|
952
985
|
@happy
|
|
953
986
|
Scenario: <mô tả business outcome — dùng động từ chính xác: create/receive/assign/block>
|
|
954
987
|
Given <input state — alias từ dataset>
|
|
@@ -959,7 +992,7 @@ Feature: <Feature name>
|
|
|
959
992
|
# Side-effects: <...>
|
|
960
993
|
# @trace.scenario: {TICKET-ID}-UC{N}-SC2
|
|
961
994
|
# @trace.sc_version: 1.0
|
|
962
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-
|
|
995
|
+
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}
|
|
963
996
|
@happy @alternative
|
|
964
997
|
Scenario: <cùng theme NHÓM 1 nhưng path khác — vd: giá trị enum khác>
|
|
965
998
|
Given <state>
|
|
@@ -973,7 +1006,7 @@ Feature: <Feature name>
|
|
|
973
1006
|
# Side-effects: <...>
|
|
974
1007
|
# @trace.scenario: {TICKET-ID}-UC{N}-SC3
|
|
975
1008
|
# @trace.sc_version: 1.0
|
|
976
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-
|
|
1009
|
+
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m+2}
|
|
977
1010
|
@edge
|
|
978
1011
|
Scenario: <scenario boundary / error>
|
|
979
1012
|
Given <state>
|
|
@@ -985,8 +1018,8 @@ Feature: <Feature name>
|
|
|
985
1018
|
# AC1 (...) → SC1, SC2
|
|
986
1019
|
# AC2 (...) → SC3
|
|
987
1020
|
# BR mapping (mỗi bullet PHẢI có ≥1 SC — C.2):
|
|
988
|
-
# {TICKET-ID}-UC{N}-
|
|
989
|
-
# {TICKET-ID}-UC{N}-
|
|
1021
|
+
# {TICKET-ID}-UC{N}-BR{m} (...) → SC1, SC2
|
|
1022
|
+
# {TICKET-ID}-UC{N}-BR{m+2} (...) → SC3
|
|
990
1023
|
# Wireframe mapping (mỗi component/action ≥1 SC — C.1):
|
|
991
1024
|
# Screen "<screen name>":
|
|
992
1025
|
# [x] <action 1> → SC1
|
|
@@ -999,6 +1032,9 @@ Feature: <Feature name>
|
|
|
999
1032
|
|
|
1000
1033
|
# === PRE-MERGE CHECKLIST ===
|
|
1001
1034
|
# - [ ] Mỗi SC có Side-effects + @trace.scenario + @trace.sc_version + @trace.business_rules
|
|
1035
|
+
# - [ ] SỬA nội dung một SC (tên / step / data table / side-effect) → đã bump @trace.sc_version của
|
|
1036
|
+
# CHÍNH SC đó (+0.1). Quên bump = code sinh từ SC cũ vẫn hiện OK, không ai biết phải regen.
|
|
1037
|
+
# (Đổi @trace.business_rules / tag / comment → KHÔNG bump: không đổi hành vi cần implement.)
|
|
1002
1038
|
# - [ ] Coverage Matrix: 0 dòng MISSING (C.1)
|
|
1003
1039
|
# - [ ] FE/App: mỗi Screen State (≠default) + AC-UI behavioral của design-spec có ≥1 SC (C.1 mở rộng)
|
|
1004
1040
|
# - [ ] Mỗi AC/BR map tới ≥1 SC (C.2)
|
|
@@ -1009,7 +1045,35 @@ Feature: <Feature name>
|
|
|
1009
1045
|
|
|
1010
1046
|
```
|
|
1011
1047
|
|
|
1012
|
-
|
|
1048
|
+
> **Template này đến từ đâu — đọc trước khi định "customize":**
|
|
1049
|
+
> Skeleton trên là **single-source** ở `templates/feature.template` **của repo framework**, được `{{include}}` **nướng cứng vào lệnh này lúc `npm run build`**. Muốn đổi cấu trúc mọi `.feature` sinh ra: sửa file đó **trong repo framework** rồi build lại + phát hành.
|
|
1050
|
+
>
|
|
1051
|
+
> **Sửa `.agent/templates/feature.template` trong project KHÔNG có tác dụng** — không lệnh nào đọc file đó; nó chỉ là bản tham khảo. Và nó **sẽ bị ghi đè im lặng** ở lần `/update-framework` kế tiếp (`--init` copy `core/` → `.agent/` vô điều kiện; file duy nhất được giữ là `.agent/project-context.yaml`).
|
|
1052
|
+
>
|
|
1053
|
+
> Coverage Matrix + Pre-merge Checklist nằm ở **cuối** template, thêm vào cuối mỗi file.
|
|
1054
|
+
|
|
1055
|
+
### Bump `@trace.sc_version` *(CHỈ khi gen lại — file `.feature` đã tồn tại)*
|
|
1056
|
+
|
|
1057
|
+
*Bỏ qua hoàn toàn khi gen mới: mọi SC nhận `1.0`.*
|
|
1058
|
+
|
|
1059
|
+
`@trace.sc_version` là version **của từng scenario** — nó là tín hiệu DUY NHẤT cho `/validate-traces` biết code của SC đó đã lỗi thời (`spec_ver != gen_ver` → `DRIFT`). Không bump = code sinh từ scenario cũ mãi mãi hiện `OK`. Phân biệt với `@trace.bdd_version` (version **cả file**, không đủ phân giải để biết SC nào cần regen).
|
|
1060
|
+
|
|
1061
|
+
Trước khi ghi file, với **mỗi** SC, so **thân scenario** bản mới vs bản trên disk theo 4 thành phần:
|
|
1062
|
+
|
|
1063
|
+
1. dòng `Scenario:` (tên)
|
|
1064
|
+
2. chuỗi step `Given` / `When` / `Then` / `And` (nội dung + thứ tự)
|
|
1065
|
+
3. nội dung data table (nếu có)
|
|
1066
|
+
4. dòng `# Side-effects:`
|
|
1067
|
+
|
|
1068
|
+
| Kết quả so | Hành động |
|
|
1069
|
+
|---|---|
|
|
1070
|
+
| Khác ở **bất kỳ** thành phần nào | `@trace.sc_version` += `0.1` (vd `1.0` → `1.1`) |
|
|
1071
|
+
| Giống hoàn toàn | **GIỮ NGUYÊN** — bump vô cớ sẽ tạo `DRIFT` giả, làm cờ mất giá trị |
|
|
1072
|
+
| SC mới (chưa có trong bản cũ) | `1.0` |
|
|
1073
|
+
|
|
1074
|
+
*(Thay đổi ngoài 4 thành phần trên — `@trace.business_rules`, tag `@happy`/`@edge`, comment — KHÔNG bump: chúng không đổi hành vi mà code phải implement.)*
|
|
1075
|
+
|
|
1076
|
+
In danh sách SC được bump vào report cuối để người dùng biết cái nào sẽ hiện `DRIFT`.
|
|
1013
1077
|
|
|
1014
1078
|
---
|
|
1015
1079
|
|
|
@@ -1021,16 +1085,33 @@ Sau khi sinh tất cả file `.feature`, tạo hoặc cập nhật **sổ trace
|
|
|
1021
1085
|
|
|
1022
1086
|
**Cột TSV (tab-separated, một header row + một data row cho mỗi scenario):**
|
|
1023
1087
|
```
|
|
1024
|
-
sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tdev_selftest\tdev_selftest_at\tqc_status\tqc_run_at\tqc_owner\tqc_blocked_by\tprd_version\tbdd_version\ttech_doc_revision\tfe_tech_doc_revision\tprd_status\tuc_status\tfe_phase\tstatus\tlast_updated
|
|
1088
|
+
sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tdev_selftest\tdev_selftest_at\tqc_status\tqc_run_at\tqc_owner\tqc_blocked_by\tprd_version\tbdd_version\ttech_doc_revision\tfe_tech_doc_revision\tprd_status\tuc_status\tfe_phase\tstatus\tlast_updated\tservice\tdesign_spec_version
|
|
1025
1089
|
```
|
|
1026
1090
|
|
|
1027
1091
|
**Rules:**
|
|
1028
1092
|
- Nếu file chưa tồn tại → tạo với header row + tất cả scenario row.
|
|
1029
1093
|
- Nếu file tồn tại (gen lại) → với mỗi SC trong `.feature` mới:
|
|
1030
|
-
- SC đã có trong `.tsv` VÀ `spec_ver` không đổi → chỉ cập nhật: `sc_title`, `prd_version`, `bdd_version`, `prd_status`, `uc_status`, `last_updated`. Giữ nguyên các cột khác.
|
|
1031
|
-
- SC đã có trong `.tsv` VÀ `spec_ver` đổi (scenario bị sửa) → cập nhật: `sc_title`, `spec_ver`, `prd_version`, `bdd_version`, `prd_status`, `uc_status`, `last_updated` VÀ set `status = DRIFT` ngay (để TSV phản ánh drift mà không cần đợi `/validate-traces`). Giữ nguyên `gen_ver`, `implemented_by`, `test_count`, `test_classes`, `tech_doc_revision`, `fe_tech_doc_revision`.
|
|
1094
|
+
- SC đã có trong `.tsv` VÀ `spec_ver` không đổi → chỉ cập nhật: `sc_title`, `prd_version`, `bdd_version`, `prd_status`, `uc_status`, `service`, `design_spec_version`, `last_updated`. Giữ nguyên các cột khác. *(`service` + `design_spec_version` là sự thật cấp-file, làm mới theo `.feature`/design-spec hiện tại — chúng KHÔNG phải tín hiệu nghiệm thu nên làm mới chúng không che giấu gì.)*
|
|
1095
|
+
- SC đã có trong `.tsv` VÀ `spec_ver` đổi (scenario bị sửa) → cập nhật: `sc_title`, `spec_ver`, `prd_version`, `bdd_version`, `prd_status`, `uc_status`, `service`, `design_spec_version`, `last_updated` VÀ set `status = DRIFT` ngay (để TSV phản ánh drift mà không cần đợi `/validate-traces`). Giữ nguyên `gen_ver`, `implemented_by`, `test_count`, `test_classes`, `tech_doc_revision`, `fe_tech_doc_revision`.
|
|
1096
|
+
**VÀ hạ hiệu lực tín hiệu kiểm thử của đúng SC đó** — spec vừa đổi nên test/QC cũ đang nghiệm thu một hành vi **không còn tồn tại**:
|
|
1097
|
+
`dev_selftest → not_run` · `dev_selftest_at → —` · `qc_status → not_run` · `qc_run_at → —`.
|
|
1098
|
+
> **Vì sao bắt buộc** *(luật "Làm mất hiệu lực ≠ ghi đè", `rules/workflow.md`)*: không hạ thì chuỗi sau báo xanh sai — spec đổi → `DRIFT` → `/generate-code` sửa method → `gen_ver = spec_ver` → `/validate-traces` Rule 4 cho `OK` (vì `test_count` vẫn > 0) → dashboard hiện `OK · ✅ 10 tests · qc pass` trong khi hành vi mới **chưa được test lần nào**. Đây là lớp lỗi nguy hiểm hơn G1: G1 làm cờ im lặng, cái này làm cờ **nói dối**.
|
|
1099
|
+
> **KHÔNG** đụng `test_count`/`test_classes` (test vẫn nằm trên đĩa — số lượng không sai, chỉ nội dung cũ; hạ số sẽ làm tỷ lệ coverage nhảy loạn) và **KHÔNG** đụng `qc_owner`/`qc_blocked_by` (con trỏ tới bug — spec đổi không làm bug biến mất).
|
|
1100
|
+
In cảnh báo kèm: `⚠️ {test_count} test của {sc_id} viết cho spec cũ — /dev-gen-test rà lại trước khi chạy`.
|
|
1032
1101
|
- SC mới (thêm trong lần gen lại này) → append row mới với `gen_ver`, `implemented_by`, `test_count`, `test_classes`, `dev_selftest`, `dev_selftest_at`, `qc_status`, `qc_run_at`, `qc_owner`, `qc_blocked_by`, `tech_doc_revision`, `fe_tech_doc_revision` đều set `—`.
|
|
1033
|
-
- SC không còn trong `.feature` (bị xoá
|
|
1102
|
+
- SC không còn trong `.feature` (bị xoá / gộp / đổi số) → **phụ thuộc SC đó đã có code chưa:**
|
|
1103
|
+
- `implemented_by == —` (**chưa** có code) → **xoá row**. Không có gì mồ côi.
|
|
1104
|
+
- `implemented_by != —` (**ĐÃ** có code) → **GIỮ row**, set `status = ORPHANED`, giữ nguyên `implemented_by` / `test_count` / `test_classes` / các cột qc, cập nhật `last_updated`. **KHÔNG xoá** — xoá row thì method đó thành vô hình: không `UNTRACKED`, không `GAP`, không `DRIFT`, không xuất hiện ở report nào, mà vẫn nằm trong code và vẫn được caller gọi. Coverage còn *đẹp hơn* thực tế vì mẫu số nhỏ đi.
|
|
1105
|
+
In cảnh báo nổi bật ở report cuối:
|
|
1106
|
+
```
|
|
1107
|
+
⚠️ ORPHANED — {UC-ID}-SC{N} "{sc_title}" đã bị xoá khỏi .feature nhưng còn code:
|
|
1108
|
+
{implemented_by} (+ {test_count} test: {test_classes})
|
|
1109
|
+
Không tự hết — chọn MỘT:
|
|
1110
|
+
(a) behavior không còn cần → xoá method + test, rồi xoá row khỏi .tsv
|
|
1111
|
+
(b) SC bị xoá do nhầm → đưa scenario trở lại .feature (row về DRIFT/OK bình thường)
|
|
1112
|
+
(/validate-traces giữ cờ ORPHANED 🔴 và chặn "pass" tới khi xử lý xong.)
|
|
1113
|
+
```
|
|
1114
|
+
*(An toàn: sổ này chỉ chứa scenario của `{active_platform}`, so với `.feature` của chính platform đó — không bao giờ đụng scenario platform khác.)*
|
|
1034
1115
|
|
|
1035
1116
|
**Giá trị ghi cho mỗi scenario:**
|
|
1036
1117
|
|
|
@@ -1058,12 +1139,38 @@ sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tde
|
|
|
1058
1139
|
| `fe_phase` | `—` (set bởi `/generate-code --phase` khi FE implement) |
|
|
1059
1140
|
| `status` | `UNTRACKED` |
|
|
1060
1141
|
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
1142
|
+
| `service` | `@trace.service` từ header `.feature` — đội/submodule sở hữu scenario này. `multi` nếu chưa chốt (map-theo-platform ở cấp PRD), `unresolved` nếu domain không khớp entry nào, `—` ở single-service mode. **Đừng bỏ trống** — trace gộp không tách theo service nên đây là chỗ DUY NHẤT mang thông tin sở hữu ở cấp row. |
|
|
1143
|
+
| `design_spec_version` | `\| **Version** \|` của design-spec đã nạp ở §Design Spec — Gate & Load. `—` cho `system`/backend (không có design-spec), và `—` khi người dùng chọn "Y — vẫn sinh BDD" mà không có design-spec. |
|
|
1061
1144
|
|
|
1062
1145
|
## Refresh Panel Mirror
|
|
1063
|
-
# Làm mới panel mirror của Living Docs *(local
|
|
1146
|
+
# Làm mới panel mirror của Living Docs *(local)*
|
|
1147
|
+
|
|
1148
|
+
> **Hai vị trí, HAI TÊN KHÁC NHAU — đọc trước khi sửa gì ở đây.**
|
|
1149
|
+
>
|
|
1150
|
+
> | Đường dẫn | Vai trò | Git |
|
|
1151
|
+
> |---|---|---|
|
|
1152
|
+
> | `{paths.trace_dir}` (`.trace/` hoặc `{spec_source}/.trace/`) | **AUTHORITATIVE** — TSV + `trace-history.jsonl`. Không regenerate được. | **PHẢI commit** |
|
|
1153
|
+
> | `./.trace-mirror/` ở gốc workspace hiện tại | **MIRROR** — bản sao tiện cho panel VS Code. Sinh lại được bất cứ lúc nào. | **Luôn gitignore** |
|
|
1154
|
+
>
|
|
1155
|
+
> Trước v0.4.3 cả hai đều tên `.trace`, nên một luật gitignore theo tên có thể **xoá sạch sổ gốc**
|
|
1156
|
+
> khi dev mở thẳng spec repo làm workspace (lúc đó hai path bằng nhau). Hai tên khác nhau làm
|
|
1157
|
+
> luật git đọc được bằng mắt và **không còn ca nhập nhằng nào**: `.trace-mirror/` không bao giờ
|
|
1158
|
+
> commit, `.trace/` không bao giờ gitignore.
|
|
1159
|
+
|
|
1160
|
+
## Khi nào CÓ mirror
|
|
1161
|
+
|
|
1162
|
+
Mirror chỉ tồn tại khi **`{paths.trace_dir}` nằm NGOÀI workspace hiện tại** — panel đọc từ workspace đang mở nên cần một bản sao ở đây.
|
|
1064
1163
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1164
|
+
| Tình huống | `{paths.trace_dir}` | Có mirror? |
|
|
1165
|
+
|---|---|---|
|
|
1166
|
+
| Single-service | `./.trace` — **trong** workspace | ❌ Không. Panel đọc thẳng `.trace/trace-report.json`. Bỏ qua cả file này. |
|
|
1167
|
+
| Dev mở thẳng **spec repo** | `./.trace` — **trong** workspace | ❌ Không. Như trên. |
|
|
1168
|
+
| Umbrella + `spec_source`, dev đứng ở umbrella hoặc service submodule | `{spec_source}/.trace` — **ngoài** workspace | ✅ Có |
|
|
1169
|
+
| Umbrella legacy (không `spec_source`) | `.trace` theo từng service | ✅ Có |
|
|
1170
|
+
|
|
1171
|
+
Quy tắc một dòng: **phân giải `panel_mirror = ./.trace-mirror` ở gốc workspace hiện tại; nếu `{paths.trace_dir}` đã nằm trong workspace này thì bỏ qua toàn bộ bước mirror.**
|
|
1172
|
+
|
|
1173
|
+
---
|
|
1067
1174
|
|
|
1068
1175
|
Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
1069
1176
|
|
|
@@ -1071,11 +1178,14 @@ Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
|
1071
1178
|
`{paths.trace_dir}` phân giải về `{spec_source}/.trace` — vị trí authoritative duy nhất.
|
|
1072
1179
|
Lệnh này chạy từ `service_root`, nên thao tác ghi là **liên-repo vào spec submodule**;
|
|
1073
1180
|
commit/push spec submodule cho lần cập nhật trace (giống như `feedback/`).
|
|
1074
|
-
|
|
1075
|
-
|
|
1181
|
+
|
|
1182
|
+
1. Phân giải `panel_mirror = ./.trace-mirror` tại **gốc workspace hiện tại**.
|
|
1183
|
+
2. Nếu `{paths.trace_dir}` **không** nằm trong workspace hiện tại, copy mỗi
|
|
1076
1184
|
`{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{UC-ID}-{platform}.tsv` (tạo thư mục; ghi đè).
|
|
1077
|
-
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang
|
|
1078
|
-
|
|
1185
|
+
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang ở
|
|
1186
|
+
**cột `service` (cột 23)** của chính từng row, do `/generate-bdd` ghi từ `@trace.service`.
|
|
1187
|
+
3. **KHÔNG copy `trace-history.jsonl`.** Nó là dữ liệu tích luỹ, không phải thứ sinh lại được —
|
|
1188
|
+
nhân bản nó ra một thư mục gitignore là tạo hai lịch sử lệch nhau rồi mất bản thật.
|
|
1079
1189
|
|
|
1080
1190
|
**Legacy (không có `spec_source` — trace theo service):**
|
|
1081
1191
|
Copy mỗi `{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{service-name}/{UC-ID}-{platform}.tsv`
|
|
@@ -1126,7 +1236,7 @@ Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **pha
|
|
|
1126
1236
|
| Phase | Commands |
|
|
1127
1237
|
|-------|----------|
|
|
1128
1238
|
| Discovery | `/define-product` |
|
|
1129
|
-
| PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
1239
|
+
| PRD | `/generate-prd` · `/extend-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
1130
1240
|
| Design Spec | `/generate-design-spec` |
|
|
1131
1241
|
| BDD | `/generate-bdd` · `/review-context` (BDD) |
|
|
1132
1242
|
| Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
|
|
@@ -1151,6 +1261,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1151
1261
|
| /setup-ai-first | `/define-product` để bắt đầu feature đầu tiên |
|
|
1152
1262
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
1153
1263
|
| /generate-prd | `/refine-prd {prd-file}` rồi `/review-context {prd-file}` |
|
|
1264
|
+
| /extend-prd | `/refine-prd {prd-file}` (soi phần vừa thêm) rồi `/review-context {prd-file}` → PO duyệt → `/generate-bdd` **chỉ cho UC MỚI**; UC cũ dùng `/validate-traces --realign-prd-version {UC-ID}` |
|
|
1154
1265
|
| /refine-prd | Mở Review Board → cập nhật PRD → `/review-context {prd-file}` |
|
|
1155
1266
|
| /review-context (PRD) | Khi 0 critical → PO đặt `Status: approved`, rồi FE/App: `/generate-design-spec {prd-file}` (→ design sign-off → BDD); BE: `/generate-bdd {prd-file}`. Còn critical/NEEDS_FIX → sửa PRD (giữ draft) |
|
|
1156
1267
|
| /generate-design-spec | Designer review → xác nhận link Figma → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
@@ -1163,6 +1274,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1163
1274
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1164
1275
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1165
1276
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1277
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1166
1278
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1167
1279
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1168
1280
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1171,11 +1283,11 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1171
1283
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1172
1284
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1173
1285
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1174
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1175
|
-
| /fix-bug |
|
|
1286
|
+
| /validate-traces | **Cờ 🔴 trước (chặn PR):** SEAM_UNWIRED → nối binding sang class thật, xoá/thay stub · STUB_UNRESOLVED → `/generate-code {owner_uc}` (lấp logic tại chỗ + xoá hàm song song) · ORPHANED/TRACE_ORPHAN → quyết định thủ công (xoá code+test, đưa scenario trở lại `.feature`, hoặc sửa `sc_id` của tag). **Rồi:** DRIFT/UNTRACKED → `/generate-code {UC-ID}` · BDD_DRIFT → `/generate-code {feature-file}` · tech-doc lỗi thời vs BDD → `/generate-tech-docs` → `/review-tech-docs` · PRD drift → `/generate-bdd {prd-file}` · GAP → `/dev-gen-test {UC-ID}`. **Chỉ tạo PR khi mọi cờ 🔴 = 0** |
|
|
1287
|
+
| /fix-bug | `/dev-run-test {UC-ID}` (dev_selftest vừa reset về not_run) → tạo PR; nếu fix một `{BUG-ID}` → QC chạy `/qc-run-test {UC-ID}` để verify + đóng bug |
|
|
1176
1288
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1177
1289
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1178
|
-
| /propose-scenario |
|
|
1290
|
+
| /propose-scenario | **Case A** (thiếu scenario cho AC có sẵn) → báo PO/Dev review trong `feedback/bdd-proposals/`; `/generate-bdd` tự chèn khi `Status: accepted`. **Case B** (requirement mới) → `feedback/prd-change-requests/` — PO phải đưa vào PRD trước, KHÔNG tự vào BDD được; `/validate-traces` nhắc lại kèm số ngày chờ chừng nào `Status: Open` |
|
|
1179
1291
|
| /learn | Tiếp tục làm việc — lesson áp dụng ở lệnh kế tiếp |
|
|
1180
1292
|
| /sync | `/validate-traces` để xem độ phủ đầy đủ; xử lý mọi `📥 tester feedback` được nêu |
|
|
1181
1293
|
| /update-framework | Review `git diff .agent/`, commit; `/sync` để đồng bộ nội dung dự án |
|
|
@@ -1207,9 +1319,9 @@ Next (spec repo):
|
|
|
1207
1319
|
→ Sau khi gen hết platform: commit + push + báo team dev
|
|
1208
1320
|
→ Team dev đọc BDD từ spec submodule — không chạy /generate-bdd ở phía họ
|
|
1209
1321
|
|
|
1210
|
-
[Umbrella mode — service: {active_service}]
|
|
1322
|
+
[Umbrella mode — service: {active_service} · platform: {active_platform} (suy từ module {active_module})]
|
|
1211
1323
|
Files:
|
|
1212
|
-
{paths.specs_dir}/{domain}/{prd-slug}/bdd/{TICKET-ID}-UC1-{slug}.feature ({N} scenarios)
|
|
1324
|
+
{paths.specs_dir}/{domain}/{prd-slug}/bdd/{active_platform}/{TICKET-ID}-UC1-{slug}.feature ({N} scenarios)
|
|
1213
1325
|
Trace:
|
|
1214
1326
|
{paths.trace_dir}/{domain}/{prd-slug}/{TICKET-ID}-UC1-{active_platform}.tsv ({N} rows)
|
|
1215
1327
|
Next (umbrella):
|
|
@@ -1217,5 +1329,19 @@ Next (umbrella):
|
|
|
1217
1329
|
→ /generate-tech-docs {feature-file}
|
|
1218
1330
|
→ /generate-code {feature-file}
|
|
1219
1331
|
|
|
1332
|
+
{chỉ khi gen lại VÀ có ≥1 SC bị bump — ngược lại bỏ cả khối}
|
|
1333
|
+
🔄 sc_version đã bump (scenario đổi nội dung → code cũ lỗi thời):
|
|
1334
|
+
{UC-ID}-SC2 1.0 → 1.1 {sc_title}
|
|
1335
|
+
{UC-ID}-SC5 1.2 → 1.3 {sc_title}
|
|
1336
|
+
→ {n} SC này sẽ hiện DRIFT ở /validate-traces. Sinh lại code: /generate-code {feature-file}
|
|
1337
|
+
|
|
1338
|
+
{cùng điều kiện — chỉ in các SC bump mà TRƯỚC ĐÓ có dev_selftest/qc_status khác "—"}
|
|
1339
|
+
🔻 Tín hiệu kiểm thử bị hạ (spec vừa đổi — nghiệm thu cũ hết hiệu lực):
|
|
1340
|
+
{UC-ID}-SC2 dev_selftest pass→not_run · qc_status pass→not_run
|
|
1341
|
+
⚠️ {n} test của các SC này viết cho spec CŨ — rà lại nội dung, đừng chỉ chạy lại.
|
|
1342
|
+
→ sau khi /generate-code: /dev-gen-test (rà test) → /dev-run-test → QC /qc-run-test
|
|
1343
|
+
ℹ️ Coverage "đã kiểm đạt" sẽ TỤT trên dashboard — đó là số đúng; số cũ mới là số sai.
|
|
1344
|
+
(Tỷ lệ phủ code/test KHÔNG đổi — test_count giữ nguyên vì test vẫn nằm trên đĩa.)
|
|
1345
|
+
|
|
1220
1346
|
📊 Living Docs: chạy /validate-traces (hoặc /sync) để push trace này lên dashboard spec-module.
|
|
1221
1347
|
```
|