@educa-corp/sdd-framework 0.3.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 +82 -17
- package/commands/define-product.md +82 -17
- package/commands/dev-gen-test.md +82 -17
- package/commands/dev-run-test.md +84 -18
- package/commands/dev-run-test.tmpl +2 -1
- package/commands/dev-smoke-test.md +82 -17
- package/commands/fix-bug.md +137 -20
- package/commands/fix-bug.tmpl +29 -3
- package/commands/generate-architecture.md +82 -17
- package/commands/generate-bdd.md +187 -44
- package/commands/generate-bdd.tmpl +92 -17
- package/commands/generate-code.md +115 -20
- package/commands/generate-code.tmpl +33 -3
- package/commands/generate-design-spec.md +82 -17
- package/commands/generate-prd.md +82 -17
- package/commands/generate-spec-manifest.md +82 -17
- package/commands/generate-tech-docs.md +85 -20
- package/commands/generate-tech-docs.tmpl +2 -2
- package/commands/learn.md +82 -17
- package/commands/map-testids.md +82 -17
- package/commands/propose-scenario.md +102 -19
- package/commands/propose-scenario.tmpl +20 -2
- package/commands/qc-analyze.md +82 -17
- package/commands/qc-design-test.md +82 -17
- package/commands/qc-plan.md +82 -17
- package/commands/qc-report.md +82 -17
- package/commands/qc-review.md +82 -17
- package/commands/qc-run-test.md +104 -19
- package/commands/qc-run-test.tmpl +22 -2
- package/commands/refine-prd.md +82 -17
- package/commands/report-bug.md +82 -17
- package/commands/review-code.md +122 -19
- package/commands/review-code.tmpl +40 -2
- package/commands/review-context.md +124 -21
- package/commands/review-context.tmpl +42 -4
- package/commands/review-tech-docs.md +113 -19
- package/commands/review-tech-docs.tmpl +31 -2
- package/commands/setup-ai-first.md +35 -16
- package/commands/setup-ai-first.tmpl +19 -6
- package/commands/sync.md +15 -4
- package/commands/sync.tmpl +12 -2
- package/commands/update-framework.md +40 -2
- package/commands/update-framework.tmpl +37 -0
- package/commands/validate-traces.md +231 -25
- package/commands/validate-traces.tmpl +149 -8
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/README.md +56 -0
- package/core/commands/debug.md +82 -17
- package/core/commands/define-product.md +82 -17
- package/core/commands/dev-gen-test.md +82 -17
- package/core/commands/dev-run-test.md +84 -18
- package/core/commands/dev-smoke-test.md +82 -17
- package/core/commands/fix-bug.md +137 -20
- package/core/commands/generate-architecture.md +82 -17
- package/core/commands/generate-bdd.md +187 -44
- package/core/commands/generate-code.md +115 -20
- package/core/commands/generate-design-spec.md +82 -17
- package/core/commands/generate-prd.md +82 -17
- package/core/commands/generate-spec-manifest.md +82 -17
- package/core/commands/generate-tech-docs.md +85 -20
- package/core/commands/learn.md +82 -17
- package/core/commands/map-testids.md +82 -17
- package/core/commands/propose-scenario.md +102 -19
- package/core/commands/qc-analyze.md +82 -17
- package/core/commands/qc-design-test.md +82 -17
- package/core/commands/qc-plan.md +82 -17
- package/core/commands/qc-report.md +82 -17
- package/core/commands/qc-review.md +82 -17
- package/core/commands/qc-run-test.md +104 -19
- package/core/commands/refine-prd.md +82 -17
- package/core/commands/report-bug.md +82 -17
- package/core/commands/review-code.md +122 -19
- package/core/commands/review-context.md +124 -21
- package/core/commands/review-tech-docs.md +113 -19
- package/core/commands/setup-ai-first.md +35 -16
- package/core/commands/sync.md +15 -4
- package/core/commands/update-framework.md +40 -2
- package/core/commands/validate-traces.md +231 -25
- 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/context-loader.md +66 -7
- 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 +49 -17
- 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/context-loader.md +66 -7
- 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 +49 -17
- package/templates/tech-design.template.md +1 -1
|
@@ -4,54 +4,100 @@
|
|
|
4
4
|
|
|
5
5
|
> Field metadata `@trace.*` và cột file `.tsv`. Giải thích khái niệm → [Traceability](../02-concepts/traceability.md).
|
|
6
6
|
|
|
7
|
+
> ⚙️ **Bản máy đọc: `bin/trace-schema.json`.** File đó là nguồn-sự-thật mà `bin/self-check.js`
|
|
8
|
+
> đối chiếu với `commands/*.tmpl` + `steps/*.md` mỗi lần `npm run build` — build **fail** nếu
|
|
9
|
+
> lệnh lệch schema. Đổi contract thì sửa file JSON **trước**, rồi sửa lệnh, rồi cập nhật trang này.
|
|
10
|
+
|
|
7
11
|
---
|
|
8
12
|
|
|
9
13
|
## Trace tags theo artifact
|
|
10
14
|
|
|
11
|
-
### BDD
|
|
15
|
+
### BDD — header file (`.feature`)
|
|
16
|
+
|
|
17
|
+
| Tag | Ý nghĩa | Bắt buộc |
|
|
18
|
+
|-----|---------|:--------:|
|
|
19
|
+
| `@trace.id` | UC-ID — `{TICKET-ID}-UC{N}` (vd `SEG01-UC1`) | ✅ |
|
|
20
|
+
| `@trace.platform` | `web` / `app` / `system` — **mọi mode, kể cả umbrella** | ✅ |
|
|
21
|
+
| `@trace.domain` | Domain nghiệp vụ | ✅ |
|
|
22
|
+
| `@trace.prd` | TICKET-ID của PRD nguồn | ✅ |
|
|
23
|
+
| `@trace.prd_version` | Version PRD lúc sinh BDD | ✅ |
|
|
24
|
+
| `@trace.bdd_version` | Version **cả file** — tăng 0.1 mỗi lần gen lại / `--fix` | ✅ |
|
|
25
|
+
| `@trace.status` | `draft` / `in-review` / `approved` — cổng duyệt BDD | ✅ |
|
|
26
|
+
| `@trace.title` · `@trace.revision` · `@trace.author` · `@trace.created_at` · `@trace.business_rules` · `@trace.dataset` | thông tin | ⚪ |
|
|
27
|
+
| `@trace.service` · `@trace.module` | chỉ **umbrella mode**; vắng ở spec repo mode là đúng | ⚪ có điều kiện |
|
|
28
|
+
| `@trace.api_source` | `existing` — chỉ khi `platform = system` và PRD brownfield | ⚪ có điều kiện |
|
|
29
|
+
|
|
30
|
+
> **`@trace.platform` là field load-bearing nhất.** Thiếu nó: `/generate-code` không quyết được BE/FE (và **cấm** fallback sang `platform_type`), không định vị được sổ trace `{UC-ID}-{platform}.tsv`, không tìm được design-spec. Nó phải **khớp** segment `{platform}` của đường dẫn file.
|
|
31
|
+
|
|
32
|
+
### BDD — mỗi scenario
|
|
12
33
|
|
|
13
34
|
| Tag | Ý nghĩa |
|
|
14
35
|
|-----|---------|
|
|
15
|
-
| `@trace.
|
|
16
|
-
|
|
|
17
|
-
| `@trace.business_rules` | BR liên quan
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
| `@trace.status` | `draft` / `in-review` / `approved` (gate) |
|
|
21
|
-
| `@trace.platform` | `web` / `app` / `system` |
|
|
22
|
-
| `@trace.domain` | Domain nghiệp vụ |
|
|
36
|
+
| `@trace.scenario` | SC-ID — `{UC-ID}-SC{N}` (vd `SEG01-UC1-SC3`) |
|
|
37
|
+
| **`@trace.sc_version`** | Version **của riêng scenario này**. Tăng 0.1 khi **thân SC** đổi (tên · step · data table · side-effect). |
|
|
38
|
+
| `@trace.business_rules` | BR liên quan — `{TICKET-ID}-UC{N}-BR{m}` |
|
|
39
|
+
|
|
40
|
+
> **`sc_version` vs `bdd_version`:** `sc_version` là tín hiệu **duy nhất** cho `DRIFT` (`spec_ver != gen_ver`). `bdd_version` bắt thay đổi cấp file mà `sc_version` không thấy (Background, dataset, Business Definition, Coverage Matrix). Quên bump `sc_version` = code sinh từ scenario cũ **vĩnh viễn** hiện `OK`.
|
|
23
41
|
|
|
24
|
-
### Code (boundary only)
|
|
42
|
+
### Code — entry-point (boundary only)
|
|
43
|
+
|
|
44
|
+
```java
|
|
45
|
+
// @trace.implements=SEG01-UC1-SC3
|
|
46
|
+
// @trace.prd_version=1.2
|
|
47
|
+
// @trace.bdd_version=1.4
|
|
48
|
+
// @trace.tech_doc_revision=3
|
|
49
|
+
// @trace.source=specs/segment/scoring/bdd/system/SEG01-UC1-scoring.feature
|
|
50
|
+
public ScoreDto calculate(...) { }
|
|
51
|
+
```
|
|
25
52
|
|
|
26
53
|
| Tag | Ý nghĩa |
|
|
27
54
|
|-----|---------|
|
|
28
55
|
| `@trace.implements` | SC mà method này hiện thực |
|
|
29
|
-
| `@trace.
|
|
56
|
+
| `@trace.prd_version` · `@trace.bdd_version` · `@trace.tech_doc_revision` | version của từng artifact upstream **tại thời điểm codegen** — nguồn của `PRD_DRIFT` / `BDD_DRIFT` / `TECHDOC_DRIFT` |
|
|
57
|
+
| `@trace.source` | `.feature` nguồn — **phải gồm segment `{platform}`** |
|
|
58
|
+
|
|
59
|
+
> **File phủ nhiều UC → lặp CẢ BLOCK theo từng method.** Không gộp về một header file, không trỏ thư mục. 3 tag version là scalar **theo từng UC**; gộp lại thì không diễn đạt được "UC1 ở bdd v1.4, UC3 ở v2.1" → drift báo oan hoặc mù. Và các lệnh tra tag bằng **khớp chuỗi chính xác**, nên `@trace.source` trỏ thư mục sẽ ra 0 kết quả → UC rơi về `UNTRACKED` dù code đã có.
|
|
60
|
+
|
|
61
|
+
### Code — chỗ chưa implement (sổ `_seams.tsv`)
|
|
30
62
|
|
|
31
|
-
|
|
63
|
+
| Tag | Đặt ở đâu | Ý nghĩa |
|
|
64
|
+
|-----|---|---------|
|
|
65
|
+
| `@trace.stub` · `@trace.stub_owner` · `@trace.stub_for` | method trắng | logic thuộc BDD **khác của cùng feature** — ai để trắng / ai sẽ lấp / trách nhiệm gì |
|
|
66
|
+
| `@trace.seam_pending` · `@trace.seam_port` | class stub | port **cross-UC** do UC khác sở hữu, hàng thật chưa có |
|
|
32
67
|
|
|
33
68
|
### Test
|
|
34
69
|
|
|
35
70
|
| Tag | Ý nghĩa |
|
|
36
71
|
|-----|---------|
|
|
37
|
-
| `@trace.verifies` | SC mà test kiểm chứng
|
|
38
|
-
| `@trace.covers` | Phạm vi phủ |
|
|
72
|
+
| `@trace.verifies` | SC mà test kiểm chứng — `{UC-ID}-SC{N}` |
|
|
39
73
|
|
|
40
74
|
### Bug fix
|
|
41
75
|
|
|
42
76
|
| Tag | Ý nghĩa |
|
|
43
77
|
|-----|---------|
|
|
44
|
-
| `@trace.fixes` |
|
|
78
|
+
| `@trace.fixes` | `{BUG-ID}` nếu fix từ bug report đã file, else TICKET_ID |
|
|
45
79
|
| `@trace.root_cause` | Nguyên nhân gốc |
|
|
46
80
|
| `@trace.regression` | Test regression thêm vào |
|
|
47
81
|
|
|
82
|
+
### Tech-doc gộp (header, cấp PRD)
|
|
83
|
+
|
|
84
|
+
| Tag | Ý nghĩa |
|
|
85
|
+
|-----|---------|
|
|
86
|
+
| `@trace.id` · `@trace.domain` · `@trace.prd` | định danh |
|
|
87
|
+
| `@trace.ucs` | **danh sách** UC mà doc này phủ |
|
|
88
|
+
| `@trace.platforms` | platform có mặt |
|
|
89
|
+
| `@trace.bdd_versions` | **map theo platform** (`system=1.5, web=1.9`). Tên **số nhiều** để phân biệt với `@trace.bdd_version` (scalar) của `.feature` — cùng tên cho hai kiểu dữ liệu sẽ làm vỡ parser generic. |
|
|
90
|
+
| `@trace.revision` | integer, bump mỗi lần sửa — nguồn của `TECHDOC_DRIFT` |
|
|
91
|
+
| `@trace.status` | `draft` / `in-review` / `approved` — cổng của `/generate-code` DS3 |
|
|
92
|
+
| `@trace.api_source` | `existing` → chế độ reverse-document, bỏ cổng T7 |
|
|
93
|
+
|
|
48
94
|
---
|
|
49
95
|
|
|
50
96
|
## Boundary-only tagging
|
|
51
97
|
|
|
52
98
|
| ✅ Tag | ❌ Không tag |
|
|
53
99
|
|--------|-------------|
|
|
54
|
-
| Controller · Handler · Middleware · Steps file | Entity · Repository · DTO · Interface · Base class |
|
|
100
|
+
| Controller · Handler · Middleware · Consumer · Steps file | Entity · Repository · DTO · Interface · Base class |
|
|
55
101
|
|
|
56
102
|
Shared code dò qua **import chain** từ boundary → tránh tag explosion.
|
|
57
103
|
|
|
@@ -59,34 +105,79 @@ Shared code dò qua **import chain** từ boundary → tránh tag explosion.
|
|
|
59
105
|
|
|
60
106
|
## Trace state — `.tsv`
|
|
61
107
|
|
|
62
|
-
Đường dẫn: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv`
|
|
108
|
+
Đường dẫn: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` — **một sổ cho mỗi UC × platform** (`sc_id` chỉ độc nhất trong phạm vi đó; `web-SC1` và `system-SC1` là hai scenario khác nhau). Ở umbrella + `spec_source`, sổ nằm trong spec repo.
|
|
109
|
+
|
|
110
|
+
**22 cột, tab-separated:**
|
|
111
|
+
|
|
112
|
+
| # | Cột | Ý nghĩa | Chủ ghi |
|
|
113
|
+
|---|-----|---------|---------|
|
|
114
|
+
| 1 | `sc_id` | `{UC-ID}-SC{N}` | generate-bdd |
|
|
115
|
+
| 2 | `sc_title` | tiêu đề scenario | generate-bdd |
|
|
116
|
+
| 3 | `spec_ver` | gương của `@trace.sc_version` hiện tại | generate-bdd · validate-traces |
|
|
117
|
+
| 4 | `gen_ver` | `spec_ver` **tại thời điểm codegen** | generate-code |
|
|
118
|
+
| 5 | `implemented_by` | `{Class}.{method}` (`—` nếu chưa) | generate-code |
|
|
119
|
+
| 6 | `test_count` | số test phủ SC | dev-gen-test · fix-bug |
|
|
120
|
+
| 7 | `test_classes` | tên test class / describe | dev-gen-test · fix-bug |
|
|
121
|
+
| 8 | `dev_selftest` | `pass`/`fail`/`not_run` — **dev tự chạy** | dev-run-test |
|
|
122
|
+
| 9 | `dev_selftest_at` | ngày | dev-run-test |
|
|
123
|
+
| 10 | `qc_status` | `pass`/`fail`/`skip`/`not_run` — **QC chính thức** | qc-run-test |
|
|
124
|
+
| 11 | `qc_run_at` | ngày | qc-run-test |
|
|
125
|
+
| 12 | `qc_owner` | SC đang chờ ai: `dev` / `po` | qc-run-test · report-bug |
|
|
126
|
+
| 13 | `qc_blocked_by` | `BUG-{id}` / `GAP-{id}` | qc-run-test · report-bug |
|
|
127
|
+
| 14 | `prd_version` | version PRD lúc sinh BDD | generate-bdd |
|
|
128
|
+
| 15 | `bdd_version` | version `.feature` | generate-bdd · review-context |
|
|
129
|
+
| 16 | `tech_doc_revision` | `@trace.revision` của tech-doc | generate-code · review-tech-docs |
|
|
130
|
+
| 17 | `fe_tech_doc_revision` | revision lúc FE wire adapter thật (§4.5.4) | generate-code |
|
|
131
|
+
| 18 | `prd_status` | gương của PRD Metadata `Status` | generate-bdd · validate-traces |
|
|
132
|
+
| 19 | `uc_status` | gương của `@trace.status` (`.feature`) | generate-bdd · validate-traces |
|
|
133
|
+
| 20 | `fe_phase` | `ui` / `integrated` / `—` | generate-code `--phase` |
|
|
134
|
+
| 21 | `status` | tổng hợp — xem bảng dưới | validate-traces |
|
|
135
|
+
| 22 | `last_updated` | `YYYY-MM-DD` | mọi lệnh ghi row |
|
|
136
|
+
|
|
137
|
+
> `dev_selftest` (dev smoke) và `qc_status` (QC chính thức) là **hai tín hiệu riêng**, không bao giờ gộp. Cả hai **trực giao** với `status` — `status` đo *coverage*, chúng đo *kết quả chạy*.
|
|
138
|
+
|
|
139
|
+
> Giá trị rỗng trong TSV là `—`. Khi xuất JSON: `implemented_by`→`null`, `test_count`→`0`, `test_classes`→`[]`, `tech_doc_revision`/`fe_tech_doc_revision`→`0`, `dev_selftest`/`qc_status`→`"not_run"`.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Phân loại `status` (thứ tự ưu tiên, first-match-wins)
|
|
63
144
|
|
|
64
|
-
|
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
| `implemented_by
|
|
68
|
-
| `spec_ver
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
145
|
+
| # | Trạng thái | Điều kiện | Hành động |
|
|
146
|
+
|---|-----------|-----------|-----------|
|
|
147
|
+
| 0 | **ORPHANED** | SC **không còn trong `.feature`** nhưng `implemented_by != —` | Người quyết định: xoá code+test, hoặc đưa scenario trở lại |
|
|
148
|
+
| 1 | **UNTRACKED** | `implemented_by == —` | `/generate-code` |
|
|
149
|
+
| 2 | **DRIFT** | có code **và** `spec_ver != gen_ver` | regen **trước khi** test |
|
|
150
|
+
| 3 | **GAP** | có code **và** `test_count == —`/`0` | `/dev-gen-test` |
|
|
151
|
+
| 4 | **OK** | version khớp, có code, có test | đủ phủ |
|
|
152
|
+
|
|
153
|
+
`code_coverage = (rows where implemented_by != —) / total_scs` — **`total_scs` loại row `ORPHANED`** (không còn là scope; tính vào sẽ bóp méo coverage vì thứ không ai cần implement).
|
|
154
|
+
|
|
155
|
+
> **ORPHANED là Rule 0** vì 4 rule kia đều giả định scenario **còn tồn tại**. Để rule khác thắng thì mỗi giá trị route người dùng sang một lệnh vô nghĩa: `GAP`→sinh test cho SC không tồn tại · `DRIFT`→regen từ SC đã xoá · `OK`→cho tạo PR.
|
|
156
|
+
>
|
|
157
|
+
> **DRIFT xét trước GAP** vì `/generate-code` xử `GAP` = "skip codegen" còn `DRIFT` = "regenerate". Nếu GAP thắng, code lỗi thời bị bỏ qua và test lại sinh trên code cũ.
|
|
75
158
|
|
|
76
159
|
---
|
|
77
160
|
|
|
78
|
-
##
|
|
161
|
+
## Cờ audit (không phải cột — do `/validate-traces` tính)
|
|
162
|
+
|
|
163
|
+
| Cờ | Nguồn | Nghĩa |
|
|
164
|
+
|---|---|---|
|
|
165
|
+
| `PRD_DRIFT` | Step 4 | code mang `@trace.prd_version` cũ hơn PRD hiện tại |
|
|
166
|
+
| `BDD_DRIFT` | Step 5c | code mang `@trace.bdd_version` cũ hơn `.feature` |
|
|
167
|
+
| `TECHDOC_DRIFT` · `FE_TECHDOC_DRIFT` | Step 5 | code sinh từ revision tech-doc cũ hơn |
|
|
168
|
+
| `TECHDOC_STALE_VS_BDD` | Step 5c | tech-doc dựng từ BDD cũ hơn `.feature` hiện tại |
|
|
169
|
+
| `TRACE_ORPHAN` 🔴 | Step 2b | tag `@trace.implements`/`@trace.verifies` trỏ SC không tồn tại **và** không có row TSV |
|
|
170
|
+
| `SEAM_UNWIRED` 🔴 | Step 5b | hàng thật đã có nhưng consumer còn wire vào stub |
|
|
171
|
+
| `STUB_UNRESOLVED` 🔴 | Step 5b | method còn trắng dù owner đã gen / có hàm song song |
|
|
172
|
+
| `SEAM_PENDING` · `STUB_PENDING` | Step 5b | owner UC chưa gen — **bình thường**, chỉ nhắc |
|
|
79
173
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
| 2 | **DRIFT** | `implemented_by != —` AND `spec_ver != gen_ver` |
|
|
84
|
-
| 3 | **GAP** | `implemented_by != —` AND (`test_count == —` OR `0`) |
|
|
85
|
-
| 4 | **OK** | `spec_ver == gen_ver` AND `implemented_by != —` AND `test_count > 0` |
|
|
174
|
+
> 🔴 = **chặn PR**. Build xanh, test từng-UC xanh, coverage đẹp — nhưng luồng ghép chạy vào no-op hoặc code trỏ vào scenario đã bị xoá.
|
|
175
|
+
|
|
176
|
+
---
|
|
86
177
|
|
|
87
|
-
|
|
178
|
+
## Xuất JSON cho panel
|
|
88
179
|
|
|
89
|
-
|
|
180
|
+
`trace-report.json` giữ enum `status` **đúng 4 giá trị** `OK`/`DRIFT`/`GAP`/`UNTRACKED` — VS Code extension "Spec Driven Docs Tools" sống ngoài repo framework và switch trên field này. Row `ORPHANED` xuất ra là `"status": "DRIFT"` + `"orphaned": true`; panel cũ hiện nó như DRIFT (đúng nghĩa, không im lặng), panel mới đọc `orphaned` để hiện nhãn riêng. **TSV giữ nguyên chữ `ORPHANED`** — TSV là nguồn-sự-thật.
|
|
90
181
|
|
|
91
182
|
---
|
|
92
183
|
|
|
@@ -23,6 +23,6 @@ coding_standards:
|
|
|
23
23
|
|
|
24
24
|
trace_tags:
|
|
25
25
|
implements: "@trace.implements={UC-ID}-SC{N}"
|
|
26
|
-
source: "@trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
26
|
+
source: "@trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
27
27
|
verifies: "@trace.verifies={UC-ID}"
|
|
28
28
|
test_type: "@trace.test_type=unit|integration"
|
|
@@ -69,6 +69,6 @@ testing:
|
|
|
69
69
|
|
|
70
70
|
trace_tags:
|
|
71
71
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
72
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
72
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
73
73
|
verifies: "// @trace.verifies={UC-ID}"
|
|
74
74
|
test_type: "// @trace.test_type=unit|e2e"
|
|
@@ -53,6 +53,6 @@ testing:
|
|
|
53
53
|
|
|
54
54
|
trace_tags:
|
|
55
55
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
56
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
56
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
57
57
|
verifies: "// @trace.verifies={UC-ID}"
|
|
58
58
|
test_type: "// @trace.test_type=unit|integration"
|
|
@@ -85,6 +85,6 @@ testing:
|
|
|
85
85
|
|
|
86
86
|
trace_tags:
|
|
87
87
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
88
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
88
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
89
89
|
verifies: "// @trace.verifies={UC-ID}"
|
|
90
90
|
test_type: "// @trace.test_type=unit|integration"
|
|
@@ -51,6 +51,6 @@ testing:
|
|
|
51
51
|
|
|
52
52
|
trace_tags:
|
|
53
53
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
54
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
54
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
55
55
|
verifies: "// @trace.verifies={UC-ID}"
|
|
56
56
|
test_type: "// @trace.test_type=unit|feature"
|
|
@@ -59,7 +59,7 @@ testing:
|
|
|
59
59
|
trace_tags:
|
|
60
60
|
# QC tests map back to the framework's scenarios — drives qc_status in the trace TSV.
|
|
61
61
|
verifies: "# @trace.verifies={UC-ID}-SC{N}"
|
|
62
|
-
source: "# @trace.source
|
|
62
|
+
source: "# @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
63
63
|
test_type: "# @trace.test_type=functional|integration|e2e|non-functional"
|
|
64
64
|
|
|
65
65
|
# qc_status: /qc-run-test writes pass|fail|skip|not_run + qc_run_at into {trace_dir}/{UC-ID}.tsv
|
|
@@ -58,6 +58,6 @@ testing:
|
|
|
58
58
|
|
|
59
59
|
trace_tags:
|
|
60
60
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
61
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
61
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
62
62
|
verifies: "// @trace.verifies={UC-ID}"
|
|
63
63
|
test_type: "// @trace.test_type=unit|integration"
|
|
@@ -60,6 +60,6 @@ testing:
|
|
|
60
60
|
|
|
61
61
|
trace_tags:
|
|
62
62
|
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
63
|
-
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
|
|
63
|
+
source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
|
|
64
64
|
verifies: "// @trace.verifies={UC-ID}"
|
|
65
65
|
test_type: "// @trace.test_type=unit|integration"
|
package/package.json
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@educa-corp/sdd-framework",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Spec Driven Development workflow framework for Claude Code",
|
|
5
|
-
"bin": {
|
|
6
|
-
"sdd-framework": "./bin/index.js"
|
|
7
|
-
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"build": "node bin/build.js",
|
|
10
|
-
"prepublishOnly": "node bin/build.js",
|
|
11
|
-
"pub": "npm publish --access=public",
|
|
12
|
-
"dev": "node bin/build.js && node bin/index.js --init",
|
|
13
|
-
"prepack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync(f)) fs.renameSync(f,'__'+f); });\"",
|
|
14
|
-
"postpack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync('__'+f)) fs.renameSync('__'+f,f); });\""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@educa-corp/sdd-framework",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Spec Driven Development workflow framework for Claude Code",
|
|
5
|
+
"bin": {
|
|
6
|
+
"sdd-framework": "./bin/index.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "node bin/build.js && node bin/self-check.js",
|
|
10
|
+
"prepublishOnly": "node bin/build.js && node bin/self-check.js",
|
|
11
|
+
"pub": "npm publish --access=public",
|
|
12
|
+
"dev": "node bin/build.js && node bin/index.js --init",
|
|
13
|
+
"prepack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync(f)) fs.renameSync(f,'__'+f); });\"",
|
|
14
|
+
"postpack": "node -e \"const fs=require('fs'); ['README.md','PUBLISHING.md','SETUP_GUIDE.md'].forEach(f=>{ if(fs.existsSync('__'+f)) fs.renameSync('__'+f,f); });\"",
|
|
15
|
+
"self-check": "node bin/self-check.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/",
|
|
19
|
+
"commands/",
|
|
20
|
+
"core/",
|
|
21
|
+
"hooks/",
|
|
22
|
+
"modules/",
|
|
23
|
+
"rules/",
|
|
24
|
+
"scripts/",
|
|
25
|
+
"skills/",
|
|
26
|
+
"steps/",
|
|
27
|
+
"templates/",
|
|
28
|
+
"docs/"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"claude-code",
|
|
32
|
+
"spec-driven",
|
|
33
|
+
"ai-first",
|
|
34
|
+
"bdd",
|
|
35
|
+
"traceability",
|
|
36
|
+
"workflow"
|
|
37
|
+
],
|
|
38
|
+
"author": "duclm2 <duclm2@edupia.com.vn>",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/duclm2/sdd-framework"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=14"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/rules/workflow.md
CHANGED
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
- Do NOT create files outside the directories specified in `project-context.yaml → paths`.
|
|
19
19
|
- If new scope is discovered mid-command, STOP and ask: "I found additional scope [{description}]. Should I include it? (Y/N)"
|
|
20
20
|
|
|
21
|
+
## Trace Contract
|
|
22
|
+
|
|
23
|
+
- Contract trace (field `@trace.*`, cột `.tsv`, path pattern, giá trị enum) có **một
|
|
24
|
+
nguồn-sự-thật máy đọc**: `bin/trace-schema.json`. Bản cho người đọc:
|
|
25
|
+
`docs/04-reference/trace-schema.md` — giữ hai file đồng bộ.
|
|
26
|
+
- Đổi contract (thêm/bỏ/đổi nghĩa một field, path, hay giá trị enum) → **sửa
|
|
27
|
+
`bin/trace-schema.json` TRƯỚC**, rồi mới sửa lệnh. `npm run build` chạy
|
|
28
|
+
`bin/self-check.js` và **fail** nếu lệnh lệch schema.
|
|
29
|
+
- Field có consumer mà **không có producer** là lỗi chặn build — đó chính là hình dạng
|
|
30
|
+
của G1 (`@trace.sc_version`: 3 consumer, 0 producer, DRIFT chết mà không ai báo).
|
|
31
|
+
|
|
21
32
|
## Code Generation
|
|
22
33
|
|
|
23
34
|
- Never generate code for files not backed by a `.feature` spec (unless `/fix-bug` or `/debug`).
|