@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.
- package/ARCHITECTURE.md +6 -2
- package/bin/index.js +105 -0
- package/commands/debug.md +189 -1
- package/commands/debug.tmpl +16 -0
- package/commands/define-product.md +94 -1
- package/commands/fix-bug.md +190 -1
- package/commands/fix-bug.tmpl +17 -0
- package/commands/generate-bdd.md +314 -14
- package/commands/generate-bdd.tmpl +220 -13
- package/commands/generate-code.md +191 -3
- package/commands/generate-code.tmpl +97 -2
- package/commands/generate-design-spec.md +811 -0
- package/commands/generate-design-spec.tmpl +399 -0
- package/commands/generate-prd.md +133 -1
- package/commands/generate-prd.tmpl +39 -0
- package/commands/generate-spec-manifest.md +576 -0
- package/commands/generate-spec-manifest.tmpl +164 -0
- package/commands/generate-tech-docs.md +116 -2
- package/commands/generate-tech-docs.tmpl +22 -1
- package/commands/generate-tests.md +94 -1
- package/commands/learn.md +554 -0
- package/commands/learn.tmpl +63 -0
- package/commands/propose-scenario.md +521 -0
- package/commands/propose-scenario.tmpl +109 -0
- package/commands/refine-prd.md +94 -1
- package/commands/report-bug.md +543 -0
- package/commands/report-bug.tmpl +131 -0
- package/commands/review-code.md +190 -1
- package/commands/review-code.tmpl +17 -0
- package/commands/review-context.md +134 -1
- package/commands/review-context.tmpl +40 -0
- package/commands/review-tech-docs.md +176 -5
- package/commands/review-tech-docs.tmpl +82 -4
- package/commands/run-tests.md +119 -1
- package/commands/run-tests.tmpl +25 -0
- package/commands/setup-ai-first.md +142 -4
- package/commands/setup-ai-first.tmpl +135 -3
- package/commands/smoke-test.md +94 -1
- package/commands/sync.md +405 -0
- package/commands/sync.tmpl +345 -0
- package/commands/update-framework.md +211 -0
- package/commands/update-framework.tmpl +151 -0
- package/commands/validate-traces.md +152 -3
- package/commands/validate-traces.tmpl +58 -2
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +189 -1
- package/core/commands/define-product.md +94 -1
- package/core/commands/fix-bug.md +190 -1
- package/core/commands/generate-bdd.md +314 -14
- package/core/commands/generate-code.md +191 -3
- package/core/commands/generate-design-spec.md +811 -0
- package/core/commands/generate-prd.md +133 -1
- package/core/commands/generate-spec-manifest.md +576 -0
- package/core/commands/generate-tech-docs.md +116 -2
- package/core/commands/generate-tests.md +94 -1
- package/core/commands/learn.md +554 -0
- package/core/commands/propose-scenario.md +521 -0
- package/core/commands/refine-prd.md +94 -1
- package/core/commands/report-bug.md +543 -0
- package/core/commands/review-code.md +190 -1
- package/core/commands/review-context.md +134 -1
- package/core/commands/review-tech-docs.md +176 -5
- package/core/commands/run-tests.md +119 -1
- package/core/commands/setup-ai-first.md +142 -4
- package/core/commands/smoke-test.md +94 -1
- package/core/commands/sync.md +405 -0
- package/core/commands/update-framework.md +211 -0
- package/core/commands/validate-traces.md +152 -3
- package/core/skills/code/SKILL.md +101 -2
- package/core/skills/debug/SKILL.md +108 -3
- package/core/skills/design-spec/SKILL.md +507 -0
- package/core/skills/discovery/SKILL.md +94 -1
- package/core/skills/prd/SKILL.md +14 -2
- package/core/skills/setup-ai-first/SKILL.md +7 -1
- package/core/skills/spec/SKILL.md +14 -2
- package/core/skills/test/SKILL.md +195 -3
- package/core/steps/capture-lesson.md +79 -0
- package/core/steps/context-loader.md +87 -0
- package/core/steps/report-footer.md +7 -1
- package/core/templates/design-spec.template.md +209 -0
- package/core/templates/project-context.yaml +40 -0
- package/package.json +1 -1
- package/skills/code/SKILL.md +101 -2
- package/skills/debug/SKILL.md +108 -3
- package/skills/design-spec/SKILL.md +507 -0
- package/skills/design-spec/SKILL.tmpl +95 -0
- package/skills/discovery/SKILL.md +94 -1
- package/skills/prd/SKILL.md +14 -2
- package/skills/setup-ai-first/SKILL.md +7 -1
- package/skills/spec/SKILL.md +14 -2
- package/skills/test/SKILL.md +195 -3
- package/steps/capture-lesson.md +79 -0
- package/steps/context-loader.md +87 -0
- package/steps/report-footer.md +7 -1
- package/templates/design-spec.template.md +209 -0
- package/templates/project-context.yaml +40 -0
|
@@ -129,6 +129,7 @@ Read `.agent/project-context.yaml`. Extract and store:
|
|
|
129
129
|
- `paths.core_entities` → path to core-entities.md
|
|
130
130
|
- `paths.tech_docs_dir` → technical documentation root
|
|
131
131
|
- `paths.trace_dir` → trace state directory
|
|
132
|
+
- `paths.design_spec_dir` → Design Spec documents root (FE/App only)
|
|
132
133
|
|
|
133
134
|
If `paths` section is absent, use these defaults:
|
|
134
135
|
- `specs_dir` = `specs/bdd`
|
|
@@ -140,11 +141,75 @@ If `paths` section is absent, use these defaults:
|
|
|
140
141
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
141
142
|
- `tech_docs_dir` = `specs/tech-docs`
|
|
142
143
|
- `trace_dir` = `.trace`
|
|
144
|
+
- `design_spec_dir` = `specs/design-spec`
|
|
143
145
|
|
|
144
146
|
If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
|
|
145
147
|
|
|
146
148
|
---
|
|
147
149
|
|
|
150
|
+
## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
|
|
151
|
+
|
|
152
|
+
*Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
|
|
153
|
+
|
|
154
|
+
If `services` section is present:
|
|
155
|
+
|
|
156
|
+
**1. Detect active domain** (in priority order):
|
|
157
|
+
- Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
|
|
158
|
+
- Extract from target file path: segment immediately after `prd_dir` base path
|
|
159
|
+
*(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
|
|
160
|
+
- If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
|
|
161
|
+
|
|
162
|
+
**2. Route to service** — if active domain matches a key in `services`:
|
|
163
|
+
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
164
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
165
|
+
- Store `active_service` = `services.{domain}.path`
|
|
166
|
+
- Store `active_service_module` = `services.{domain}.module`
|
|
167
|
+
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
168
|
+
|
|
169
|
+
**3. Fallback** — if domain not detected or no matching service key:
|
|
170
|
+
- Keep default paths from Step 1
|
|
171
|
+
- Set `active_service = unresolved`
|
|
172
|
+
|
|
173
|
+
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
174
|
+
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
175
|
+
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
176
|
+
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
177
|
+
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
178
|
+
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
179
|
+
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
180
|
+
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
181
|
+
|
|
182
|
+
> **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.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Step 1.6 — [SERVICE CONVENTIONS] Load service-specific conventions (umbrella mode)
|
|
187
|
+
|
|
188
|
+
*Skip this step entirely if `active_service` is `"unresolved"` or context is single-service mode.*
|
|
189
|
+
|
|
190
|
+
When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-service/`):
|
|
191
|
+
|
|
192
|
+
**1. Locate service config** — try in priority order:
|
|
193
|
+
- `{active_service}/.agent/project-context.yaml`
|
|
194
|
+
- `{active_service}/project-context.yaml`
|
|
195
|
+
|
|
196
|
+
**2. If found, override with service-specific values:**
|
|
197
|
+
|
|
198
|
+
| Variable | Source |
|
|
199
|
+
|----------|--------|
|
|
200
|
+
| `conventions.test_command` | service's `conventions.test_command` |
|
|
201
|
+
| `conventions.build_command` | service's `conventions.build_command` |
|
|
202
|
+
| `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` — default: `{active_service}/.trace` |
|
|
203
|
+
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
204
|
+
|
|
205
|
+
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
206
|
+
- Shell commands (`/run-tests`, `/generate-tests`) run **from within** `service_root`
|
|
207
|
+
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
208
|
+
|
|
209
|
+
**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).
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
148
213
|
## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
|
|
149
214
|
|
|
150
215
|
If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
|
|
@@ -235,6 +300,25 @@ These two variables (`active_module`, `platform_type`) are the canonical source
|
|
|
235
300
|
|
|
236
301
|
---
|
|
237
302
|
|
|
303
|
+
## Step 6.7 — [GUARDRAILS] Load Project Lessons (conditional)
|
|
304
|
+
|
|
305
|
+
*Accumulated mistakes the AI must not repeat in this project. These are added over time via `/learn`
|
|
306
|
+
or accepted during `/review-code`, `/fix-bug`, `/debug`.*
|
|
307
|
+
|
|
308
|
+
Resolve the lessons file path:
|
|
309
|
+
- Use `paths.lessons_file` if set (may be service-overridden in umbrella mode, Step 1.6)
|
|
310
|
+
- Else default `specs/domain-knowledge/lessons-learned.md`
|
|
311
|
+
- In umbrella/service mode (when `service_root` is set), if `paths.lessons_file` is unset, default to `{service_root}/.agent/project-lessons.md`
|
|
312
|
+
|
|
313
|
+
If the file exists, read it and store ALL lessons as **ACTIVE GUARDRAILS** for the session:
|
|
314
|
+
- Treat each lesson's **Rule** as a hard constraint — same priority as CLAUDE.md coding standards (Step 3).
|
|
315
|
+
- 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).
|
|
316
|
+
- If a generated output would violate a lesson → correct it **before** presenting, and note which lesson (`L-NNN`) was applied.
|
|
317
|
+
|
|
318
|
+
If the file does not exist → skip silently (no lessons captured yet).
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
238
322
|
## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
|
|
239
323
|
|
|
240
324
|
After loading all context, synthesize and output a compact summary block.
|
|
@@ -250,6 +334,9 @@ Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Ser
|
|
|
250
334
|
Ticket : {ticket_prefix}-
|
|
251
335
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
252
336
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
337
|
+
Lessons : {loaded — N guardrails | none yet}
|
|
338
|
+
Service : {active_service} ({active_service_module}) | single-service
|
|
339
|
+
Svc Root : {service_root} — conventions + trace_dir loaded from service config | —
|
|
253
340
|
Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
254
341
|
```
|
|
255
342
|
|
|
@@ -271,6 +358,194 @@ After completing all steps, you have loaded:
|
|
|
271
358
|
Proceed to the next step of the calling command.
|
|
272
359
|
|
|
273
360
|
|
|
361
|
+
> **Tester proposals (optional input):** before generating, check `{paths.bdd_proposals_dir}/` (default `{spec_source}/feedback/bdd-proposals/`) for scenarios proposed by testers via `/propose-scenario` that map to this UC's ACs. Incorporate any the PO/Dev has accepted — then the tester's draft is removed/archived from `feedback/`. Skip if the folder is empty.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Repo Mode Detection
|
|
366
|
+
|
|
367
|
+
After loading context, determine which mode to operate in:
|
|
368
|
+
|
|
369
|
+
- **Spec repo mode**: `project-context.yaml` has NO `services` section OR `setup.mode: spec`
|
|
370
|
+
- **Umbrella mode**: `project-context.yaml` HAS `services` section AND `setup.mode: umbrella`
|
|
371
|
+
|
|
372
|
+
→ Spec repo mode → proceed to **Platform Selection** below (skip Service Detection)
|
|
373
|
+
→ Umbrella mode → proceed to **Service Detection** below (skip Platform Selection)
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Platform Selection (Spec Repo Mode Only)
|
|
378
|
+
|
|
379
|
+
*Skip this section if running in umbrella mode.*
|
|
380
|
+
|
|
381
|
+
Ask the user to select the target platform:
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
Which platform is this BDD for?
|
|
385
|
+
1. web — FE/Web (React, Next.js, Angular, Vue, Nuxt)
|
|
386
|
+
2. app — Mobile (Flutter, React Native, iOS, Android)
|
|
387
|
+
3. system — System/BE BDD (synthesized from existing web + app BDDs)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Wait for user selection. Set `active_platform` = chosen value.
|
|
391
|
+
|
|
392
|
+
**Output path (spec repo mode):**
|
|
393
|
+
`{paths.specs_dir}/{domain}/{active_platform}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
394
|
+
|
|
395
|
+
**Platform vocabulary:**
|
|
396
|
+
|
|
397
|
+
| Platform | "user action" | "type/input" | "observe" | "navigate" |
|
|
398
|
+
|---|---|---|---|---|
|
|
399
|
+
| web | "clicks" | "types into" / "enters" | "sees" / "the page shows" | "navigates to" / "goes to" |
|
|
400
|
+
| app | "taps" | "enters" / "inputs" | "sees" / "the screen shows" | "navigates to" / "opens" |
|
|
401
|
+
| system | N/A — use business events | — | "the system returns" / "receives response" | — |
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## System BDD Synthesis (active_platform = system)
|
|
406
|
+
|
|
407
|
+
*Only applies when platform = system. Skip for web and app.*
|
|
408
|
+
|
|
409
|
+
### Step S0 — Brownfield Check
|
|
410
|
+
|
|
411
|
+
Check the source PRD Metadata table for `| **API Source** | existing |`.
|
|
412
|
+
|
|
413
|
+
**Nếu `API Source: existing`:**
|
|
414
|
+
- API contract đã được PO ghi trong phần "Existing API Contract" của PRD.
|
|
415
|
+
- **Skip Steps S1–S3** — không cần scan FE/App BDD, không cần conflict resolution.
|
|
416
|
+
- Dùng bảng "Existing API Contract" trong PRD làm contract input cho Step S4.
|
|
417
|
+
- Set `# @trace.api_source: existing` trong header của file system BDD được gen.
|
|
418
|
+
|
|
419
|
+
**Nếu `API Source` không có hoặc không phải `existing`:**
|
|
420
|
+
- Tiếp tục Steps S1–S3 (normal synthesis flow).
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
### Step S1 — Scan available FE/App BDDs
|
|
425
|
+
|
|
426
|
+
Search for existing BDDs for this TICKET-ID:
|
|
427
|
+
- Web BDDs: `{paths.specs_dir}/{domain}/web/{TICKET-ID}-*.feature`
|
|
428
|
+
- App BDDs: `{paths.specs_dir}/{domain}/app/{TICKET-ID}-*.feature`
|
|
429
|
+
|
|
430
|
+
Classify the feature:
|
|
431
|
+
|
|
432
|
+
| Condition | Mode |
|
|
433
|
+
|---|---|
|
|
434
|
+
| Both web + app BDDs found | **Multi-platform** — synthesize from both |
|
|
435
|
+
| Only web BDD found | **Web-only** — synthesize from web |
|
|
436
|
+
| Only app BDD found | **App-only** — synthesize from app |
|
|
437
|
+
| No FE/App BDDs found | **Backend-only** — gen directly from PRD |
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### Step S2 — Extract expected contracts per platform
|
|
442
|
+
|
|
443
|
+
For each found BDD file, extract:
|
|
444
|
+
- **Triggers**: what user actions call the backend? (map to logical "request" events)
|
|
445
|
+
- **Expected response data**: what fields/shape does each `Then` clause need from the system?
|
|
446
|
+
- **Error signals**: what error states must the backend signal?
|
|
447
|
+
- **Business rules**: what invariants does each platform assume the system enforces?
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
### Step S3 — Cross-Platform Conflict Check (multi-platform mode only)
|
|
452
|
+
|
|
453
|
+
*Skip if web-only, app-only, or backend-only.*
|
|
454
|
+
|
|
455
|
+
Compare the extracted contracts across platforms. Flag a conflict if any of these differ:
|
|
456
|
+
|
|
457
|
+
| Conflict type | Example |
|
|
458
|
+
|---|---|
|
|
459
|
+
| **Response shape mismatch** | Web expects `{ token, redirect_url }`, App expects `{ token, user_profile }` |
|
|
460
|
+
| **Error semantics mismatch** | Web expects HTTP 423 for lock, App expects custom error code `ACC_LOCKED` |
|
|
461
|
+
| **Business rule contradiction** | Web BDD says "lock after 5 attempts", App BDD says "lock after 3 attempts" |
|
|
462
|
+
| **Data field conflict** | Web expects `expires_in: seconds`, App expects `expires_at: ISO timestamp` |
|
|
463
|
+
|
|
464
|
+
**If conflicts detected → CHECKPOINT (mandatory, cannot skip):**
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
⚠️ CROSS-PLATFORM CONTRACT CONFLICT
|
|
468
|
+
──────────────────────────────────────────────────────────────────
|
|
469
|
+
Feature : {TICKET-ID} — {UC name}
|
|
470
|
+
|
|
471
|
+
Conflict 1: Response shape mismatch
|
|
472
|
+
Web BDD (Then): user sees dashboard → implies { token, redirect_url }
|
|
473
|
+
App BDD (Then): app navigates to HomeScreen → implies { token, user_profile }
|
|
474
|
+
|
|
475
|
+
Resolution options:
|
|
476
|
+
A — Union response
|
|
477
|
+
BE returns all fields: { token, redirect_url, user_profile }
|
|
478
|
+
Clients ignore fields they don't use. Simple, slight over-fetch.
|
|
479
|
+
B — Platform hint in request
|
|
480
|
+
Client sends X-Platform: web|app in header, BE tailors response.
|
|
481
|
+
Cleaner responses, more BE logic.
|
|
482
|
+
C — Separate endpoints
|
|
483
|
+
POST /auth/login/web and POST /auth/login/app
|
|
484
|
+
Maximum flexibility, more endpoints to maintain.
|
|
485
|
+
D — Custom: describe your approach
|
|
486
|
+
──────────────────────────────────────────────────────────────────
|
|
487
|
+
Choose resolution for each conflict (A/B/C/D):
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Wait for PO's resolution per conflict. Record each decision as a `# @system.resolution:` annotation in the generated system BDD file.
|
|
491
|
+
|
|
492
|
+
**If no conflicts → proceed to Step S4 directly.**
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### Step S4 — Generate System BDD scenarios
|
|
497
|
+
|
|
498
|
+
Generate scenarios based on mode and resolved conflicts:
|
|
499
|
+
|
|
500
|
+
- **Multi-platform**: synthesize from both web + app contracts, applying resolved resolutions
|
|
501
|
+
- **Web-only / App-only**: derive from the single platform's contracts
|
|
502
|
+
- **Backend-only**: derive directly from PRD AC/BR using business event language (not HTTP)
|
|
503
|
+
|
|
504
|
+
System BDD step vocabulary (always use — regardless of FE/App vocabulary):
|
|
505
|
+
- Triggers: "the system receives {event}" / "a {actor} submits {action}"
|
|
506
|
+
- Assertions: "the system returns {data}" / "the system signals {error}" / "the system stores {state}"
|
|
507
|
+
- Do NOT use UI words (click, tap, see, navigate) in system BDD
|
|
508
|
+
|
|
509
|
+
**If multi-platform with resolution A (union):**
|
|
510
|
+
- System BDD shows the full response contract: all fields from all platforms
|
|
511
|
+
- Add comment: `# @system.resolution: union — clients receive all fields`
|
|
512
|
+
|
|
513
|
+
**If resolution B (platform hint):**
|
|
514
|
+
- Write separate `Scenario Outline` using Examples table for `web` vs `app` response variants
|
|
515
|
+
- Add comment: `# @system.resolution: platform-hint — X-Platform header determines response shape`
|
|
516
|
+
|
|
517
|
+
**If resolution C (separate endpoints):**
|
|
518
|
+
- Write separate Scenarios for each endpoint
|
|
519
|
+
- Note the endpoint split explicitly in the SCOPE section
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## Service Detection (Umbrella Mode Only)
|
|
524
|
+
|
|
525
|
+
*Skip this section if running in spec repo mode.*
|
|
526
|
+
|
|
527
|
+
Read the PRD Metadata table for `| **Service** |` and `| **Module** |` rows.
|
|
528
|
+
|
|
529
|
+
| Condition | Action |
|
|
530
|
+
|---|---|
|
|
531
|
+
| PRD has `Service` row AND value is not "default" | Use it as `active_service` + `active_module`. Load catalog for that module. |
|
|
532
|
+
| PRD has no `Service` row AND `services` defined in project-context.yaml | Ask: "Which service is this BDD for?" (list services, wait for selection) |
|
|
533
|
+
| Single-service project (no `services` array) | `active_service = "default"`, `active_module = tech_stack.module` |
|
|
534
|
+
|
|
535
|
+
**Output path (umbrella mode):**
|
|
536
|
+
- `active_service = "default"` → `{paths.specs_dir}/{domain}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
537
|
+
- `active_service ≠ "default"` → `{paths.specs_dir}/{domain}/{active_service}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
538
|
+
|
|
539
|
+
**Platform vocabulary** — adapt BDD step wording based on `active_module`:
|
|
540
|
+
|
|
541
|
+
| Platform type | Modules | "click" | "type" | "see" | "navigate" |
|
|
542
|
+
|---|---|---|---|---|---|
|
|
543
|
+
| Web | react, nextjs, vue, nuxt, angular | "clicks" | "types into" / "enters" | "sees" / "the page shows" | "navigates to" / "goes to" |
|
|
544
|
+
| Mobile | flutter, react-native, ios-swiftui, android-compose | "taps" | "enters" / "inputs" | "sees" / "the screen shows" | "navigates to" / "opens" |
|
|
545
|
+
| Backend / API | java-spring, golang, dotnet, php-laravel | *(no UI steps — use)* "submits a request" / "calls the API" | — | "receives response" / "the system returns" | — |
|
|
546
|
+
|
|
547
|
+
Apply this vocabulary silently when writing Gherkin steps. Do NOT mix web and mobile terms in the same feature file.
|
|
548
|
+
|
|
274
549
|
---
|
|
275
550
|
|
|
276
551
|
## Orchestration Check
|
|
@@ -307,7 +582,9 @@ After generating all `.feature` and `.tsv` files for the assigned UC, return the
|
|
|
307
582
|
|
|
308
583
|
Before generating, check for existing `.feature` files for this PRD:
|
|
309
584
|
|
|
310
|
-
1.
|
|
585
|
+
1. Resolve the search path based on mode:
|
|
586
|
+
- **Spec repo mode**: `{paths.specs_dir}/{domain}/{active_platform}/{TICKET-ID}-UC*.feature`
|
|
587
|
+
- **Umbrella mode**: `{paths.specs_dir}/{domain}/{TICKET-ID}-UC*.feature` (or with `{active_service}/` if multi-service)
|
|
311
588
|
2. Read current PRD `| **Version** |` from metadata (e.g., `1.2`).
|
|
312
589
|
|
|
313
590
|
**If no existing feature files** → fresh generation, proceed normally. Use PRD version as `@trace.prd_version`.
|
|
@@ -410,7 +687,12 @@ CHECKPOINT: "Does this outline look correct? Do you want to add or remove any SC
|
|
|
410
687
|
|
|
411
688
|
## Generate
|
|
412
689
|
|
|
413
|
-
|
|
690
|
+
**Output path by mode:**
|
|
691
|
+
- **Spec repo mode**: `{paths.specs_dir}/{domain}/{active_platform}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
692
|
+
- **Umbrella mode (single-service)**: `{paths.specs_dir}/{domain}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
693
|
+
- **Umbrella mode (multi-service)**: `{paths.specs_dir}/{domain}/{active_service}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
694
|
+
|
|
695
|
+
For each UC, write to the resolved path above. Use vocabulary for the active platform (from Platform Selection or Service Detection).
|
|
414
696
|
|
|
415
697
|
```gherkin
|
|
416
698
|
# ============================================================
|
|
@@ -418,8 +700,9 @@ For each UC, write `{paths.specs_dir}/{domain}/{TICKET-ID}-UC{N}-{slug}.feature`
|
|
|
418
700
|
# @trace.title: <Feature name>
|
|
419
701
|
# @trace.revision: 1 ← static field; use @trace.bdd_version for version tracking (incremented by /review-context --fix or --resume)
|
|
420
702
|
# @trace.domain: <domain>
|
|
421
|
-
# @trace.
|
|
422
|
-
# @trace.
|
|
703
|
+
# @trace.platform: {active_platform — web | app | system | (omit in umbrella mode)}
|
|
704
|
+
# @trace.service: {active_service — omit in spec repo mode}
|
|
705
|
+
# @trace.module: {active_module in umbrella mode; "unknown" in spec repo mode}
|
|
423
706
|
# @trace.status: draft
|
|
424
707
|
# @trace.author: AI-generated
|
|
425
708
|
# @trace.created_at: {YYYY-MM-DD}
|
|
@@ -527,7 +810,7 @@ After generating all `.feature` files, create or update `{paths.trace_dir}/{UC-I
|
|
|
527
810
|
|
|
528
811
|
**TSV columns (tab-separated, one header row + one data row per scenario):**
|
|
529
812
|
```
|
|
530
|
-
sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tprd_version\tbdd_version\ttech_doc_revision\tprd_status\tuc_status\tstatus\tlast_updated
|
|
813
|
+
sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tprd_version\tbdd_version\ttech_doc_revision\tprd_status\tuc_status\tfe_phase\tstatus\tlast_updated
|
|
531
814
|
```
|
|
532
815
|
|
|
533
816
|
**Rules:**
|
|
@@ -554,6 +837,7 @@ sc_id\tsc_title\tspec_ver\tgen_ver\timplemented_by\ttest_count\ttest_classes\tpr
|
|
|
554
837
|
| `tech_doc_revision` | `—` |
|
|
555
838
|
| `prd_status` | read `\| **Status** \|` from PRD metadata |
|
|
556
839
|
| `uc_status` | `draft` for new UCs; keep existing value for re-gen |
|
|
840
|
+
| `fe_phase` | `—` (set by `/generate-code --phase` when FE implements) |
|
|
557
841
|
| `status` | `UNTRACKED` |
|
|
558
842
|
| `last_updated` | today `YYYY-MM-DD` |
|
|
559
843
|
|
|
@@ -591,7 +875,8 @@ Suggest the logical next command based on workflow phase:
|
|
|
591
875
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
592
876
|
| /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
|
|
593
877
|
| /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
|
|
594
|
-
| /review-context (PRD) | `/generate-
|
|
878
|
+
| /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 |
|
|
879
|
+
| /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
595
880
|
| /generate-bdd | `/review-context {feature-file}` to verify coverage |
|
|
596
881
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
597
882
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
@@ -605,6 +890,11 @@ Suggest the logical next command based on workflow phase:
|
|
|
605
890
|
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
606
891
|
| /fix-bug | Create PR and link to ticket |
|
|
607
892
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
893
|
+
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
894
|
+
| /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
|
|
895
|
+
| /learn | Continue working — lesson applies on next command |
|
|
896
|
+
| /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
|
|
897
|
+
| /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
|
|
608
898
|
|
|
609
899
|
Format the footer as:
|
|
610
900
|
```
|
|
@@ -617,16 +907,26 @@ Next : {suggested command with example arguments}
|
|
|
617
907
|
|
|
618
908
|
```
|
|
619
909
|
/generate-bdd Complete
|
|
910
|
+
|
|
911
|
+
[Spec repo mode — platform: {active_platform}]
|
|
620
912
|
Files:
|
|
621
|
-
{paths.specs_dir}/{domain}/{TICKET-ID}-UC1-{slug}.feature ({N} scenarios)
|
|
622
|
-
{paths.specs_dir}/{domain}/{TICKET-ID}-UC2-{slug}.feature ({N} scenarios)
|
|
913
|
+
{paths.specs_dir}/{domain}/{active_platform}/{TICKET-ID}-UC1-{slug}.feature ({N} scenarios)
|
|
914
|
+
{paths.specs_dir}/{domain}/{active_platform}/{TICKET-ID}-UC2-{slug}.feature ({N} scenarios)
|
|
623
915
|
Trace:
|
|
624
916
|
{paths.trace_dir}/{TICKET-ID}-UC1.tsv ({N} rows)
|
|
625
917
|
{paths.trace_dir}/{TICKET-ID}-UC2.tsv ({N} rows)
|
|
626
|
-
Next
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
918
|
+
Next (spec repo):
|
|
919
|
+
→ Run /generate-bdd again for other platforms (web → app → system)
|
|
920
|
+
→ After all platforms generated: commit + push + notify dev team
|
|
921
|
+
→ Dev team reads BDD from spec submodule — no /generate-bdd on their side
|
|
922
|
+
|
|
923
|
+
[Umbrella mode — service: {active_service}]
|
|
924
|
+
Files:
|
|
925
|
+
{paths.specs_dir}/{domain}/{TICKET-ID}-UC1-{slug}.feature ({N} scenarios)
|
|
926
|
+
Trace:
|
|
927
|
+
{paths.trace_dir}/{TICKET-ID}-UC1.tsv ({N} rows)
|
|
928
|
+
Next (umbrella):
|
|
929
|
+
→ /review-context {feature-file} to verify coverage
|
|
930
|
+
→ /generate-tech-docs {feature-file}
|
|
931
|
+
→ /generate-code {feature-file}
|
|
632
932
|
```
|