@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.
Files changed (126) hide show
  1. package/bin/build.js +9 -0
  2. package/bin/index.js +115 -4
  3. package/bin/self-check.js +236 -0
  4. package/bin/trace-schema.json +692 -0
  5. package/commands/debug.md +82 -17
  6. package/commands/define-product.md +82 -17
  7. package/commands/dev-gen-test.md +82 -17
  8. package/commands/dev-run-test.md +84 -18
  9. package/commands/dev-run-test.tmpl +2 -1
  10. package/commands/dev-smoke-test.md +82 -17
  11. package/commands/fix-bug.md +137 -20
  12. package/commands/fix-bug.tmpl +29 -3
  13. package/commands/generate-architecture.md +82 -17
  14. package/commands/generate-bdd.md +187 -44
  15. package/commands/generate-bdd.tmpl +92 -17
  16. package/commands/generate-code.md +115 -20
  17. package/commands/generate-code.tmpl +33 -3
  18. package/commands/generate-design-spec.md +82 -17
  19. package/commands/generate-prd.md +82 -17
  20. package/commands/generate-spec-manifest.md +82 -17
  21. package/commands/generate-tech-docs.md +85 -20
  22. package/commands/generate-tech-docs.tmpl +2 -2
  23. package/commands/learn.md +82 -17
  24. package/commands/map-testids.md +82 -17
  25. package/commands/propose-scenario.md +102 -19
  26. package/commands/propose-scenario.tmpl +20 -2
  27. package/commands/qc-analyze.md +82 -17
  28. package/commands/qc-design-test.md +82 -17
  29. package/commands/qc-plan.md +82 -17
  30. package/commands/qc-report.md +82 -17
  31. package/commands/qc-review.md +82 -17
  32. package/commands/qc-run-test.md +104 -19
  33. package/commands/qc-run-test.tmpl +22 -2
  34. package/commands/refine-prd.md +82 -17
  35. package/commands/report-bug.md +82 -17
  36. package/commands/review-code.md +122 -19
  37. package/commands/review-code.tmpl +40 -2
  38. package/commands/review-context.md +124 -21
  39. package/commands/review-context.tmpl +42 -4
  40. package/commands/review-tech-docs.md +113 -19
  41. package/commands/review-tech-docs.tmpl +31 -2
  42. package/commands/setup-ai-first.md +35 -16
  43. package/commands/setup-ai-first.tmpl +19 -6
  44. package/commands/sync.md +15 -4
  45. package/commands/sync.tmpl +12 -2
  46. package/commands/update-framework.md +40 -2
  47. package/commands/update-framework.tmpl +37 -0
  48. package/commands/validate-traces.md +231 -25
  49. package/commands/validate-traces.tmpl +149 -8
  50. package/core/FRAMEWORK_VERSION +1 -1
  51. package/core/README.md +56 -0
  52. package/core/commands/debug.md +82 -17
  53. package/core/commands/define-product.md +82 -17
  54. package/core/commands/dev-gen-test.md +82 -17
  55. package/core/commands/dev-run-test.md +84 -18
  56. package/core/commands/dev-smoke-test.md +82 -17
  57. package/core/commands/fix-bug.md +137 -20
  58. package/core/commands/generate-architecture.md +82 -17
  59. package/core/commands/generate-bdd.md +187 -44
  60. package/core/commands/generate-code.md +115 -20
  61. package/core/commands/generate-design-spec.md +82 -17
  62. package/core/commands/generate-prd.md +82 -17
  63. package/core/commands/generate-spec-manifest.md +82 -17
  64. package/core/commands/generate-tech-docs.md +85 -20
  65. package/core/commands/learn.md +82 -17
  66. package/core/commands/map-testids.md +82 -17
  67. package/core/commands/propose-scenario.md +102 -19
  68. package/core/commands/qc-analyze.md +82 -17
  69. package/core/commands/qc-design-test.md +82 -17
  70. package/core/commands/qc-plan.md +82 -17
  71. package/core/commands/qc-report.md +82 -17
  72. package/core/commands/qc-review.md +82 -17
  73. package/core/commands/qc-run-test.md +104 -19
  74. package/core/commands/refine-prd.md +82 -17
  75. package/core/commands/report-bug.md +82 -17
  76. package/core/commands/review-code.md +122 -19
  77. package/core/commands/review-context.md +124 -21
  78. package/core/commands/review-tech-docs.md +113 -19
  79. package/core/commands/setup-ai-first.md +35 -16
  80. package/core/commands/sync.md +15 -4
  81. package/core/commands/update-framework.md +40 -2
  82. package/core/commands/validate-traces.md +231 -25
  83. package/core/modules/android-compose/stack-profile.yaml +1 -1
  84. package/core/modules/flutter/stack-profile.yaml +1 -1
  85. package/core/modules/ios-swiftui/stack-profile.yaml +1 -1
  86. package/core/modules/java-spring/stack-profile.yaml +1 -1
  87. package/core/modules/nextjs/stack-profile.yaml +1 -1
  88. package/core/modules/nuxt/stack-profile.yaml +1 -1
  89. package/core/modules/phaser-game/stack-profile.yaml +1 -1
  90. package/core/modules/php-laravel/stack-profile.yaml +1 -1
  91. package/core/modules/qc-playwright/stack-profile.yaml +1 -1
  92. package/core/modules/react/stack-profile.yaml +1 -1
  93. package/core/modules/react-native/stack-profile.yaml +1 -1
  94. package/core/modules/vue/stack-profile.yaml +1 -1
  95. package/core/rules/workflow.md +11 -0
  96. package/core/steps/context-loader.md +66 -7
  97. package/core/steps/gate.md +13 -8
  98. package/core/steps/report-footer.md +3 -2
  99. package/core/templates/README.md +47 -0
  100. package/core/templates/feature.template +13 -10
  101. package/core/templates/project-context.yaml +49 -17
  102. package/core/templates/tech-design.template.md +1 -1
  103. package/docs/02-concepts/traceability.md +29 -6
  104. package/docs/04-reference/trace-schema.md +128 -37
  105. package/modules/android-compose/stack-profile.yaml +1 -1
  106. package/modules/flutter/stack-profile.yaml +1 -1
  107. package/modules/ios-swiftui/stack-profile.yaml +1 -1
  108. package/modules/java-spring/stack-profile.yaml +1 -1
  109. package/modules/nextjs/stack-profile.yaml +1 -1
  110. package/modules/nuxt/stack-profile.yaml +1 -1
  111. package/modules/phaser-game/stack-profile.yaml +1 -1
  112. package/modules/php-laravel/stack-profile.yaml +1 -1
  113. package/modules/qc-playwright/stack-profile.yaml +1 -1
  114. package/modules/react/stack-profile.yaml +1 -1
  115. package/modules/react-native/stack-profile.yaml +1 -1
  116. package/modules/vue/stack-profile.yaml +1 -1
  117. package/package.json +50 -49
  118. package/rules/workflow.md +11 -0
  119. package/scripts/migrate-bdd-platform.js +286 -0
  120. package/steps/context-loader.md +66 -7
  121. package/steps/gate.md +13 -8
  122. package/steps/report-footer.md +3 -2
  123. package/templates/README.md +47 -0
  124. package/templates/feature.template +13 -10
  125. package/templates/project-context.yaml +49 -17
  126. 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 scenario (`.feature`)
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.id` | UC-ID (vd `UC-02`) |
16
- | `@trace.scenario` | SC-ID (vd `SC-02.1`) |
17
- | `@trace.business_rules` | BR liên quan (vd `BR-03`) |
18
- | `@trace.bdd_version` | Version của `.feature` (phát hiện drift) |
19
- | `@trace.prd_version` | Version PRD nguồn |
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.source` | `.feature` nguồn |
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
- > **KHÔNG** lưu version trong code tránh dual SSOT. Version dò qua `.tsv`.
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 (vd `UC-02-SC1`) |
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` | Bug/ticket được sửa |
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` (mỗi UC × platform một sổ; trong umbrella nằm spec repo).
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
- | Cột | Chủ sở hữu | Ý nghĩa |
65
- |-----|-----------|---------|
66
- | `status` | `/generate-code`, `/validate-traces` | OK / GAP / DRIFT / UNTRACKED |
67
- | `implemented_by` | `/generate-code` | File code hiện thực SC (`—` nếu chưa) |
68
- | `spec_ver` | spec | Version spec hiện tại |
69
- | `gen_ver` | `/generate-code` | Version lúc sinh code (`—` nếu chưa) |
70
- | `test_count` | test | Số test phủ SC |
71
- | `dev_selftest` | `/dev-run-test` | Smoke của dev (pass/fail/`—`) |
72
- | `qc_status` | `/qc-run-test`, `/report-bug` | QC chính thức (pass/fail/gap) |
73
- | `bdd_version` | spec | Version BDD |
74
- | `last_updated` | nhiều | Mốc cập nhật |
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** | 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 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
- ## Phân loại coverage (thứ tự ưu tiên)
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
- | # | Trạng thái | Điều kiện |
81
- |---|-----------|-----------|
82
- | 1 | **UNTRACKED** | `gen_ver == —` |
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
- `code_coverage = (rows where implemented_by != —) / total_scs`
178
+ ## Xuất JSON cho panel
88
179
 
89
- > DRIFT xét **trước** GAP: code lỗi thời + chưa test + spec drift phải hiện DRIFT (regen) không phải GAP (skip).
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 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
 
@@ -54,4 +54,4 @@ testing:
54
54
 
55
55
  trace_tags:
56
56
  implements: "// @trace.implements={UC-ID}-SC{N}"
57
- source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
57
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
@@ -56,4 +56,4 @@ testing:
56
56
 
57
57
  trace_tags:
58
58
  implements: "// @trace.implements={UC-ID}-SC{N}"
59
- source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
59
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
@@ -52,4 +52,4 @@ testing:
52
52
 
53
53
  trace_tags:
54
54
  implements: "// @trace.implements={UC-ID}-SC{N}"
55
- source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
55
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature"
@@ -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=<official .feature path>"
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"
@@ -53,4 +53,4 @@ 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"
@@ -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.3.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
- "files": [
17
- "bin/",
18
- "commands/",
19
- "core/",
20
- "hooks/",
21
- "modules/",
22
- "rules/",
23
- "scripts/",
24
- "skills/",
25
- "steps/",
26
- "templates/",
27
- "docs/"
28
- ],
29
- "keywords": [
30
- "claude-code",
31
- "spec-driven",
32
- "ai-first",
33
- "bdd",
34
- "traceability",
35
- "workflow"
36
- ],
37
- "author": "duclm2 <duclm2@edupia.com.vn>",
38
- "license": "MIT",
39
- "repository": {
40
- "type": "git",
41
- "url": "https://github.com/duclm2/sdd-framework"
42
- },
43
- "engines": {
44
- "node": ">=14"
45
- },
46
- "publishConfig": {
47
- "access": "public"
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`).