@educa-corp/sdd-framework 0.6.0 → 0.7.1

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 (223) hide show
  1. package/bin/gate-trace.js +25 -2
  2. package/bin/index.js +32 -5
  3. package/bin/lint-trace.js +41 -0
  4. package/bin/self-check.js +430 -3
  5. package/bin/trace-schema.json +418 -31
  6. package/core/FRAMEWORK_VERSION +1 -1
  7. package/{commands/extend-prd.md → core/commands/amend-prd.md} +206 -173
  8. package/core/commands/dev-run-test.md +48 -10
  9. package/core/commands/extend-prd.md +39 -12
  10. package/core/commands/generate-bdd.md +52 -10
  11. package/core/commands/generate-code.md +35 -2
  12. package/core/commands/generate-tech-docs.md +36 -4
  13. package/core/commands/map-testids.md +1 -1
  14. package/core/commands/qc-run-test.md +29 -3
  15. package/core/commands/refine-prd.md +13 -2
  16. package/core/commands/review-context.md +43 -8
  17. package/core/commands/sync.md +105 -1
  18. package/core/commands/validate-traces.md +289 -16
  19. package/core/rules/workflow.md +34 -0
  20. package/core/steps/context-loader.md +27 -6
  21. package/core/templates/feature.template +1 -1
  22. package/core/templates/project-context.yaml +3 -3
  23. package/core/templates/tech-design.template.md +2 -2
  24. package/docs/02-concepts/architecture.md +37 -1
  25. package/docs/02-concepts/overview.md +1 -1
  26. package/docs/02-concepts/pipeline-steps/02-specification.md +13 -7
  27. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +2 -0
  28. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -0
  29. package/docs/02-concepts/pipeline-steps/09-validate-traces.md +34 -3
  30. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +10 -1
  31. package/docs/02-concepts/traceability.md +187 -183
  32. package/docs/03-guides/architect.md +13 -4
  33. package/docs/03-guides/developer.md +1 -0
  34. package/docs/03-guides/product-owner.md +89 -72
  35. package/docs/03-guides/tester-qa.md +81 -81
  36. package/docs/04-reference/commands.md +148 -134
  37. package/docs/04-reference/trace-schema.md +45 -1
  38. package/docs/explain/02b-extend-prd.md +1 -1
  39. package/docs/explain/02c-amend-prd.md +152 -0
  40. package/docs/explain/06-generate-bdd.md +1 -1
  41. package/docs/explain/13-dev-run-test.md +15 -1
  42. package/docs/explain/19-qc-run-test.md +91 -87
  43. package/docs/explain/21-validate-traces.md +79 -75
  44. package/docs/explain/28-sync.md +25 -0
  45. package/docs/explain/README.md +136 -135
  46. package/package.json +1 -8
  47. package/commands/debug.md +0 -529
  48. package/commands/debug.tmpl +0 -260
  49. package/commands/define-product.md +0 -438
  50. package/commands/define-product.tmpl +0 -225
  51. package/commands/dev-gen-test.md +0 -700
  52. package/commands/dev-gen-test.tmpl +0 -490
  53. package/commands/dev-run-test.md +0 -435
  54. package/commands/dev-run-test.tmpl +0 -225
  55. package/commands/dev-smoke-test.md +0 -374
  56. package/commands/dev-smoke-test.tmpl +0 -217
  57. package/commands/extend-prd.tmpl +0 -273
  58. package/commands/fix-bug.md +0 -519
  59. package/commands/fix-bug.tmpl +0 -197
  60. package/commands/generate-architecture.md +0 -354
  61. package/commands/generate-architecture.tmpl +0 -197
  62. package/commands/generate-bdd.md +0 -923
  63. package/commands/generate-bdd.tmpl +0 -590
  64. package/commands/generate-code.md +0 -859
  65. package/commands/generate-code.tmpl +0 -649
  66. package/commands/generate-design-spec.md +0 -737
  67. package/commands/generate-design-spec.tmpl +0 -524
  68. package/commands/generate-prd.md +0 -722
  69. package/commands/generate-prd.tmpl +0 -226
  70. package/commands/generate-spec-manifest.md +0 -321
  71. package/commands/generate-spec-manifest.tmpl +0 -164
  72. package/commands/generate-tech-docs.md +0 -920
  73. package/commands/generate-tech-docs.tmpl +0 -273
  74. package/commands/learn.md +0 -399
  75. package/commands/learn.tmpl +0 -130
  76. package/commands/map-testids.md +0 -238
  77. package/commands/map-testids.tmpl +0 -81
  78. package/commands/propose-scenario.md +0 -359
  79. package/commands/propose-scenario.tmpl +0 -202
  80. package/commands/qc-analyze.md +0 -269
  81. package/commands/qc-analyze.tmpl +0 -112
  82. package/commands/qc-design-test.md +0 -226
  83. package/commands/qc-design-test.tmpl +0 -69
  84. package/commands/qc-plan.md +0 -206
  85. package/commands/qc-plan.tmpl +0 -49
  86. package/commands/qc-report.md +0 -217
  87. package/commands/qc-report.tmpl +0 -60
  88. package/commands/qc-review.md +0 -210
  89. package/commands/qc-review.tmpl +0 -53
  90. package/commands/qc-run-test.md +0 -326
  91. package/commands/qc-run-test.tmpl +0 -116
  92. package/commands/refine-prd.md +0 -653
  93. package/commands/refine-prd.tmpl +0 -281
  94. package/commands/report-bug.md +0 -305
  95. package/commands/report-bug.tmpl +0 -148
  96. package/commands/review-code.md +0 -415
  97. package/commands/review-code.tmpl +0 -146
  98. package/commands/review-context.md +0 -902
  99. package/commands/review-context.tmpl +0 -530
  100. package/commands/review-tech-docs.md +0 -561
  101. package/commands/review-tech-docs.tmpl +0 -404
  102. package/commands/setup-ai-first.md +0 -602
  103. package/commands/setup-ai-first.tmpl +0 -450
  104. package/commands/sync.md +0 -430
  105. package/commands/sync.tmpl +0 -429
  106. package/commands/update-framework.md +0 -203
  107. package/commands/update-framework.tmpl +0 -202
  108. package/commands/validate-traces.md +0 -1077
  109. package/commands/validate-traces.tmpl +0 -920
  110. package/hooks/data-guard.js +0 -232
  111. package/hooks/settings.json +0 -19
  112. package/modules/android-compose/module.yaml +0 -13
  113. package/modules/android-compose/stack-profile.yaml +0 -57
  114. package/modules/angular/architecture-snippets/component-patterns.md +0 -187
  115. package/modules/angular/module.yaml +0 -6
  116. package/modules/angular/stack-profile.yaml +0 -38
  117. package/modules/context-engineering/architecture-snippets/context-design.md +0 -119
  118. package/modules/context-engineering/module.yaml +0 -9
  119. package/modules/context-engineering/stack-profile.yaml +0 -61
  120. package/modules/dotnet/architecture-snippets/clean-arch.md +0 -160
  121. package/modules/dotnet/module.yaml +0 -6
  122. package/modules/dotnet/stack-profile.yaml +0 -50
  123. package/modules/flutter/module.yaml +0 -14
  124. package/modules/flutter/stack-profile.yaml +0 -59
  125. package/modules/golang/architecture-snippets/domain-layout.md +0 -283
  126. package/modules/golang/module.yaml +0 -6
  127. package/modules/golang/stack-profile.yaml +0 -40
  128. package/modules/ios-swiftui/module.yaml +0 -13
  129. package/modules/ios-swiftui/stack-profile.yaml +0 -55
  130. package/modules/java-spring/architecture-snippets/layered-arch.md +0 -201
  131. package/modules/java-spring/module.yaml +0 -15
  132. package/modules/java-spring/stack-profile.yaml +0 -28
  133. package/modules/nextjs/architecture-snippets/app-router-patterns.md +0 -269
  134. package/modules/nextjs/module.yaml +0 -14
  135. package/modules/nextjs/stack-profile.yaml +0 -74
  136. package/modules/nuxt/module.yaml +0 -14
  137. package/modules/nuxt/stack-profile.yaml +0 -58
  138. package/modules/phaser-game/architecture-snippets/phaser-scene-patterns.md +0 -646
  139. package/modules/phaser-game/module.yaml +0 -15
  140. package/modules/phaser-game/stack-profile.yaml +0 -90
  141. package/modules/php-laravel/architecture-snippets/service-repository.md +0 -302
  142. package/modules/php-laravel/module.yaml +0 -15
  143. package/modules/php-laravel/stack-profile.yaml +0 -56
  144. package/modules/qc-playwright/stack-profile.yaml +0 -66
  145. package/modules/react/architecture-snippets/hooks-query-patterns.md +0 -254
  146. package/modules/react/module.yaml +0 -14
  147. package/modules/react/stack-profile.yaml +0 -63
  148. package/modules/react-native/module.yaml +0 -14
  149. package/modules/react-native/stack-profile.yaml +0 -56
  150. package/modules/vue/module.yaml +0 -14
  151. package/modules/vue/stack-profile.yaml +0 -65
  152. package/rules/data-protection.md +0 -80
  153. package/rules/workflow.md +0 -99
  154. package/skills/code/SKILL.md +0 -19
  155. package/skills/code/SKILL.tmpl +0 -19
  156. package/skills/debug/SKILL.md +0 -19
  157. package/skills/debug/SKILL.tmpl +0 -19
  158. package/skills/design-spec/SKILL.md +0 -11
  159. package/skills/design-spec/SKILL.tmpl +0 -11
  160. package/skills/discovery/SKILL.md +0 -14
  161. package/skills/discovery/SKILL.tmpl +0 -14
  162. package/skills/prd/SKILL.md +0 -19
  163. package/skills/prd/SKILL.tmpl +0 -19
  164. package/skills/qc/qa-analyst/DOC_GAPS.template.md +0 -63
  165. package/skills/qc/qa-analyst/acceptance-criteria.md +0 -60
  166. package/skills/qc/qa-analyst/business-rules.md +0 -59
  167. package/skills/qc/qa-analyst/data-flow.md +0 -64
  168. package/skills/qc/qa-analyst/spec-breakdown.md +0 -61
  169. package/skills/qc/qa-designer/e2e/journey.md +0 -41
  170. package/skills/qc/qa-designer/exploratory/charter.md +0 -68
  171. package/skills/qc/qa-designer/exploratory/explore-to-functional.md +0 -43
  172. package/skills/qc/qa-designer/functional/api.md +0 -45
  173. package/skills/qc/qa-designer/functional/gui-feature.md +0 -46
  174. package/skills/qc/qa-designer/functional/gui-screen.md +0 -52
  175. package/skills/qc/qa-designer/integration/api.md +0 -42
  176. package/skills/qc/qa-designer/integration/db.md +0 -39
  177. package/skills/qc/qa-designer/integration/gui.md +0 -40
  178. package/skills/qc/qa-designer/integration/kafka.md +0 -40
  179. package/skills/qc/qa-designer/non-functional.md +0 -40
  180. package/skills/qc/qa-planner/test-plan.md +0 -120
  181. package/skills/qc/qa-reviewer/script/e2e.md +0 -87
  182. package/skills/qc/qa-reviewer/script/exploratory.md +0 -45
  183. package/skills/qc/qa-reviewer/script/functional.md +0 -101
  184. package/skills/qc/qa-reviewer/script/integration.md +0 -91
  185. package/skills/qc/qa-reviewer/script/non-functional.md +0 -126
  186. package/skills/qc/qa-reviewer/test-case/e2e.md +0 -73
  187. package/skills/qc/qa-reviewer/test-case/exploratory.md +0 -43
  188. package/skills/qc/qa-reviewer/test-case/functional.md +0 -76
  189. package/skills/qc/qa-reviewer/test-case/integration.md +0 -69
  190. package/skills/qc/qa-reviewer/test-case/non-functional.md +0 -73
  191. package/skills/qc/qa-runner/e2e.md +0 -49
  192. package/skills/qc/qa-runner/exploratory/session.md +0 -36
  193. package/skills/qc/qa-runner/functional/api.md +0 -35
  194. package/skills/qc/qa-runner/functional/gui-feature.md +0 -51
  195. package/skills/qc/qa-runner/functional/gui-screen.md +0 -55
  196. package/skills/qc/qa-runner/integration.md +0 -47
  197. package/skills/qc/qa-runner/non-functional.md +0 -49
  198. package/skills/qc/qa-runner/report/report.md +0 -37
  199. package/skills/setup-ai-first/SKILL.md +0 -19
  200. package/skills/setup-ai-first/SKILL.tmpl +0 -19
  201. package/skills/spec/SKILL.md +0 -19
  202. package/skills/spec/SKILL.tmpl +0 -19
  203. package/skills/test/SKILL.md +0 -18
  204. package/skills/test/SKILL.tmpl +0 -18
  205. package/steps/business-language.md +0 -56
  206. package/steps/capture-lesson.md +0 -112
  207. package/steps/context-loader.md +0 -406
  208. package/steps/gate.md +0 -151
  209. package/steps/report-footer.md +0 -125
  210. package/steps/review-fanout.md +0 -159
  211. package/steps/spawn-agent.md +0 -129
  212. package/steps/trace-mirror.md +0 -53
  213. package/templates/README.md +0 -70
  214. package/templates/architecture.template.md +0 -394
  215. package/templates/ci/trace-gate.yml +0 -146
  216. package/templates/design-spec.template.md +0 -217
  217. package/templates/feature.template +0 -123
  218. package/templates/hooks/pre-push +0 -61
  219. package/templates/platform-guide.template.md +0 -145
  220. package/templates/prd.template.md +0 -283
  221. package/templates/product-definition.template.md +0 -188
  222. package/templates/project-context.yaml +0 -212
  223. package/templates/tech-design.template.md +0 -490
package/commands/sync.md DELETED
@@ -1,430 +0,0 @@
1
- # /sync — Sync & Refresh Umbrella Project
2
-
3
- Một lệnh cho cả **setup lần đầu** lẫn **cập nhật hằng ngày** một umbrella repo có git submodule.
4
- An toàn chạy lặp lại — tự phát hiện cần làm gì.
5
-
6
- **Argument tuỳ chọn:** `/sync [spec-branch]` — branch của spec submodule để pull (vd `/sync develop`). Nếu bỏ, branch được phân giải tự động (xem Step 0-D).
7
-
8
- ---
9
-
10
- ## Step 0 — Pre-flight Checks
11
-
12
- **A. Git repo check**
13
-
14
- Xác minh thư mục hiện tại nằm trong git repo. Nếu không → dừng:
15
- ```
16
- ❌ Not a git repository. Open Claude Code from umbrella root and retry.
17
- ```
18
-
19
- **B. Đọc project config sớm**
20
-
21
- Đọc `.agent/project-context.yaml` trước khi chạy lệnh git nào. Trích:
22
- - `setup.spec_source` → path của spec submodule (vd `"my-project-specs"`)
23
- - `services` → map domain → `{path, module, ...}` cho mỗi service submodule
24
-
25
- Cần cái này để phân biệt spec vs service submodule ở Step 1.
26
-
27
- Nếu `.agent/project-context.yaml` không tồn tại → cảnh báo và set `spec_source = null`, `services = {}`.
28
-
29
- **C. Submodule status scan**
30
-
31
- Chạy `git submodule status --recursive` và phân loại mỗi entry theo ký tự đầu:
32
-
33
- | Char | Ý nghĩa | Hành động |
34
- |------|---------|--------|
35
- | `-` | Chưa init | → **Setup mode** |
36
- | ` ` | Khớp pointer đã ghi | → OK |
37
- | `+` | Ahead của pointer đã ghi (local advance chưa commit) | → cảnh báo từng submodule |
38
- | `U` | Merge conflict | → **STOP** |
39
-
40
- Nếu **bất kỳ** entry nào có `U`:
41
- ```
42
- ❌ Merge conflict in submodule: {path}
43
- Resolve manually before running /sync:
44
- cd {path} && git status
45
- ```
46
-
47
- Nếu **bất kỳ** entry nào có `+` (commit đang checkout khác pointer đã ghi):
48
- ```
49
- ℹ️ {path} is ahead of the umbrella's recorded pointer.
50
- /sync classifies it in Step 1b — if you're on a branch there, it stays untouched.
51
- ```
52
- Đừng xử lý `+` ở đây — Step 1b quyết định cách xử lý đúng cho từng submodule.
53
-
54
- In mode phát hiện: `Mode: Setup (first-time init)` hoặc `Mode: Update (sync latest)`.
55
-
56
- ---
57
-
58
- ## Step 1 — Umbrella Pull
59
-
60
- Ghi branch umbrella hiện tại trước (đây là cái `git pull` cập nhật):
61
- `git rev-parse --abbrev-ref HEAD` → lưu thành `umbrella_branch` và hiển thị.
62
-
63
- ```bash
64
- # 1. Pull latest umbrella (includes updated submodule pointer records)
65
- git pull
66
-
67
- # 2. Sync .gitmodules config into local git config
68
- # (needed when new submodules were added since last clone)
69
- git submodule sync --recursive
70
-
71
- # 3. Initialize any NOT-yet-cloned submodules ONLY (the '-' entries from Step 0-C).
72
- # Do NOT run a blanket `git submodule update --recursive` — that would detach
73
- # a submodule you are actively working in. Per-submodule handling is Step 1b.
74
- git submodule update --init {paths that were '-' in Step 0-C}
75
- ```
76
-
77
- Nếu `git pull` exit khác 0 → in lỗi và dừng với `❌`.
78
-
79
- ---
80
-
81
- ## Step 1b — Phân loại & Sync từng Submodule
82
-
83
- **Ý tưởng cốt lõi:** `/sync` không bao giờ áp một branch lên submodule. Nó **kiểm tra checkout hiện tại của từng submodule** và tôn trọng nó. Đây là cách nó biết submodule nào bạn đang làm vs cái nào là dependency thụ động.
84
-
85
- Với mỗi submodule (dùng `git submodule foreach` hoặc lặp các path), đọc state:
86
-
87
- ```bash
88
- # Inside each submodule:
89
- git symbolic-ref --short -q HEAD # → branch name, or empty/non-zero if DETACHED
90
- git status --porcelain # → non-empty means uncommitted local changes
91
- ```
92
-
93
- Phân loại vào một trong bốn case và xử lý tương ứng:
94
-
95
- | Case | State phát hiện | Hành động |
96
- |------|----------------|--------|
97
- | **Spec submodule** | `path == spec_source` | Advance tới `spec_branch` (Step 1c bên dưới) |
98
- | **Active (on a branch)** | HEAD là một branch, không detached | **KHÔNG checkout.** Đây là nơi bạn (hoặc đồng đội) đang code. Chỉ `git -C {path} fetch` và report branch + ahead/behind. Để working tree y nguyên. |
99
- | **Passive (detached, clean)** | Detached HEAD, không có thay đổi local | An toàn align về pointer đã ghi của umbrella: `git submodule update {path}` |
100
- | **Dirty (uncommitted changes)** | `git status --porcelain` non-empty | **Đừng đụng.** Cảnh báo: `⚠️ {path} has uncommitted changes — skipped. Commit or stash before syncing this submodule.` |
101
-
102
- > **Vì sao quan trọng:** Một `git submodule update` toàn bộ checkout mọi submodule về **detached HEAD** ở pointer đã ghi. Nếu bạn đang checkout `feature/FEAT-01` trong `user-service/` và đang làm dở, cái đó sẽ âm thầm chuyển bạn khỏi branch. Phân loại trước bảo vệ công việc đang làm của bạn.
103
-
104
- ---
105
-
106
- ## Step 1c — Advance Spec Submodule *(chỉ khi `spec_source` được cấu hình)*
107
-
108
- Spec submodule là submodule duy nhất ta cố ý advance tới một branch HEAD (PO push spec liên tục).
109
-
110
- **Phân giải spec branch** (giờ submodule đã init), theo thứ tự ưu tiên:
111
-
112
- 1. **Command argument** — nếu `$ARGUMENTS` chứa tên branch → dùng nó (override một lần)
113
- 2. **`.gitmodules` config** — `git config -f .gitmodules --get submodule.{spec_source}.branch`. Nếu set → dùng nó (default committed của team)
114
- 3. **Remote default** — else branch default của spec repo: `git -C {spec_source} rev-parse --abbrev-ref origin/HEAD` (bỏ prefix `origin/`)
115
-
116
- Lưu thành `spec_branch` + `spec_branch_source` (argument | .gitmodules | remote-default). Nếu nó rơi xuống remote-default mà không có gì pin, thêm hint này vào output:
117
- ```
118
- ℹ️ Spec submodule branch not pinned in .gitmodules — using remote default '{spec_branch}'.
119
- To pin it for the whole team:
120
- git config -f .gitmodules submodule.{spec_source}.branch {spec_branch}
121
- git add .gitmodules && git commit -m "chore: pin spec submodule branch"
122
- ```
123
-
124
- Rồi kiểm tra an toàn: nếu spec submodule có thay đổi chưa commit → cảnh báo và skip (dev nên coi spec là read-only). Ngược lại dùng **explicit checkout** (không phải `--remote` trần) để branch rõ ràng:
125
-
126
- ```bash
127
- cd {spec_source}
128
- git fetch origin
129
- git checkout {spec_branch} # branch resolved in Step 0-D
130
- git pull origin {spec_branch}
131
- cd - # back to umbrella root
132
- ```
133
-
134
- In: `Spec submodule {spec_source}: pulled branch '{spec_branch}' (source: {spec_branch_source})`
135
-
136
- > **Vì sao không `--remote` cho service submodule?** Service submodule bị version-lock bởi pointer đã ghi của umbrella — cố ý để mọi dev làm từ cùng commit. `--remote` sẽ bỏ qua lock này và tạo pointer drift chưa commit. Spec submodule là ngoại lệ: PO push liên tục, nên ta advance nó tới branch HEAD — nhưng làm bằng explicit `checkout {spec_branch}` thay vì `--remote` để nó không bao giờ âm thầm theo sai branch.
137
-
138
- Nếu `git pull` hoặc `git submodule update` exit khác 0 → in lỗi và dừng với `❌`.
139
-
140
- Thu từ output:
141
- - Submodule nào đổi SHA
142
- - Cái nào đã up to date
143
- - `{old_sha}..{new_sha}` của spec submodule (cần cho Step 1d)
144
-
145
- ---
146
-
147
- ## Step 1d — Surface Feedback của Tester/QC *(bug report / scenario proposal / PRD change request)*
148
-
149
- `/report-bug`, `/propose-scenario` của tester & QC (gồm cả PRD change request Case B) commit feedback vào spec repo. Step này cho PO/Dev biết cái gì tới trong **lần** pull này, để họ được thông báo qua routine bình thường. Nó phủ cả hai đối tượng:
150
-
151
- - **Dev/tester trong umbrella** → feedback tới qua spec submodule advance (Step 1c)
152
- - **PO làm trực tiếp trong spec repo** → feedback tới qua `git pull` của umbrella/current-repo (Step 1)
153
-
154
- Chọn repo + range đã pull feedback:
155
- - Umbrella có `spec_source` → `REPO={spec_source}`, range = spec submodule `{old_sha}..{new_sha}`
156
- - Ngược lại (chạy trong chính spec repo) → `REPO=.`, range = `{old_sha}..{new_sha}` của `git pull` từ Step 1
157
-
158
- Nếu `feedback/` không tồn tại trong REPO → skip âm thầm.
159
-
160
- ```bash
161
- git -C {REPO} diff --name-status {old_sha}..{new_sha} -- feedback/bug-reports/ feedback/bdd-proposals/ feedback/prd-change-requests/
162
- ```
163
-
164
- Với mỗi entry, đọc title/summary + `State` và report. **Bug report: chỉ surface `State: Open`** là cần chú ý; liệt kê `Fixed`/`Closed` riêng (hoặc bỏ) để PO/PM thấy cái gì còn pending:
165
- ```
166
- 📥 New feedback (pulled this sync):
167
- Bug reports (open):
168
- BUG-20260608-01 FT-001 — account locks after 6 fails (spec says 5) [layer: Code · waiting: dev]
169
- Bug reports (fixed, awaiting QC re-verify): BUG-20260605-02
170
- Scenario proposals:
171
- FT-001-trailing-spaces.md → maps to AC2 (pending review)
172
- PRD change requests:
173
- FT-001-bulk-export.md → new requirement, needs an AC (waiting: PO)
174
- ```
175
-
176
- Nếu không có gì đổi → in `📥 Feedback: none new this sync`.
177
-
178
- Nếu người đọc là PO/Dev, thêm một dòng nudge:
179
- `→ Review feedback/ then act: /fix-bug {BUG-ID} · promote proposal via /generate-bdd · or add an AC to the PRD.`
180
-
181
- ---
182
-
183
- ## Step 2 — Post-sync State Check
184
-
185
- Chạy `git status --short` và kiểm tra entry submodule bị modified (dòng bắt đầu bằng ` M` mà path khớp một submodule).
186
-
187
- Nếu pointer submodule nào đổi (thường là spec submodule sau `--remote`):
188
- ```
189
- ⚠️ Submodule pointer(s) updated — commit to lock new version into umbrella:
190
- git add {spec_source} && git commit -m "chore: sync {spec_source} to latest"
191
- ```
192
-
193
- Nếu không có thay đổi → `✅ Umbrella state clean — no commit needed`.
194
-
195
- ---
196
-
197
- ## Step 3 — Bootstrap Service Configs
198
-
199
- *Skip nếu `services` rỗng.*
200
-
201
- **Trước tiên — làm phẳng `services` thành danh sách submodule.** Một giá trị trong `services` có thể lồng tới ba tầng (xem `context-loader.md` Bước 1.5), nên duyệt nông sẽ **bỏ sót** submodule:
202
-
203
- | Dạng | Cách lấy submodule |
204
- |---|---|
205
- | `services.{domain}.path` (2a) | một entry |
206
- | `services.{domain}.{platform}.path` (2b) | một entry mỗi platform |
207
- | `…by_prd_slug.{slug}.path` (2c) | một entry mỗi `slug` — ở cấp domain hoặc cấp platform |
208
-
209
- Kết quả là tập các cặp `{path, module}` **duy nhất theo `path`** (nhiều domain/platform/slug có thể trỏ chung một submodule — chỉ xử lý một lần). Mọi bước dưới đây chạy trên danh sách đã làm phẳng này.
210
-
211
- Với mỗi entry trong danh sách đó:
212
-
213
- **A. Nếu `{service.path}/.agent/project-context.yaml` đã tồn tại:**
214
- - Đọc `conventions.test_command` và `conventions.build_command`
215
- - Report: `✅ {service.path} — test: {test_command} | build: {build_command}`
216
-
217
- **B. Nếu thiếu — tự tạo:**
218
-
219
- 1. Xác định `module` từ umbrella `services[].module` (authoritative). Nếu không set, auto-detect từ file trong `{service.path}/`:
220
-
221
- | File có mặt | Module phát hiện | test_command | build_command |
222
- |---|---|---|---|
223
- | `pom.xml` | `java-spring` | `mvn test` | `mvn compile` |
224
- | `build.gradle` or `build.gradle.kts` | `java-spring` | `./gradlew test` | `./gradlew build` |
225
- | `go.mod` | `golang` | `go test ./...` | `go build ./...` |
226
- | `*.csproj` or `*.sln` | `dotnet` | `dotnet test` | `dotnet build` |
227
- | `composer.json` | `php-laravel` | `php artisan test` | `composer install` |
228
- | `pubspec.yaml` | `flutter` | `flutter test` | `flutter build apk` |
229
- | `angular.json` | `angular` | `npx ng test --watch=false` | `npm run build` |
230
- | `next.config.*` | `nextjs` | `npx vitest run` | `npm run build` |
231
- | `package.json` + `nest-cli.json` | `nestjs` | `npm test` | `npm run build` |
232
- | `package.json` (fallback) | `react` | `npx vitest run` | `npm run build` |
233
- | `requirements.txt` or `pyproject.toml` | `context-engineering` | `pytest tests/ -v` | `pip install -r requirements.txt` |
234
- | *(none matched)* | `unknown` | `{{TEST_COMMAND}}` | `{{BUILD_COMMAND}}` |
235
-
236
- 2. Tạo thư mục `{service.path}/.agent/` nếu chưa có.
237
-
238
- 3. Ghi `{service.path}/.agent/project-context.yaml`:
239
-
240
- ```yaml
241
- # Auto-generated by /sync — review and update as needed
242
- tech_stack:
243
- language: "{detected or from module}"
244
- framework: "{detected or from module}"
245
- module: "{module}"
246
-
247
- conventions:
248
- test_command: "{test_command}"
249
- build_command: "{build_command}"
250
-
251
- paths:
252
- trace_dir: ".trace"
253
- lessons_file: ".agent/project-lessons.md" # per-service guardrails (see /learn)
254
- ```
255
-
256
- 4. Report:
257
- - Nếu auto-detect: `✅ Created {service.path}/.agent/project-context.yaml (module: {module}, test: {test_command})`
258
- - Nếu unknown/placeholder: `⚠️ Created {service.path}/.agent/project-context.yaml — fill in {{TEST_COMMAND}} and {{BUILD_COMMAND}}`
259
-
260
- ---
261
-
262
- ## Step 4 — Check luật git cho sổ trace
263
-
264
- *Step 4a/4b kiểm **có được commit hay không** (hai chiều ngược nhau — nhầm chiều là mất dữ liệu).
265
- Step 4c kiểm **merge thế nào khi hai người cùng ghi**. Cả hai đều là đường mất sổ, và 4c không
266
- cần ai làm sai gì cả — chỉ cần hai người làm việc cùng lúc.*
267
-
268
- *Đọc bảng trước:*
269
-
270
- | Đường dẫn | Vai trò | Kỳ vọng |
271
- |---|---|---|
272
- | `{paths.trace_dir}` (`.trace/` hoặc `{spec_source}/.trace/`) | **AUTHORITATIVE** — TSV + `trace-history.jsonl`, không regenerate được | **PHẢI commit** — gitignore nó là **lỗi nghiêm trọng** |
273
- | `.trace-mirror/` | bản sao tiện cho panel VS Code | phải gitignore |
274
- | `.living-docs/` | report sinh ra | phải gitignore |
275
-
276
- **4a. Cảnh báo mềm — mirror chưa gitignore.**
277
- Kiểm `.trace-mirror/` trong `.gitignore` của repo hiện tại (hoặc `.git/info/exclude`), và `.living-docs/` trong `.gitignore` của **specs module** (khi `setup.spec_source` được set). Thiếu cái nào:
278
- ```
279
- ⚠️ Mirror chưa gitignore — chúng được sinh ra, đừng bao giờ commit:
280
- echo ".trace-mirror/" >> .gitignore
281
- echo ".living-docs/" >> {spec_source}/.gitignore # specs module (nếu có spec_source)
282
- ```
283
-
284
- **4b. 🔴 Báo động — sổ gốc ĐANG bị bỏ qua.**
285
- Phân giải `{paths.trace_dir}`; nếu nó nằm trong một git repo, chạy `git -C {repo} check-ignore -q {trace_dir}`. **Trúng** (exit 0) → in ngay, mức chặn:
286
- ```
287
- 🔴 NGUY HIỂM — sổ gốc trace ĐANG bị git bỏ qua: {paths.trace_dir}
288
- Toàn bộ trạng thái theo dõi (spec_ver · gen_ver · implemented_by · test_count ·
289
- dev_selftest · qc_status) VÀ trace-history.jsonl KHÔNG được lưu vào git.
290
- Người khác clone repo về sẽ không thấy gì, và lịch sử thì KHÔNG dựng lại được.
291
-
292
- Sửa:
293
- 1. Gỡ dòng khớp `.trace` khỏi .gitignore của {repo}
294
- 2. git -C {repo} add -f {trace_dir} && git -C {repo} commit -m "restore trace state"
295
- Nguyên nhân thường gặp: bản trước v0.4.3 gọi panel mirror là `.trace` (trùng tên sổ gốc),
296
- nên gợi ý "gitignore .trace/" của chính lệnh này có thể đã nhắm trúng sổ gốc.
297
- ```
298
- > **Vì sao cần báo động này:** trước v0.4.3, mirror và sổ gốc **cùng tên `.trace`**. Khi dev mở thẳng spec repo làm workspace thì hai path bằng nhau — và Step 4 (bản cũ) gợi ý gitignore theo **tên**, không theo vai trò. Làm theo là mất sổ gốc, **im lặng**: máy vẫn chạy, dashboard vẫn có số; chỉ người thứ hai clone về mới phát hiện. Bản v0.4.3 đổi tên mirror thành `.trace-mirror` để cái bẫy biến mất, nhưng **dự án đã dính từ trước thì vẫn dính** — 4b là để tìm ra chúng.
299
-
300
- **4c. Luật merge cho sổ trace.**
301
-
302
- Sổ trace **phải commit** (4b) và **được nhiều người ghi trên nhiều nhánh song song**. Git cần biết
303
- merge nó thế nào — mặc định thì không biết, và mặc định là đường mất row.
304
-
305
- Kiểm `{paths.trace_dir}/.gitattributes` có tồn tại và có đủ hai dòng dưới. **Thiếu → tạo/bổ sung
306
- ngay** (đây là hành động ghi duy nhất của Step 4; nó chỉ thêm file luật, không đụng dữ liệu):
307
-
308
- ```gitattributes
309
- # Sổ trace — dữ liệu KHÔNG regenerate được. Hai luật, hai lý do khác nhau:
310
- #
311
- # merge=union — giữ row của CẢ HAI nhánh thay vì bắt người chọn một bên. Trùng sc_id sau
312
- # union là ca ĐÚNG VÀ ĐƯỢC MONG ĐỢI: `--lint-trace` T4 bắt nó, rồi /validate-traces
313
- # reconcile về một row. Mất row thì KHÔNG có gì bắt được. Đánh đổi có chủ ý — đừng "dọn".
314
- # (union là driver built-in của git: không ai cần chạy git config gì thêm.)
315
- #
316
- # text eol=lf — BẮT BUỘC đi kèm union, không phải cho đẹp. Thiếu nó: một máy ghi CRLF →
317
- # git thấy MỌI dòng đã đổi → union giữ cả hai bản → NHÂN ĐÔI CẢ FILE, gồm cả dòng header.
318
- # Team mixed Windows/macOS gặp ca này mà không ai làm gì sai.
319
- *.tsv text eol=lf merge=union
320
- *.jsonl text eol=lf merge=union
321
- ```
322
-
323
- > **Vì sao đặt `.gitattributes` BÊN TRONG `{paths.trace_dir}` thay vì gốc repo:** `trace_dir` là
324
- > đường dẫn **cấu hình được** (`.trace/`, `../.trace`, `{spec_source}/.trace/`), nên một luật ở gốc
325
- > repo phải nhắc lại đúng đường dẫn đó và sẽ lệch ngay khi ai đổi config. Đặt trong thư mục thì
326
- > pattern là `*.tsv` thuần — không phụ thuộc `trace_dir` tên gì, nằm ở đâu, và **đi theo sổ** khi
327
- > spec repo được mount vào một umbrella khác. Git đọc `.gitattributes` ở mọi cấp thư mục.
328
-
329
- > **KHÔNG thêm `*.json`.** `trace-report.json` có thể nằm cùng thư mục và union trên JSON tạo ra
330
- > **JSON không hợp lệ** — panel VS Code parse lỗi. Nó là file **sinh lại được**: conflict ở đó thì
331
- > chạy lại `/validate-traces`, đừng merge tay.
332
-
333
- In vào report:
334
- ```
335
- ✅ {paths.trace_dir}/.gitattributes (merge=union + eol=lf)
336
- (hoặc: ✅ vừa tạo — sổ trace giờ merge được khi hai người cùng ghi)
337
- ```
338
-
339
- ---
340
-
341
- ## Step 5 — Refresh Living Docs *(chỉ umbrella mode)*
342
-
343
- *Skip nếu `services` rỗng.*
344
-
345
- **Phân giải Living Docs home (cùng quy tắc như `/validate-traces`):**
346
- - `living_docs_dir` = `{spec_source}/.living-docs` nếu `setup.spec_source` được set, else `.living-docs` ở umbrella root. *(Specs module được mount trong mọi service workspace, nên panel phân giải nó kể cả khi dev mở một service submodule đơn.)*
347
- - `panel_mirror` = `./.trace-mirror` ở gốc workspace hiện tại. *(Cố ý KHÁC tên `.trace` — xem Step 4.)*
348
-
349
- 1. Với mỗi service trong danh sách **đã làm phẳng** ở Step 3 (gồm cả các submodule nằm dưới `by_prd_slug` — bỏ sót chúng là mất trace của các repo chia theo feature): nếu `{service.path}/.trace/` có file `.tsv` → copy chúng vào `{living_docs_dir}/{service-name}/` (tạo dir nếu cần).
350
- 2. Ghi merged `{living_docs_dir}/trace-report.json`:
351
- - Tổng hợp TSV `.trace/` của mỗi service, thêm field `"service"` **và `"platform"`** (suy từ tên file `{UC-ID}-{platform}.tsv`) cho mỗi row, tính lại summary totals. **Không dedupe theo `sc_id` giữa các platform** — `web·SC1` và `system·SC1` là 2 row khác nhau; nhờ field `platform` dashboard hiển thị tách bạch coverage từng platform.
352
- 3. **Mirror tới panel location:** copy `{living_docs_dir}/trace-report.json` (+ TSV namespaced) → `{panel_mirror}/` để panel trong repo đang mở không rỗng. Skip nếu `panel_mirror` đã bằng `living_docs_dir`, hoặc nếu `{paths.trace_dir}` đã nằm trong workspace hiện tại (panel đọc thẳng ở đó). **KHÔNG** copy `trace-history.jsonl` — nó là dữ liệu tích luỹ, không phải thứ sinh lại được.
353
-
354
- In kết quả sync:
355
- ```
356
- Living Docs → {living_docs_dir}/ synced (canonical, specs module)
357
- {service-name}: {N} TSVs
358
- trace-report.json: {total} scenarios across {S} services
359
- Panel mirror → {panel_mirror}/ (current workspace)
360
- ```
361
-
362
- Nếu không tìm thấy dir `.trace/` → `Living Docs: no trace data yet — run /generate-bdd then /generate-code first.`
363
-
364
- ---
365
-
366
- ## Step 6 — Refresh Spec Manifest *(nếu có spec_source)*
367
-
368
- *Skip nếu `setup.spec_source` vắng.*
369
-
370
- Nếu `spec-manifest.yaml` tồn tại HOẶC `setup.spec_source` được cấu hình:
371
- - Re-scan các file PRD `{spec_source}/specs/*/*/*.md` (file `.md` ở gốc mỗi feature folder = PRD; tech-docs/design-spec `.md` nằm sâu hơn nên không bị quét nhầm)
372
- - Rebuild `spec-manifest.yaml` map TICKET-ID → path PRD/BDD/tech-doc
373
- - In: `spec-manifest.yaml refreshed — {N} features indexed`
374
-
375
- ---
376
-
377
- ## Output
378
-
379
- **Đọc `.agent/steps/report-footer.md`** và áp đúng khuôn footer trong đó (Status Badge ·
380
- Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
381
-
382
- ```
383
- /sync — {Setup | Update}
384
-
385
- Git
386
- ✅ git pull — umbrella on branch '{umbrella_branch}'
387
- ✅ submodule sync — .gitmodules config refreshed
388
-
389
- Submodules (each handled by its current state)
390
- ✅ {spec_source} [spec] — pulled branch '{spec_branch}' ({spec_branch_source}) → {new-sha}
391
- ✋ user-service [active] — on 'feature/FEAT-01' — left untouched, fetched (↓2 behind origin)
392
- ✅ order-service [passive] — aligned to umbrella pointer {sha}
393
- ⚠️ payment-service [dirty] — uncommitted changes, skipped (commit/stash first)
394
-
395
- Umbrella state
396
- ⚠️ Pointer changed: git add {spec_source} && git commit -m "chore: sync specs"
397
- (or: ✅ Clean — no commit needed)
398
-
399
- Tester feedback (pulled this sync)
400
- 📥 1 bug report: BUG-20260608-01 FT-001 [Code]
401
- 1 proposal: FT-001-trailing-spaces → AC2 (pending review)
402
- (or: 📥 none new this sync)
403
- → /fix-bug {BUG-ID} · promote proposal into BDD · or update PRD
404
-
405
- Service Configs
406
- ✅ user-service — test: mvn test | build: mvn compile
407
- ✅ order-service — test: mvn test | build: mvn compile
408
- ⚠️ payment-service — .agent/project-context.yaml missing
409
- → create it so /dev-run-test works correctly
410
-
411
- Luật git cho sổ trace
412
- ✅ .trace-mirror/ + .living-docs/ gitignored (mirror — sinh lại được)
413
- ✅ {paths.trace_dir}/ KHÔNG bị gitignore (sổ gốc — phải commit)
414
- ✅ {paths.trace_dir}/.gitattributes (merge=union + eol=lf — hai người ghi song song)
415
- (hoặc: ⚠️ Thêm .trace-mirror/ vào .gitignore)
416
- (hoặc: 🔴 NGUY HIỂM — sổ gốc {paths.trace_dir} đang bị gitignore, xem Step 4b)
417
- (hoặc: ✅ vừa tạo .gitattributes — trước đó merge song song sẽ conflict và mất row)
418
-
419
- Living Docs
420
- ✅ {panel_mirror}/ synced — {N} TSVs across {S} services
421
- (chạy /validate-traces để có report coverage đầy đủ)
422
-
423
- Spec Manifest
424
- ✅ spec-manifest.yaml — {N} features indexed
425
-
426
- ---
427
- Status : ✅ Complete | ⚠️ Warnings
428
- Output Artifacts: updated .trace-mirror/ (panel mirror), spec-manifest.yaml
429
- Next : /validate-traces (full coverage check) | /generate-code {UC-ID} (start coding)
430
- ```