@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
@@ -135,6 +135,7 @@ Read `.agent/project-context.yaml`. Extract and store:
135
135
  - `paths.core_entities` → path to core-entities.md
136
136
  - `paths.tech_docs_dir` → technical documentation root
137
137
  - `paths.trace_dir` → trace state directory
138
+ - `paths.design_spec_dir` → Design Spec documents root (FE/App only)
138
139
 
139
140
  If `paths` section is absent, use these defaults:
140
141
  - `specs_dir` = `specs/bdd`
@@ -146,11 +147,75 @@ If `paths` section is absent, use these defaults:
146
147
  - `core_entities` = `specs/domain-knowledge/core-entities.md`
147
148
  - `tech_docs_dir` = `specs/tech-docs`
148
149
  - `trace_dir` = `.trace`
150
+ - `design_spec_dir` = `specs/design-spec`
149
151
 
150
152
  If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
151
153
 
152
154
  ---
153
155
 
156
+ ## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
157
+
158
+ *Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
159
+
160
+ If `services` section is present:
161
+
162
+ **1. Detect active domain** (in priority order):
163
+ - Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
164
+ - Extract from target file path: segment immediately after `prd_dir` base path
165
+ *(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
166
+ - If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
167
+
168
+ **2. Route to service** — if active domain matches a key in `services`:
169
+ - Override `paths.specs_dir` → `services.{domain}.specs_dir`
170
+ - Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
171
+ - Store `active_service` = `services.{domain}.path`
172
+ - Store `active_service_module` = `services.{domain}.module`
173
+ - If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
174
+
175
+ **3. Fallback** — if domain not detected or no matching service key:
176
+ - Keep default paths from Step 1
177
+ - Set `active_service = unresolved`
178
+
179
+ **4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
180
+ - Override `paths.prd_dir` → `{spec_source}/specs/prd`
181
+ - Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
182
+ - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
183
+ - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
184
+ - Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
185
+ - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
186
+ - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
187
+
188
+ > **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.
189
+
190
+ ---
191
+
192
+ ## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
193
+
194
+ *Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
195
+
196
+ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
197
+
198
+ **1. Locate service config** — try in priority order:
199
+ - `{active_service}/.agent/project-context.yaml`
200
+ - `{active_service}/project-context.yaml`
201
+
202
+ **2. If found, override with service-specific values:**
203
+
204
+ | Variable | Source |
205
+ |----------|--------|
206
+ | `conventions.test_command` | service's `conventions.test_command` |
207
+ | `conventions.build_command` | service's `conventions.build_command` |
208
+ | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
209
+ | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
210
+
211
+ **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
212
+ - Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
213
+ - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
214
+
215
+ **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).
216
+
217
+ ---
218
+
154
219
  ## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
155
220
 
156
221
  If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
@@ -241,6 +306,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
241
306
 
242
307
  ---
243
308
 
309
+ ## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
310
+
311
+ *Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
312
+ or accepted during `/review-code`, `/fix-bug`, `/debug`.*
313
+
314
+ Resolve the lessons file path:
315
+ - Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
316
+ - Else default `specs/domain-knowledge/lessons-learned.md`
317
+ - In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
318
+
319
+ If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
320
+ - Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
321
+ - 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).
322
+ - If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
323
+
324
+ If the file does not exist → skip silently (no lessons captured yet).
325
+
326
+ ---
327
+
244
328
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
245
329
 
246
330
  After loading all context, synthesize and output a compact summary block.
@@ -256,6 +340,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
256
340
  Ticket : {ticket_prefix}-
257
341
  Dict : {loaded — N canonical terms, M banned terms | missing}
258
342
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
343
+ Lessons : {loaded — N guardrails | none yet}
344
+ Service : {active_service} ({active_service_module}) | single-service
345
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
259
346
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
260
347
  ```
261
348
 
@@ -387,6 +474,59 @@ Check all standard sections are present and non-empty:
387
474
 
388
475
  → All T6 missing-section findings are **auto-fixable**: AI adds skeleton section with prompts.
389
476
 
477
+ ### T7 — Cross-Team API Contract Review
478
+
479
+ *Only applies when ALL of the following are true:*
480
+ *1. Source BDD has `@trace.platform: system`.*
481
+ *2. Tech-doc header does NOT have `@trace.api_source: existing`.*
482
+
483
+ *If `@trace.api_source: existing` → **skip T7 entirely**. Contract đã được PO xác định trong PRD — không có API design mới để đồng thuận.*
484
+
485
+ This dimension ensures FE, App, and BE teams all agree on the API contract before implementation starts.
486
+
487
+ **Step 1 — Check sign-off status in tech-doc header:**
488
+
489
+ Read the `@trace.sign_off` block in the tech doc header. If absent → add it as a finding (auto-fixable: add skeleton).
490
+
491
+ ```yaml
492
+ # @trace.sign_off:
493
+ # be_team: pending # author — set to "done" when BE satisfied with design
494
+ # fe_team: pending # FE/Web — must confirm contract matches web BDD expectations
495
+ # app_team: pending # App — must confirm contract matches app BDD expectations (if applicable)
496
+ # sa: pending # SA/Tech Lead — final approval
497
+ ```
498
+
499
+ **Step 2 — Contract vs BDD cross-check:**
500
+
501
+ Load the web and app BDDs for this TICKET-ID (from `{paths.specs_dir}/{domain}/web/` and `{paths.specs_dir}/{domain}/app/` in the spec submodule or spec repo).
502
+
503
+ For each platform BDD, verify the tech doc's API contract satisfies the BDD's `Then` clauses:
504
+
505
+ | Check | Severity |
506
+ |---|---|
507
+ | Response fields in API contract don't cover what web BDD `Then` expects | Critical |
508
+ | Response fields in API contract don't cover what app BDD `Then` expects | Critical |
509
+ | Error response shape doesn't match what platform BDDs expect | Major |
510
+ | System BDD `@system.resolution` annotation contradicts the API contract design | Critical |
511
+
512
+ **Step 3 — Pending sign-off report:**
513
+
514
+ After the review, list which sign-offs are still `pending`:
515
+
516
+ ```
517
+ ⏳ Pending sign-offs before tech docs can be approved:
518
+ fe_team — FE/Web team must confirm API contract matches web BDD expectations
519
+ app_team — App team must confirm API contract matches app BDD expectations
520
+ sa — SA/Tech Lead final approval
521
+
522
+ Once sign-offs are collected → update @trace.sign_off in tech doc header, then re-run /review-tech-docs.
523
+ Tech docs cannot be set to "approved" while any required sign-off is pending.
524
+ ```
525
+
526
+ **Approval gate:**
527
+ - If `be_team: done` AND `fe_team: done` AND `app_team: done` (or N/A) AND `sa: done` → tech docs may be set to `approved`
528
+ - Otherwise → `@trace.status` stays `in-review` — `generate-code` is blocked
529
+
390
530
  ---
391
531
 
392
532
  ## Write Findings File
@@ -400,10 +540,18 @@ domain: "{domain}"
400
540
  generated_at: "{ISO datetime}"
401
541
  review_type: "tech-design"
402
542
  status: "pending_review"
543
+ is_system_bdd: {true | false} # true if source BDD has @trace.platform: system
544
+
545
+ sign_off: # only present when is_system_bdd: true
546
+ be_team: pending # read from @trace.sign_off in tech-doc header
547
+ fe_team: pending
548
+ app_team: pending # "n/a" if project has no app platform
549
+ sa: pending
550
+ sign_off_gate: blocked # blocked | ready — "ready" only when all required are "done"
403
551
 
404
552
  findings:
405
553
  - id: "F001"
406
- check_id: "T1" # T1–T6
554
+ check_id: "T1" # T1–T7
407
555
  severity: "critical" # critical | major | minor
408
556
  section: "{section heading or component name where issue was found}"
409
557
  finding: "{clear description of the violation or gap}"
@@ -417,6 +565,7 @@ summary:
417
565
  auto_fixable: {N}
418
566
  requires_human_decision: {N}
419
567
  recommendation: "APPROVED | NEEDS_REVISION | BLOCKED"
568
+ sign_off_gate: "{blocked — pending: fe_team, app_team, sa | ready}"
420
569
  ```
421
570
 
422
571
  ## Report
@@ -453,7 +602,8 @@ Suggest the logical next command based on workflow phase:
453
602
  | /define-product | `/generate-prd {product-definition-file}` |
454
603
  | /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
455
604
  | /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
456
- | /review-context (PRD) | `/generate-bdd {prd-file}` if APPROVED; fix PRD if NEEDS_FIX |
605
+ | /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 |
606
+ | /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
457
607
  | /generate-bdd | `/review-context {feature-file}` to verify coverage |
458
608
  | /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
459
609
  | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
@@ -467,6 +617,11 @@ Suggest the logical next command based on workflow phase:
467
617
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
468
618
  | /fix-bug | Create PR and link to ticket |
469
619
  | /debug | `/fix-bug {ticket-id}` if fix needed |
620
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
621
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
622
+ | /learn | Continue working — lesson applies on next command |
623
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
624
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
470
625
 
471
626
  Format the footer as:
472
627
  ```
@@ -483,9 +638,17 @@ UC: {UC-ID} | Domain: {domain}
483
638
  Findings: {total} | 🔴 Critical: {N} | 🟡 Major: {N} | 🟢 Minor: {N}
484
639
  Auto-fixable: {N} | Needs human decision: {N}
485
640
 
641
+ Sign-off gate (system BDD only):
642
+ be_team : {done | pending}
643
+ fe_team : {done | pending} ← {name / "needs sign-off" }
644
+ app_team : {done | pending | n/a}
645
+ sa : {done | pending}
646
+ Gate : {🔒 BLOCKED — pending: fe_team, sa | ✅ READY}
647
+
486
648
  Findings file: {paths.refinement_dir}/{uc-id}-tech-review-findings.yaml
487
649
  Next: Open in Review Board → Accept/Modify/Reject each finding
488
650
  Then run: /review-tech-docs --resume {tech-design-file}
651
+ After all sign-offs collected → update @trace.sign_off in tech doc, re-run review
489
652
  ```
490
653
 
491
654
  ---
@@ -520,7 +683,10 @@ Review Board "Modify" note. Apply exactly what the note says. Do not invent the
520
683
 
521
684
  Edit the tech-doc file directly:
522
685
  1. Find `@trace.revision:` in the header — increment its integer value by 1.
523
- 2. Find `@trace.status:` in the header — set its value to `draft`.
686
+ 2. Find `@trace.status:` in the header:
687
+ - If sign_off_gate = `ready` (all sign-offs done) → set to `approved`
688
+ - Otherwise → set to `in-review` (blocks `/generate-code`)
689
+ 3. If `@trace.sign_off` block is absent and this is a system BDD tech doc → add it with all values `pending`.
524
690
 
525
691
  Write both changes to the file.
526
692
 
@@ -542,8 +708,13 @@ Changes:
542
708
  - {change 2}
543
709
 
544
710
  Revision : {old} → {new}
545
- Status : reset to draft (re-approval required)
711
+ Status : {approved | in-review}
712
+
713
+ Sign-off : {✅ All done — status set to approved
714
+ | 🔒 Pending: fe_team, sa — status set to in-review
715
+ Update @trace.sign_off in tech doc when each team confirms, then re-run /review-tech-docs}
546
716
 
547
717
  Re-run /review-tech-docs {file} to confirm 0 remaining critical findings.
548
- Next: /generate-code {feature-file}
718
+ Next: {/generate-code {feature-file} ← only if status = approved
719
+ | Collect pending sign-offs → update @trace.sign_off → re-run /review-tech-docs}
549
720
  ```
@@ -122,6 +122,59 @@ Check all standard sections are present and non-empty:
122
122
 
123
123
  → All T6 missing-section findings are **auto-fixable**: AI adds skeleton section with prompts.
124
124
 
125
+ ### T7 — Cross-Team API Contract Review
126
+
127
+ *Only applies when ALL of the following are true:*
128
+ *1. Source BDD has `@trace.platform: system`.*
129
+ *2. Tech-doc header does NOT have `@trace.api_source: existing`.*
130
+
131
+ *If `@trace.api_source: existing` → **skip T7 entirely**. Contract đã được PO xác định trong PRD — không có API design mới để đồng thuận.*
132
+
133
+ This dimension ensures FE, App, and BE teams all agree on the API contract before implementation starts.
134
+
135
+ **Step 1 — Check sign-off status in tech-doc header:**
136
+
137
+ Read the `@trace.sign_off` block in the tech doc header. If absent → add it as a finding (auto-fixable: add skeleton).
138
+
139
+ ```yaml
140
+ # @trace.sign_off:
141
+ # be_team: pending # author — set to "done" when BE satisfied with design
142
+ # fe_team: pending # FE/Web — must confirm contract matches web BDD expectations
143
+ # app_team: pending # App — must confirm contract matches app BDD expectations (if applicable)
144
+ # sa: pending # SA/Tech Lead — final approval
145
+ ```
146
+
147
+ **Step 2 — Contract vs BDD cross-check:**
148
+
149
+ Load the web and app BDDs for this TICKET-ID (from `{paths.specs_dir}/{domain}/web/` and `{paths.specs_dir}/{domain}/app/` in the spec submodule or spec repo).
150
+
151
+ For each platform BDD, verify the tech doc's API contract satisfies the BDD's `Then` clauses:
152
+
153
+ | Check | Severity |
154
+ |---|---|
155
+ | Response fields in API contract don't cover what web BDD `Then` expects | Critical |
156
+ | Response fields in API contract don't cover what app BDD `Then` expects | Critical |
157
+ | Error response shape doesn't match what platform BDDs expect | Major |
158
+ | System BDD `@system.resolution` annotation contradicts the API contract design | Critical |
159
+
160
+ **Step 3 — Pending sign-off report:**
161
+
162
+ After the review, list which sign-offs are still `pending`:
163
+
164
+ ```
165
+ ⏳ Pending sign-offs before tech docs can be approved:
166
+ fe_team — FE/Web team must confirm API contract matches web BDD expectations
167
+ app_team — App team must confirm API contract matches app BDD expectations
168
+ sa — SA/Tech Lead final approval
169
+
170
+ Once sign-offs are collected → update @trace.sign_off in tech doc header, then re-run /review-tech-docs.
171
+ Tech docs cannot be set to "approved" while any required sign-off is pending.
172
+ ```
173
+
174
+ **Approval gate:**
175
+ - If `be_team: done` AND `fe_team: done` AND `app_team: done` (or N/A) AND `sa: done` → tech docs may be set to `approved`
176
+ - Otherwise → `@trace.status` stays `in-review` — `generate-code` is blocked
177
+
125
178
  ---
126
179
 
127
180
  ## Write Findings File
@@ -135,10 +188,18 @@ domain: "{domain}"
135
188
  generated_at: "{ISO datetime}"
136
189
  review_type: "tech-design"
137
190
  status: "pending_review"
191
+ is_system_bdd: {true | false} # true if source BDD has @trace.platform: system
192
+
193
+ sign_off: # only present when is_system_bdd: true
194
+ be_team: pending # read from @trace.sign_off in tech-doc header
195
+ fe_team: pending
196
+ app_team: pending # "n/a" if project has no app platform
197
+ sa: pending
198
+ sign_off_gate: blocked # blocked | ready — "ready" only when all required are "done"
138
199
 
139
200
  findings:
140
201
  - id: "F001"
141
- check_id: "T1" # T1–T6
202
+ check_id: "T1" # T1–T7
142
203
  severity: "critical" # critical | major | minor
143
204
  section: "{section heading or component name where issue was found}"
144
205
  finding: "{clear description of the violation or gap}"
@@ -152,6 +213,7 @@ summary:
152
213
  auto_fixable: {N}
153
214
  requires_human_decision: {N}
154
215
  recommendation: "APPROVED | NEEDS_REVISION | BLOCKED"
216
+ sign_off_gate: "{blocked — pending: fe_team, app_team, sa | ready}"
155
217
  ```
156
218
 
157
219
  ## Report
@@ -164,9 +226,17 @@ UC: {UC-ID} | Domain: {domain}
164
226
  Findings: {total} | 🔴 Critical: {N} | 🟡 Major: {N} | 🟢 Minor: {N}
165
227
  Auto-fixable: {N} | Needs human decision: {N}
166
228
 
229
+ Sign-off gate (system BDD only):
230
+ be_team : {done | pending}
231
+ fe_team : {done | pending} ← {name / "needs sign-off" }
232
+ app_team : {done | pending | n/a}
233
+ sa : {done | pending}
234
+ Gate : {🔒 BLOCKED — pending: fe_team, sa | ✅ READY}
235
+
167
236
  Findings file: {paths.refinement_dir}/{uc-id}-tech-review-findings.yaml
168
237
  Next: Open in Review Board → Accept/Modify/Reject each finding
169
238
  Then run: /review-tech-docs --resume {tech-design-file}
239
+ After all sign-offs collected → update @trace.sign_off in tech doc, re-run review
170
240
  ```
171
241
 
172
242
  ---
@@ -201,7 +271,10 @@ Review Board "Modify" note. Apply exactly what the note says. Do not invent the
201
271
 
202
272
  Edit the tech-doc file directly:
203
273
  1. Find `@trace.revision:` in the header — increment its integer value by 1.
204
- 2. Find `@trace.status:` in the header — set its value to `draft`.
274
+ 2. Find `@trace.status:` in the header:
275
+ - If sign_off_gate = `ready` (all sign-offs done) → set to `approved`
276
+ - Otherwise → set to `in-review` (blocks `/generate-code`)
277
+ 3. If `@trace.sign_off` block is absent and this is a system BDD tech doc → add it with all values `pending`.
205
278
 
206
279
  Write both changes to the file.
207
280
 
@@ -223,8 +296,13 @@ Changes:
223
296
  - {change 2}
224
297
 
225
298
  Revision : {old} → {new}
226
- Status : reset to draft (re-approval required)
299
+ Status : {approved | in-review}
300
+
301
+ Sign-off : {✅ All done — status set to approved
302
+ | 🔒 Pending: fe_team, sa — status set to in-review
303
+ Update @trace.sign_off in tech doc when each team confirms, then re-run /review-tech-docs}
227
304
 
228
305
  Re-run /review-tech-docs {file} to confirm 0 remaining critical findings.
229
- Next: /generate-code {feature-file}
306
+ Next: {/generate-code {feature-file} ← only if status = approved
307
+ | Collect pending sign-offs → update @trace.sign_off → re-run /review-tech-docs}
230
308
  ```
@@ -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
 
@@ -282,6 +369,31 @@ Use it to select the correct run command and error analysis table below.
282
369
 
283
370
  ---
284
371
 
372
+ ## Submodule Working Directory
373
+
374
+ *Skip this section if `service_root` is not set (single-service mode).*
375
+
376
+ When running in **umbrella/submodule mode** (`service_root` was resolved in context-loader Step 1.6):
377
+
378
+ - All commands in the **Run** section below must execute from within `{service_root}/`
379
+ - `conventions.test_command` was loaded from `{service_root}/.agent/project-context.yaml` — already service-specific
380
+ - Prefix every shell command with `cd {service_root} &&`:
381
+
382
+ ```bash
383
+ cd {service_root}
384
+
385
+ # Then run any of the commands in the Run section below, e.g.:
386
+ {conventions.test_command}
387
+ mvn test -Dtest={ClassName} # java-spring
388
+ go test ./... -run Test{FunctionName} # golang
389
+ npx vitest run src/... # web-frontend
390
+ flutter test test/{domain}/... # flutter
391
+ ```
392
+
393
+ > **Why cd?** Claude Code session is opened at umbrella root. Each service submodule has its own build tool, test runner, and dependency tree — tests must run from inside the service directory.
394
+
395
+ ---
396
+
285
397
  ## Run
286
398
 
287
399
  ### If `platform_type = backend`
@@ -444,7 +556,8 @@ Suggest the logical next command based on workflow phase:
444
556
  | /define-product | `/generate-prd {product-definition-file}` |
445
557
  | /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
446
558
  | /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
447
- | /review-context (PRD) | `/generate-bdd {prd-file}` if APPROVED; fix PRD if NEEDS_FIX |
559
+ | /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 |
560
+ | /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
448
561
  | /generate-bdd | `/review-context {feature-file}` to verify coverage |
449
562
  | /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
450
563
  | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
@@ -458,6 +571,11 @@ Suggest the logical next command based on workflow phase:
458
571
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
459
572
  | /fix-bug | Create PR and link to ticket |
460
573
  | /debug | `/fix-bug {ticket-id}` if fix needed |
574
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
575
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
576
+ | /learn | Continue working — lesson applies on next command |
577
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
578
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
461
579
 
462
580
  Format the footer as:
463
581
  ```
@@ -17,6 +17,31 @@ Use it to select the correct run command and error analysis table below.
17
17
 
18
18
  ---
19
19
 
20
+ ## Submodule Working Directory
21
+
22
+ *Skip this section if `service_root` is not set (single-service mode).*
23
+
24
+ When running in **umbrella/submodule mode** (`service_root` was resolved in context-loader Step 1.6):
25
+
26
+ - All commands in the **Run** section below must execute from within `{service_root}/`
27
+ - `conventions.test_command` was loaded from `{service_root}/.agent/project-context.yaml` — already service-specific
28
+ - Prefix every shell command with `cd {service_root} &&`:
29
+
30
+ ```bash
31
+ cd {service_root}
32
+
33
+ # Then run any of the commands in the Run section below, e.g.:
34
+ {conventions.test_command}
35
+ mvn test -Dtest={ClassName} # java-spring
36
+ go test ./... -run Test{FunctionName} # golang
37
+ npx vitest run src/... # web-frontend
38
+ flutter test test/{domain}/... # flutter
39
+ ```
40
+
41
+ > **Why cd?** Claude Code session is opened at umbrella root. Each service submodule has its own build tool, test runner, and dependency tree — tests must run from inside the service directory.
42
+
43
+ ---
44
+
20
45
  ## Run
21
46
 
22
47
  ### If `platform_type = backend`