@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/review-code.md
CHANGED
|
@@ -34,23 +34,23 @@ Hiển thị và chờ phản hồi:
|
|
|
34
34
|
```
|
|
35
35
|
⚙️ MODEL CHECK
|
|
36
36
|
──────────────────────────────────────────────────────────────────
|
|
37
|
-
Recommended :
|
|
37
|
+
Recommended : model Opus mới nhất
|
|
38
38
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
39
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
39
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
40
40
|
|
|
41
41
|
Cách đổi trong Claude Code:
|
|
42
|
-
•
|
|
43
|
-
• hoặc:
|
|
42
|
+
• /model → chọn model Opus
|
|
43
|
+
• hoặc: Settings → Model
|
|
44
44
|
|
|
45
|
-
Đang chạy
|
|
46
|
-
Y — đúng
|
|
45
|
+
Đang chạy một model Opus?
|
|
46
|
+
Y — đúng → tiếp tục
|
|
47
47
|
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)
|
|
48
48
|
──────────────────────────────────────────────────────────────────
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
- "Y" → tiếp tục sang Bước 1.
|
|
52
52
|
- "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).
|
|
53
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
53
|
+
- "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."
|
|
54
54
|
|
|
55
55
|
## Bước 1 — Xác định Target File
|
|
56
56
|
|
|
@@ -59,7 +59,12 @@ Hiển thị và chờ phản hồi:
|
|
|
59
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
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
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
|
|
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`.)*
|
|
63
68
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
64
69
|
|
|
65
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.
|
|
@@ -509,8 +514,24 @@ Chờ "Y" rõ ràng trước khi tiếp tục.
|
|
|
509
514
|
## Review Dimensions
|
|
510
515
|
|
|
511
516
|
### 1. Traceability
|
|
512
|
-
|
|
513
|
-
-
|
|
517
|
+
|
|
518
|
+
*Đây là lăng kính bảo vệ toàn bộ cơ chế drift-detection. `/generate-code` phải ghi **5 tag** lên mỗi entry-point (**6** với FE/App); thiếu bất kỳ tag nào thì `/validate-traces` mù ở file đó — **im lặng**, không lệnh nào khác bắt được.*
|
|
519
|
+
|
|
520
|
+
- [ ] Mỗi entry-point (layer theo CLAUDE.md §2) có `@trace.implements={UC-ID}-SC{N}`?
|
|
521
|
+
- [ ] **Mỗi block `@trace.implements` có đủ tag đi kèm?** → thiếu bất kỳ tag nào = **major** (không phải minor):
|
|
522
|
+
|
|
523
|
+
| Tag | Thiếu thì mù cái gì |
|
|
524
|
+
|---|---|
|
|
525
|
+
| `@trace.prd_version` | `/validate-traces` Step 4 — PRD drift |
|
|
526
|
+
| `@trace.bdd_version` | Step 5c — BDD drift |
|
|
527
|
+
| `@trace.tech_doc_revision` | Step 5 — tech-doc drift *(bỏ được nếu UC không có tech-doc)* |
|
|
528
|
+
| `@trace.design_spec_version` | Step 5d — design-spec drift. **CHỈ FE/App** (`@trace.platform` = `web`/`app`): thiếu ở FE = **major**; có ở `system`/backend = **minor** (tag thừa, không có design-spec để so) |
|
|
529
|
+
| `@trace.source` | mất con trỏ ngược về spec |
|
|
530
|
+
|
|
531
|
+
- [ ] `@trace.source` trỏ tới file `.feature` **có thật**, đúng platform (`bdd/{platform}/{UC-ID}-{slug}.feature`)? → sai path = **major**
|
|
532
|
+
- [ ] **File phủ nhiều UC: mỗi UC có block tag RIÊNG đặt trên method của nó?** → gộp về một header file, hoặc `@trace.source` trỏ **thư mục**, = **major**. Lý do: 4 tag version là scalar theo từng UC (gộp → Step 4/5/5c/5d báo drift oan hoặc mù drift thật); và các lệnh tra tag bằng **khớp chuỗi chính xác** nên tag trỏ folder ra 0 kết quả → UC rơi về `UNTRACKED` dù code đã có.
|
|
533
|
+
- [ ] Mỗi test file có tag `@trace.verifies={UC-ID}-SC{N}`?
|
|
534
|
+
- [ ] **Không có tag mồ côi** — `@trace.implements`/`@trace.verifies` trỏ tới SC **không tồn tại** trong `.feature`? → **critical** (`TRACE_ORPHAN`; xem `/validate-traces` Step 2b)
|
|
514
535
|
- [ ] Không có tag `@trace` ở sai layer?
|
|
515
536
|
- [ ] `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` cập nhật chưa? (nếu stale → chạy `/validate-traces {UC-ID}` trước, rồi chạy lại review này)
|
|
516
537
|
|
|
@@ -530,6 +551,20 @@ Chờ "Y" rõ ràng trước khi tiếp tục.
|
|
|
530
551
|
- [ ] Mỗi scenario trong .feature có implementation?
|
|
531
552
|
- [ ] Không có endpoint không tài liệu (code không có spec backing)?
|
|
532
553
|
|
|
554
|
+
### 5. Seam & Stub — mồ côi khi ghép luồng
|
|
555
|
+
|
|
556
|
+
*`/generate-code` vừa sinh ra sổ `_seams.tsv` ở bước trước. Đây là lớp lỗi mà **build xanh + test từng-UC xanh** vẫn không bắt được: luồng ghép chạy vào no-op, hoặc hàm thật không ai gọi. `/validate-traces` Step 5b cũng soi — trùng có chủ đích, vì bắt ở đây rẻ hơn (ngay sau codegen, trước khi sinh test).*
|
|
557
|
+
|
|
558
|
+
Đọc sổ `{paths.trace_dir}/{domain}/{prd-slug}/_seams.tsv` (nếu có) + quét code dưới `{code_base_package}`:
|
|
559
|
+
|
|
560
|
+
- [ ] Sổ **0 dòng** `status = READY`? (`READY` = đồng nghĩa cờ 🔴 `SEAM_UNWIRED` / `STUB_UNRESOLVED`) → còn dòng nào = **critical**
|
|
561
|
+
- [ ] Không có class `*Stub*`/`*Mock*` nào **còn là binding đang dùng** trong khi hàng thật đã tồn tại? → `SEAM_UNWIRED`, **critical**
|
|
562
|
+
- [ ] Không có method nào còn `@trace.stub` rỗng trong khi `@trace.stub_owner` **đã gen**? → `STUB_UNRESOLVED`, **critical**
|
|
563
|
+
- [ ] Không có method thật **mồ côi** — logic thật được đẻ **song song** thay vì lấp vào stub cũ (Fill-before-create bị trượt)? → **critical**
|
|
564
|
+
- [ ] Mỗi stub/seam **mới** sinh trong lần này có đủ tag (`@trace.stub` + `@trace.stub_owner` + `@trace.stub_for`, hoặc `@trace.seam_pending` + `@trace.seam_port`) **và** một dòng `PENDING` trong sổ? → thiếu = **major** (nợ không ghi sổ = nợ tàng hình)
|
|
565
|
+
|
|
566
|
+
> `SEAM_PENDING` / `STUB_PENDING` (owner UC chưa gen) là **bình thường** — chỉ nhắc, không tạo finding.
|
|
567
|
+
|
|
533
568
|
## Output
|
|
534
569
|
|
|
535
570
|
# Report Footer — Định dạng output chuẩn cho mọi lệnh
|
|
@@ -568,7 +603,7 @@ Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **pha
|
|
|
568
603
|
| Phase | Commands |
|
|
569
604
|
|-------|----------|
|
|
570
605
|
| Discovery | `/define-product` |
|
|
571
|
-
| PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
606
|
+
| PRD | `/generate-prd` · `/extend-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
572
607
|
| Design Spec | `/generate-design-spec` |
|
|
573
608
|
| BDD | `/generate-bdd` · `/review-context` (BDD) |
|
|
574
609
|
| Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
|
|
@@ -593,6 +628,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
593
628
|
| /setup-ai-first | `/define-product` để bắt đầu feature đầu tiên |
|
|
594
629
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
595
630
|
| /generate-prd | `/refine-prd {prd-file}` rồi `/review-context {prd-file}` |
|
|
631
|
+
| /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}` |
|
|
596
632
|
| /refine-prd | Mở Review Board → cập nhật PRD → `/review-context {prd-file}` |
|
|
597
633
|
| /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) |
|
|
598
634
|
| /generate-design-spec | Designer review → xác nhận link Figma → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
@@ -605,6 +641,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
605
641
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
606
642
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
607
643
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
644
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
608
645
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
609
646
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
610
647
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -613,11 +650,11 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
613
650
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
614
651
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
615
652
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
616
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
617
|
-
| /fix-bug |
|
|
653
|
+
| /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** |
|
|
654
|
+
| /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 |
|
|
618
655
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
619
656
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
620
|
-
| /propose-scenario |
|
|
657
|
+
| /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` |
|
|
621
658
|
| /learn | Tiếp tục làm việc — lesson áp dụng ở lệnh kế tiếp |
|
|
622
659
|
| /sync | `/validate-traces` để xem độ phủ đầy đủ; xử lý mọi `📥 tester feedback` được nêu |
|
|
623
660
|
| /update-framework | Review `git diff .agent/`, commit; `/sync` để đồng bộ nội dung dự án |
|
|
@@ -650,12 +687,21 @@ Critical: {X} | Major: {Y} | Minor: {Z}
|
|
|
650
687
|
Output Artifacts: none (read-only)
|
|
651
688
|
|
|
652
689
|
Verdict: APPROVED ✅ | NEEDS_FIX ❌
|
|
690
|
+
(Bất kỳ finding critical nào ở lăng kính 5 → NEEDS_FIX, KỂ CẢ khi build xanh
|
|
691
|
+
và test từng-UC xanh — đó chính là loại lỗi hai thứ đó không bắt được.)
|
|
653
692
|
|
|
654
693
|
Nếu APPROVED ✅:
|
|
655
694
|
Next: /dev-gen-test {UC-ID}
|
|
656
695
|
|
|
657
696
|
Nếu NEEDS_FIX ❌:
|
|
658
697
|
- Fix nhỏ (1–3 dòng, không đổi logic) → fix inline → chạy lại /review-code {UC-ID}
|
|
698
|
+
- Thiếu tag version / @trace.source sai → bổ sung tại chỗ (giá trị lấy từ header .feature
|
|
699
|
+
+ tech-doc), rồi chạy lại /validate-traces {UC-ID}
|
|
700
|
+
- Tag mồ côi (TRACE_ORPHAN) → sửa sc_id cho đúng SC hiện có, hoặc xoá code/test
|
|
701
|
+
nếu behavior không còn cần
|
|
702
|
+
- SEAM_UNWIRED 🔴 → trỏ binding sang class thật, xoá/thay stub, build lại
|
|
703
|
+
- STUB_UNRESOLVED 🔴 → /generate-code {owner_uc} (lấp logic TẠI CHỖ vào
|
|
704
|
+
method trắng, xoá hàm song song)
|
|
659
705
|
- Vấn đề logic / kiến trúc → /fix-bug {TICKET_ID}
|
|
660
706
|
- Spec mismatch (code ≠ scenario) → /generate-code {feature-file} (gen lại UC bị ảnh hưởng)
|
|
661
707
|
```
|
|
@@ -35,8 +35,24 @@ Chờ "Y" rõ ràng trước khi tiếp tục.
|
|
|
35
35
|
## Review Dimensions
|
|
36
36
|
|
|
37
37
|
### 1. Traceability
|
|
38
|
-
|
|
39
|
-
-
|
|
38
|
+
|
|
39
|
+
*Đây là lăng kính bảo vệ toàn bộ cơ chế drift-detection. `/generate-code` phải ghi **5 tag** lên mỗi entry-point (**6** với FE/App); thiếu bất kỳ tag nào thì `/validate-traces` mù ở file đó — **im lặng**, không lệnh nào khác bắt được.*
|
|
40
|
+
|
|
41
|
+
- [ ] Mỗi entry-point (layer theo CLAUDE.md §2) có `@trace.implements={UC-ID}-SC{N}`?
|
|
42
|
+
- [ ] **Mỗi block `@trace.implements` có đủ tag đi kèm?** → thiếu bất kỳ tag nào = **major** (không phải minor):
|
|
43
|
+
|
|
44
|
+
| Tag | Thiếu thì mù cái gì |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `@trace.prd_version` | `/validate-traces` Step 4 — PRD drift |
|
|
47
|
+
| `@trace.bdd_version` | Step 5c — BDD drift |
|
|
48
|
+
| `@trace.tech_doc_revision` | Step 5 — tech-doc drift *(bỏ được nếu UC không có tech-doc)* |
|
|
49
|
+
| `@trace.design_spec_version` | Step 5d — design-spec drift. **CHỈ FE/App** (`@trace.platform` = `web`/`app`): thiếu ở FE = **major**; có ở `system`/backend = **minor** (tag thừa, không có design-spec để so) |
|
|
50
|
+
| `@trace.source` | mất con trỏ ngược về spec |
|
|
51
|
+
|
|
52
|
+
- [ ] `@trace.source` trỏ tới file `.feature` **có thật**, đúng platform (`bdd/{platform}/{UC-ID}-{slug}.feature`)? → sai path = **major**
|
|
53
|
+
- [ ] **File phủ nhiều UC: mỗi UC có block tag RIÊNG đặt trên method của nó?** → gộp về một header file, hoặc `@trace.source` trỏ **thư mục**, = **major**. Lý do: 4 tag version là scalar theo từng UC (gộp → Step 4/5/5c/5d báo drift oan hoặc mù drift thật); và các lệnh tra tag bằng **khớp chuỗi chính xác** nên tag trỏ folder ra 0 kết quả → UC rơi về `UNTRACKED` dù code đã có.
|
|
54
|
+
- [ ] Mỗi test file có tag `@trace.verifies={UC-ID}-SC{N}`?
|
|
55
|
+
- [ ] **Không có tag mồ côi** — `@trace.implements`/`@trace.verifies` trỏ tới SC **không tồn tại** trong `.feature`? → **critical** (`TRACE_ORPHAN`; xem `/validate-traces` Step 2b)
|
|
40
56
|
- [ ] Không có tag `@trace` ở sai layer?
|
|
41
57
|
- [ ] `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` cập nhật chưa? (nếu stale → chạy `/validate-traces {UC-ID}` trước, rồi chạy lại review này)
|
|
42
58
|
|
|
@@ -56,6 +72,20 @@ Chờ "Y" rõ ràng trước khi tiếp tục.
|
|
|
56
72
|
- [ ] Mỗi scenario trong .feature có implementation?
|
|
57
73
|
- [ ] Không có endpoint không tài liệu (code không có spec backing)?
|
|
58
74
|
|
|
75
|
+
### 5. Seam & Stub — mồ côi khi ghép luồng
|
|
76
|
+
|
|
77
|
+
*`/generate-code` vừa sinh ra sổ `_seams.tsv` ở bước trước. Đây là lớp lỗi mà **build xanh + test từng-UC xanh** vẫn không bắt được: luồng ghép chạy vào no-op, hoặc hàm thật không ai gọi. `/validate-traces` Step 5b cũng soi — trùng có chủ đích, vì bắt ở đây rẻ hơn (ngay sau codegen, trước khi sinh test).*
|
|
78
|
+
|
|
79
|
+
Đọc sổ `{paths.trace_dir}/{domain}/{prd-slug}/_seams.tsv` (nếu có) + quét code dưới `{code_base_package}`:
|
|
80
|
+
|
|
81
|
+
- [ ] Sổ **0 dòng** `status = READY`? (`READY` = đồng nghĩa cờ 🔴 `SEAM_UNWIRED` / `STUB_UNRESOLVED`) → còn dòng nào = **critical**
|
|
82
|
+
- [ ] Không có class `*Stub*`/`*Mock*` nào **còn là binding đang dùng** trong khi hàng thật đã tồn tại? → `SEAM_UNWIRED`, **critical**
|
|
83
|
+
- [ ] Không có method nào còn `@trace.stub` rỗng trong khi `@trace.stub_owner` **đã gen**? → `STUB_UNRESOLVED`, **critical**
|
|
84
|
+
- [ ] Không có method thật **mồ côi** — logic thật được đẻ **song song** thay vì lấp vào stub cũ (Fill-before-create bị trượt)? → **critical**
|
|
85
|
+
- [ ] Mỗi stub/seam **mới** sinh trong lần này có đủ tag (`@trace.stub` + `@trace.stub_owner` + `@trace.stub_for`, hoặc `@trace.seam_pending` + `@trace.seam_port`) **và** một dòng `PENDING` trong sổ? → thiếu = **major** (nợ không ghi sổ = nợ tàng hình)
|
|
86
|
+
|
|
87
|
+
> `SEAM_PENDING` / `STUB_PENDING` (owner UC chưa gen) là **bình thường** — chỉ nhắc, không tạo finding.
|
|
88
|
+
|
|
59
89
|
## Output
|
|
60
90
|
|
|
61
91
|
{{include:steps/report-footer.md}}
|
|
@@ -76,12 +106,21 @@ Critical: {X} | Major: {Y} | Minor: {Z}
|
|
|
76
106
|
Output Artifacts: none (read-only)
|
|
77
107
|
|
|
78
108
|
Verdict: APPROVED ✅ | NEEDS_FIX ❌
|
|
109
|
+
(Bất kỳ finding critical nào ở lăng kính 5 → NEEDS_FIX, KỂ CẢ khi build xanh
|
|
110
|
+
và test từng-UC xanh — đó chính là loại lỗi hai thứ đó không bắt được.)
|
|
79
111
|
|
|
80
112
|
Nếu APPROVED ✅:
|
|
81
113
|
Next: /dev-gen-test {UC-ID}
|
|
82
114
|
|
|
83
115
|
Nếu NEEDS_FIX ❌:
|
|
84
116
|
- Fix nhỏ (1–3 dòng, không đổi logic) → fix inline → chạy lại /review-code {UC-ID}
|
|
117
|
+
- Thiếu tag version / @trace.source sai → bổ sung tại chỗ (giá trị lấy từ header .feature
|
|
118
|
+
+ tech-doc), rồi chạy lại /validate-traces {UC-ID}
|
|
119
|
+
- Tag mồ côi (TRACE_ORPHAN) → sửa sc_id cho đúng SC hiện có, hoặc xoá code/test
|
|
120
|
+
nếu behavior không còn cần
|
|
121
|
+
- SEAM_UNWIRED 🔴 → trỏ binding sang class thật, xoá/thay stub, build lại
|
|
122
|
+
- STUB_UNRESOLVED 🔴 → /generate-code {owner_uc} (lấp logic TẠI CHỖ vào
|
|
123
|
+
method trắng, xoá hàm song song)
|
|
85
124
|
- Vấn đề logic / kiến trúc → /fix-bug {TICKET_ID}
|
|
86
125
|
- Spec mismatch (code ≠ scenario) → /generate-code {feature-file} (gen lại UC bị ảnh hưởng)
|
|
87
126
|
```
|
|
@@ -35,23 +35,23 @@ Hiển thị và chờ phản hồi:
|
|
|
35
35
|
```
|
|
36
36
|
⚙️ MODEL CHECK
|
|
37
37
|
──────────────────────────────────────────────────────────────────
|
|
38
|
-
Recommended :
|
|
38
|
+
Recommended : model Opus mới nhất
|
|
39
39
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
40
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
40
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
41
41
|
|
|
42
42
|
Cách đổi trong Claude Code:
|
|
43
|
-
•
|
|
44
|
-
• hoặc:
|
|
43
|
+
• /model → chọn model Opus
|
|
44
|
+
• hoặc: Settings → Model
|
|
45
45
|
|
|
46
|
-
Đang chạy
|
|
47
|
-
Y — đúng
|
|
46
|
+
Đang chạy một model Opus?
|
|
47
|
+
Y — đúng → tiếp tục
|
|
48
48
|
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)
|
|
49
49
|
──────────────────────────────────────────────────────────────────
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
- "Y" → tiếp tục sang Bước 1.
|
|
53
53
|
- "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).
|
|
54
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
54
|
+
- "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."
|
|
55
55
|
|
|
56
56
|
## Bước 1 — Xác định Target File
|
|
57
57
|
|
|
@@ -60,7 +60,12 @@ Hiển thị và chờ phản hồi:
|
|
|
60
60
|
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/`):
|
|
61
61
|
- **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 đó.
|
|
62
62
|
- **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.)*
|
|
63
|
-
- **Lệnh tech-docs
|
|
63
|
+
- **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:
|
|
64
|
+
- `$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`.
|
|
65
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
66
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
67
|
+
- 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.
|
|
68
|
+
*(Đừ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
69
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
65
70
|
|
|
66
71
|
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.
|
|
@@ -872,7 +877,7 @@ finding với `check_id: "P5"` và severity phù hợp.
|
|
|
872
877
|
### B1 — PRD Coverage Check
|
|
873
878
|
|
|
874
879
|
Nạp PRD được tham chiếu bởi `# @trace.prd:` trong header file feature.
|
|
875
|
-
Map
|
|
880
|
+
Map các AC/BR **thuộc UC này** sang scenario — tập AC lấy từ dòng `**AC liên quan:**` của UC trong PRD §3, tập BR lấy từ bảng Business Rule của chính UC đó. AC ở PRD là **global cấp PRD** còn `.feature` là **per-UC**, nên KHÔNG đối chiếu toàn bộ §2 (sẽ ra MISSING giả cho AC thuộc UC khác):
|
|
876
881
|
|
|
877
882
|
```
|
|
878
883
|
AC1 ({short text}) → SC1, SC2 ✅
|
|
@@ -920,9 +925,39 @@ Dùng `{paths.business_dictionary}` và `{paths.core_entities}`:
|
|
|
920
925
|
|
|
921
926
|
### B5 — Metadata & Structural Check
|
|
922
927
|
|
|
923
|
-
|
|
924
|
-
|
|
928
|
+
Header file phải đủ field `@trace.*` — kiểm **từng cái tường minh**, chia 3 nhóm theo mức thiệt hại khi thiếu:
|
|
929
|
+
|
|
930
|
+
**Nhóm A — chặn (`major`, `auto_fixable: true`; suy được từ path/PRD, không phải đoán):**
|
|
931
|
+
|
|
932
|
+
| Field | Thiếu thì hỏng gì | Nguồn để auto-fix |
|
|
933
|
+
|---|---|---|
|
|
934
|
+
| `@trace.id` | không định danh được UC | tên file |
|
|
935
|
+
| **`@trace.platform`** | **`/generate-code` không quyết được BE/FE** (`system`→BE · `web`/`app`→FE, và nó **cấm** fallback sang `platform_type`) · không định vị được sổ trace `{UC-ID}-{platform}.tsv` · không tìm được design-spec `-design-spec-{platform}-` · `/generate-tech-docs` + context-loader cũng đọc nó | segment `bdd/{platform}/` của chính path file |
|
|
936
|
+
| `@trace.domain` | routing service + path artifact sai | segment `{domain}/` của path |
|
|
937
|
+
| `@trace.prd` | B1 không nạp được PRD để đối chiếu coverage | `{TICKET-ID}` trong `@trace.id` |
|
|
938
|
+
| `@trace.prd_version` | `/validate-traces` Step 4 mù PRD drift | Metadata PRD |
|
|
939
|
+
| `@trace.bdd_version` | `/validate-traces` Step 5c mù BDD drift · cổng T3b của tech-doc mất mốc so | `1.0` nếu file mới |
|
|
940
|
+
| `@trace.status` | mất cổng duyệt BDD (`/generate-code` DS1) · `uc_status` không sync được | `draft` |
|
|
941
|
+
|
|
942
|
+
> `@trace.platform` là **`major`, không phải `minor`** — nó là field load-bearing nhất của header. Thiếu nó thì cả chuỗi codegen mất phương hướng, mà không lệnh nào báo lỗi.
|
|
943
|
+
|
|
944
|
+
**Nhóm B — thông tin (`minor`, auto-fixable):** `@trace.title`, `@trace.revision`, `@trace.author`, `@trace.created_at`, `@trace.business_rules`, `@trace.dataset`.
|
|
945
|
+
- `@trace.revision` luôn là `1` (field tĩnh — xem generate-bdd.tmpl). Chỉ kiểm **có mặt**; KHÔNG gắn cờ giá trị là stale.
|
|
946
|
+
|
|
947
|
+
**Nhóm C — có điều kiện (chỉ flag khi điều kiện đúng; vắng trong ca còn lại là ĐÚNG, không tạo finding):**
|
|
948
|
+
|
|
949
|
+
| Field | Bắt buộc khi | Vắng khi nào là đúng |
|
|
950
|
+
|---|---|---|
|
|
951
|
+
| `@trace.module` | umbrella mode | spec repo mode; giá trị `unknown` cũng **hợp lệ**, không flag |
|
|
952
|
+
| `@trace.api_source` | `@trace.platform = system` **và** PRD Metadata có `API Source: existing` | mọi ca khác (greenfield / FE / App) |
|
|
953
|
+
|
|
954
|
+
> **Đừng flag Nhóm C khi không đúng điều kiện.** Trước đây B5 đòi `@trace.module` vô điều kiện, nên mọi `.feature` **đúng-theo-template** ở spec repo mode đều ăn finding minor — và `--fix` sẽ **thêm field bịa** vào header. Nhiễu review + làm bẩn spec.
|
|
955
|
+
|
|
956
|
+
> **`@trace.service` đã RỜI Nhóm C — giờ bắt buộc MỌI mode (`major`).** Từ khi trace TSV có cột `service` (cột 23), tag này là **nguồn duy nhất** của cột đó, và trace gộp (`spec_source`) **không tách theo service** — nên thiếu nó là mất hẳn thông tin sở hữu ở cấp row: dashboard không nhóm được coverage theo đội, `/validate-traces` không nói được "service X còn N chỗ lệch". Giá trị hợp lệ ở **mọi** mode: path service · `multi` (chưa chốt) · `unresolved` (routing sai) · `—` (single-service / spec repo mode). Auto-fix: suy từ `services.{domain}` trong `project-context.yaml`; không suy được → điền `—` ở single-service, hoặc `unresolved` kèm finding **major** ở umbrella (đó là lỗi cấu hình routing thật, đừng che).
|
|
957
|
+
|
|
925
958
|
- [ ] Mỗi scenario có `# @trace.scenario`, `# @trace.sc_version`, `# @trace.business_rules`, `# Side-effects:` → **minor**, auto-fixable
|
|
959
|
+
- **Ngoại lệ `@trace.sc_version` → `major`:** 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`). Thiếu nó thì SC đó **vĩnh viễn** hiện `OK` dù scenario có đổi bao nhiêu lần. Auto-fix: thêm `1.0`.
|
|
960
|
+
- [ ] Không còn tag lạc ngoài contract — cụ thể `@trace.uc=` / `@trace.ac=` (vocabulary của proposal cũ, xem G11) hoặc tag vòng đời `@proposed` / `@from-test` rò vào BDD canonical → **minor**, auto-fixable (map sang `@trace.scenario`/`# Covers:`, strip tag vòng đời)
|
|
926
961
|
- [ ] Coverage Matrix ở cuối file → **major**, auto-fixable (AI sinh lại)
|
|
927
962
|
- [ ] Pre-merge Checklist ở cuối file → **minor**, auto-fixable
|
|
928
963
|
|
|
@@ -1030,7 +1065,7 @@ Tìm lệnh hiện tại trong bảng phase dưới đây và đánh dấu **pha
|
|
|
1030
1065
|
| Phase | Commands |
|
|
1031
1066
|
|-------|----------|
|
|
1032
1067
|
| Discovery | `/define-product` |
|
|
1033
|
-
| PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
1068
|
+
| PRD | `/generate-prd` · `/extend-prd` · `/refine-prd` · `/review-context` (PRD) |
|
|
1034
1069
|
| Design Spec | `/generate-design-spec` |
|
|
1035
1070
|
| BDD | `/generate-bdd` · `/review-context` (BDD) |
|
|
1036
1071
|
| Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
|
|
@@ -1055,6 +1090,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1055
1090
|
| /setup-ai-first | `/define-product` để bắt đầu feature đầu tiên |
|
|
1056
1091
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
1057
1092
|
| /generate-prd | `/refine-prd {prd-file}` rồi `/review-context {prd-file}` |
|
|
1093
|
+
| /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}` |
|
|
1058
1094
|
| /refine-prd | Mở Review Board → cập nhật PRD → `/review-context {prd-file}` |
|
|
1059
1095
|
| /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) |
|
|
1060
1096
|
| /generate-design-spec | Designer review → xác nhận link Figma → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
@@ -1067,6 +1103,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1067
1103
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1068
1104
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1069
1105
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1106
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1070
1107
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1071
1108
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1072
1109
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1075,11 +1112,11 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1075
1112
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1076
1113
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1077
1114
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1078
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1079
|
-
| /fix-bug |
|
|
1115
|
+
| /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** |
|
|
1116
|
+
| /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 |
|
|
1080
1117
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1081
1118
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1082
|
-
| /propose-scenario |
|
|
1119
|
+
| /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` |
|
|
1083
1120
|
| /learn | Tiếp tục làm việc — lesson áp dụng ở lệnh kế tiếp |
|
|
1084
1121
|
| /sync | `/validate-traces` để xem độ phủ đầy đủ; xử lý mọi `📥 tester feedback` được nêu |
|
|
1085
1122
|
| /update-framework | Review `git diff .agent/`, commit; `/sync` để đồng bộ nội dung dự án |
|
|
@@ -1173,6 +1210,9 @@ Sau khi áp dụng mỗi finding, đánh dấu nó `status: "applied"` + `applie
|
|
|
1173
1210
|
- **PRD**: nếu ≥1 finding được áp dụng → bump version **minor** (auto-fix chỉ áp dụng thay banned-term P1 và thêm skeleton P4 — không bao giờ thay đổi cấu trúc UC hay nội dung BR, nên minor bump luôn đúng), **reset `| **Status** | draft |` trong Metadata** (PRD vừa đổi sau khi duyệt → con dấu duyệt cũ hết hiệu lực, phải duyệt lại — đồng bộ với /refine-prd), thêm entry Changelog:
|
|
1174
1211
|
`| {new_version} | {today} | Auto-fix: applied {N} auto-fixable findings |` — bảng phẳng + **rollover giữ 5 row gần nhất** (dồn dư sang `changelog/{TICKET-ID}-{prd-slug}.changelog.md`); xem quy ước đầy đủ ở refine-prd Phase 3.
|
|
1175
1212
|
- **BDD**: nếu ≥1 finding được áp dụng → tăng `@trace.bdd_version` lên 0.1, **reset `# @trace.status: draft`** trong header (BDD đổi sau khi duyệt → phải duyệt lại — đồng bộ với cơ chế reset draft của PRD)
|
|
1213
|
+
- **BDD — `@trace.sc_version` theo từng scenario (BẮT BUỘC):** với **mỗi scenario có ≥1 finding được áp dụng làm đổi thân nó** — R3 (diễn đạt lại step), R7 (thay giá trị cụ thể), R9 (thêm cột data table), R10 (thêm Note), B6 (thêm `And` side-effect), B2 (đổi tên entity/field trong step/table) — tăng `# @trace.sc_version` của **đúng scenario đó** lên 0.1. Scenario không bị sửa → **giữ nguyên**.
|
|
1214
|
+
- Đây 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`). `bdd_version` ở cấp file không đủ phân giải để biết SC nào cần regen.
|
|
1215
|
+
- Finding **không** đổi thân scenario (sửa header file, thêm Coverage Matrix/Pre-merge Checklist, đổi `@trace.business_rules`, C.5 gom NHÓM) → **KHÔNG** bump: code không cần sinh lại. Bump vô cớ tạo `DRIFT` giả và làm cờ mất giá trị.
|
|
1176
1216
|
- **Cả hai**: ghi `applied_to_version: "{version vừa bump tới}"` ở root level của findings — đóng dấu "target đổi tới version này là do lệnh này áp", để lần review delta sau phân biệt thay đổi của chính mình với thay đổi do actor khác (xem "Chọn full vs delta").
|
|
1177
1217
|
|
|
1178
1218
|
### Phase 4 — Report
|
|
@@ -1190,6 +1230,8 @@ Còn pending (cần quyết định của con người): {N}
|
|
|
1190
1230
|
|
|
1191
1231
|
{If PRD}: Version bumped: {old} → {new} | Status: reset về draft (cần duyệt lại)
|
|
1192
1232
|
{If BDD}: bdd_version: {old} → {new} | @trace.status: reset về draft (cần duyệt lại)
|
|
1233
|
+
{If BDD, chỉ khi có ≥1 SC bump}: sc_version: {UC-ID}-SC2 1.0→1.1, {UC-ID}-SC5 1.2→1.3
|
|
1234
|
+
↳ {n} SC này sẽ hiện DRIFT ở /validate-traces → /generate-code {feature-file} để sinh lại
|
|
1193
1235
|
|
|
1194
1236
|
File findings:
|
|
1195
1237
|
{If PRD}: {paths.refinement_dir}/{prd-slug}-review-context-findings.yaml
|
|
@@ -1250,11 +1292,13 @@ Với mỗi finding `accepted`/`modified` sau khi áp xong → đặt `status: "
|
|
|
1250
1292
|
| B2 (Terminology) | Thay banned term, fix tên entity/field |
|
|
1251
1293
|
| B3 (Gherkin rule) | Áp dụng fix theo từng rule (thay tech term, thêm giá trị cụ thể, v.v.) |
|
|
1252
1294
|
| B4 (Compliance) | Thêm NHÓM grouping, fix tag @trace |
|
|
1253
|
-
| B5 (Metadata) | Thêm
|
|
1295
|
+
| B5 (Metadata) | Thêm `@trace.*` header còn thiếu, sinh lại Coverage Matrix / Pre-merge Checklist. **Nguồn giá trị, không đoán:** `@trace.platform` ← segment `bdd/{platform}/` của path file · `@trace.domain` ← segment `{domain}/` · `@trace.prd*` ← PRD · `@trace.sc_version` thiếu → `1.0`. **KHÔNG bịa** `@trace.service`/`@trace.module` ở spec repo mode (vắng là đúng — Nhóm C). Tag lạc `@trace.uc`/`@trace.ac`/`@proposed` → map sang canonical rồi strip. |
|
|
1254
1296
|
| B6 (Side effects) | Thêm `And <side-effect>` còn thiếu vào block Then |
|
|
1255
1297
|
|
|
1256
1298
|
→ Sau khi áp dụng, tăng `@trace.bdd_version` trong header file lên 0.1, **reset `# @trace.status: draft`** trong header (BDD đổi sau khi duyệt → phải duyệt lại).
|
|
1299
|
+
→ **Bump `# @trace.sc_version` +0.1 cho mỗi scenario có finding làm đổi thân nó** (B1 sinh mới → `1.0`; B2/B3/B6 sửa step/table/side-effect → bump; B4/B5 chỉ sửa header·NHÓM·Coverage Matrix → **KHÔNG** bump). Quy tắc đầy đủ + lý do: xem Phase 3 của `--fix`.
|
|
1257
1300
|
→ Đồng thời cập nhật **sổ của platform đang review** `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{@trace.platform}.tsv` (platform lấy từ header `.feature` đang review): đặt cột `bdd_version` thành giá trị `@trace.bdd_version` mới cho mọi row (của sổ này), đặt `uc_status = draft` (khớp header), và đặt `last_updated` thành ngày hôm nay.
|
|
1301
|
+
→ Với các SC vừa bump: đặt cột `spec_ver` = `@trace.sc_version` mới (giữ nguyên `gen_ver` → row hiện `DRIFT` đúng như mong đợi). Với SC **mới** do B1 sinh: append row mới, `spec_ver = 1.0`, các cột gen/test/qc = `—`, `status = UNTRACKED`. *(Nếu bỏ qua bước này, `/validate-traces` Step 2 vẫn tự reconcile ở lần chạy sau — nhưng dashboard sẽ trễ một nhịp.)*
|
|
1258
1302
|
→ Ghi `applied_to_version: "{@trace.bdd_version mới}"` ở root level của findings (xem "Chọn full vs delta").
|
|
1259
1303
|
|
|
1260
1304
|
### Phase 3 — Report
|
|
@@ -1270,6 +1314,8 @@ Changes:
|
|
|
1270
1314
|
|
|
1271
1315
|
{If PRD}: Version bumped: {old} → {new} | Status: reset về draft (cần duyệt lại)
|
|
1272
1316
|
{If BDD}: bdd_version: {old} → {new} | @trace.status: reset về draft (cần duyệt lại)
|
|
1317
|
+
{If BDD, chỉ khi có ≥1 SC bump}: sc_version: {UC-ID}-SC2 1.0→1.1, {UC-ID}-SC5 1.2→1.3
|
|
1318
|
+
↳ {n} SC này sẽ hiện DRIFT ở /validate-traces → /generate-code {feature-file} để sinh lại
|
|
1273
1319
|
|
|
1274
1320
|
Chạy lại /review-context {file} để xác nhận 0 finding critical còn lại.
|
|
1275
1321
|
{If PRD}: Khi sạch critical + PO duyệt → đặt | **Status** | approved | trong Metadata rồi /generate-bdd.
|
|
@@ -183,7 +183,7 @@ finding với `check_id: "P5"` và severity phù hợp.
|
|
|
183
183
|
### B1 — PRD Coverage Check
|
|
184
184
|
|
|
185
185
|
Nạp PRD được tham chiếu bởi `# @trace.prd:` trong header file feature.
|
|
186
|
-
Map
|
|
186
|
+
Map các AC/BR **thuộc UC này** sang scenario — tập AC lấy từ dòng `**AC liên quan:**` của UC trong PRD §3, tập BR lấy từ bảng Business Rule của chính UC đó. AC ở PRD là **global cấp PRD** còn `.feature` là **per-UC**, nên KHÔNG đối chiếu toàn bộ §2 (sẽ ra MISSING giả cho AC thuộc UC khác):
|
|
187
187
|
|
|
188
188
|
```
|
|
189
189
|
AC1 ({short text}) → SC1, SC2 ✅
|
|
@@ -231,9 +231,39 @@ Dùng `{paths.business_dictionary}` và `{paths.core_entities}`:
|
|
|
231
231
|
|
|
232
232
|
### B5 — Metadata & Structural Check
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
234
|
+
Header file phải đủ field `@trace.*` — kiểm **từng cái tường minh**, chia 3 nhóm theo mức thiệt hại khi thiếu:
|
|
235
|
+
|
|
236
|
+
**Nhóm A — chặn (`major`, `auto_fixable: true`; suy được từ path/PRD, không phải đoán):**
|
|
237
|
+
|
|
238
|
+
| Field | Thiếu thì hỏng gì | Nguồn để auto-fix |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| `@trace.id` | không định danh được UC | tên file |
|
|
241
|
+
| **`@trace.platform`** | **`/generate-code` không quyết được BE/FE** (`system`→BE · `web`/`app`→FE, và nó **cấm** fallback sang `platform_type`) · không định vị được sổ trace `{UC-ID}-{platform}.tsv` · không tìm được design-spec `-design-spec-{platform}-` · `/generate-tech-docs` + context-loader cũng đọc nó | segment `bdd/{platform}/` của chính path file |
|
|
242
|
+
| `@trace.domain` | routing service + path artifact sai | segment `{domain}/` của path |
|
|
243
|
+
| `@trace.prd` | B1 không nạp được PRD để đối chiếu coverage | `{TICKET-ID}` trong `@trace.id` |
|
|
244
|
+
| `@trace.prd_version` | `/validate-traces` Step 4 mù PRD drift | Metadata PRD |
|
|
245
|
+
| `@trace.bdd_version` | `/validate-traces` Step 5c mù BDD drift · cổng T3b của tech-doc mất mốc so | `1.0` nếu file mới |
|
|
246
|
+
| `@trace.status` | mất cổng duyệt BDD (`/generate-code` DS1) · `uc_status` không sync được | `draft` |
|
|
247
|
+
|
|
248
|
+
> `@trace.platform` là **`major`, không phải `minor`** — nó là field load-bearing nhất của header. Thiếu nó thì cả chuỗi codegen mất phương hướng, mà không lệnh nào báo lỗi.
|
|
249
|
+
|
|
250
|
+
**Nhóm B — thông tin (`minor`, auto-fixable):** `@trace.title`, `@trace.revision`, `@trace.author`, `@trace.created_at`, `@trace.business_rules`, `@trace.dataset`.
|
|
251
|
+
- `@trace.revision` luôn là `1` (field tĩnh — xem generate-bdd.tmpl). Chỉ kiểm **có mặt**; KHÔNG gắn cờ giá trị là stale.
|
|
252
|
+
|
|
253
|
+
**Nhóm C — có điều kiện (chỉ flag khi điều kiện đúng; vắng trong ca còn lại là ĐÚNG, không tạo finding):**
|
|
254
|
+
|
|
255
|
+
| Field | Bắt buộc khi | Vắng khi nào là đúng |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `@trace.module` | umbrella mode | spec repo mode; giá trị `unknown` cũng **hợp lệ**, không flag |
|
|
258
|
+
| `@trace.api_source` | `@trace.platform = system` **và** PRD Metadata có `API Source: existing` | mọi ca khác (greenfield / FE / App) |
|
|
259
|
+
|
|
260
|
+
> **Đừng flag Nhóm C khi không đúng điều kiện.** Trước đây B5 đòi `@trace.module` vô điều kiện, nên mọi `.feature` **đúng-theo-template** ở spec repo mode đều ăn finding minor — và `--fix` sẽ **thêm field bịa** vào header. Nhiễu review + làm bẩn spec.
|
|
261
|
+
|
|
262
|
+
> **`@trace.service` đã RỜI Nhóm C — giờ bắt buộc MỌI mode (`major`).** Từ khi trace TSV có cột `service` (cột 23), tag này là **nguồn duy nhất** của cột đó, và trace gộp (`spec_source`) **không tách theo service** — nên thiếu nó là mất hẳn thông tin sở hữu ở cấp row: dashboard không nhóm được coverage theo đội, `/validate-traces` không nói được "service X còn N chỗ lệch". Giá trị hợp lệ ở **mọi** mode: path service · `multi` (chưa chốt) · `unresolved` (routing sai) · `—` (single-service / spec repo mode). Auto-fix: suy từ `services.{domain}` trong `project-context.yaml`; không suy được → điền `—` ở single-service, hoặc `unresolved` kèm finding **major** ở umbrella (đó là lỗi cấu hình routing thật, đừng che).
|
|
263
|
+
|
|
236
264
|
- [ ] Mỗi scenario có `# @trace.scenario`, `# @trace.sc_version`, `# @trace.business_rules`, `# Side-effects:` → **minor**, auto-fixable
|
|
265
|
+
- **Ngoại lệ `@trace.sc_version` → `major`:** 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`). Thiếu nó thì SC đó **vĩnh viễn** hiện `OK` dù scenario có đổi bao nhiêu lần. Auto-fix: thêm `1.0`.
|
|
266
|
+
- [ ] Không còn tag lạc ngoài contract — cụ thể `@trace.uc=` / `@trace.ac=` (vocabulary của proposal cũ, xem G11) hoặc tag vòng đời `@proposed` / `@from-test` rò vào BDD canonical → **minor**, auto-fixable (map sang `@trace.scenario`/`# Covers:`, strip tag vòng đời)
|
|
237
267
|
- [ ] Coverage Matrix ở cuối file → **major**, auto-fixable (AI sinh lại)
|
|
238
268
|
- [ ] Pre-merge Checklist ở cuối file → **minor**, auto-fixable
|
|
239
269
|
|
|
@@ -384,6 +414,9 @@ Sau khi áp dụng mỗi finding, đánh dấu nó `status: "applied"` + `applie
|
|
|
384
414
|
- **PRD**: nếu ≥1 finding được áp dụng → bump version **minor** (auto-fix chỉ áp dụng thay banned-term P1 và thêm skeleton P4 — không bao giờ thay đổi cấu trúc UC hay nội dung BR, nên minor bump luôn đúng), **reset `| **Status** | draft |` trong Metadata** (PRD vừa đổi sau khi duyệt → con dấu duyệt cũ hết hiệu lực, phải duyệt lại — đồng bộ với /refine-prd), thêm entry Changelog:
|
|
385
415
|
`| {new_version} | {today} | Auto-fix: applied {N} auto-fixable findings |` — bảng phẳng + **rollover giữ 5 row gần nhất** (dồn dư sang `changelog/{TICKET-ID}-{prd-slug}.changelog.md`); xem quy ước đầy đủ ở refine-prd Phase 3.
|
|
386
416
|
- **BDD**: nếu ≥1 finding được áp dụng → tăng `@trace.bdd_version` lên 0.1, **reset `# @trace.status: draft`** trong header (BDD đổi sau khi duyệt → phải duyệt lại — đồng bộ với cơ chế reset draft của PRD)
|
|
417
|
+
- **BDD — `@trace.sc_version` theo từng scenario (BẮT BUỘC):** với **mỗi scenario có ≥1 finding được áp dụng làm đổi thân nó** — R3 (diễn đạt lại step), R7 (thay giá trị cụ thể), R9 (thêm cột data table), R10 (thêm Note), B6 (thêm `And` side-effect), B2 (đổi tên entity/field trong step/table) — tăng `# @trace.sc_version` của **đúng scenario đó** lên 0.1. Scenario không bị sửa → **giữ nguyên**.
|
|
418
|
+
- Đây 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`). `bdd_version` ở cấp file không đủ phân giải để biết SC nào cần regen.
|
|
419
|
+
- Finding **không** đổi thân scenario (sửa header file, thêm Coverage Matrix/Pre-merge Checklist, đổi `@trace.business_rules`, C.5 gom NHÓM) → **KHÔNG** bump: code không cần sinh lại. Bump vô cớ tạo `DRIFT` giả và làm cờ mất giá trị.
|
|
387
420
|
- **Cả hai**: ghi `applied_to_version: "{version vừa bump tới}"` ở root level của findings — đóng dấu "target đổi tới version này là do lệnh này áp", để lần review delta sau phân biệt thay đổi của chính mình với thay đổi do actor khác (xem "Chọn full vs delta").
|
|
388
421
|
|
|
389
422
|
### Phase 4 — Report
|
|
@@ -401,6 +434,8 @@ Còn pending (cần quyết định của con người): {N}
|
|
|
401
434
|
|
|
402
435
|
{If PRD}: Version bumped: {old} → {new} | Status: reset về draft (cần duyệt lại)
|
|
403
436
|
{If BDD}: bdd_version: {old} → {new} | @trace.status: reset về draft (cần duyệt lại)
|
|
437
|
+
{If BDD, chỉ khi có ≥1 SC bump}: sc_version: {UC-ID}-SC2 1.0→1.1, {UC-ID}-SC5 1.2→1.3
|
|
438
|
+
↳ {n} SC này sẽ hiện DRIFT ở /validate-traces → /generate-code {feature-file} để sinh lại
|
|
404
439
|
|
|
405
440
|
File findings:
|
|
406
441
|
{If PRD}: {paths.refinement_dir}/{prd-slug}-review-context-findings.yaml
|
|
@@ -461,11 +496,13 @@ Với mỗi finding `accepted`/`modified` sau khi áp xong → đặt `status: "
|
|
|
461
496
|
| B2 (Terminology) | Thay banned term, fix tên entity/field |
|
|
462
497
|
| B3 (Gherkin rule) | Áp dụng fix theo từng rule (thay tech term, thêm giá trị cụ thể, v.v.) |
|
|
463
498
|
| B4 (Compliance) | Thêm NHÓM grouping, fix tag @trace |
|
|
464
|
-
| B5 (Metadata) | Thêm
|
|
499
|
+
| B5 (Metadata) | Thêm `@trace.*` header còn thiếu, sinh lại Coverage Matrix / Pre-merge Checklist. **Nguồn giá trị, không đoán:** `@trace.platform` ← segment `bdd/{platform}/` của path file · `@trace.domain` ← segment `{domain}/` · `@trace.prd*` ← PRD · `@trace.sc_version` thiếu → `1.0`. **KHÔNG bịa** `@trace.service`/`@trace.module` ở spec repo mode (vắng là đúng — Nhóm C). Tag lạc `@trace.uc`/`@trace.ac`/`@proposed` → map sang canonical rồi strip. |
|
|
465
500
|
| B6 (Side effects) | Thêm `And <side-effect>` còn thiếu vào block Then |
|
|
466
501
|
|
|
467
502
|
→ Sau khi áp dụng, tăng `@trace.bdd_version` trong header file lên 0.1, **reset `# @trace.status: draft`** trong header (BDD đổi sau khi duyệt → phải duyệt lại).
|
|
503
|
+
→ **Bump `# @trace.sc_version` +0.1 cho mỗi scenario có finding làm đổi thân nó** (B1 sinh mới → `1.0`; B2/B3/B6 sửa step/table/side-effect → bump; B4/B5 chỉ sửa header·NHÓM·Coverage Matrix → **KHÔNG** bump). Quy tắc đầy đủ + lý do: xem Phase 3 của `--fix`.
|
|
468
504
|
→ Đồng thời cập nhật **sổ của platform đang review** `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{@trace.platform}.tsv` (platform lấy từ header `.feature` đang review): đặt cột `bdd_version` thành giá trị `@trace.bdd_version` mới cho mọi row (của sổ này), đặt `uc_status = draft` (khớp header), và đặt `last_updated` thành ngày hôm nay.
|
|
505
|
+
→ Với các SC vừa bump: đặt cột `spec_ver` = `@trace.sc_version` mới (giữ nguyên `gen_ver` → row hiện `DRIFT` đúng như mong đợi). Với SC **mới** do B1 sinh: append row mới, `spec_ver = 1.0`, các cột gen/test/qc = `—`, `status = UNTRACKED`. *(Nếu bỏ qua bước này, `/validate-traces` Step 2 vẫn tự reconcile ở lần chạy sau — nhưng dashboard sẽ trễ một nhịp.)*
|
|
469
506
|
→ Ghi `applied_to_version: "{@trace.bdd_version mới}"` ở root level của findings (xem "Chọn full vs delta").
|
|
470
507
|
|
|
471
508
|
### Phase 3 — Report
|
|
@@ -481,6 +518,8 @@ Changes:
|
|
|
481
518
|
|
|
482
519
|
{If PRD}: Version bumped: {old} → {new} | Status: reset về draft (cần duyệt lại)
|
|
483
520
|
{If BDD}: bdd_version: {old} → {new} | @trace.status: reset về draft (cần duyệt lại)
|
|
521
|
+
{If BDD, chỉ khi có ≥1 SC bump}: sc_version: {UC-ID}-SC2 1.0→1.1, {UC-ID}-SC5 1.2→1.3
|
|
522
|
+
↳ {n} SC này sẽ hiện DRIFT ở /validate-traces → /generate-code {feature-file} để sinh lại
|
|
484
523
|
|
|
485
524
|
Chạy lại /review-context {file} để xác nhận 0 finding critical còn lại.
|
|
486
525
|
{If PRD}: Khi sạch critical + PO duyệt → đặt | **Status** | approved | trong Metadata rồi /generate-bdd.
|