@educa-corp/sdd-framework 0.4.0 → 0.4.2
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 +236 -0
- package/bin/trace-schema.json +692 -0
- package/commands/debug.md +16 -10
- package/commands/define-product.md +16 -10
- package/commands/dev-gen-test.md +16 -10
- package/commands/dev-run-test.md +18 -11
- package/commands/dev-run-test.tmpl +2 -1
- package/commands/dev-smoke-test.md +16 -10
- package/commands/fix-bug.md +71 -13
- package/commands/fix-bug.tmpl +29 -3
- package/commands/generate-architecture.md +16 -10
- package/commands/generate-bdd.md +118 -35
- package/commands/generate-bdd.tmpl +89 -15
- package/commands/generate-code.md +49 -13
- package/commands/generate-code.tmpl +33 -3
- package/commands/generate-design-spec.md +16 -10
- package/commands/generate-prd.md +16 -10
- package/commands/generate-spec-manifest.md +16 -10
- package/commands/generate-tech-docs.md +19 -13
- package/commands/generate-tech-docs.tmpl +2 -2
- package/commands/learn.md +16 -10
- package/commands/map-testids.md +16 -10
- package/commands/propose-scenario.md +36 -12
- package/commands/propose-scenario.tmpl +20 -2
- package/commands/qc-analyze.md +16 -10
- package/commands/qc-design-test.md +16 -10
- package/commands/qc-plan.md +16 -10
- package/commands/qc-report.md +16 -10
- package/commands/qc-review.md +16 -10
- package/commands/qc-run-test.md +38 -12
- package/commands/qc-run-test.tmpl +22 -2
- package/commands/refine-prd.md +16 -10
- package/commands/report-bug.md +16 -10
- package/commands/review-code.md +56 -12
- package/commands/review-code.tmpl +40 -2
- package/commands/review-context.md +58 -14
- package/commands/review-context.tmpl +42 -4
- package/commands/review-tech-docs.md +47 -12
- package/commands/review-tech-docs.tmpl +31 -2
- package/commands/setup-ai-first.md +23 -14
- package/commands/setup-ai-first.tmpl +7 -4
- package/commands/sync.md +3 -2
- package/commands/update-framework.md +40 -2
- package/commands/update-framework.tmpl +37 -0
- package/commands/validate-traces.md +165 -18
- package/commands/validate-traces.tmpl +149 -8
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/README.md +56 -0
- package/core/commands/debug.md +16 -10
- package/core/commands/define-product.md +16 -10
- package/core/commands/dev-gen-test.md +16 -10
- package/core/commands/dev-run-test.md +18 -11
- package/core/commands/dev-smoke-test.md +16 -10
- package/core/commands/fix-bug.md +71 -13
- package/core/commands/generate-architecture.md +16 -10
- package/core/commands/generate-bdd.md +118 -35
- package/core/commands/generate-code.md +49 -13
- package/core/commands/generate-design-spec.md +16 -10
- package/core/commands/generate-prd.md +16 -10
- package/core/commands/generate-spec-manifest.md +16 -10
- package/core/commands/generate-tech-docs.md +19 -13
- package/core/commands/learn.md +16 -10
- package/core/commands/map-testids.md +16 -10
- package/core/commands/propose-scenario.md +36 -12
- package/core/commands/qc-analyze.md +16 -10
- package/core/commands/qc-design-test.md +16 -10
- package/core/commands/qc-plan.md +16 -10
- package/core/commands/qc-report.md +16 -10
- package/core/commands/qc-review.md +16 -10
- package/core/commands/qc-run-test.md +38 -12
- package/core/commands/refine-prd.md +16 -10
- package/core/commands/report-bug.md +16 -10
- package/core/commands/review-code.md +56 -12
- package/core/commands/review-context.md +58 -14
- package/core/commands/review-tech-docs.md +47 -12
- package/core/commands/setup-ai-first.md +23 -14
- package/core/commands/sync.md +3 -2
- package/core/commands/update-framework.md +40 -2
- package/core/commands/validate-traces.md +165 -18
- 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 +11 -0
- package/core/steps/gate.md +13 -8
- package/core/steps/report-footer.md +3 -2
- package/core/templates/README.md +47 -0
- package/core/templates/feature.template +13 -10
- package/core/templates/project-context.yaml +26 -14
- package/core/templates/tech-design.template.md +1 -1
- package/docs/02-concepts/traceability.md +29 -6
- package/docs/04-reference/trace-schema.md +128 -37
- 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 +50 -49
- package/rules/workflow.md +11 -0
- package/scripts/migrate-bdd-platform.js +286 -0
- package/steps/gate.md +13 -8
- package/steps/report-footer.md +3 -2
- package/templates/README.md +47 -0
- package/templates/feature.template +13 -10
- package/templates/project-context.yaml +26 -14
- package/templates/tech-design.template.md +1 -1
|
@@ -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.
|
|
@@ -537,6 +542,14 @@ Lệnh này giới hạn nghiêm ngặt trong **một file feature** được tr
|
|
|
537
542
|
```
|
|
538
543
|
Chỉ tiếp khi Y. *(Khác FE: FE degrade êm để prototype qua mock; BE thì contract là sản phẩm chính → chặn mềm.)*
|
|
539
544
|
- **Có §4 nhưng `@trace.status = draft/in-review`, HOẶC §12 GAP Register còn 🔴 blocker `open` chạm UC này** → WARN (không chặn): "contract chưa chốt / còn {n} blocker-GAP open — có thể phải rework khi contract đổi."
|
|
545
|
+
- **Tech-doc lỗi thời so với BDD** — so entry `{@trace.platform}` trong map `@trace.bdd_versions` của tech-doc vs `@trace.bdd_version` của `.feature` target. Tech-doc **cũ hơn** → WARN (không chặn), kể cả khi `@trace.status: approved`:
|
|
546
|
+
```
|
|
547
|
+
⚠️ §4 contract dựng từ BDD v{old}, .feature này giờ v{new}.
|
|
548
|
+
Doc vẫn 'approved' nên shape dưới đây được lấy nguyên văn — nhưng nó phản ánh
|
|
549
|
+
behavior CŨ. Nếu BDD đổi request/response/error thì code sinh ra sẽ sai từ nguồn.
|
|
550
|
+
Khuyến nghị: /generate-tech-docs {feature-file} → /review-tech-docs (cổng T3b) trước.
|
|
551
|
+
```
|
|
552
|
+
*(Chỉ WARN chứ không chặn: BDD hay bump vì lý do không chạm contract — sửa từ ngữ step, thêm side-effect assertion. Người đọc warning là người biết. `/validate-traces` giữ cờ `TECHDOC_STALE_VS_BDD` song song.)*
|
|
540
553
|
- **Có §4 + `@trace.status: approved` + 0 blocker-GAP** → dùng §4 làm nguồn contract (shape DTO/endpoint/error lấy nguyên văn từ đây, KHÔNG tự chế).
|
|
541
554
|
|
|
542
555
|
---
|
|
@@ -679,6 +692,7 @@ Phân giải design điều khiển adapter từ **tech-doc gộp của PRD** `{
|
|
|
679
692
|
| `DRIFT` | `spec_ver != gen_ver` | Sửa **tại chỗ đúng method** của scenario đó (Edit) — KHÔNG viết lại cả file (file chung sẽ mất method UC khác) |
|
|
680
693
|
| `OK` | đã implement + test | Skip trừ khi gen lại tường minh |
|
|
681
694
|
| `GAP` | đã implement, chưa test | Skip codegen — đã code rồi; chạy `/dev-gen-test` thay vì |
|
|
695
|
+
| `ORPHANED` | SC không còn trong `.feature` nhưng code còn | **Skip codegen** — không có scenario nào để implement. **KHÔNG xoá** code/row (cần người quyết định behavior đó còn cần hay không). Nêu ở report cuối: `⚠️ {sc_id} ORPHANED — code {implemented_by} còn tồn tại nhưng scenario đã bị xoá khỏi .feature. Xử: xoá code+test, hoặc đưa scenario trở lại. (/validate-traces giữ cờ 🔴.)` |
|
|
682
696
|
|
|
683
697
|
Dùng các status này để điền số **Scenarios** trong plan CHECKPOINT (`{X} new, {Y} drifted, {Z} synced-skip`).
|
|
684
698
|
Nếu `.tsv` không tồn tại → coi mọi scenario là `UNTRACKED`.
|
|
@@ -874,7 +888,7 @@ DTOs → Entity/Model → Repository → Service interface → Service impl →
|
|
|
874
888
|
@trace.prd_version={đọc @trace.prd_version từ header file .feature}
|
|
875
889
|
@trace.bdd_version={đọc @trace.bdd_version từ header file .feature}
|
|
876
890
|
@trace.tech_doc_revision={đọc @trace.revision từ header tech-doc, hoặc bỏ nếu không có tech-doc}
|
|
877
|
-
@trace.source={paths.specs_dir}/{domain}/{prd-slug}/bdd/{UC-ID}-{slug}.feature
|
|
891
|
+
@trace.source={paths.specs_dir}/{domain}/{prd-slug}/bdd/{@trace.platform}/{UC-ID}-{slug}.feature
|
|
878
892
|
```
|
|
879
893
|
|
|
880
894
|
`@trace.prd_version` ghi code này được viết theo version PRD nào.
|
|
@@ -884,6 +898,27 @@ DTOs → Entity/Model → Repository → Service interface → Service impl →
|
|
|
884
898
|
|
|
885
899
|
> **Quy tắc entry-point:** `@trace.implements` phải xuất hiện ở **layer entry-point** như định nghĩa trong `CLAUDE.md §2`. Với REST API → Controller. Với module event-driven → event handler / consumer class. Với context-engineering → hàm orchestration prompt. Không bao giờ chỉ đặt ở layer trong.
|
|
886
900
|
|
|
901
|
+
> **File phủ NHIỀU UC → lặp CẢ BLOCK 5 tag, đặt trên method của từng UC. CẤM trỏ thư mục, CẤM gộp về một header file.**
|
|
902
|
+
>
|
|
903
|
+
> Đây là hình dạng đúng:
|
|
904
|
+
> ```
|
|
905
|
+
> // @trace.implements=USR-UC1-SC3
|
|
906
|
+
> // @trace.prd_version=1.2 @trace.bdd_version=1.4 @trace.tech_doc_revision=3
|
|
907
|
+
> // @trace.source=specs/user/create-account/bdd/system/USR-UC1-create-account.feature
|
|
908
|
+
> public AccountDto createAccount(...) { }
|
|
909
|
+
>
|
|
910
|
+
> // @trace.implements=USR-UC3-SC1
|
|
911
|
+
> // @trace.prd_version=2.0 @trace.bdd_version=2.1 @trace.tech_doc_revision=5
|
|
912
|
+
> // @trace.source=specs/user/create-account/bdd/system/USR-UC3-verify-email.feature
|
|
913
|
+
> public void verifyEmail(...) { }
|
|
914
|
+
> ```
|
|
915
|
+
>
|
|
916
|
+
> **Vì sao không được gộp:** 3 tag version là **scalar theo từng UC**. Một file phủ UC1 + UC3 mà chỉ có một header thì không diễn đạt được "UC1 ở bdd v1.4, UC3 ở v2.1" → `/validate-traces` Step 4/5/5c báo drift oan hoặc **mù** drift thật. Version phải nằm cạnh member nó mô tả.
|
|
917
|
+
>
|
|
918
|
+
> **Vì sao không được trỏ thư mục** (`@trace.source=…/bdd/system/`): độ phân giải của trace là `UC × SC`, thư mục làm mất cả hai bậc. Và các lệnh tra tag bằng **khớp chuỗi chính xác** (`/dev-gen-test`, `/dev-smoke-test`, `/review-code` đều tìm "file gắn `@trace.implements={UC-ID}`") → tag trỏ folder ra 0 kết quả, UC rơi về `UNTRACKED` dù code đã có.
|
|
919
|
+
>
|
|
920
|
+
> Quy tắc EXTEND ở §File Scan vốn đã yêu cầu giữ **nguyên si** mọi `@trace.implements` cũ *kể cả của UC khác* — tức là thiết kế vốn là **tích luỹ nhiều block**, không phải gộp lại.
|
|
921
|
+
|
|
887
922
|
> **Quy tắc nguồn giá trị (chống hard-code):** MỌI giá trị cụ thể (endpoint path, error code, tên field/DTO, enum, limit/timeout, header) phải lấy từ **nguồn đã chốt** — **KHÔNG bịa inline**. Nếu một hằng số nghiệp vụ lặp lại hoặc mang ý nghĩa (retry count, ngưỡng, key) → **đặt tên hằng số** (constant/config), không rải magic number/string trong code.
|
|
888
923
|
>
|
|
889
924
|
> **VÉT CẠN NGUỒN TRƯỚC KHI HỎI (SRC-CHAIN) — bắt buộc.** Khi một giá trị chưa thấy ở nguồn chính, PHẢI quét lần lượt các nguồn đã có trong context/spec-package theo thứ tự sau, **dừng ngay khi tìm thấy** (skip-if-answered), KHÔNG hỏi người ngay:
|
|
@@ -1009,7 +1044,7 @@ Cập nhật `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{@trace.platform}.ts
|
|
|
1009
1044
|
| `bdd_version` | `@trace.bdd_version` từ header `.feature` |
|
|
1010
1045
|
| `tech_doc_revision` | `@trace.revision` từ tech-doc gộp `{TICKET-ID}-tech-design.md` (§4 backend đã điều khiển codegen của UC này), hoặc `—` nếu chưa có doc |
|
|
1011
1046
|
| `fe_tech_doc_revision` | `@trace.revision` của cùng tech-doc gộp, ghi khi sinh FE có wire adapter theo §4.5.4 (`--phase=integration` **hoặc** `fe_full`); `—` cho BE, hoặc cho FE `--phase=ui` / chưa có §4.5.4 |
|
|
1012
|
-
| `fe_phase` | `ui` nếu `--phase=ui` \| `
|
|
1047
|
+
| `fe_phase` | `ui` nếu `--phase=ui` \| `integration` nếu `--phase=integration` **hoặc** `fe_full` (đều đã wire real adapter) \| `—` cho BE |
|
|
1013
1048
|
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
1014
1049
|
|
|
1015
1050
|
Giữ nguyên mọi cột khác (`sc_title`, `spec_ver`, `prd_version`, `prd_status`, `uc_status`, `test_count`, `test_classes`, `dev_selftest`, `dev_selftest_at`, `qc_status`, `qc_run_at`, `qc_owner`, `qc_blocked_by`).
|
|
@@ -1130,6 +1165,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1130
1165
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1131
1166
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1132
1167
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1168
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1133
1169
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1134
1170
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1135
1171
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1138,8 +1174,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1138
1174
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1139
1175
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1140
1176
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1141
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1142
|
-
| /fix-bug |
|
|
1177
|
+
| /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** |
|
|
1178
|
+
| /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 |
|
|
1143
1179
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1144
1180
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1145
1181
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -1164,7 +1200,7 @@ Next : {lệnh gợi ý kèm ví dụ tham số}
|
|
|
1164
1200
|
Files: created={N}, extended={M}, filled={F} stub, skipped={K} | Build: SUCCESS
|
|
1165
1201
|
Branch: feature/{TICKET_ID}-{slug}
|
|
1166
1202
|
Phase : {UI (mock layer) | Integration (real API) | FE full (UI + real API) | BE full}
|
|
1167
|
-
fe_phase : {ui |
|
|
1203
|
+
fe_phase : {ui | integration (—phase=integration | fe_full) | —}
|
|
1168
1204
|
Figma : {Dev Mode MCP local (grounded) | ⚠️ chỉ link web + text spec (không có MCP local) | n/a cho BE} ← chỉ UI FE/App
|
|
1169
1205
|
|
|
1170
1206
|
Next:
|
|
@@ -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.
|
|
@@ -1101,6 +1106,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1101
1106
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1102
1107
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1103
1108
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1109
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1104
1110
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1105
1111
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1106
1112
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1109,8 +1115,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1109
1115
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1110
1116
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1111
1117
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1112
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1113
|
-
| /fix-bug |
|
|
1118
|
+
| /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** |
|
|
1119
|
+
| /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 |
|
|
1114
1120
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1115
1121
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1116
1122
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -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.
|
|
@@ -1065,6 +1070,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1065
1070
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1066
1071
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1067
1072
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1073
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1068
1074
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1069
1075
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1070
1076
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1073,8 +1079,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1073
1079
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1074
1080
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1075
1081
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1076
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1077
|
-
| /fix-bug |
|
|
1082
|
+
| /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** |
|
|
1083
|
+
| /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 |
|
|
1078
1084
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1079
1085
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1080
1086
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -36,23 +36,23 @@ Hiển thị và chờ phản hồi:
|
|
|
36
36
|
```
|
|
37
37
|
⚙️ MODEL CHECK
|
|
38
38
|
──────────────────────────────────────────────────────────────────
|
|
39
|
-
Recommended :
|
|
39
|
+
Recommended : model Opus mới nhất
|
|
40
40
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
41
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
41
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
42
42
|
|
|
43
43
|
Cách đổi trong Claude Code:
|
|
44
|
-
•
|
|
45
|
-
• hoặc:
|
|
44
|
+
• /model → chọn model Opus
|
|
45
|
+
• hoặc: Settings → Model
|
|
46
46
|
|
|
47
|
-
Đang chạy
|
|
48
|
-
Y — đúng
|
|
47
|
+
Đang chạy một model Opus?
|
|
48
|
+
Y — đúng → tiếp tục
|
|
49
49
|
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)
|
|
50
50
|
──────────────────────────────────────────────────────────────────
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
- "Y" → tiếp tục sang Bước 1.
|
|
54
54
|
- "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).
|
|
55
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
55
|
+
- "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."
|
|
56
56
|
|
|
57
57
|
## Bước 1 — Xác định Target File
|
|
58
58
|
|
|
@@ -61,7 +61,12 @@ Hiển thị và chờ phản hồi:
|
|
|
61
61
|
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/`):
|
|
62
62
|
- **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 đó.
|
|
63
63
|
- **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.)*
|
|
64
|
-
- **Lệnh tech-docs
|
|
64
|
+
- **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:
|
|
65
|
+
- `$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`.
|
|
66
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
67
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
68
|
+
- 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.
|
|
69
|
+
*(Đừ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`.)*
|
|
65
70
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
66
71
|
|
|
67
72
|
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.
|
|
@@ -685,6 +690,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
685
690
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
686
691
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
687
692
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
693
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
688
694
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
689
695
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
690
696
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -693,8 +699,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
693
699
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
694
700
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
695
701
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
696
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
697
|
-
| /fix-bug |
|
|
702
|
+
| /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** |
|
|
703
|
+
| /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 |
|
|
698
704
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
699
705
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
700
706
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -44,23 +44,23 @@ Hiển thị và chờ phản hồi:
|
|
|
44
44
|
```
|
|
45
45
|
⚙️ MODEL CHECK
|
|
46
46
|
──────────────────────────────────────────────────────────────────
|
|
47
|
-
Recommended :
|
|
47
|
+
Recommended : model Opus mới nhất
|
|
48
48
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
49
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
49
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
50
50
|
|
|
51
51
|
Cách đổi trong Claude Code:
|
|
52
|
-
•
|
|
53
|
-
• hoặc:
|
|
52
|
+
• /model → chọn model Opus
|
|
53
|
+
• hoặc: Settings → Model
|
|
54
54
|
|
|
55
|
-
Đang chạy
|
|
56
|
-
Y — đúng
|
|
55
|
+
Đang chạy một model Opus?
|
|
56
|
+
Y — đúng → tiếp tục
|
|
57
57
|
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)
|
|
58
58
|
──────────────────────────────────────────────────────────────────
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
- "Y" → tiếp tục sang Bước 1.
|
|
62
62
|
- "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).
|
|
63
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
63
|
+
- "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."
|
|
64
64
|
|
|
65
65
|
## Bước 1 — Xác định Target File
|
|
66
66
|
|
|
@@ -69,7 +69,12 @@ Hiển thị và chờ phản hồi:
|
|
|
69
69
|
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/`):
|
|
70
70
|
- **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 đó.
|
|
71
71
|
- **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.)*
|
|
72
|
-
- **Lệnh tech-docs
|
|
72
|
+
- **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:
|
|
73
|
+
- `$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`.
|
|
74
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
75
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
76
|
+
- 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.
|
|
77
|
+
*(Đừ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`.)*
|
|
73
78
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
74
79
|
|
|
75
80
|
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.
|
|
@@ -514,7 +519,7 @@ Tiếp tục sang bước kế tiếp của lệnh đang gọi.
|
|
|
514
519
|
- feature `web/` và/hoặc `app/` → sinh/mở rộng block **client §4.5** cho platform đó, và thêm flow của platform đó vào lane **§5** (5.B/5.C).
|
|
515
520
|
- batch không có feature client → không có việc §4.5 lần này (lần chạy sau trỏ vào BDD `web/`·`app/` sẽ append).
|
|
516
521
|
- **batch không có feature `system/` (PRD chỉ client):** **đừng** bịa BE contract. §4.1 chỉ liệt kê các endpoint mà client **tiêu thụ** (external / bên thứ ba / của team khác / existing), reverse-document từ mệnh đề Then của client BDD + PRD và đánh dấu "consumed (external)"; nếu feature không gọi mạng → §4 = "N/A — client-only, không backend". §4.5.4 map tới bất cứ gì §4.1 liệt kê (hoặc không có).
|
|
517
|
-
- Ghi `@trace.
|
|
522
|
+
- Ghi `@trace.bdd_versions` (**số nhiều** — map theo platform, vd `system=1.5, web=1.9`) từ `@trace.bdd_version` (**số ít**, scalar) của mỗi feature — đừng làm phẳng về một số. *(Tên khác nhau là cố ý: cùng một tên cho hai kiểu dữ liệu sẽ làm vỡ mọi parser generic.)*
|
|
518
523
|
6. Đường dẫn output — doc **duy nhất** của PRD:
|
|
519
524
|
```
|
|
520
525
|
{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md
|
|
@@ -664,7 +669,7 @@ Ghi/mở rộng `{output_path}` dùng template dưới đây, chỉ sinh **nội
|
|
|
664
669
|
- **§1/§2** (Overview/Actors, Architecture) là cấp PRD: viết ở lần chạy đầu; các lần sau chỉ mở rộng nếu batch thêm actor/integration thật sự mới.
|
|
665
670
|
- **§10 UC Coverage** — một row UC (có cột Platforms) + bảng con coverage-scenario khoá theo **(platform, SC)** — mỗi platform×SC một row, vì cùng số SC ở platform khác nhau là scenario khác nhau. Đây là mỏ neo mà chế độ APPEND đọc. Luôn cập nhật nó cho (các) UC/platform của batch.
|
|
666
671
|
|
|
667
|
-
**Chế độ APPEND (doc đã tồn tại):** **đừng** viết lại section có sẵn. Chèn diagram §5 của UC batch **vào đúng lane platform** (5.A/5.B/5.C, đánh số sau cái cuối trong lane đó, tiêu đề `platform · SC`), các row mới ở §3/§4.3/§8/§9; với §4.5 — platform mới → nhóm `### 4.5 — {platform}` mới, ngược lại thêm sub-block `§4.5.1.x {Screen} — {UC}` + row vào §4.5.6 dùng chung của nhóm (không lặp nhóm); rồi cập nhật §10 (row khoá theo platform×SC) và thêm một row Changelog. Bump `@trace.revision` và làm mới `@trace.ucs` / `@trace.platforms` ở header, và cập nhật entry của platform vừa đụng trong map `@trace.
|
|
672
|
+
**Chế độ APPEND (doc đã tồn tại):** **đừng** viết lại section có sẵn. Chèn diagram §5 của UC batch **vào đúng lane platform** (5.A/5.B/5.C, đánh số sau cái cuối trong lane đó, tiêu đề `platform · SC`), các row mới ở §3/§4.3/§8/§9; với §4.5 — platform mới → nhóm `### 4.5 — {platform}` mới, ngược lại thêm sub-block `§4.5.1.x {Screen} — {UC}` + row vào §4.5.6 dùng chung của nhóm (không lặp nhóm); rồi cập nhật §10 (row khoá theo platform×SC) và thêm một row Changelog. Bump `@trace.revision` và làm mới `@trace.ucs` / `@trace.platforms` ở header, và cập nhật entry của platform vừa đụng trong map `@trace.bdd_versions` (vd set `web=2.0`, giữ nguyên `system`).
|
|
668
673
|
|
|
669
674
|
<!--
|
|
670
675
|
════════════════════════════════════════════════════════════════════════════
|
|
@@ -708,7 +713,7 @@ Ghi/mở rộng `{output_path}` dùng template dưới đây, chỉ sinh **nội
|
|
|
708
713
|
@trace.service: {service — từ header BDD @trace.service}
|
|
709
714
|
@trace.module: {module liên quan — vd dotnet, angular}
|
|
710
715
|
@trace.platforms: {system | web | app — tuỳ thư mục BDD nào tồn tại}
|
|
711
|
-
@trace.
|
|
716
|
+
@trace.bdd_versions: {MAP theo từng platform — số nhiều, KHÁC @trace.bdd_version (scalar) của .feature — vd system=1.5, web=1.9, app=1.7; chỉ platform có mặt. Mỗi feature mang bdd_version riêng; đừng gộp về một số.}
|
|
712
717
|
@trace.api_source: {existing | —}
|
|
713
718
|
@trace.revision: 1
|
|
714
719
|
@trace.status: draft
|
|
@@ -1294,6 +1299,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1294
1299
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1295
1300
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1296
1301
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1302
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1297
1303
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1298
1304
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1299
1305
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1302,8 +1308,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1302
1308
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1303
1309
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1304
1310
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1305
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1306
|
-
| /fix-bug |
|
|
1311
|
+
| /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** |
|
|
1312
|
+
| /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 |
|
|
1307
1313
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1308
1314
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1309
1315
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
package/core/commands/learn.md
CHANGED
|
@@ -41,23 +41,23 @@ Hiển thị và chờ phản hồi:
|
|
|
41
41
|
```
|
|
42
42
|
⚙️ MODEL CHECK
|
|
43
43
|
──────────────────────────────────────────────────────────────────
|
|
44
|
-
Recommended :
|
|
44
|
+
Recommended : model Opus mới nhất
|
|
45
45
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
46
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
46
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
47
47
|
|
|
48
48
|
Cách đổi trong Claude Code:
|
|
49
|
-
•
|
|
50
|
-
• hoặc:
|
|
49
|
+
• /model → chọn model Opus
|
|
50
|
+
• hoặc: Settings → Model
|
|
51
51
|
|
|
52
|
-
Đang chạy
|
|
53
|
-
Y — đúng
|
|
52
|
+
Đang chạy một model Opus?
|
|
53
|
+
Y — đúng → tiếp tục
|
|
54
54
|
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)
|
|
55
55
|
──────────────────────────────────────────────────────────────────
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
- "Y" → tiếp tục sang Bước 1.
|
|
59
59
|
- "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).
|
|
60
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
60
|
+
- "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."
|
|
61
61
|
|
|
62
62
|
## Bước 1 — Xác định Target File
|
|
63
63
|
|
|
@@ -66,7 +66,12 @@ Hiển thị và chờ phản hồi:
|
|
|
66
66
|
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/`):
|
|
67
67
|
- **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 đó.
|
|
68
68
|
- **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.)*
|
|
69
|
-
- **Lệnh tech-docs
|
|
69
|
+
- **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:
|
|
70
|
+
- `$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`.
|
|
71
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
72
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
73
|
+
- 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.
|
|
74
|
+
*(Đừ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`.)*
|
|
70
75
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
71
76
|
|
|
72
77
|
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.
|
|
@@ -669,6 +674,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
669
674
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
670
675
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
671
676
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
677
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
672
678
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
673
679
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
674
680
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -677,8 +683,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
677
683
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
678
684
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
679
685
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
680
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
681
|
-
| /fix-bug |
|
|
686
|
+
| /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** |
|
|
687
|
+
| /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 |
|
|
682
688
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
683
689
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
684
690
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -42,23 +42,23 @@ Hiển thị và chờ phản hồi:
|
|
|
42
42
|
```
|
|
43
43
|
⚙️ MODEL CHECK
|
|
44
44
|
──────────────────────────────────────────────────────────────────
|
|
45
|
-
Recommended :
|
|
45
|
+
Recommended : model Opus mới nhất
|
|
46
46
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
47
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
47
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
48
48
|
|
|
49
49
|
Cách đổi trong Claude Code:
|
|
50
|
-
•
|
|
51
|
-
• hoặc:
|
|
50
|
+
• /model → chọn model Opus
|
|
51
|
+
• hoặc: Settings → Model
|
|
52
52
|
|
|
53
|
-
Đang chạy
|
|
54
|
-
Y — đúng
|
|
53
|
+
Đang chạy một model Opus?
|
|
54
|
+
Y — đúng → tiếp tục
|
|
55
55
|
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)
|
|
56
56
|
──────────────────────────────────────────────────────────────────
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
- "Y" → tiếp tục sang Bước 1.
|
|
60
60
|
- "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).
|
|
61
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
61
|
+
- "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."
|
|
62
62
|
|
|
63
63
|
## Bước 1 — Xác định Target File
|
|
64
64
|
|
|
@@ -67,7 +67,12 @@ Hiển thị và chờ phản hồi:
|
|
|
67
67
|
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/`):
|
|
68
68
|
- **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 đó.
|
|
69
69
|
- **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.)*
|
|
70
|
-
- **Lệnh tech-docs
|
|
70
|
+
- **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:
|
|
71
|
+
- `$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`.
|
|
72
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
73
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
74
|
+
- 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.
|
|
75
|
+
*(Đừ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`.)*
|
|
71
76
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
72
77
|
|
|
73
78
|
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.
|
|
@@ -616,6 +621,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
616
621
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
617
622
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
618
623
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
624
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
619
625
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
620
626
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
621
627
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -624,8 +630,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
624
630
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
625
631
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
626
632
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
627
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
628
|
-
| /fix-bug |
|
|
633
|
+
| /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** |
|
|
634
|
+
| /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 |
|
|
629
635
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
630
636
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
631
637
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|