@anhth2/spec-driven-dev-plugin 0.7.0 → 0.9.0

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 (96) hide show
  1. package/ARCHITECTURE.md +6 -2
  2. package/bin/index.js +105 -0
  3. package/commands/debug.md +189 -1
  4. package/commands/debug.tmpl +16 -0
  5. package/commands/define-product.md +94 -1
  6. package/commands/fix-bug.md +190 -1
  7. package/commands/fix-bug.tmpl +17 -0
  8. package/commands/generate-bdd.md +314 -14
  9. package/commands/generate-bdd.tmpl +220 -13
  10. package/commands/generate-code.md +191 -3
  11. package/commands/generate-code.tmpl +97 -2
  12. package/commands/generate-design-spec.md +811 -0
  13. package/commands/generate-design-spec.tmpl +399 -0
  14. package/commands/generate-prd.md +133 -1
  15. package/commands/generate-prd.tmpl +39 -0
  16. package/commands/generate-spec-manifest.md +576 -0
  17. package/commands/generate-spec-manifest.tmpl +164 -0
  18. package/commands/generate-tech-docs.md +116 -2
  19. package/commands/generate-tech-docs.tmpl +22 -1
  20. package/commands/generate-tests.md +94 -1
  21. package/commands/learn.md +554 -0
  22. package/commands/learn.tmpl +63 -0
  23. package/commands/propose-scenario.md +521 -0
  24. package/commands/propose-scenario.tmpl +109 -0
  25. package/commands/refine-prd.md +94 -1
  26. package/commands/report-bug.md +543 -0
  27. package/commands/report-bug.tmpl +131 -0
  28. package/commands/review-code.md +190 -1
  29. package/commands/review-code.tmpl +17 -0
  30. package/commands/review-context.md +134 -1
  31. package/commands/review-context.tmpl +40 -0
  32. package/commands/review-tech-docs.md +176 -5
  33. package/commands/review-tech-docs.tmpl +82 -4
  34. package/commands/run-tests.md +119 -1
  35. package/commands/run-tests.tmpl +25 -0
  36. package/commands/setup-ai-first.md +142 -4
  37. package/commands/setup-ai-first.tmpl +135 -3
  38. package/commands/smoke-test.md +94 -1
  39. package/commands/sync.md +405 -0
  40. package/commands/sync.tmpl +345 -0
  41. package/commands/update-framework.md +211 -0
  42. package/commands/update-framework.tmpl +151 -0
  43. package/commands/validate-traces.md +152 -3
  44. package/commands/validate-traces.tmpl +58 -2
  45. package/core/FRAMEWORK_VERSION +1 -1
  46. package/core/commands/debug.md +189 -1
  47. package/core/commands/define-product.md +94 -1
  48. package/core/commands/fix-bug.md +190 -1
  49. package/core/commands/generate-bdd.md +314 -14
  50. package/core/commands/generate-code.md +191 -3
  51. package/core/commands/generate-design-spec.md +811 -0
  52. package/core/commands/generate-prd.md +133 -1
  53. package/core/commands/generate-spec-manifest.md +576 -0
  54. package/core/commands/generate-tech-docs.md +116 -2
  55. package/core/commands/generate-tests.md +94 -1
  56. package/core/commands/learn.md +554 -0
  57. package/core/commands/propose-scenario.md +521 -0
  58. package/core/commands/refine-prd.md +94 -1
  59. package/core/commands/report-bug.md +543 -0
  60. package/core/commands/review-code.md +190 -1
  61. package/core/commands/review-context.md +134 -1
  62. package/core/commands/review-tech-docs.md +176 -5
  63. package/core/commands/run-tests.md +119 -1
  64. package/core/commands/setup-ai-first.md +142 -4
  65. package/core/commands/smoke-test.md +94 -1
  66. package/core/commands/sync.md +405 -0
  67. package/core/commands/update-framework.md +211 -0
  68. package/core/commands/validate-traces.md +152 -3
  69. package/core/skills/code/SKILL.md +101 -2
  70. package/core/skills/debug/SKILL.md +108 -3
  71. package/core/skills/design-spec/SKILL.md +507 -0
  72. package/core/skills/discovery/SKILL.md +94 -1
  73. package/core/skills/prd/SKILL.md +14 -2
  74. package/core/skills/setup-ai-first/SKILL.md +7 -1
  75. package/core/skills/spec/SKILL.md +14 -2
  76. package/core/skills/test/SKILL.md +195 -3
  77. package/core/steps/capture-lesson.md +79 -0
  78. package/core/steps/context-loader.md +87 -0
  79. package/core/steps/report-footer.md +7 -1
  80. package/core/templates/design-spec.template.md +209 -0
  81. package/core/templates/project-context.yaml +40 -0
  82. package/package.json +1 -1
  83. package/skills/code/SKILL.md +101 -2
  84. package/skills/debug/SKILL.md +108 -3
  85. package/skills/design-spec/SKILL.md +507 -0
  86. package/skills/design-spec/SKILL.tmpl +95 -0
  87. package/skills/discovery/SKILL.md +94 -1
  88. package/skills/prd/SKILL.md +14 -2
  89. package/skills/setup-ai-first/SKILL.md +7 -1
  90. package/skills/spec/SKILL.md +14 -2
  91. package/skills/test/SKILL.md +195 -3
  92. package/steps/capture-lesson.md +79 -0
  93. package/steps/context-loader.md +87 -0
  94. package/steps/report-footer.md +7 -1
  95. package/templates/design-spec.template.md +209 -0
  96. package/templates/project-context.yaml +40 -0
@@ -0,0 +1,164 @@
1
+ # /generate-spec-manifest — Generate Spec Manifest for External Agents
2
+
3
+ Scans all spec files and writes a `spec-manifest.yaml` at the project root.
4
+ This file is for **external agents only** (e.g. tester's agent) — it is not committed to git.
5
+
6
+ ## Gate
7
+
8
+ {{include:steps/gate.md}}
9
+
10
+ *Note: For this command, there is no target file — it scans the entire project. Ignore `$ARGUMENTS` unless a domain filter is passed.*
11
+
12
+ ## Context
13
+
14
+ {{include:steps/context-loader.md}}
15
+
16
+ ---
17
+
18
+ ## Process
19
+
20
+ ### Step 1 — Determine scan roots
21
+
22
+ Read `project-context.yaml` to determine mode and paths:
23
+
24
+ **Umbrella mode** (`setup.mode: umbrella`):
25
+ ```
26
+ spec_root = {setup.spec_source} ← PO's spec submodule
27
+ prd_glob = {spec_root}/specs/prd/**/*.md
28
+ pdd_glob = {spec_root}/specs/product-definition/**/*.md
29
+ services = {services} ← map of domain → paths
30
+ ```
31
+
32
+ **Single-service mode** (no `setup.mode`):
33
+ ```
34
+ spec_root = .
35
+ prd_glob = {paths.prd_dir}/**/*.md
36
+ pdd_glob = {paths.product_definitions_dir}/**/*.md
37
+ services = { default: { specs_dir: {paths.specs_dir}, tech_docs_dir: {paths.tech_docs_dir} } }
38
+ ```
39
+
40
+ If a domain filter was passed in `$ARGUMENTS` → only scan PRDs matching that domain.
41
+
42
+ ---
43
+
44
+ ### Step 2 — Scan PRD files
45
+
46
+ For each `.md` file matched by `prd_glob`:
47
+
48
+ 1. Read the file metadata table:
49
+ - `TICKET-ID` from `| **PRD ID** |`
50
+ - `domain` from `| **Domain** |`
51
+ - `status` from `| **Status** |`
52
+ - `version` from `| **Version** |`
53
+ 2. Also read frontmatter `@trace.domain` if present (use this over metadata table domain if both exist)
54
+ 3. Record: `{ ticket_id, domain, status, version, prd_path }` — path relative to manifest root
55
+
56
+ Skip files where `TICKET-ID` cannot be determined.
57
+
58
+ ---
59
+
60
+ ### Step 3 — Match PDD files
61
+
62
+ For each TICKET-ID found in Step 2:
63
+
64
+ Search `pdd_glob` for a file whose name contains the TICKET-ID (e.g. `FT-001-*.md`).
65
+ - Found → record `pdd_path` (relative to manifest root)
66
+ - Not found → record `pdd: null`
67
+
68
+ ---
69
+
70
+ ### Step 4 — Match BDD and Tech-Doc files per service
71
+
72
+ For each TICKET-ID, for each service in `services` map:
73
+
74
+ **BDD:**
75
+ - Glob `{service.specs_dir}/**/{TICKET-ID}*.feature`
76
+ - Also check files containing `@trace.prd: {TICKET-ID}` in frontmatter if glob returns nothing
77
+ - Found → record path under `bdd.{service_key}`
78
+ - Not found → omit key (do not write `null` for services with no BDD yet)
79
+
80
+ **Tech-docs:**
81
+ - Glob `{service.tech_docs_dir}/**/{TICKET-ID}*.md`
82
+ - Also check files containing `@trace.prd: {TICKET-ID}` if glob returns nothing
83
+ - Found → record path under `tech_docs.{service_key}`
84
+ - Not found → omit key
85
+
86
+ All paths relative to manifest root (umbrella root or project root).
87
+
88
+ ---
89
+
90
+ ### Step 5 — Write spec-manifest.yaml
91
+
92
+ Write to `{manifest_root}/spec-manifest.yaml` (overwrite if exists).
93
+
94
+ Format:
95
+
96
+ ```yaml
97
+ # Auto-generated by /generate-spec-manifest — DO NOT edit manually
98
+ # To regenerate: /generate-spec-manifest
99
+ # This file is excluded from git — see .gitignore
100
+
101
+ version: "1.0"
102
+ generated_at: "{YYYY-MM-DD}"
103
+ project_mode: "{umbrella | single}"
104
+
105
+ features:
106
+ {TICKET-ID}:
107
+ domain: {domain}
108
+ status: {status}
109
+ prd_version: "{version}"
110
+ prd: "{prd_path}"
111
+ pdd: "{pdd_path}" # omit if null
112
+ tech_docs:
113
+ {service_key}: "{path}" # only include services where file was found
114
+ bdd:
115
+ {service_key}: "{path}" # only include services where file was found
116
+ ```
117
+
118
+ Sort features by TICKET-ID alphabetically.
119
+ Omit `tech_docs` block entirely if no tech-doc found for any service.
120
+ Omit `bdd` block entirely if no BDD found for any service.
121
+
122
+ ---
123
+
124
+ ### Step 6 — Ensure .gitignore
125
+
126
+ Check `{manifest_root}/.gitignore`:
127
+ - If `spec-manifest.yaml` is already listed → no action
128
+ - If not → append the following to `.gitignore`:
129
+
130
+ ```
131
+ # Auto-generated — do not commit
132
+ spec-manifest.yaml
133
+ ```
134
+
135
+ Print: `✅ spec-manifest.yaml added to .gitignore`
136
+
137
+ ---
138
+
139
+ ## Output
140
+
141
+ {{include:steps/report-footer.md}}
142
+
143
+ ```
144
+ /generate-spec-manifest Complete
145
+ ---
146
+ Status : ✅ Complete
147
+ Output : spec-manifest.yaml ({N} features)
148
+ Mode : {umbrella | single}
149
+ .gitignore : ✅ spec-manifest.yaml excluded
150
+
151
+ Summary:
152
+ {N} PRDs scanned ({A} approved, {D} draft)
153
+ {N} PDDs matched
154
+ {N} BDD files matched (across {S} services)
155
+ {N} Tech-doc files matched (across {S} services)
156
+
157
+ ⚠️ {N} PRDs with no matching BDD:
158
+ - {TICKET-ID} ({domain}) — run /generate-bdd first
159
+ ⚠️ {N} PRDs with no matching tech-docs:
160
+ - {TICKET-ID} ({domain}) — run /generate-tech-docs first
161
+
162
+ Next : Share spec-manifest.yaml path with tester agent
163
+ Regenerate anytime: /generate-spec-manifest
164
+ ```
@@ -152,6 +152,7 @@ Read `.agent/project-context.yaml`. Extract and store:
152
152
  - `paths.core_entities` → path to core-entities.md
153
153
  - `paths.tech_docs_dir` → technical documentation root
154
154
  - `paths.trace_dir` → trace state directory
155
+ - `paths.design_spec_dir` → Design Spec documents root (FE/App only)
155
156
 
156
157
  If `paths` section is absent, use these defaults:
157
158
  - `specs_dir` = `specs/bdd`
@@ -163,11 +164,75 @@ If `paths` section is absent, use these defaults:
163
164
  - `core_entities` = `specs/domain-knowledge/core-entities.md`
164
165
  - `tech_docs_dir` = `specs/tech-docs`
165
166
  - `trace_dir` = `.trace`
167
+ - `design_spec_dir` = `specs/design-spec`
166
168
 
167
169
  If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
168
170
 
169
171
  ---
170
172
 
173
+ ## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
174
+
175
+ *Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
176
+
177
+ If `services` section is present:
178
+
179
+ **1. Detect active domain** (in priority order):
180
+ - Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
181
+ - Extract from target file path: segment immediately after `prd_dir` base path
182
+ *(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
183
+ - If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
184
+
185
+ **2. Route to service** — if active domain matches a key in `services`:
186
+ - Override `paths.specs_dir` → `services.{domain}.specs_dir`
187
+ - Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
188
+ - Store `active_service` = `services.{domain}.path`
189
+ - Store `active_service_module` = `services.{domain}.module`
190
+ - If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
191
+
192
+ **3. Fallback** — if domain not detected or no matching service key:
193
+ - Keep default paths from Step 1
194
+ - Set `active_service = unresolved`
195
+
196
+ **4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
197
+ - Override `paths.prd_dir` → `{spec_source}/specs/prd`
198
+ - Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
199
+ - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
200
+ - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
201
+ - Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
202
+ - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
203
+ - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
204
+
205
+ > **Why under `spec_source`:** tester feedback (`/report-bug`, `/propose-scenario`) must land in the **shared spec repo** so PO/Dev see it when they `/sync`. In single-service mode (no `spec_source`), these default to `feedback/bug-reports` and `feedback/bdd-proposals` at repo root — still shared, same repo.
206
+
207
+ ---
208
+
209
+ ## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
210
+
211
+ *Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
212
+
213
+ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
214
+
215
+ **1. Locate service config** — try in priority order:
216
+ - `{active_service}/.agent/project-context.yaml`
217
+ - `{active_service}/project-context.yaml`
218
+
219
+ **2. If found, override with service-specific values:**
220
+
221
+ | Variable | Source |
222
+ |----------|--------|
223
+ | `conventions.test_command` | service's `conventions.test_command` |
224
+ | `conventions.build_command` | service's `conventions.build_command` |
225
+ | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
226
+ | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
227
+
228
+ **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
229
+ - Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
230
+ - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
231
+
232
+ **4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
233
+
234
+ ---
235
+
171
236
  ## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
172
237
 
173
238
  If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
@@ -258,6 +323,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
258
323
 
259
324
  ---
260
325
 
326
+ ## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
327
+
328
+ *Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
329
+ or accepted during `/review-code`, `/fix-bug`, `/debug`.*
330
+
331
+ Resolve the lessons file path:
332
+ - Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
333
+ - Else default `specs/domain-knowledge/lessons-learned.md`
334
+ - In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
335
+
336
+ If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
337
+ - Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
338
+ - Before generating or modifying any artifact (PRD, BDD, tech-doc, code, test), check the output against every lesson whose `category` matches the current command AND whose `scope` matches the target (domain / file).
339
+ - If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
340
+
341
+ If the file does not exist → skip silently (no lessons captured yet).
342
+
343
+ ---
344
+
261
345
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
262
346
 
263
347
  After loading all context, synthesize and output a compact summary block.
@@ -273,6 +357,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
273
357
  Ticket : {ticket_prefix}-
274
358
  Dict : {loaded — N canonical terms, M banned terms | missing}
275
359
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
360
+ Lessons : {loaded — N guardrails | none yet}
361
+ Service : {active_service} ({active_service_module}) | single-service
362
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
276
363
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
277
364
  ```
278
365
 
@@ -294,6 +381,22 @@ After completing all steps, you have loaded:
294
381
  Proceed to the next step of the calling command.
295
382
 
296
383
 
384
+ ---
385
+
386
+ ## Brownfield Check
387
+
388
+ Read the source `.feature` file header for `@trace.api_source`.
389
+ Also check the source PRD Metadata table for `| **API Source** | existing |`.
390
+
391
+ | Value | Mode |
392
+ |-------|------|
393
+ | `existing` | **Reverse-document** — API đã tồn tại; mô tả lại as-is, note gaps, không cần design mới |
394
+ | absent / other | **Greenfield** — thiết kế API từ đầu |
395
+
396
+ Store `active_mode = {reverse-document | greenfield}`.
397
+
398
+ If `active_mode = reverse-document` → load bảng "Existing API Contract" từ PRD làm input cho §2.
399
+
297
400
  ---
298
401
 
299
402
  ## CHECKPOINT — Tech Design Plan
@@ -306,13 +409,14 @@ Tech Design Plan — {UC-ID}
306
409
  UC : {UC-ID} — {feature title}
307
410
  Service : {trace.service}
308
411
  Module : {trace.module}
412
+ Mode : {Reverse-document (API đã tồn tại) | Greenfield (thiết kế mới)}
309
413
  Scenarios: {N} scenarios
310
414
  BDD ver : {trace.bdd_version}
311
415
  Output : {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
312
416
 
313
417
  Sections to generate:
314
418
  §1 Overview
315
- §2 API Endpoints ({N} endpoints inferred from scenarios)
419
+ §2 API Endpoints ({Reverse-document: tả lại từ PRD contract | Greenfield: infer từ scenarios})
316
420
  §3 Data Model ({entities from core-entities.md relevant to this UC})
317
421
  §4 Service Flow
318
422
  §5 Business Rules ({N} BRs from feature header)
@@ -344,11 +448,15 @@ Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md`:
344
448
  @trace.bdd_version: {read @trace.bdd_version from the .feature file header}
345
449
  @trace.revision: 1
346
450
  @trace.status: draft
451
+ @trace.api_source: {existing | —}
347
452
  @trace.generated_at: {YYYY-MM-DD}
348
453
  ---
349
454
 
350
455
  ## §1. Overview
351
456
  ## §2. API Endpoints
457
+ *Greenfield:* endpoints được infer từ BDD scenarios — thiết kế mới.
458
+ *Reverse-document:* mô tả lại API đã tồn tại từ bảng "Existing API Contract" trong PRD.
459
+ Ghi chú gaps nếu contract thực tế khác với BDD expectations.
352
460
  | Method | Path | Auth/Role | Request | Response |
353
461
  ## §3. Data Model
354
462
  Key entities and relationships.
@@ -406,7 +514,8 @@ Suggest the logical next command based on workflow phase:
406
514
  | /define-product | `/generate-prd {product-definition-file}` |
407
515
  | /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
408
516
  | /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
409
- | /review-context (PRD) | `/generate-bdd {prd-file}` if APPROVED; fix PRD if NEEDS_FIX |
517
+ | /review-context (PRD) | FE/App: `/generate-design-spec {prd-file}` (then BDD after sign-off); BE: `/generate-bdd {prd-file}` directly; fix PRD if NEEDS_FIX |
518
+ | /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
410
519
  | /generate-bdd | `/review-context {feature-file}` to verify coverage |
411
520
  | /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
412
521
  | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
@@ -420,6 +529,11 @@ Suggest the logical next command based on workflow phase:
420
529
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
421
530
  | /fix-bug | Create PR and link to ticket |
422
531
  | /debug | `/fix-bug {ticket-id}` if fix needed |
532
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
533
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
534
+ | /learn | Continue working — lesson applies on next command |
535
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
536
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
423
537
 
424
538
  Format the footer as:
425
539
  ```
@@ -31,6 +31,22 @@
31
31
 
32
32
  ---
33
33
 
34
+ ## Brownfield Check
35
+
36
+ Read the source `.feature` file header for `@trace.api_source`.
37
+ Also check the source PRD Metadata table for `| **API Source** | existing |`.
38
+
39
+ | Value | Mode |
40
+ |-------|------|
41
+ | `existing` | **Reverse-document** — API đã tồn tại; mô tả lại as-is, note gaps, không cần design mới |
42
+ | absent / other | **Greenfield** — thiết kế API từ đầu |
43
+
44
+ Store `active_mode = {reverse-document | greenfield}`.
45
+
46
+ If `active_mode = reverse-document` → load bảng "Existing API Contract" từ PRD làm input cho §2.
47
+
48
+ ---
49
+
34
50
  ## CHECKPOINT — Tech Design Plan
35
51
 
36
52
  Before generating, scan the feature file for scenario count, referenced BRs, and entities. Display and wait for Y:
@@ -41,13 +57,14 @@ Tech Design Plan — {UC-ID}
41
57
  UC : {UC-ID} — {feature title}
42
58
  Service : {trace.service}
43
59
  Module : {trace.module}
60
+ Mode : {Reverse-document (API đã tồn tại) | Greenfield (thiết kế mới)}
44
61
  Scenarios: {N} scenarios
45
62
  BDD ver : {trace.bdd_version}
46
63
  Output : {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
47
64
 
48
65
  Sections to generate:
49
66
  §1 Overview
50
- §2 API Endpoints ({N} endpoints inferred from scenarios)
67
+ §2 API Endpoints ({Reverse-document: tả lại từ PRD contract | Greenfield: infer từ scenarios})
51
68
  §3 Data Model ({entities from core-entities.md relevant to this UC})
52
69
  §4 Service Flow
53
70
  §5 Business Rules ({N} BRs from feature header)
@@ -79,11 +96,15 @@ Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md`:
79
96
  @trace.bdd_version: {read @trace.bdd_version from the .feature file header}
80
97
  @trace.revision: 1
81
98
  @trace.status: draft
99
+ @trace.api_source: {existing | —}
82
100
  @trace.generated_at: {YYYY-MM-DD}
83
101
  ---
84
102
 
85
103
  ## §1. Overview
86
104
  ## §2. API Endpoints
105
+ *Greenfield:* endpoints được infer từ BDD scenarios — thiết kế mới.
106
+ *Reverse-document:* mô tả lại API đã tồn tại từ bảng "Existing API Contract" trong PRD.
107
+ Ghi chú gaps nếu contract thực tế khác với BDD expectations.
87
108
  | Method | Path | Auth/Role | Request | Response |
88
109
  ## §3. Data Model
89
110
  Key entities and relationships.
@@ -131,6 +131,7 @@ Read `.agent/project-context.yaml`. Extract and store:
131
131
  - `paths.core_entities` → path to core-entities.md
132
132
  - `paths.tech_docs_dir` → technical documentation root
133
133
  - `paths.trace_dir` → trace state directory
134
+ - `paths.design_spec_dir` → Design Spec documents root (FE/App only)
134
135
 
135
136
  If `paths` section is absent, use these defaults:
136
137
  - `specs_dir` = `specs/bdd`
@@ -142,11 +143,75 @@ If `paths` section is absent, use these defaults:
142
143
  - `core_entities` = `specs/domain-knowledge/core-entities.md`
143
144
  - `tech_docs_dir` = `specs/tech-docs`
144
145
  - `trace_dir` = `.trace`
146
+ - `design_spec_dir` = `specs/design-spec`
145
147
 
146
148
  If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
147
149
 
148
150
  ---
149
151
 
152
+ ## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
153
+
154
+ *Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
155
+
156
+ If `services` section is present:
157
+
158
+ **1. Detect active domain** (in priority order):
159
+ - Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
160
+ - Extract from target file path: segment immediately after `prd_dir` base path
161
+ *(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
162
+ - If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
163
+
164
+ **2. Route to service** — if active domain matches a key in `services`:
165
+ - Override `paths.specs_dir` → `services.{domain}.specs_dir`
166
+ - Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
167
+ - Store `active_service` = `services.{domain}.path`
168
+ - Store `active_service_module` = `services.{domain}.module`
169
+ - If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
170
+
171
+ **3. Fallback** — if domain not detected or no matching service key:
172
+ - Keep default paths from Step 1
173
+ - Set `active_service = unresolved`
174
+
175
+ **4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
176
+ - Override `paths.prd_dir` → `{spec_source}/specs/prd`
177
+ - Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
178
+ - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
179
+ - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
180
+ - Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
181
+ - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
182
+ - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
183
+
184
+ > **Why under `spec_source`:** tester feedback (`/report-bug`, `/propose-scenario`) must land in the **shared spec repo** so PO/Dev see it when they `/sync`. In single-service mode (no `spec_source`), these default to `feedback/bug-reports` and `feedback/bdd-proposals` at repo root — still shared, same repo.
185
+
186
+ ---
187
+
188
+ ## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
189
+
190
+ *Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
191
+
192
+ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
193
+
194
+ **1. Locate service config** — try in priority order:
195
+ - `{active_service}/.agent/project-context.yaml`
196
+ - `{active_service}/project-context.yaml`
197
+
198
+ **2. If found, override with service-specific values:**
199
+
200
+ | Variable | Source |
201
+ |----------|--------|
202
+ | `conventions.test_command` | service's `conventions.test_command` |
203
+ | `conventions.build_command` | service's `conventions.build_command` |
204
+ | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
205
+ | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
206
+
207
+ **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
208
+ - Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
209
+ - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
210
+
211
+ **4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
212
+
213
+ ---
214
+
150
215
  ## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
151
216
 
152
217
  If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
@@ -237,6 +302,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
237
302
 
238
303
  ---
239
304
 
305
+ ## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
306
+
307
+ *Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
308
+ or accepted during `/review-code`, `/fix-bug`, `/debug`.*
309
+
310
+ Resolve the lessons file path:
311
+ - Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
312
+ - Else default `specs/domain-knowledge/lessons-learned.md`
313
+ - In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
314
+
315
+ If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
316
+ - Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
317
+ - Before generating or modifying any artifact (PRD, BDD, tech-doc, code, test), check the output against every lesson whose `category` matches the current command AND whose `scope` matches the target (domain / file).
318
+ - If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
319
+
320
+ If the file does not exist → skip silently (no lessons captured yet).
321
+
322
+ ---
323
+
240
324
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
241
325
 
242
326
  After loading all context, synthesize and output a compact summary block.
@@ -252,6 +336,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
252
336
  Ticket : {ticket_prefix}-
253
337
  Dict : {loaded — N canonical terms, M banned terms | missing}
254
338
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
339
+ Lessons : {loaded — N guardrails | none yet}
340
+ Service : {active_service} ({active_service_module}) | single-service
341
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
255
342
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
256
343
  ```
257
344
 
@@ -762,7 +849,8 @@ Suggest the logical next command based on workflow phase:
762
849
  | /define-product | `/generate-prd {product-definition-file}` |
763
850
  | /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
764
851
  | /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
765
- | /review-context (PRD) | `/generate-bdd {prd-file}` if APPROVED; fix PRD if NEEDS_FIX |
852
+ | /review-context (PRD) | FE/App: `/generate-design-spec {prd-file}` (then BDD after sign-off); BE: `/generate-bdd {prd-file}` directly; fix PRD if NEEDS_FIX |
853
+ | /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
766
854
  | /generate-bdd | `/review-context {feature-file}` to verify coverage |
767
855
  | /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
768
856
  | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
@@ -776,6 +864,11 @@ Suggest the logical next command based on workflow phase:
776
864
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
777
865
  | /fix-bug | Create PR and link to ticket |
778
866
  | /debug | `/fix-bug {ticket-id}` if fix needed |
867
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
868
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
869
+ | /learn | Continue working — lesson applies on next command |
870
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
871
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
779
872
 
780
873
  Format the footer as:
781
874
  ```