@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
package/commands/debug.md
CHANGED
|
@@ -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.
|
|
@@ -762,6 +767,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
762
767
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
763
768
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
764
769
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
770
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
765
771
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
766
772
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
767
773
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -770,8 +776,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
770
776
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
771
777
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
772
778
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
773
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
774
|
-
| /fix-bug |
|
|
779
|
+
| /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** |
|
|
780
|
+
| /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 |
|
|
775
781
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
776
782
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
777
783
|
| /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.
|
|
@@ -814,6 +819,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
814
819
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
815
820
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
816
821
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
822
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
817
823
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
818
824
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
819
825
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -822,8 +828,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
822
828
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
823
829
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
824
830
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
825
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
826
|
-
| /fix-bug |
|
|
831
|
+
| /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** |
|
|
832
|
+
| /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 |
|
|
827
833
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
828
834
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
829
835
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
package/commands/dev-gen-test.md
CHANGED
|
@@ -38,23 +38,23 @@ Hiển thị và chờ phản hồi:
|
|
|
38
38
|
```
|
|
39
39
|
⚙️ MODEL CHECK
|
|
40
40
|
──────────────────────────────────────────────────────────────────
|
|
41
|
-
Recommended :
|
|
41
|
+
Recommended : model Opus mới nhất
|
|
42
42
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
43
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
43
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
44
44
|
|
|
45
45
|
Cách đổi trong Claude Code:
|
|
46
|
-
•
|
|
47
|
-
• hoặc:
|
|
46
|
+
• /model → chọn model Opus
|
|
47
|
+
• hoặc: Settings → Model
|
|
48
48
|
|
|
49
|
-
Đang chạy
|
|
50
|
-
Y — đúng
|
|
49
|
+
Đang chạy một model Opus?
|
|
50
|
+
Y — đúng → tiếp tục
|
|
51
51
|
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)
|
|
52
52
|
──────────────────────────────────────────────────────────────────
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
- "Y" → tiếp tục sang Bước 1.
|
|
56
56
|
- "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).
|
|
57
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
57
|
+
- "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."
|
|
58
58
|
|
|
59
59
|
## Bước 1 — Xác định Target File
|
|
60
60
|
|
|
@@ -63,7 +63,12 @@ Hiển thị và chờ phản hồi:
|
|
|
63
63
|
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/`):
|
|
64
64
|
- **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 đó.
|
|
65
65
|
- **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.)*
|
|
66
|
-
- **Lệnh tech-docs
|
|
66
|
+
- **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:
|
|
67
|
+
- `$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`.
|
|
68
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
69
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
70
|
+
- 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.
|
|
71
|
+
*(Đừ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`.)*
|
|
67
72
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
68
73
|
|
|
69
74
|
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.
|
|
@@ -1050,6 +1055,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1050
1055
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
1051
1056
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
1052
1057
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
1058
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
1053
1059
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
1054
1060
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
1055
1061
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -1058,8 +1064,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
1058
1064
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
1059
1065
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
1060
1066
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
1061
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
1062
|
-
| /fix-bug |
|
|
1067
|
+
| /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** |
|
|
1068
|
+
| /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 |
|
|
1063
1069
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
1064
1070
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
1065
1071
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
package/commands/dev-run-test.md
CHANGED
|
@@ -38,23 +38,23 @@ Hiển thị và chờ phản hồi:
|
|
|
38
38
|
```
|
|
39
39
|
⚙️ MODEL CHECK
|
|
40
40
|
──────────────────────────────────────────────────────────────────
|
|
41
|
-
Recommended :
|
|
41
|
+
Recommended : model Opus mới nhất
|
|
42
42
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
43
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
43
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
44
44
|
|
|
45
45
|
Cách đổi trong Claude Code:
|
|
46
|
-
•
|
|
47
|
-
• hoặc:
|
|
46
|
+
• /model → chọn model Opus
|
|
47
|
+
• hoặc: Settings → Model
|
|
48
48
|
|
|
49
|
-
Đang chạy
|
|
50
|
-
Y — đúng
|
|
49
|
+
Đang chạy một model Opus?
|
|
50
|
+
Y — đúng → tiếp tục
|
|
51
51
|
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)
|
|
52
52
|
──────────────────────────────────────────────────────────────────
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
- "Y" → tiếp tục sang Bước 1.
|
|
56
56
|
- "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).
|
|
57
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
57
|
+
- "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."
|
|
58
58
|
|
|
59
59
|
## Bước 1 — Xác định Target File
|
|
60
60
|
|
|
@@ -63,7 +63,12 @@ Hiển thị và chờ phản hồi:
|
|
|
63
63
|
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/`):
|
|
64
64
|
- **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 đó.
|
|
65
65
|
- **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.)*
|
|
66
|
-
- **Lệnh tech-docs
|
|
66
|
+
- **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:
|
|
67
|
+
- `$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`.
|
|
68
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
69
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
70
|
+
- 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.
|
|
71
|
+
*(Đừ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`.)*
|
|
67
72
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
68
73
|
|
|
69
74
|
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.
|
|
@@ -663,11 +668,12 @@ Cập nhật **sổ của platform đang test** `{paths.trace_dir}/{domain}/{prd
|
|
|
663
668
|
|--------|-------|
|
|
664
669
|
| `dev_selftest` | `pass` nếu mọi test của SC này pass · `fail` nếu có cái fail · `not_run` nếu test của nó bị skip/vắng |
|
|
665
670
|
| `dev_selftest_at` | hôm nay `YYYY-MM-DD` |
|
|
671
|
+
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
666
672
|
|
|
667
673
|
Giữ nguyên mọi cột khác — đặc biệt **không bao giờ** đụng `qc_status`/`qc_run_at`
|
|
668
674
|
(kết quả QC automation chính thức, do `/qc-run-test` sở hữu). `dev_selftest` (dev smoke)
|
|
669
675
|
và `qc_status` (QC chính thức) là hai tín hiệu riêng. `dev_selftest`/`dev_selftest_at` cũng
|
|
670
|
-
trực giao với `status` (OK/GAP/DRIFT/UNTRACKED): `status` theo dõi *coverage*, `dev_selftest`
|
|
676
|
+
trực giao với `status` (OK/GAP/DRIFT/UNTRACKED/ORPHANED): `status` theo dõi *coverage*, `dev_selftest`
|
|
671
677
|
theo dõi *kết quả chạy* gần nhất của dev.
|
|
672
678
|
|
|
673
679
|
## Refresh Panel Mirror
|
|
@@ -774,6 +780,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
774
780
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
775
781
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
776
782
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
783
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
777
784
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
778
785
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
779
786
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -782,8 +789,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
782
789
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
783
790
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
784
791
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
785
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
786
|
-
| /fix-bug |
|
|
792
|
+
| /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** |
|
|
793
|
+
| /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 |
|
|
787
794
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
788
795
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
789
796
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -189,11 +189,12 @@ Cập nhật **sổ của platform đang test** `{paths.trace_dir}/{domain}/{prd
|
|
|
189
189
|
|--------|-------|
|
|
190
190
|
| `dev_selftest` | `pass` nếu mọi test của SC này pass · `fail` nếu có cái fail · `not_run` nếu test của nó bị skip/vắng |
|
|
191
191
|
| `dev_selftest_at` | hôm nay `YYYY-MM-DD` |
|
|
192
|
+
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
192
193
|
|
|
193
194
|
Giữ nguyên mọi cột khác — đặc biệt **không bao giờ** đụng `qc_status`/`qc_run_at`
|
|
194
195
|
(kết quả QC automation chính thức, do `/qc-run-test` sở hữu). `dev_selftest` (dev smoke)
|
|
195
196
|
và `qc_status` (QC chính thức) là hai tín hiệu riêng. `dev_selftest`/`dev_selftest_at` cũng
|
|
196
|
-
trực giao với `status` (OK/GAP/DRIFT/UNTRACKED): `status` theo dõi *coverage*, `dev_selftest`
|
|
197
|
+
trực giao với `status` (OK/GAP/DRIFT/UNTRACKED/ORPHANED): `status` theo dõi *coverage*, `dev_selftest`
|
|
197
198
|
theo dõi *kết quả chạy* gần nhất của dev.
|
|
198
199
|
|
|
199
200
|
## Refresh Panel Mirror
|
|
@@ -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.
|
|
@@ -748,6 +753,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
748
753
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
749
754
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
750
755
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
756
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
751
757
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
752
758
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
753
759
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -756,8 +762,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
756
762
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
757
763
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
758
764
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
759
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
760
|
-
| /fix-bug |
|
|
765
|
+
| /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** |
|
|
766
|
+
| /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 |
|
|
761
767
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
762
768
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
763
769
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
package/commands/fix-bug.md
CHANGED
|
@@ -32,23 +32,23 @@ Hiển thị và chờ phản hồi:
|
|
|
32
32
|
```
|
|
33
33
|
⚙️ MODEL CHECK
|
|
34
34
|
──────────────────────────────────────────────────────────────────
|
|
35
|
-
Recommended :
|
|
35
|
+
Recommended : model Opus mới nhất
|
|
36
36
|
Why needed : Phân tích spec, review kiến trúc, sinh code đòi hỏi
|
|
37
|
-
suy luận sâu. Model nhỏ hơn dễ bỏ sót edge case.
|
|
37
|
+
suy luận sâu. Model nhỏ hơn (Haiku/Sonnet) dễ bỏ sót edge case.
|
|
38
38
|
|
|
39
39
|
Cách đổi trong Claude Code:
|
|
40
|
-
•
|
|
41
|
-
• hoặc:
|
|
40
|
+
• /model → chọn model Opus
|
|
41
|
+
• hoặc: Settings → Model
|
|
42
42
|
|
|
43
|
-
Đang chạy
|
|
44
|
-
Y — đúng
|
|
43
|
+
Đang chạy một model Opus?
|
|
44
|
+
Y — đúng → tiếp tục
|
|
45
45
|
S — bỏ qua kiểm tra (tôi chấp nhận rủi ro chất lượng thấp hơn với model hiện tại)
|
|
46
46
|
──────────────────────────────────────────────────────────────────
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
- "Y" → tiếp tục sang Bước 1.
|
|
50
50
|
- "S" → tiếp tục sang Bước 1 (người dùng chấp nhận rủi ro, thêm ⚠️ vào report cuối).
|
|
51
|
-
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang
|
|
51
|
+
- "N" hoặc bất kỳ giá trị nào khác → **DỪNG.** Xuất: "Vui lòng chuyển sang một model Opus (`/model`) rồi chạy lại lệnh này."
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
@@ -57,7 +57,12 @@ Hiển thị và chờ phản hồi:
|
|
|
57
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
58
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
59
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
60
|
-
- **Lệnh tech-docs
|
|
60
|
+
- **Lệnh tech-docs** — target là tech-doc **gộp cấp PRD** `{TICKET-ID}-tech-design.md` (MỘT doc phủ nhiều UC; danh sách UC nằm ở `@trace.ucs`). Vì tên file mang `{TICKET-ID}` chứ **không** mang `{UC-ID}`, phải tách trước khi glob:
|
|
61
|
+
- `$ARGUMENTS` là **UC-ID** (`{TICKET-ID}-UC{N}`) → lấy `{TICKET-ID}` = phần **trước** `-UC`, rồi glob `{specs_dir}/{domain}/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
62
|
+
- `$ARGUMENTS` là **TICKET-ID** → glob trực tiếp như trên.
|
|
63
|
+
- Chưa biết domain → `{specs_dir}/*/*/tech-docs/{TICKET-ID}-tech-design.md`.
|
|
64
|
+
- Vẫn không khớp → glob rộng `{specs_dir}/*/*/tech-docs/*tech-design*.md` rồi liệt kê để người dùng chọn.
|
|
65
|
+
*(Đừng glob `{UC-ID}*-tech-design*.md` — nó nở thành `FT-001-UC1*-tech-design*.md` và **không bao giờ** khớp `FT-001-tech-design.md`.)*
|
|
61
66
|
- **Lệnh design-spec**: `{specs_dir}/{domain}/*/design-spec/{TICKET-ID}*.md`.
|
|
62
67
|
|
|
63
68
|
Khi một file khớp: đặt nó làm target **và** ghi lại `domain` + `prd_slug` từ path của nó (theo quy tắc trích xuất trong `context-loader.md` Bước 1 — `prd_slug` = segment đầu tiên sau `{specs_dir}/{domain}/`). Mọi path mà lệnh đọc/ghi về sau (BDD/tech-docs/design-spec/trace cùng cấp) đều dùng **`prd_slug` đã phân giải đó**, nên tất cả artifact nằm chung một feature package. Nếu nhiều file khớp (vd: nhiều platform), chọn theo platform/scope của lệnh hoặc liệt kê ra và hỏi.
|
|
@@ -569,9 +574,10 @@ git checkout -b fix/{TICKET_ID}-{description}
|
|
|
569
574
|
```
|
|
570
575
|
Áp dụng fix. Thêm trace annotation nếu file có `@trace.implements`:
|
|
571
576
|
```
|
|
572
|
-
@trace.fixes={TICKET_ID}
|
|
577
|
+
@trace.fixes={BUG-ID nếu fix từ một bug report đã file · else TICKET_ID}
|
|
573
578
|
@trace.root_cause={brief description}
|
|
574
579
|
```
|
|
580
|
+
*(Ưu tiên `{BUG-ID}`: khi fix bắt nguồn từ `/report-bug` thì thường **không có** ticket ID nào, và `{BUG-ID}` mới là thứ trace ngược được về spec context + AC bị vi phạm.)*
|
|
575
581
|
|
|
576
582
|
## Phase 4 — Regression Test
|
|
577
583
|
```
|
|
@@ -581,7 +587,56 @@ Test: "Regression {TICKET_ID}: {bug description}"
|
|
|
581
587
|
```
|
|
582
588
|
Chạy test. Nếu fail → debug và fix (tối đa 3 vòng).
|
|
583
589
|
|
|
584
|
-
## Phase 5 —
|
|
590
|
+
## Phase 4.5 — Cập nhật sổ trace
|
|
591
|
+
|
|
592
|
+
*Bỏ qua nếu fix không chạm SC nào có row trace (vd fix hạ tầng/config).*
|
|
593
|
+
|
|
594
|
+
Đây là lệnh **duy nhất** sinh test mà trước đây không ghi sổ — hệ quả: `test_count` under-report vĩnh viễn (SC đứng `GAP` dù vừa có regression test, rồi `/validate-traces` khuyên `/dev-gen-test` → dev sinh test trùng), và `dev_selftest` giữ `pass` cũ **trên code đã đổi**.
|
|
595
|
+
|
|
596
|
+
Định vị sổ platform `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` — `{platform}` = platform của code vừa fix; không rõ → glob `{UC-ID}-*.tsv` tìm sổ nào chứa `sc_id` đó, khớp nhiều sổ → **hỏi** (cùng luật với `/report-bug` Step 5.5).
|
|
597
|
+
|
|
598
|
+
Với mỗi SC mà regression test phủ (theo `@trace.verifies` của test vừa viết):
|
|
599
|
+
|
|
600
|
+
| Cột | Giá trị |
|
|
601
|
+
|---|---|
|
|
602
|
+
| `test_count` | **+=** số test method regression vừa thêm (cộng dồn, không ghi đè) |
|
|
603
|
+
| `test_classes` | **append** tên test class/describe mới, giữ nguyên tên cũ |
|
|
604
|
+
| `dev_selftest` | `not_run` — code vừa đổi nên tín hiệu self-test cũ hết hiệu lực |
|
|
605
|
+
| `dev_selftest_at` | `—` |
|
|
606
|
+
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
607
|
+
|
|
608
|
+
Giữ nguyên mọi cột khác. Đặc biệt:
|
|
609
|
+
- **KHÔNG** đụng `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` — QC sở hữu; `/qc-run-test` sẽ flip khi re-verify (và chính nó đóng `{BUG-ID}` → `🟢 Closed`).
|
|
610
|
+
- **KHÔNG** đụng `spec_ver`/`gen_ver` — fix bug **không** đổi spec, nên không được tạo tín hiệu DRIFT giả.
|
|
611
|
+
|
|
612
|
+
Rồi làm mới panel mirror:
|
|
613
|
+
# Làm mới panel mirror của Living Docs *(local, chế độ umbrella)*
|
|
614
|
+
|
|
615
|
+
*Bỏ qua hoàn toàn ở chế độ single-service (không có `services` và không có `setup.spec_source`) — ở đó
|
|
616
|
+
`.trace/` của chính repo CHÍNH LÀ vị trí panel, nên không có gì để mirror.*
|
|
617
|
+
|
|
618
|
+
Sau khi cập nhật TSV authoritative tại `{paths.trace_dir}`:
|
|
619
|
+
|
|
620
|
+
**Khi `setup.spec_source` được đặt (trace gộp — trường hợp phổ biến):**
|
|
621
|
+
`{paths.trace_dir}` phân giải về `{spec_source}/.trace` — vị trí authoritative duy nhất.
|
|
622
|
+
Lệnh này chạy từ `service_root`, nên thao tác ghi là **liên-repo vào spec submodule**;
|
|
623
|
+
commit/push spec submodule cho lần cập nhật trace (giống như `feedback/`).
|
|
624
|
+
1. Phân giải `panel_mirror = ./.trace` tại **gốc workspace hiện tại**.
|
|
625
|
+
2. Nếu `panel_mirror` phân giải ra path khác với `{paths.trace_dir}`, copy mỗi
|
|
626
|
+
`{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{UC-ID}-{platform}.tsv` (tạo thư mục; ghi đè).
|
|
627
|
+
Không namespace theo service — chỉ có một bộ trace; service sở hữu được mang trong
|
|
628
|
+
`@trace.service` của từng row.
|
|
629
|
+
|
|
630
|
+
**Legacy (không có `spec_source` — trace theo service):**
|
|
631
|
+
Copy mỗi `{UC-ID}-{platform}.tsv` vừa cập nhật → `{panel_mirror}/{service-name}/{UC-ID}-{platform}.tsv`
|
|
632
|
+
(namespace theo `active_service`).
|
|
633
|
+
|
|
634
|
+
Cách này giữ panel Living Docs của workspace đang mở luôn mới **giữa các lần sync** — nó chỉ là
|
|
635
|
+
một **mirror tiện lợi cục bộ**. File `trace-report.json` đã merge (canonical, trong
|
|
636
|
+
`{spec_source}/.living-docs/`) được build lại bởi `/sync` hoặc `/validate-traces`. Với các lệnh
|
|
637
|
+
được orchestrate, làm việc này một lần trong orchestrator sau khi tất cả sub-agent trả về — không phải
|
|
638
|
+
bên trong từng sub-agent.
|
|
639
|
+
|
|
585
640
|
```bash
|
|
586
641
|
{conventions.build_command} # tối đa 3 retry — chạy trong {service_root} ở umbrella mode
|
|
587
642
|
# Tầng 1 — push fix branch trong service submodule (nơi code sống):
|
|
@@ -783,6 +838,7 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
783
838
|
| /qc-run-test | `/qc-report {UC-ID}` rồi `/qc-review {UC-ID}` (review script) |
|
|
784
839
|
| /qc-review (script) | `/qc-report {UC-ID}` rồi tạo PR nếu APPROVED |
|
|
785
840
|
| /qc-report | `/validate-traces {UC-ID}` để làm mới Living Docs (qc_status) |
|
|
841
|
+
| /map-testids | `/qc-design-test {UC-ID}` (QC dựng Page Object từ contract §4.5.6 vừa ghi) |
|
|
786
842
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
787
843
|
| /review-tech-docs | `/generate-code {feature-file}` nếu APPROVED; sửa doc nếu NEEDS_FIX |
|
|
788
844
|
| /generate-code | Lần gen đầu → `/review-code {UC-ID}`; gen lại → `/dev-gen-test {UC-ID}` |
|
|
@@ -791,8 +847,8 @@ Gợi ý lệnh kế tiếp hợp lý theo phase của workflow:
|
|
|
791
847
|
| /dev-run-test (failing) | `/fix-bug {ticket-id}` hoặc `/debug {error}` |
|
|
792
848
|
| /review-code | `/dev-smoke-test {UC-ID}` hoặc tạo PR |
|
|
793
849
|
| /dev-smoke-test | Tạo PR và link tới ticket |
|
|
794
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}
|
|
795
|
-
| /fix-bug |
|
|
850
|
+
| /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** |
|
|
851
|
+
| /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 |
|
|
796
852
|
| /debug | `/fix-bug {ticket-id}` nếu cần sửa |
|
|
797
853
|
| /report-bug | Gửi cho dev (`/fix-bug {BUG-ID}`); nếu thiếu coverage → `/propose-scenario {UC-ID}` |
|
|
798
854
|
| /propose-scenario | Báo PO/Dev review proposal trong `feedback/bdd-proposals/` |
|
|
@@ -817,8 +873,10 @@ Next : {lệnh gợi ý kèm ví dụ tham số}
|
|
|
817
873
|
Root Cause: {analysis}
|
|
818
874
|
Changes: {list}
|
|
819
875
|
✅ Regression test added | ✅ Build: SUCCESS
|
|
876
|
+
{Trace: {UC-ID}-{platform}.tsv updated — test_count +{n}, dev_selftest → not_run | nếu có chạm row trace}
|
|
820
877
|
{🐞 BUG-{id} → State: Fixed (pushed) — Closed sau khi /qc-run-test re-verify pass | nếu fix một bug đã file}
|
|
821
878
|
{📝 Lesson L-NNN recorded (nếu đã capture)}
|
|
822
879
|
Branch: fix/{TICKET_ID}-{slug}
|
|
823
|
-
Next:
|
|
880
|
+
Next: /dev-run-test {UC-ID} ← dev_selftest vừa bị reset về not_run, chạy để lấy lại tín hiệu xanh
|
|
881
|
+
Rồi tạo PR và link tới ticket. {QC: chạy lại /qc-run-test {UC-ID} để verify + đóng bug | nếu áp dụng}
|
|
824
882
|
```
|
package/commands/fix-bug.tmpl
CHANGED
|
@@ -95,9 +95,10 @@ git checkout -b fix/{TICKET_ID}-{description}
|
|
|
95
95
|
```
|
|
96
96
|
Áp dụng fix. Thêm trace annotation nếu file có `@trace.implements`:
|
|
97
97
|
```
|
|
98
|
-
@trace.fixes={TICKET_ID}
|
|
98
|
+
@trace.fixes={BUG-ID nếu fix từ một bug report đã file · else TICKET_ID}
|
|
99
99
|
@trace.root_cause={brief description}
|
|
100
100
|
```
|
|
101
|
+
*(Ưu tiên `{BUG-ID}`: khi fix bắt nguồn từ `/report-bug` thì thường **không có** ticket ID nào, và `{BUG-ID}` mới là thứ trace ngược được về spec context + AC bị vi phạm.)*
|
|
101
102
|
|
|
102
103
|
## Phase 4 — Regression Test
|
|
103
104
|
```
|
|
@@ -107,7 +108,30 @@ Test: "Regression {TICKET_ID}: {bug description}"
|
|
|
107
108
|
```
|
|
108
109
|
Chạy test. Nếu fail → debug và fix (tối đa 3 vòng).
|
|
109
110
|
|
|
110
|
-
## Phase 5 —
|
|
111
|
+
## Phase 4.5 — Cập nhật sổ trace
|
|
112
|
+
|
|
113
|
+
*Bỏ qua nếu fix không chạm SC nào có row trace (vd fix hạ tầng/config).*
|
|
114
|
+
|
|
115
|
+
Đây là lệnh **duy nhất** sinh test mà trước đây không ghi sổ — hệ quả: `test_count` under-report vĩnh viễn (SC đứng `GAP` dù vừa có regression test, rồi `/validate-traces` khuyên `/dev-gen-test` → dev sinh test trùng), và `dev_selftest` giữ `pass` cũ **trên code đã đổi**.
|
|
116
|
+
|
|
117
|
+
Định vị sổ platform `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` — `{platform}` = platform của code vừa fix; không rõ → glob `{UC-ID}-*.tsv` tìm sổ nào chứa `sc_id` đó, khớp nhiều sổ → **hỏi** (cùng luật với `/report-bug` Step 5.5).
|
|
118
|
+
|
|
119
|
+
Với mỗi SC mà regression test phủ (theo `@trace.verifies` của test vừa viết):
|
|
120
|
+
|
|
121
|
+
| Cột | Giá trị |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `test_count` | **+=** số test method regression vừa thêm (cộng dồn, không ghi đè) |
|
|
124
|
+
| `test_classes` | **append** tên test class/describe mới, giữ nguyên tên cũ |
|
|
125
|
+
| `dev_selftest` | `not_run` — code vừa đổi nên tín hiệu self-test cũ hết hiệu lực |
|
|
126
|
+
| `dev_selftest_at` | `—` |
|
|
127
|
+
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
128
|
+
|
|
129
|
+
Giữ nguyên mọi cột khác. Đặc biệt:
|
|
130
|
+
- **KHÔNG** đụng `qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by` — QC sở hữu; `/qc-run-test` sẽ flip khi re-verify (và chính nó đóng `{BUG-ID}` → `🟢 Closed`).
|
|
131
|
+
- **KHÔNG** đụng `spec_ver`/`gen_ver` — fix bug **không** đổi spec, nên không được tạo tín hiệu DRIFT giả.
|
|
132
|
+
|
|
133
|
+
Rồi làm mới panel mirror:
|
|
134
|
+
{{include:steps/trace-mirror.md}}
|
|
111
135
|
```bash
|
|
112
136
|
{conventions.build_command} # tối đa 3 retry — chạy trong {service_root} ở umbrella mode
|
|
113
137
|
# Tầng 1 — push fix branch trong service submodule (nơi code sống):
|
|
@@ -164,8 +188,10 @@ Nếu `Y` → chạy quy trình capture bên dưới với `source=/fix-bug {TIC
|
|
|
164
188
|
Root Cause: {analysis}
|
|
165
189
|
Changes: {list}
|
|
166
190
|
✅ Regression test added | ✅ Build: SUCCESS
|
|
191
|
+
{Trace: {UC-ID}-{platform}.tsv updated — test_count +{n}, dev_selftest → not_run | nếu có chạm row trace}
|
|
167
192
|
{🐞 BUG-{id} → State: Fixed (pushed) — Closed sau khi /qc-run-test re-verify pass | nếu fix một bug đã file}
|
|
168
193
|
{📝 Lesson L-NNN recorded (nếu đã capture)}
|
|
169
194
|
Branch: fix/{TICKET_ID}-{slug}
|
|
170
|
-
Next:
|
|
195
|
+
Next: /dev-run-test {UC-ID} ← dev_selftest vừa bị reset về not_run, chạy để lấy lại tín hiệu xanh
|
|
196
|
+
Rồi tạo PR và link tới ticket. {QC: chạy lại /qc-run-test {UC-ID} để verify + đóng bug | nếu áp dụng}
|
|
171
197
|
```
|