@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,399 @@
1
+ # /generate-design-spec — Generate Design Specification (FE / App)
2
+
3
+ ## Gate
4
+ {{include:steps/gate.md}}
5
+
6
+ *Note: For this command, the target file is a Business PRD in `{paths.prd_dir}/`. Resolve from `$ARGUMENTS` or list the directory and ask. Only FE and mobile PRDs are supported — BE PRDs will be rejected at the Platform Check step.*
7
+
8
+ ## Context
9
+ {{include:steps/context-loader.md}}
10
+
11
+ *Additional context for this command: Read the full target PRD. Extract: **TICKET-ID**, **domain**, **feature name**, **Service** and **Module** from PRD metadata (rows `| **Service** |` and `| **Module** |`), User Flow (Section 4a), and Wireframe screen names (Section 4b).*
12
+
13
+ *Service extraction rules (same as /generate-prd):*
14
+ - *If PRD metadata has `| **Service** |` → use as `active_service` and `| **Module** |` as `active_module`.*
15
+ - *If absent AND `services` defined in `project-context.yaml` → ask: "Which service is this Design Spec for?" (list FE/App services only, wait for selection).*
16
+ - *If single-service project → `active_service = "default"`, `active_module = tech_stack.module`.*
17
+
18
+ ---
19
+
20
+ ## Platform Check
21
+
22
+ Using `active_module` and `platform_type` derived from context loading:
23
+
24
+ 1. If `platform_type = "backend"` → **STOP**. Output:
25
+ ```
26
+ ❌ Design Spec is only for FE and mobile platforms.
27
+ For BE services, API contracts belong in the Business PRD (Use Case → Business Logic section).
28
+ ```
29
+
30
+ 2. If `platform_type = "web-frontend"` → set `active_platform = "web"`.
31
+
32
+ 3. If `platform_type = "mobile"`:
33
+ - `flutter` or `react-native` → set `active_platform = "app"`
34
+ - `ios-swiftui` → set `active_platform = "app-ios"`
35
+ - `android-compose` → set `active_platform = "app-android"`
36
+
37
+ 4. If `platform_type = "unknown"` → ask: "Which platform is this Design Spec for?"
38
+ ```
39
+ Options:
40
+ 1 — web (React / Next.js / Vue / Angular)
41
+ 2 — app (Flutter / React Native)
42
+ 3 — app-ios (iOS SwiftUI)
43
+ 4 — app-android (Android Compose)
44
+ ```
45
+ Wait for selection. Map choice to `active_platform` and infer `active_module` if possible.
46
+
47
+ ---
48
+
49
+ ## Figma Check
50
+
51
+ Ask:
52
+
53
+ ```
54
+ Do you have a Figma link for this feature? (paste URL or press Enter to skip)
55
+ ```
56
+
57
+ - If URL provided → store as `figma_url`.
58
+ - If skipped → `figma_url = "TBD"`. Add AI Assumption: "Figma link not provided — all screen descriptions are text-based. Link must be added and verified before Design Spec sign-off."
59
+
60
+ ---
61
+
62
+ ## Screen Discovery
63
+
64
+ From the PRD's Section 4 (User Flow + Wireframe), extract all screen / page / modal names mentioned.
65
+
66
+ Present the list and ask PO to confirm:
67
+
68
+ ```
69
+ Screens detected from PRD:
70
+ 1. {Screen name 1}
71
+ 2. {Screen name 2}
72
+ ...
73
+
74
+ Are these all the screens for the {active_platform} platform?
75
+ Add any missing, remove any that don't apply, or confirm with Y.
76
+ ```
77
+
78
+ Wait for confirmation. Store the confirmed list as `screen_list`.
79
+
80
+ ---
81
+
82
+ ## CHECKPOINT
83
+
84
+ ```
85
+ CHECKPOINT — Design Spec
86
+ -------------------------
87
+ Target PRD : {prd-file-path}
88
+ Platform : {active_platform}
89
+ Module : {active_module}
90
+ Service : {active_service}
91
+ Domain : {domain}
92
+ Screens : {N} — {comma-separated screen_list}
93
+ Figma : {figma_url}
94
+ Output path : {paths.design_spec_dir}/{domain}/{TICKET-ID}-design-spec-{active_platform}-{slug}.md
95
+
96
+ Generate? (Y/N)
97
+ ```
98
+
99
+ Wait for explicit Y before proceeding.
100
+
101
+ ---
102
+
103
+ ## Generation Rules
104
+
105
+ Apply these rules consistently when generating all sections:
106
+
107
+ **Component mapping (C.M — mandatory):**
108
+ - For each component referenced, check `figma-components/{active_module}.md` (loaded in context).
109
+ - ✅ Matched → use the exact `Code Component` and `Import Path` from the catalog.
110
+ - ⚠️ Matched but `[TODO]` → mark the component cell as `[TODO — implementation pending]`.
111
+ - ❌ Not in catalog → mark as `[NEW — confirm with designer before generating code]`.
112
+ - Never invent component names or import paths.
113
+
114
+ **Platform-adaptive sections:**
115
+ - Section 3 (Interaction Patterns) and Section 4 (Platform Considerations) adapt to `active_platform`:
116
+ - `web` → include responsive breakpoints, hover/focus states, keyboard navigation, accessibility.
117
+ - `app` / `app-ios` / `app-android` → include gestures, safe area, minimum touch targets, navigation pattern, deep links, permissions, offline behavior.
118
+ - Only generate the section relevant to `active_platform`. Omit the other platform's section entirely.
119
+
120
+ **Screen states (mandatory per screen):**
121
+ - Every screen must document at minimum: `default`, `loading`, `error`.
122
+ - Add `empty` when the screen can display zero-data state.
123
+ - Add `success` when a completed action produces a distinct confirmation state.
124
+ - If a state does not apply → mark `N/A` with a short reason.
125
+
126
+ ---
127
+
128
+ ## Generate
129
+
130
+ Write `{paths.design_spec_dir}/{domain}/{TICKET-ID}-design-spec-{active_platform}-{slug}.md`:
131
+
132
+ ````markdown
133
+ # {TICKET-ID} {Feature Name} — Design Spec [{active_platform}]
134
+
135
+ ---
136
+
137
+ ## Metadata
138
+
139
+ | Field | Value |
140
+ |--------------------|---------------------------------------------------------------|
141
+ | **Spec ID** | {TICKET-ID}-DS-{active_platform} |
142
+ | **Version** | 1.0 |
143
+ | **Status** | draft |
144
+ | **Platform** | {active_platform} |
145
+ | **Module** | {active_module} |
146
+ | **Service** | {active_service} |
147
+ | **Domain** | {domain} |
148
+ | **Business PRD** | [{TICKET-ID}]({relative-path-to-prd.md}) |
149
+ | **Figma** | {figma_url} |
150
+ | **Author** | {PO name or "AI-assisted"} |
151
+ | **Created** | {YYYY-MM-DD} |
152
+ | **Updated** | {YYYY-MM-DD} |
153
+
154
+ ---
155
+
156
+ # 1. Screen Inventory
157
+
158
+ | # | Screen Name | Entry Point | Figma Frame | Notes |
159
+ |---|-------------|-------------|-------------|-------|
160
+ | 1 | {Screen 1} | {how user arrives — e.g., tap CTA on Home} | [Frame]({figma_url}#screen1) | |
161
+ | 2 | {Screen 2} | {entry point} | [Frame]({figma_url}#screen2) | |
162
+
163
+ ---
164
+
165
+ # 2. Screen Specs
166
+
167
+ <!--
168
+ Repeat this block for every screen in the Screen Inventory.
169
+ Each screen must have: Layout, Component Inventory, Screen States, Actions & Navigation.
170
+ -->
171
+
172
+ ## Screen 1: {Screen Name}
173
+
174
+ **Figma**: [{Frame name}]({figma_frame_url})
175
+
176
+ ### Layout
177
+
178
+ {Describe the layout: grid columns, max-width container, section order, padding, key spacing values.
179
+ Reference design tokens where applicable (e.g., `spacing.md = 16px`, `color.surface`).}
180
+
181
+ ### Component Inventory
182
+
183
+ | Component (Figma) | Code Component | Import Path | States | Notes |
184
+ |---------------------|-----------------|------------------------|---------------------------------|--------------------|
185
+ | {Figma/Button/Primary} | Button | @/components/ui/Button | default, loading, disabled | |
186
+ | {Figma/Input/Text} | TextInput | @/components/ui/Input | default, focus, error, disabled | |
187
+ | {Figma/Card/Order} | OrderCard | @/features/{domain}/components/OrderCard | default, skeleton | |
188
+
189
+ ### Screen States
190
+
191
+ | State | Trigger | UI Behavior |
192
+ |-----------|-------------------------------------|--------------------------------------------------------------|
193
+ | default | Screen loaded, data available | {Describe full rendered appearance} |
194
+ | loading | API call in flight | {Skeleton layout / spinner position — reference component} |
195
+ | error | API failure or validation error | {Toast / inline message / error screen — exact copy TBD} |
196
+ | empty | API returns empty list / no data | {Empty state illustration + CTA text — e.g., "No orders yet. Start shopping →"} |
197
+ | success | Action completed (if applicable) | {Confirmation message / navigation / state change} |
198
+
199
+ ### Actions & Navigation
200
+
201
+ | Action | Trigger | Result |
202
+ |-----------------|--------------------------------|-------------------------------------------------|
203
+ | {Action name} | Tap/click {element name} | Navigate to {Screen N} / Open {Modal name} |
204
+ | {Action name} | Swipe left on {list item} | Show delete confirmation |
205
+ | {Back / Cancel} | Back gesture / Cancel button | Return to {previous screen} without saving |
206
+
207
+ ---
208
+
209
+ <!-- Repeat ## Screen N block for each additional screen -->
210
+
211
+ ---
212
+
213
+ # 3. Interaction Patterns
214
+
215
+ <!--
216
+ Web platform: include sections A + B. Remove section C.
217
+ App platform: include section C. Remove sections A + B.
218
+ -->
219
+
220
+ <!-- ═══════════════════════════ WEB ONLY ═══════════════════════════ -->
221
+
222
+ ## A. Responsive Behavior *(web only)*
223
+
224
+ | Breakpoint | Width | Layout Changes |
225
+ |------------|------------|----------------------------------------------------|
226
+ | Mobile | < 768px | {Single column, bottom navigation bar, CTA full-width} |
227
+ | Tablet | 768–1279px | {2-column grid, sidebar collapsed, tab navigation} |
228
+ | Desktop | ≥ 1280px | {Full layout, sidebar visible, max-width 1440px} |
229
+
230
+ ## B. Hover / Focus / Keyboard *(web only)*
231
+
232
+ | Element | Hover state | Focus state | Keyboard shortcut |
233
+ |----------------|-------------------------------|---------------------------------|-------------------|
234
+ | Primary button | Background → {color.hover} | Outline 2px {color.focus} | Enter / Space |
235
+ | Text input | Border → {color.border.hover} | Border → {color.primary}, label floats | Tab to focus |
236
+ | Dropdown | Background highlight | Same as hover + ring | Arrow keys to navigate |
237
+
238
+ <!-- ═══════════════════════════ APP ONLY ═══════════════════════════ -->
239
+
240
+ ## C. Gestures & Navigation *(app only)*
241
+
242
+ | Gesture | Screen / Element | Behavior |
243
+ |-------------------|---------------------------|-------------------------------------------------------|
244
+ | Back gesture (iOS swipe-right / Android back) | All screens | {Return to previous screen / Show "Discard changes?" dialog} |
245
+ | Pull-to-refresh | {Screen names} | Refresh data, spinner at top |
246
+ | Swipe left on row | {List item name} | Reveal {Delete / Archive} action |
247
+ | Long press | {Element name} | {Context menu / selection mode} |
248
+ | Pinch / zoom | {Image viewer} | Scale image, double-tap to reset |
249
+
250
+ ### Navigation Pattern *(app only)*
251
+
252
+ ```
253
+ {Draw the navigation stack for this feature, e.g.:
254
+ BottomTab(Home) → FeatureListPage → FeatureDetailPage → EditPage
255
+ BottomTab(Home) → FeatureListPage ↘ (modal) CreatePage
256
+ }
257
+ ```
258
+
259
+ Entry: {how the user enters this feature — tab / deeplink / push from another screen}
260
+ Exit: {how the user leaves — back stack / tab switch / deeplink out}
261
+
262
+ ### Platform Conventions *(app only)*
263
+
264
+ | Aspect | iOS behavior | Android behavior |
265
+ |--------------------------|-----------------------------------------|-----------------------------------------|
266
+ | Navigation bar | {Back button top-left, title centered} | {Up arrow top-left, title left-aligned} |
267
+ | Sheet / bottom modal | {UISheetPresentation, grabber visible} | {BottomSheet, drag handle} |
268
+ | Alert / confirm dialog | {UIAlertController, actions right-aligned} | {Material AlertDialog, actions left-aligned} |
269
+ | Loading indicator | {UIActivityIndicatorView, center} | {CircularProgressIndicator} |
270
+ | Toast / snackbar | {Custom toast, bottom center} | {Material Snackbar, bottom} |
271
+
272
+ ---
273
+
274
+ # 4. Platform Considerations
275
+
276
+ <!--
277
+ Web: include section A. App: include section B. Remove the non-applicable section.
278
+ -->
279
+
280
+ <!-- ═══════════════════════════ WEB ONLY ═══════════════════════════ -->
281
+
282
+ ## A. Accessibility *(web only)*
283
+
284
+ - [ ] All interactive elements reachable via Tab key — no keyboard traps
285
+ - [ ] Focus trap inside modal dialogs (Tab cycles within modal only)
286
+ - [ ] Icon-only buttons have `aria-label` describing the action
287
+ - [ ] Dynamic content updates (loading → loaded) announce via `aria-live`
288
+ - [ ] Color contrast meets WCAG AA: text ≥ 4.5:1, large text ≥ 3:1
289
+ - [ ] Form inputs have visible labels (not placeholder-only)
290
+ - [ ] Error messages linked to inputs via `aria-describedby`
291
+
292
+ <!-- ═══════════════════════════ APP ONLY ═══════════════════════════ -->
293
+
294
+ ## B. Device & OS *(app only)*
295
+
296
+ - [ ] Safe area insets applied on all screens — top (status bar) and bottom (home indicator)
297
+ - [ ] Minimum touch target: 44×44pt (iOS) / 48×48dp (Android)
298
+ - [ ] Tested on small screen: 375pt wide (iPhone SE) / 360dp wide (common Android)
299
+ - [ ] Deep link entry: `{scheme}://{host}/{path}` → lands on {screen name} with {param} pre-filled
300
+ - [ ] Permission gates: {list permissions needed — Camera / Location / Notification}
301
+ - {Permission}: requested on {screen name} with rationale copy: "{copy TBD}"
302
+ - [ ] Offline / no-network behavior:
303
+ - {Screen name}: show cached data + offline banner
304
+ - {Action name}: disable button, show tooltip "Requires connection"
305
+ - [ ] Dark mode: all screens tested in dark mode — no hardcoded colors
306
+
307
+ ---
308
+
309
+ # 5. AC-UI — Design Acceptance Criteria
310
+
311
+ > Reviewed and signed off by **PO + Designer** together before BDD generation.
312
+ > These complement (not replace) the business-level AC in the [Business PRD]({prd-path}).
313
+
314
+ | ID | Acceptance Criterion | Verified by |
315
+ |--------|--------------------------------------------------------------------------------|-----------------|
316
+ | AC-UI1 | All screens match approved Figma frames within design-system tolerances | Designer |
317
+ | AC-UI2 | Loading skeleton/spinner appears within 200ms of initiating any API call | QA |
318
+ | AC-UI3 | All error messages are visible, descriptive, and include a recovery action | PO |
319
+ | AC-UI4 | Empty states include an illustration and a clear call-to-action | PO + Designer |
320
+ | AC-UI5 | {Platform-specific — e.g., web: "All screens pass WCAG AA contrast check"} | QA |
321
+ | AC-UI6 | {Platform-specific — e.g., app: "Back gesture on all screens returns to correct previous screen"} | QA |
322
+ | AC-UI7 | {Feature-specific UI criterion from Business PRD wireframe section} | PO |
323
+
324
+ ---
325
+
326
+ # Appendix
327
+
328
+ ## Figma Summary
329
+
330
+ | Screen | Figma Frame | Designer Status |
331
+ |-----------------|-------------------------------|------------------------|
332
+ | {Screen 1} | [Link]({figma_frame_url}) | ✅ Ready / ⏳ WIP / ❌ Missing |
333
+ | {Screen 2} | [Link]({figma_frame_url}) | ✅ Ready / ⏳ WIP / ❌ Missing |
334
+
335
+ ## Design Tokens Referenced
336
+
337
+ | Token | Value | Used in |
338
+ |-----------------------|---------------|---------------------------------|
339
+ | `color.primary` | {#hex} | Primary buttons, links, active states |
340
+ | `color.surface` | {#hex} | Card backgrounds |
341
+ | `spacing.md` | {16px / 4} | Standard vertical gap |
342
+ | `typography.heading2` | {font/size} | Screen titles |
343
+
344
+ ## References
345
+
346
+ - [{TICKET-ID}]({prd-path}) — Business PRD (source of AC, UC, BR)
347
+ - {[Other Design Spec](./other-ds.md) — if this feature shares screens}
348
+
349
+ ## AI Assumptions
350
+
351
+ > Each assumption below was made because PO input was incomplete.
352
+ > PO must review and confirm before sign-off.
353
+
354
+ - {Assumption 1 — [AI DRAFT]}
355
+
356
+ ---
357
+
358
+ ## Changelog
359
+
360
+ | Version | Date | Changes |
361
+ |---------|--------------|-----------------|
362
+ | 1.0 | {YYYY-MM-DD} | Initial version |
363
+
364
+ <!--
365
+ NEXT STEPS:
366
+ 1. Share with Designer — verify Figma links, update component inventory.
367
+ 2. PO + Designer sign off: change Status → "approved".
368
+ 3. Run /generate-bdd "{prd-file}" — BDD uses AC-UI from this spec for FE scenarios.
369
+ -->
370
+ ````
371
+
372
+ ---
373
+
374
+ ## Quality Checklist *(verify before writing)*
375
+
376
+ - [ ] Every screen in Screen Inventory has a complete Screen Spec in Section 2
377
+ - [ ] Every screen has at minimum: default, loading, error states defined
378
+ - [ ] All Figma components mapped in Component Inventory — unmapped flagged as `[NEW]` or `[TODO]`
379
+ - [ ] Only the platform-relevant section generated in Section 3 (no web section in app docs, and vice versa)
380
+ - [ ] Only the platform-relevant section generated in Section 4
381
+ - [ ] AC-UI items are testable (clear pass/fail, not "looks good")
382
+ - [ ] Business PRD cross-reference link is valid relative path
383
+ - [ ] If `figma_url = "TBD"` → AI Assumption added in Appendix
384
+
385
+ ---
386
+
387
+ ## Output
388
+
389
+ {{include:steps/report-footer.md}}
390
+
391
+ ```
392
+ /generate-design-spec Complete — {TICKET-ID} [{active_platform}]
393
+ ---
394
+ Status : ✅ Complete
395
+ Output Artifacts:
396
+ created {paths.design_spec_dir}/{domain}/{TICKET-ID}-design-spec-{active_platform}-{slug}.md (v1.0)
397
+ Next : Share with Designer → add Figma links → PO + Designer sign-off (Status: approved)
398
+ → /generate-bdd {prd-file} (generates BDD per service; reads AC-UI from Design Spec)
399
+ ```
@@ -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
 
@@ -306,6 +393,27 @@ Never leave TICKET-ID as plain text if a corresponding PRD file exists in `{path
306
393
 
307
394
  ---
308
395
 
396
+ ## Platform Strategy — PRD is platform-agnostic (Option C)
397
+
398
+ PRD mô tả **WHAT** (yêu cầu nghiệp vụ) — không phụ thuộc vào platform nào implement.
399
+ Viết AC theo business outcome, không theo UI/API details:
400
+
401
+ | ✅ Viết trong PRD (platform-agnostic) | ❌ Không viết trong PRD |
402
+ |---|---|
403
+ | "Đăng nhập thành công → truy cập được tính năng" | "Click button → show toast" ← Design Spec |
404
+ | "Sai password 5 lần → khoá tài khoản 30 phút" | "API trả về JWT token" ← Tech Docs |
405
+ | "Session hết hạn → yêu cầu xác thực lại" | "Hiển thị spinner khi loading" ← Design Spec |
406
+
407
+ **Một PRD phục vụ tất cả platform:**
408
+ - **FE/App team** → đọc PRD + Design Spec → `/generate-bdd` (UI-level scenarios)
409
+ - **BE team** → đọc PRD trực tiếp → `/generate-bdd` (API-level scenarios)
410
+ - Design Spec là tài liệu riêng cho FE/App — **không trộn vào PRD**
411
+
412
+ Khi viết AC, nếu PO đề cập chi tiết UI (màu sắc, layout, animation) → nhắc nhở:
413
+ *"Chi tiết UI này thuộc về Design Spec, không thuộc PRD. Ghi nhận lại để tạo Design Spec sau."*
414
+
415
+ ---
416
+
309
417
  ## Generate
310
418
 
311
419
  Write `{paths.prd_dir}/{domain}/{TICKET-ID}-{slug}.md` using the structure below.
@@ -328,6 +436,7 @@ Write `{paths.prd_dir}/{domain}/{TICKET-ID}-{slug}.md` using the structure below
328
436
  | **Domain** | {domain} |
329
437
  | **Created** | {YYYY-MM-DD} |
330
438
  | **Updated** | {YYYY-MM-DD} |
439
+ | **API Source** | *(bỏ trống nếu greenfield — thêm `existing` nếu API đã tồn tại trên hệ thống)* |
331
440
 
332
441
  ---
333
442
 
@@ -412,6 +521,23 @@ flowchart TD
412
521
 
413
522
  - {[TICKET-ID](./TICKET-ID-slug.md) — relationship description}
414
523
 
524
+ ## Existing API Contract *(chỉ điền khi API Source = existing)*
525
+
526
+ > API đã tồn tại trên hệ thống. PO ghi lại contract để BDD generation dùng trực tiếp —
527
+ > không cần tổng hợp từ FE/App BDD, không cần T7 sign-off gate.
528
+
529
+ | Method | Path | Auth | Request | Response |
530
+ |--------|------|------|---------|----------|
531
+ | {GET/POST/PUT/DELETE} | {/api/v1/path} | {Bearer / none} | `{ field: type }` | `{ field: type }` |
532
+
533
+ **Error responses:**
534
+
535
+ | HTTP Status | Error Code | Khi nào xảy ra |
536
+ |-------------|------------|----------------|
537
+ | {4xx/5xx} | {ERR_CODE} | {condition} |
538
+
539
+ ---
540
+
415
541
  ## AI Assumptions
416
542
 
417
543
  > Assumptions AI made when information was incomplete. Needs PO review and confirmation.
@@ -480,7 +606,8 @@ Suggest the logical next command based on workflow phase:
480
606
  | /define-product | `/generate-prd {product-definition-file}` |
481
607
  | /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
482
608
  | /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
483
- | /review-context (PRD) | `/generate-bdd {prd-file}` if APPROVED; fix PRD if NEEDS_FIX |
609
+ | /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 |
610
+ | /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
484
611
  | /generate-bdd | `/review-context {feature-file}` to verify coverage |
485
612
  | /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
486
613
  | /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
@@ -494,6 +621,11 @@ Suggest the logical next command based on workflow phase:
494
621
  | /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
495
622
  | /fix-bug | Create PR and link to ticket |
496
623
  | /debug | `/fix-bug {ticket-id}` if fix needed |
624
+ | /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
625
+ | /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
626
+ | /learn | Continue working — lesson applies on next command |
627
+ | /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
628
+ | /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
497
629
 
498
630
  Format the footer as:
499
631
  ```
@@ -41,6 +41,27 @@ Never leave TICKET-ID as plain text if a corresponding PRD file exists in `{path
41
41
 
42
42
  ---
43
43
 
44
+ ## Platform Strategy — PRD is platform-agnostic (Option C)
45
+
46
+ PRD mô tả **WHAT** (yêu cầu nghiệp vụ) — không phụ thuộc vào platform nào implement.
47
+ Viết AC theo business outcome, không theo UI/API details:
48
+
49
+ | ✅ Viết trong PRD (platform-agnostic) | ❌ Không viết trong PRD |
50
+ |---|---|
51
+ | "Đăng nhập thành công → truy cập được tính năng" | "Click button → show toast" ← Design Spec |
52
+ | "Sai password 5 lần → khoá tài khoản 30 phút" | "API trả về JWT token" ← Tech Docs |
53
+ | "Session hết hạn → yêu cầu xác thực lại" | "Hiển thị spinner khi loading" ← Design Spec |
54
+
55
+ **Một PRD phục vụ tất cả platform:**
56
+ - **FE/App team** → đọc PRD + Design Spec → `/generate-bdd` (UI-level scenarios)
57
+ - **BE team** → đọc PRD trực tiếp → `/generate-bdd` (API-level scenarios)
58
+ - Design Spec là tài liệu riêng cho FE/App — **không trộn vào PRD**
59
+
60
+ Khi viết AC, nếu PO đề cập chi tiết UI (màu sắc, layout, animation) → nhắc nhở:
61
+ *"Chi tiết UI này thuộc về Design Spec, không thuộc PRD. Ghi nhận lại để tạo Design Spec sau."*
62
+
63
+ ---
64
+
44
65
  ## Generate
45
66
 
46
67
  Write `{paths.prd_dir}/{domain}/{TICKET-ID}-{slug}.md` using the structure below.
@@ -63,6 +84,7 @@ Write `{paths.prd_dir}/{domain}/{TICKET-ID}-{slug}.md` using the structure below
63
84
  | **Domain** | {domain} |
64
85
  | **Created** | {YYYY-MM-DD} |
65
86
  | **Updated** | {YYYY-MM-DD} |
87
+ | **API Source** | *(bỏ trống nếu greenfield — thêm `existing` nếu API đã tồn tại trên hệ thống)* |
66
88
 
67
89
  ---
68
90
 
@@ -147,6 +169,23 @@ flowchart TD
147
169
 
148
170
  - {[TICKET-ID](./TICKET-ID-slug.md) — relationship description}
149
171
 
172
+ ## Existing API Contract *(chỉ điền khi API Source = existing)*
173
+
174
+ > API đã tồn tại trên hệ thống. PO ghi lại contract để BDD generation dùng trực tiếp —
175
+ > không cần tổng hợp từ FE/App BDD, không cần T7 sign-off gate.
176
+
177
+ | Method | Path | Auth | Request | Response |
178
+ |--------|------|------|---------|----------|
179
+ | {GET/POST/PUT/DELETE} | {/api/v1/path} | {Bearer / none} | `{ field: type }` | `{ field: type }` |
180
+
181
+ **Error responses:**
182
+
183
+ | HTTP Status | Error Code | Khi nào xảy ra |
184
+ |-------------|------------|----------------|
185
+ | {4xx/5xx} | {ERR_CODE} | {condition} |
186
+
187
+ ---
188
+
150
189
  ## AI Assumptions
151
190
 
152
191
  > Assumptions AI made when information was incomplete. Needs PO review and confirmation.