@anhth2/spec-driven-dev-plugin 0.8.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 (89) hide show
  1. package/ARCHITECTURE.md +6 -2
  2. package/commands/debug.md +152 -0
  3. package/commands/debug.tmpl +16 -0
  4. package/commands/define-product.md +57 -0
  5. package/commands/fix-bug.md +153 -0
  6. package/commands/fix-bug.tmpl +17 -0
  7. package/commands/generate-bdd.md +277 -13
  8. package/commands/generate-bdd.tmpl +220 -13
  9. package/commands/generate-code.md +154 -2
  10. package/commands/generate-code.tmpl +97 -2
  11. package/commands/generate-design-spec.md +57 -0
  12. package/commands/generate-prd.md +75 -0
  13. package/commands/generate-prd.tmpl +18 -0
  14. package/commands/generate-spec-manifest.md +57 -0
  15. package/commands/generate-tech-docs.md +79 -1
  16. package/commands/generate-tech-docs.tmpl +22 -1
  17. package/commands/generate-tests.md +57 -0
  18. package/commands/learn.md +554 -0
  19. package/commands/learn.tmpl +63 -0
  20. package/commands/propose-scenario.md +521 -0
  21. package/commands/propose-scenario.tmpl +109 -0
  22. package/commands/refine-prd.md +57 -0
  23. package/commands/report-bug.md +543 -0
  24. package/commands/report-bug.tmpl +131 -0
  25. package/commands/review-code.md +153 -0
  26. package/commands/review-code.tmpl +17 -0
  27. package/commands/review-context.md +57 -0
  28. package/commands/review-tech-docs.md +139 -4
  29. package/commands/review-tech-docs.tmpl +82 -4
  30. package/commands/run-tests.md +82 -0
  31. package/commands/run-tests.tmpl +25 -0
  32. package/commands/setup-ai-first.md +15 -5
  33. package/commands/setup-ai-first.tmpl +10 -5
  34. package/commands/smoke-test.md +57 -0
  35. package/commands/sync.md +405 -0
  36. package/commands/sync.tmpl +345 -0
  37. package/commands/update-framework.md +211 -0
  38. package/commands/update-framework.tmpl +151 -0
  39. package/commands/validate-traces.md +115 -2
  40. package/commands/validate-traces.tmpl +58 -2
  41. package/core/FRAMEWORK_VERSION +1 -1
  42. package/core/commands/debug.md +152 -0
  43. package/core/commands/define-product.md +57 -0
  44. package/core/commands/fix-bug.md +153 -0
  45. package/core/commands/generate-bdd.md +277 -13
  46. package/core/commands/generate-code.md +154 -2
  47. package/core/commands/generate-design-spec.md +57 -0
  48. package/core/commands/generate-prd.md +75 -0
  49. package/core/commands/generate-spec-manifest.md +57 -0
  50. package/core/commands/generate-tech-docs.md +79 -1
  51. package/core/commands/generate-tests.md +57 -0
  52. package/core/commands/learn.md +554 -0
  53. package/core/commands/propose-scenario.md +521 -0
  54. package/core/commands/refine-prd.md +57 -0
  55. package/core/commands/report-bug.md +543 -0
  56. package/core/commands/review-code.md +153 -0
  57. package/core/commands/review-context.md +57 -0
  58. package/core/commands/review-tech-docs.md +139 -4
  59. package/core/commands/run-tests.md +82 -0
  60. package/core/commands/setup-ai-first.md +15 -5
  61. package/core/commands/smoke-test.md +57 -0
  62. package/core/commands/sync.md +405 -0
  63. package/core/commands/update-framework.md +211 -0
  64. package/core/commands/validate-traces.md +115 -2
  65. package/core/skills/code/SKILL.md +62 -0
  66. package/core/skills/debug/SKILL.md +67 -0
  67. package/core/skills/design-spec/SKILL.md +57 -0
  68. package/core/skills/discovery/SKILL.md +57 -0
  69. package/core/skills/prd/SKILL.md +10 -0
  70. package/core/skills/setup-ai-first/SKILL.md +5 -0
  71. package/core/skills/spec/SKILL.md +10 -0
  72. package/core/skills/test/SKILL.md +119 -0
  73. package/core/steps/capture-lesson.md +79 -0
  74. package/core/steps/context-loader.md +52 -0
  75. package/core/steps/report-footer.md +5 -0
  76. package/core/templates/project-context.yaml +11 -0
  77. package/package.json +1 -1
  78. package/skills/code/SKILL.md +62 -0
  79. package/skills/debug/SKILL.md +67 -0
  80. package/skills/design-spec/SKILL.md +57 -0
  81. package/skills/discovery/SKILL.md +57 -0
  82. package/skills/prd/SKILL.md +10 -0
  83. package/skills/setup-ai-first/SKILL.md +5 -0
  84. package/skills/spec/SKILL.md +10 -0
  85. package/skills/test/SKILL.md +119 -0
  86. package/steps/capture-lesson.md +79 -0
  87. package/steps/context-loader.md +52 -0
  88. package/steps/report-footer.md +5 -0
  89. package/templates/project-context.yaml +11 -0
@@ -0,0 +1,131 @@
1
+ # /report-bug — File a Spec-Traced Bug (Tester-Facing)
2
+
3
+ For **testers**. Produces a structured bug report with full spec context, classifies the likely
4
+ layer, and saves it for handoff to the dev team.
5
+
6
+ **READ-ONLY on specs and code.** This command never edits PRD, BDD, tech-docs, or source.
7
+ Fixing is the dev's job (`/fix-bug`); writing scenarios is `/propose-scenario`.
8
+
9
+ Usage: `/report-bug {UC-ID or TICKET} {short description}`
10
+ Example: `/report-bug FT-001 account locks after 6 failed logins, spec says 5`
11
+
12
+ ## Gate
13
+ {{include:steps/gate.md}}
14
+
15
+ *Note: For this command, the target in Step 1 is a UC-ID / TICKET from `$ARGUMENTS`. Resolve the matching `.feature` file if one exists; if not, continue — a bug can still be filed.*
16
+
17
+ ## Context
18
+ {{include:steps/context-loader.md}}
19
+
20
+ ---
21
+
22
+ ## Step 1 — Resolve Spec Context
23
+
24
+ Locate the spec chain for the bug's UC/TICKET. Prefer `spec-manifest.yaml` (umbrella/tester setup) if present; else use resolved `paths`.
25
+
26
+ Gather and store:
27
+ - `prd_path` + current PRD `Version`
28
+ - `bdd_path` (the `.feature` for this UC) + the specific **failing scenario** title, if one matches
29
+ - `tech_doc_path` (if any)
30
+ - `service` / domain
31
+
32
+ If no `.feature` scenario matches the reported behavior → set `coverage_gap = true` (the behavior is untested by BDD).
33
+
34
+ ## Step 2 — Gather Bug Details
35
+
36
+ If not already in `$ARGUMENTS`, ask the tester (one compact prompt):
37
+
38
+ ```
39
+ File a bug — answer what you can:
40
+ 1. Where does it occur? (endpoint / screen / flow)
41
+ 2. Steps to reproduce?
42
+ 3. Expected (per spec) vs Actual?
43
+ 4. Error / log / status code?
44
+ 5. Environment? (staging / prod / local)
45
+ ```
46
+
47
+ ## Step 3 — Identify the AC Violated
48
+
49
+ Read the PRD acceptance criteria for this UC. Match the bug to the specific **AC** it violates
50
+ (e.g. `AC3: "5 failed logins → lock 30m"`). Quote it verbatim. If the behavior maps to no AC →
51
+ note "No AC covers this" and treat as a possible PRD gap.
52
+
53
+ ## Step 4 — Classify Likely Layer (BUG_FLOW)
54
+
55
+ Apply the BUG_FLOW decision table to suggest where the root cause likely is — this routes the bug:
56
+
57
+ | If… | Likely layer | Route to |
58
+ |------|-------------|----------|
59
+ | Code contradicts a BDD scenario | **Code bug** (Case 1) | Dev → `/fix-bug` |
60
+ | BDD scenario contradicts PRD AC | **BDD bug** (Case 2) | Dev/PO fix BDD |
61
+ | PRD AC is ambiguous / silent | **PRD ambiguity** (Case 3) | PO clarifies PRD |
62
+ | Behavior correct but **no scenario covers it** | **BDD coverage gap** | Tester → `/propose-scenario` |
63
+ | UI ≠ Design Spec | **Design Spec bug** (Case 5) | Dev/Designer |
64
+ | Env / data only | **Environment** (Case 6) | DevOps |
65
+
66
+ State the classification as a suggestion (dev confirms during `/fix-bug`).
67
+
68
+ ## Step 5 — Write the Report
69
+
70
+ Assign `BUG-{today YYYYMMDD}-{NN}` (NN = next sequence among existing reports).
71
+ Write to `{paths.bug_reports_dir}/{BUG-ID}.md` (resolved to `{spec_source}/feedback/bug-reports/` in umbrella mode; create dir if needed) using the structure in the Output block, and also print it for pasting into Jira/Slack.
72
+
73
+ ## Step 6 — Handoff (so PO/Dev actually see it)
74
+
75
+ The report only reaches PO/Dev if it is **committed and pushed to the shared spec repo**. A local file is a dead drop.
76
+
77
+ Determine the repo that owns `{paths.bug_reports_dir}`:
78
+ - Umbrella mode → the spec submodule at `{spec_source}`
79
+ - Single-service → the current repo
80
+
81
+ Then commit + push **that** repo:
82
+
83
+ ```bash
84
+ cd {spec_source} # umbrella: the spec submodule; single-service: omit
85
+ git add feedback/bug-reports/{BUG-ID}.md
86
+ git commit -m "qa(bug): {BUG-ID} — {short description}"
87
+ git push # → PO/Dev see it on their next /sync
88
+ ```
89
+
90
+ - If the tester lacks push rights to the spec repo → open a PR / MR instead, or hand the file to whoever owns it. Print this fallback.
91
+ - Print the exact commands if you do not run them automatically.
92
+
93
+ > PO/Dev are notified through their normal routine: `/sync` lists newly-pulled bug reports.
94
+
95
+ ---
96
+
97
+ ## Output
98
+
99
+ {{include:steps/report-footer.md}}
100
+
101
+ ```
102
+ 🐞 {BUG-ID} → {paths.bug_reports_dir}/{BUG-ID}.md (in shared spec repo)
103
+
104
+ Feature : {UC-ID} — {feature name} | Service: {service} | Severity: {Critical|Major|Minor}
105
+
106
+ Spec context
107
+ PRD : {prd_path} (v{prd_version})
108
+ BDD : {bdd_path} → Scenario: "{scenario title}" {or: ⚠️ no scenario covers this}
109
+ Tech Doc : {tech_doc_path}
110
+
111
+ AC violated
112
+ {AC-N}: "{AC text}"
113
+
114
+ Expected (per spec) : {expected}
115
+ Actual : {actual}
116
+ Steps to reproduce : {1..N}
117
+ Environment : {env}
118
+
119
+ Likely layer : {Code | BDD | PRD | Design Spec | Env} → {route}
120
+
121
+ Handoff : {✅ committed + pushed to spec repo | ⚠️ run the git commands above / open a PR}
122
+
123
+ ---
124
+ Status : ✅ Complete (read-only on specs/code — only wrote the feedback file)
125
+ Output Artifacts: created {paths.bug_reports_dir}/{BUG-ID}.md (pushed to shared spec repo)
126
+ Next :
127
+ - PO/Dev will see this on their next /sync
128
+ - Code bug → dev runs /fix-bug {BUG-ID}
129
+ - PRD ambiguity → PO (BUG_FLOW Case 3)
130
+ - Coverage gap → /propose-scenario {UC-ID}
131
+ ```
@@ -180,6 +180,37 @@ If `services` section is present:
180
180
  - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
181
181
  - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
182
182
  - Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
183
+ - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
184
+ - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
185
+
186
+ > **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.
187
+
188
+ ---
189
+
190
+ ## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
191
+
192
+ *Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
193
+
194
+ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
195
+
196
+ **1. Locate service config** — try in priority order:
197
+ - `{active_service}/.agent/project-context.yaml`
198
+ - `{active_service}/project-context.yaml`
199
+
200
+ **2. If found, override with service-specific values:**
201
+
202
+ | Variable | Source |
203
+ |----------|--------|
204
+ | `conventions.test_command` | service's `conventions.test_command` |
205
+ | `conventions.build_command` | service's `conventions.build_command` |
206
+ | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
207
+ | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
208
+
209
+ **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
210
+ - Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
211
+ - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
212
+
213
+ **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).
183
214
 
184
215
  ---
185
216
 
@@ -273,6 +304,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
273
304
 
274
305
  ---
275
306
 
307
+ ## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
308
+
309
+ *Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
310
+ or accepted during `/review-code`, `/fix-bug`, `/debug`.*
311
+
312
+ Resolve the lessons file path:
313
+ - Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
314
+ - Else default `specs/domain-knowledge/lessons-learned.md`
315
+ - In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
316
+
317
+ If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
318
+ - Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
319
+ - 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).
320
+ - If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
321
+
322
+ If the file does not exist → skip silently (no lessons captured yet).
323
+
324
+ ---
325
+
276
326
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
277
327
 
278
328
  After loading all context, synthesize and output a compact summary block.
@@ -288,7 +338,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
288
338
  Ticket : {ticket_prefix}-
289
339
  Dict : {loaded — N canonical terms, M banned terms | missing}
290
340
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
341
+ Lessons : {loaded — N guardrails | none yet}
291
342
  Service : {active_service} ({active_service_module}) | single-service
343
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
292
344
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
293
345
  ```
294
346
 
@@ -405,6 +457,11 @@ Suggest the logical next command based on workflow phase:
405
457
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
406
458
  | /fix-bug | Create PR and link to ticket |
407
459
  | /debug | `/fix-bug {ticket-id}` if fix needed |
460
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
461
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
462
+ | /learn | Continue working — lesson applies on next command |
463
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
464
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
408
465
 
409
466
  Format the footer as:
410
467
  ```
@@ -440,3 +497,99 @@ If NEEDS_FIX ❌:
440
497
  - Logic / architecture issue → /fix-bug {TICKET_ID}
441
498
  - Spec mismatch (code ≠ scenario) → /generate-code {feature-file} (re-gen affected UC)
442
499
  ```
500
+
501
+ ---
502
+
503
+ ## Offer to Record Lessons (optional)
504
+
505
+ For each **Critical/Major** finding that represents a **repeatable AI mistake** during code generation
506
+ (an architecture/standards violation the AI is likely to make again — NOT a one-off typo or an external cause), ask:
507
+
508
+ ```
509
+ Finding "{issue}" looks like a repeatable mistake.
510
+ Record it as a project lesson so /generate-code won't repeat it? (Y/N)
511
+ ```
512
+
513
+ If `Y` → run the capture procedure below with `category=code-gen`, `source=/review-code {UC-ID}`,
514
+ `scope` = the affected domain or file glob.
515
+
516
+ # Capture Lesson — Record a Recurring Mistake as a Guardrail
517
+
518
+ Reusable procedure to persist a "lesson" so the AI does not repeat a mistake in this project.
519
+ Used by `/learn` (manual) and offered by `/review-code`, `/fix-bug`, `/debug` (auto).
520
+
521
+ > **Project memory, not model training.** A lesson is plain text injected into context at the
522
+ > start of every command (context-loader Step 6.7). Functionally this stops the repeat — the AI
523
+ > sees the guardrail before it generates. No model weights change.
524
+
525
+ ## L1 — Resolve the lessons file
526
+
527
+ Resolve `lessons_path` in this order:
528
+ 1. `paths.lessons_file` from loaded context (may be service-overridden in umbrella mode, Step 1.6)
529
+ 2. Default `specs/domain-knowledge/lessons-learned.md` (single-service)
530
+ 3. In umbrella/service mode (when `service_root` is set) default `{service_root}/.agent/project-lessons.md`
531
+
532
+ ## L2 — Build the lesson
533
+
534
+ Gather these fields — from `$ARGUMENTS` (for `/learn`) or from the calling command's findings
535
+ (for `/review-code`, `/fix-bug`, `/debug`):
536
+
537
+ | Field | Meaning |
538
+ |-------|---------|
539
+ | `category` | one of: `code-gen` \| `bdd` \| `tech-docs` \| `tests` \| `prd` \| `general` |
540
+ | `title` | short phrase naming the mistake |
541
+ | `mistake` | concretely, what the AI did wrong |
542
+ | `rule` | imperative correction — "Always …" / "Never …" — testable, not vague |
543
+ | `scope` | where it applies: a domain, a file glob (e.g. `*Controller.*`), or `all` |
544
+ | `source` | how captured: `/learn` \| `/review-code {UC-ID}` \| `/fix-bug {TICKET}` \| `/debug` |
545
+
546
+ If `rule` is vague (e.g. "be careful"), rewrite it into a concrete, checkable instruction before saving.
547
+
548
+ ## L3 — De-duplicate
549
+
550
+ Read existing lessons in `lessons_path`. If one already covers the same mistake:
551
+ - **Refine** that entry (tighten the Rule, widen/narrow Scope, bump Date, append the new Source) — do NOT add a duplicate.
552
+
553
+ Otherwise assign the next id `L-{NNN}` = (highest existing number + 1), zero-padded to 3 digits.
554
+
555
+ ## L4 — Write
556
+
557
+ If `lessons_path` does not exist, create it with this header first:
558
+
559
+ ```markdown
560
+ # Project Lessons — Learned Guardrails
561
+
562
+ > Mistakes the AI must NOT repeat in this project. Loaded by context-loader at the start of
563
+ > every command and treated as hard constraints (same priority as CLAUDE.md coding standards).
564
+ > Add with /learn, or accept the prompt during /review-code, /fix-bug, /debug.
565
+ > Commit this file so the whole team shares the guardrails.
566
+
567
+ | Category | Applies to |
568
+ |----------|-----------|
569
+ | code-gen | /generate-code output |
570
+ | bdd | /generate-bdd output |
571
+ | tech-docs | /generate-tech-docs output |
572
+ | tests | /generate-tests output |
573
+ | prd | /generate-prd, /refine-prd output |
574
+ | general | every command |
575
+
576
+ ---
577
+ ```
578
+
579
+ Insert the new lesson directly under the `---` separator (**newest first**), in this exact shape:
580
+
581
+ ```markdown
582
+ ### L-{NNN} — [{category}] {title}
583
+ - **Date**: {today YYYY-MM-DD}
584
+ - **Scope**: {scope}
585
+ - **Mistake**: {mistake}
586
+ - **Rule**: {rule}
587
+ - **Source**: {source}
588
+
589
+ ```
590
+
591
+ ## L5 — Confirm
592
+
593
+ Print: `📝 Lesson {id} recorded → {lessons_path} ([{category}] {title})`
594
+ Then remind: `Commit {lessons_path} so the team shares this guardrail.`
595
+
@@ -85,3 +85,20 @@ If NEEDS_FIX ❌:
85
85
  - Logic / architecture issue → /fix-bug {TICKET_ID}
86
86
  - Spec mismatch (code ≠ scenario) → /generate-code {feature-file} (re-gen affected UC)
87
87
  ```
88
+
89
+ ---
90
+
91
+ ## Offer to Record Lessons (optional)
92
+
93
+ For each **Critical/Major** finding that represents a **repeatable AI mistake** during code generation
94
+ (an architecture/standards violation the AI is likely to make again — NOT a one-off typo or an external cause), ask:
95
+
96
+ ```
97
+ Finding "{issue}" looks like a repeatable mistake.
98
+ Record it as a project lesson so /generate-code won't repeat it? (Y/N)
99
+ ```
100
+
101
+ If `Y` → run the capture procedure below with `category=code-gen`, `source=/review-code {UC-ID}`,
102
+ `scope` = the affected domain or file glob.
103
+
104
+ {{include:steps/capture-lesson.md}}
@@ -185,6 +185,37 @@ If `services` section is present:
185
185
  - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
186
186
  - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
187
187
  - Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
188
+ - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
189
+ - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
190
+
191
+ > **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.
192
+
193
+ ---
194
+
195
+ ## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
196
+
197
+ *Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
198
+
199
+ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
200
+
201
+ **1. Locate service config** — try in priority order:
202
+ - `{active_service}/.agent/project-context.yaml`
203
+ - `{active_service}/project-context.yaml`
204
+
205
+ **2. If found, override with service-specific values:**
206
+
207
+ | Variable | Source |
208
+ |----------|--------|
209
+ | `conventions.test_command` | service's `conventions.test_command` |
210
+ | `conventions.build_command` | service's `conventions.build_command` |
211
+ | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
212
+ | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
213
+
214
+ **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
215
+ - Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
216
+ - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
217
+
218
+ **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).
188
219
 
189
220
  ---
190
221
 
@@ -278,6 +309,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
278
309
 
279
310
  ---
280
311
 
312
+ ## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
313
+
314
+ *Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
315
+ or accepted during `/review-code`, `/fix-bug`, `/debug`.*
316
+
317
+ Resolve the lessons file path:
318
+ - Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
319
+ - Else default `specs/domain-knowledge/lessons-learned.md`
320
+ - In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
321
+
322
+ If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
323
+ - Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
324
+ - 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).
325
+ - If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
326
+
327
+ If the file does not exist → skip silently (no lessons captured yet).
328
+
329
+ ---
330
+
281
331
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
282
332
 
283
333
  After loading all context, synthesize and output a compact summary block.
@@ -293,7 +343,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
293
343
  Ticket : {ticket_prefix}-
294
344
  Dict : {loaded — N canonical terms, M banned terms | missing}
295
345
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
346
+ Lessons : {loaded — N guardrails | none yet}
296
347
  Service : {active_service} ({active_service_module}) | single-service
348
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
297
349
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
298
350
  ```
299
351
 
@@ -581,6 +633,11 @@ Suggest the logical next command based on workflow phase:
581
633
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
582
634
  | /fix-bug | Create PR and link to ticket |
583
635
  | /debug | `/fix-bug {ticket-id}` if fix needed |
636
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
637
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
638
+ | /learn | Continue working — lesson applies on next command |
639
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
640
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
584
641
 
585
642
  Format the footer as:
586
643
  ```
@@ -182,6 +182,37 @@ If `services` section is present:
182
182
  - Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
183
183
  - Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
184
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).
185
216
 
186
217
  ---
187
218
 
@@ -275,6 +306,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
275
306
 
276
307
  ---
277
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
+
278
328
  ## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
279
329
 
280
330
  After loading all context, synthesize and output a compact summary block.
@@ -290,7 +340,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
290
340
  Ticket : {ticket_prefix}-
291
341
  Dict : {loaded — N canonical terms, M banned terms | missing}
292
342
  Entities : {loaded — EntityA, EntityB, EntityC | missing}
343
+ Lessons : {loaded — N guardrails | none yet}
293
344
  Service : {active_service} ({active_service_module}) | single-service
345
+ Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
294
346
  Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
295
347
  ```
296
348
 
@@ -422,6 +474,59 @@ Check all standard sections are present and non-empty:
422
474
 
423
475
  → All T6 missing-section findings are **auto-fixable**: AI adds skeleton section with prompts.
424
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
+
425
530
  ---
426
531
 
427
532
  ## Write Findings File
@@ -435,10 +540,18 @@ domain: "{domain}"
435
540
  generated_at: "{ISO datetime}"
436
541
  review_type: "tech-design"
437
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"
438
551
 
439
552
  findings:
440
553
  - id: "F001"
441
- check_id: "T1" # T1–T6
554
+ check_id: "T1" # T1–T7
442
555
  severity: "critical" # critical | major | minor
443
556
  section: "{section heading or component name where issue was found}"
444
557
  finding: "{clear description of the violation or gap}"
@@ -452,6 +565,7 @@ summary:
452
565
  auto_fixable: {N}
453
566
  requires_human_decision: {N}
454
567
  recommendation: "APPROVED | NEEDS_REVISION | BLOCKED"
568
+ sign_off_gate: "{blocked — pending: fe_team, app_team, sa | ready}"
455
569
  ```
456
570
 
457
571
  ## Report
@@ -503,6 +617,11 @@ Suggest the logical next command based on workflow phase:
503
617
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
504
618
  | /fix-bug | Create PR and link to ticket |
505
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 |
506
625
 
507
626
  Format the footer as:
508
627
  ```
@@ -519,9 +638,17 @@ UC: {UC-ID} | Domain: {domain}
519
638
  Findings: {total} | 🔴 Critical: {N} | 🟡 Major: {N} | 🟢 Minor: {N}
520
639
  Auto-fixable: {N} | Needs human decision: {N}
521
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
+
522
648
  Findings file: {paths.refinement_dir}/{uc-id}-tech-review-findings.yaml
523
649
  Next: Open in Review Board → Accept/Modify/Reject each finding
524
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
525
652
  ```
526
653
 
527
654
  ---
@@ -556,7 +683,10 @@ Review Board "Modify" note. Apply exactly what the note says. Do not invent the
556
683
 
557
684
  Edit the tech-doc file directly:
558
685
  1. Find `@trace.revision:` in the header — increment its integer value by 1.
559
- 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`.
560
690
 
561
691
  Write both changes to the file.
562
692
 
@@ -578,8 +708,13 @@ Changes:
578
708
  - {change 2}
579
709
 
580
710
  Revision : {old} → {new}
581
- 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}
582
716
 
583
717
  Re-run /review-tech-docs {file} to confirm 0 remaining critical findings.
584
- 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}
585
720
  ```