@anhth2/spec-driven-dev-plugin 0.8.0 → 0.9.1
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/commands/debug.md +152 -0
- package/commands/debug.tmpl +16 -0
- package/commands/define-product.md +57 -0
- package/commands/fix-bug.md +153 -0
- package/commands/fix-bug.tmpl +17 -0
- package/commands/generate-bdd.md +277 -13
- package/commands/generate-bdd.tmpl +220 -13
- package/commands/generate-code.md +154 -2
- package/commands/generate-code.tmpl +97 -2
- package/commands/generate-design-spec.md +57 -0
- package/commands/generate-prd.md +114 -20
- package/commands/generate-prd.tmpl +57 -20
- package/commands/generate-spec-manifest.md +57 -0
- package/commands/generate-tech-docs.md +79 -1
- package/commands/generate-tech-docs.tmpl +22 -1
- package/commands/generate-tests.md +57 -0
- 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 +66 -1
- package/commands/refine-prd.tmpl +9 -1
- package/commands/report-bug.md +543 -0
- package/commands/report-bug.tmpl +131 -0
- package/commands/review-code.md +153 -0
- package/commands/review-code.tmpl +17 -0
- package/commands/review-context.md +65 -0
- package/commands/review-context.tmpl +8 -0
- package/commands/review-tech-docs.md +146 -4
- package/commands/review-tech-docs.tmpl +89 -4
- package/commands/run-tests.md +82 -0
- package/commands/run-tests.tmpl +25 -0
- package/commands/setup-ai-first.md +15 -5
- package/commands/setup-ai-first.tmpl +10 -5
- package/commands/smoke-test.md +57 -0
- 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 +115 -2
- package/commands/validate-traces.tmpl +58 -2
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +152 -0
- package/core/commands/define-product.md +57 -0
- package/core/commands/fix-bug.md +153 -0
- package/core/commands/generate-bdd.md +277 -13
- package/core/commands/generate-code.md +154 -2
- package/core/commands/generate-design-spec.md +57 -0
- package/core/commands/generate-prd.md +114 -20
- package/core/commands/generate-spec-manifest.md +57 -0
- package/core/commands/generate-tech-docs.md +79 -1
- package/core/commands/generate-tests.md +57 -0
- package/core/commands/learn.md +554 -0
- package/core/commands/propose-scenario.md +521 -0
- package/core/commands/refine-prd.md +66 -1
- package/core/commands/report-bug.md +543 -0
- package/core/commands/review-code.md +153 -0
- package/core/commands/review-context.md +65 -0
- package/core/commands/review-tech-docs.md +146 -4
- package/core/commands/run-tests.md +82 -0
- package/core/commands/setup-ai-first.md +15 -5
- package/core/commands/smoke-test.md +57 -0
- package/core/commands/sync.md +405 -0
- package/core/commands/update-framework.md +211 -0
- package/core/commands/validate-traces.md +115 -2
- package/core/skills/code/SKILL.md +62 -0
- package/core/skills/debug/SKILL.md +67 -0
- package/core/skills/design-spec/SKILL.md +57 -0
- package/core/skills/discovery/SKILL.md +57 -0
- package/core/skills/prd/SKILL.md +10 -0
- package/core/skills/setup-ai-first/SKILL.md +5 -0
- package/core/skills/spec/SKILL.md +10 -0
- package/core/skills/test/SKILL.md +119 -0
- package/core/steps/capture-lesson.md +79 -0
- package/core/steps/context-loader.md +52 -0
- package/core/steps/report-footer.md +5 -0
- package/core/templates/prd.template.md +35 -20
- package/core/templates/project-context.yaml +11 -0
- package/package.json +9 -2
- package/skills/code/SKILL.md +62 -0
- package/skills/debug/SKILL.md +67 -0
- package/skills/design-spec/SKILL.md +57 -0
- package/skills/discovery/SKILL.md +57 -0
- package/skills/prd/SKILL.md +10 -0
- package/skills/setup-ai-first/SKILL.md +5 -0
- package/skills/spec/SKILL.md +10 -0
- package/skills/test/SKILL.md +119 -0
- package/steps/capture-lesson.md +79 -0
- package/steps/context-loader.md +52 -0
- package/steps/report-footer.md +5 -0
- package/templates/prd.template.md +35 -20
- package/templates/project-context.yaml +11 -0
|
@@ -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
|
|
|
@@ -548,6 +600,11 @@ Suggest the logical next command based on workflow phase:
|
|
|
548
600
|
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
549
601
|
| /fix-bug | Create PR and link to ticket |
|
|
550
602
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
603
|
+
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
604
|
+
| /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
|
|
605
|
+
| /learn | Continue working — lesson applies on next command |
|
|
606
|
+
| /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
|
|
607
|
+
| /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
|
|
551
608
|
|
|
552
609
|
Format the footer as:
|
|
553
610
|
```
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
# /sync — Sync & Refresh Umbrella Project
|
|
2
|
+
|
|
3
|
+
One command for both **first-time setup** and **daily update** of an umbrella repo with git submodules.
|
|
4
|
+
Safe to run repeatedly — detects what needs to be done automatically.
|
|
5
|
+
|
|
6
|
+
**Optional argument:** `/sync [spec-branch]` — branch of the spec submodule to pull (e.g. `/sync develop`). If omitted, the branch is resolved automatically (see Step 0-D).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Step 0 — Pre-flight Checks
|
|
11
|
+
|
|
12
|
+
**A. Git repo check**
|
|
13
|
+
|
|
14
|
+
Verify current directory is inside a git repo. If not → stop:
|
|
15
|
+
```
|
|
16
|
+
❌ Not a git repository. Open Claude Code from umbrella root and retry.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**B. Read project config early**
|
|
20
|
+
|
|
21
|
+
Read `.agent/project-context.yaml` before running any git commands. Extract:
|
|
22
|
+
- `setup.spec_source` → path of the spec submodule (e.g., `"my-project-specs"`)
|
|
23
|
+
- `services` → map of domain → `{path, module, ...}` for each service submodule
|
|
24
|
+
|
|
25
|
+
This is needed to differentiate spec vs service submodules in Step 1.
|
|
26
|
+
|
|
27
|
+
If `.agent/project-context.yaml` does not exist → warn and set `spec_source = null`, `services = {}`.
|
|
28
|
+
|
|
29
|
+
**C. Submodule status scan**
|
|
30
|
+
|
|
31
|
+
Run `git submodule status --recursive` and classify each entry by its first character:
|
|
32
|
+
|
|
33
|
+
| Char | Meaning | Action |
|
|
34
|
+
|------|---------|--------|
|
|
35
|
+
| `-` | Not initialized | → **Setup mode** |
|
|
36
|
+
| ` ` | Matches recorded pointer | → OK |
|
|
37
|
+
| `+` | Ahead of recorded pointer (local advance uncommitted) | → warn per submodule |
|
|
38
|
+
| `U` | Merge conflict | → **STOP** |
|
|
39
|
+
|
|
40
|
+
If **any** entry has `U`:
|
|
41
|
+
```
|
|
42
|
+
❌ Merge conflict in submodule: {path}
|
|
43
|
+
Resolve manually before running /sync:
|
|
44
|
+
cd {path} && git status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If **any** entry has `+` (checked-out commit differs from the recorded pointer):
|
|
48
|
+
```
|
|
49
|
+
ℹ️ {path} is ahead of the umbrella's recorded pointer.
|
|
50
|
+
/sync classifies it in Step 1b — if you're on a branch there, it stays untouched.
|
|
51
|
+
```
|
|
52
|
+
Do not act on `+` here — Step 1b decides the right handling per submodule.
|
|
53
|
+
|
|
54
|
+
Print detected mode: `Mode: Setup (first-time init)` or `Mode: Update (sync latest)`.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Step 1 — Umbrella Pull
|
|
59
|
+
|
|
60
|
+
Note the current umbrella branch first (this is what `git pull` updates):
|
|
61
|
+
`git rev-parse --abbrev-ref HEAD` → store as `umbrella_branch` and display it.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 1. Pull latest umbrella (includes updated submodule pointer records)
|
|
65
|
+
git pull
|
|
66
|
+
|
|
67
|
+
# 2. Sync .gitmodules config into local git config
|
|
68
|
+
# (needed when new submodules were added since last clone)
|
|
69
|
+
git submodule sync --recursive
|
|
70
|
+
|
|
71
|
+
# 3. Initialize any NOT-yet-cloned submodules ONLY (the '-' entries from Step 0-C).
|
|
72
|
+
# Do NOT run a blanket `git submodule update --recursive` — that would detach
|
|
73
|
+
# a submodule you are actively working in. Per-submodule handling is Step 1b.
|
|
74
|
+
git submodule update --init {paths that were '-' in Step 0-C}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If `git pull` exits non-zero → print the error and stop with `❌`.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Step 1b — Classify & Sync Each Submodule
|
|
82
|
+
|
|
83
|
+
**The key idea:** `/sync` never imposes a branch on a submodule. It **inspects each submodule's current checkout** and respects it. This is how it knows which submodule you are working in vs which are passive dependencies.
|
|
84
|
+
|
|
85
|
+
For each submodule (use `git submodule foreach` or iterate the paths), read its state:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Inside each submodule:
|
|
89
|
+
git symbolic-ref --short -q HEAD # → branch name, or empty/non-zero if DETACHED
|
|
90
|
+
git status --porcelain # → non-empty means uncommitted local changes
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Classify into one of four cases and act accordingly:
|
|
94
|
+
|
|
95
|
+
| Case | Detected state | Action |
|
|
96
|
+
|------|----------------|--------|
|
|
97
|
+
| **Spec submodule** | `path == spec_source` | Advance to `spec_branch` (Step 1c below) |
|
|
98
|
+
| **Active (on a branch)** | HEAD is a branch, not detached | **Do NOT checkout.** This is where you (or a teammate) are coding. Just `git -C {path} fetch` and report branch + ahead/behind. Leave the working tree exactly as-is. |
|
|
99
|
+
| **Passive (detached, clean)** | Detached HEAD, no local changes | Safe to align to the umbrella's recorded pointer: `git submodule update {path}` |
|
|
100
|
+
| **Dirty (uncommitted changes)** | `git status --porcelain` non-empty | **Never touch.** Warn: `⚠️ {path} has uncommitted changes — skipped. Commit or stash before syncing this submodule.` |
|
|
101
|
+
|
|
102
|
+
> **Why this matters:** A blanket `git submodule update` checks every submodule out to a **detached HEAD** at the recorded pointer. If you have `feature/FEAT-01` checked out inside `user-service/` and are mid-work, that would silently move you off your branch. Classifying first protects your active work.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Step 1c — Advance Spec Submodule *(only if `spec_source` is configured)*
|
|
107
|
+
|
|
108
|
+
The spec submodule is the one submodule we deliberately advance to a branch HEAD (PO pushes specs continuously).
|
|
109
|
+
|
|
110
|
+
**Resolve the spec branch** (now that the submodule is initialized), in priority order:
|
|
111
|
+
|
|
112
|
+
1. **Command argument** — if `$ARGUMENTS` contains a branch name → use it (one-off override)
|
|
113
|
+
2. **`.gitmodules` config** — `git config -f .gitmodules --get submodule.{spec_source}.branch`. If set → use it (team's committed default)
|
|
114
|
+
3. **Remote default** — else the spec repo's default branch: `git -C {spec_source} rev-parse --abbrev-ref origin/HEAD` (strip the `origin/` prefix)
|
|
115
|
+
|
|
116
|
+
Store as `spec_branch` + `spec_branch_source` (argument | .gitmodules | remote-default). If it fell through to remote-default with nothing pinned, add this hint to the output:
|
|
117
|
+
```
|
|
118
|
+
ℹ️ Spec submodule branch not pinned in .gitmodules — using remote default '{spec_branch}'.
|
|
119
|
+
To pin it for the whole team:
|
|
120
|
+
git config -f .gitmodules submodule.{spec_source}.branch {spec_branch}
|
|
121
|
+
git add .gitmodules && git commit -m "chore: pin spec submodule branch"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then check it is safe: if the spec submodule has uncommitted changes → warn and skip (devs should treat specs as read-only). Otherwise use an **explicit checkout** (not bare `--remote`) so the branch is unambiguous:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cd {spec_source}
|
|
128
|
+
git fetch origin
|
|
129
|
+
git checkout {spec_branch} # branch resolved in Step 0-D
|
|
130
|
+
git pull origin {spec_branch}
|
|
131
|
+
cd - # back to umbrella root
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Print: `Spec submodule {spec_source}: pulled branch '{spec_branch}' (source: {spec_branch_source})`
|
|
135
|
+
|
|
136
|
+
> **Why not `--remote` for service submodules?** Service submodules are version-locked by the umbrella's recorded pointer — this is intentional so all devs work from the same commit. `--remote` would bypass this lock and create uncommitted pointer drift. The spec submodule is the exception: PO pushes continuously, so we advance it to a branch HEAD — but we do it with an explicit `checkout {spec_branch}` rather than `--remote` so it never silently follows the wrong branch.
|
|
137
|
+
|
|
138
|
+
If `git pull` or `git submodule update` exits non-zero → print the error and stop with `❌`.
|
|
139
|
+
|
|
140
|
+
Collect from output:
|
|
141
|
+
- Which submodules changed SHA
|
|
142
|
+
- Which were already up to date
|
|
143
|
+
- The spec submodule's `{old_sha}..{new_sha}` (needed by Step 1d)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Step 1d — Surface Tester Feedback *(new bug reports / scenario proposals)*
|
|
148
|
+
|
|
149
|
+
Tester `/report-bug` and `/propose-scenario` commit feedback into the spec repo. This step tells PO/Dev what arrived in **this** pull, so they are notified through their normal routine. It covers both audiences:
|
|
150
|
+
|
|
151
|
+
- **Dev/tester in umbrella** → feedback came in via the spec submodule advance (Step 1c)
|
|
152
|
+
- **PO working directly in the spec repo** → feedback came in via the umbrella/current-repo `git pull` (Step 1)
|
|
153
|
+
|
|
154
|
+
Pick the repo + range that pulled the feedback:
|
|
155
|
+
- Umbrella with `spec_source` → `REPO={spec_source}`, range = spec submodule `{old_sha}..{new_sha}`
|
|
156
|
+
- Otherwise (running inside the spec repo itself) → `REPO=.`, range = the `git pull` `{old_sha}..{new_sha}` from Step 1
|
|
157
|
+
|
|
158
|
+
If `feedback/` does not exist in REPO → skip silently.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
git -C {REPO} diff --name-status {old_sha}..{new_sha} -- feedback/bug-reports/ feedback/bdd-proposals/
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For each entry, read its title/summary and report:
|
|
165
|
+
```
|
|
166
|
+
📥 New tester feedback (pulled this sync):
|
|
167
|
+
Bug reports:
|
|
168
|
+
BUG-20260608-01 FT-001 — account locks after 6 fails (spec says 5) [layer: Code]
|
|
169
|
+
Scenario proposals:
|
|
170
|
+
FT-001-trailing-spaces.md → maps to AC2 (pending review)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
If none changed → print `📥 Tester feedback: none new this sync`.
|
|
174
|
+
|
|
175
|
+
If the reader is a PO/Dev, add a one-line nudge:
|
|
176
|
+
`→ Review feedback/ then act: /fix-bug {BUG-ID} · promote proposal into BDD · or update PRD.`
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Step 2 — Post-sync State Check
|
|
181
|
+
|
|
182
|
+
Run `git status --short` and check for modified submodule entries (lines starting with ` M` where the path matches a submodule).
|
|
183
|
+
|
|
184
|
+
If any submodule pointer changed (typically the spec submodule after `--remote`):
|
|
185
|
+
```
|
|
186
|
+
⚠️ Submodule pointer(s) updated — commit to lock new version into umbrella:
|
|
187
|
+
git add {spec_source} && git commit -m "chore: sync {spec_source} to latest"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
If no changes → `✅ Umbrella state clean — no commit needed`.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Step 3 — Bootstrap Service Configs
|
|
195
|
+
|
|
196
|
+
*Skip if `services` is empty.*
|
|
197
|
+
|
|
198
|
+
For each entry in `services[]`:
|
|
199
|
+
|
|
200
|
+
**A. If `{service.path}/.agent/project-context.yaml` already exists:**
|
|
201
|
+
- Read `conventions.test_command` and `conventions.build_command`
|
|
202
|
+
- Report: `✅ {service.path} — test: {test_command} | build: {build_command}`
|
|
203
|
+
|
|
204
|
+
**B. If missing — auto-create it:**
|
|
205
|
+
|
|
206
|
+
1. Determine `module` from umbrella `services[].module` (authoritative). If not set, auto-detect from files in `{service.path}/`:
|
|
207
|
+
|
|
208
|
+
| File present | Detected module | test_command | build_command |
|
|
209
|
+
|---|---|---|---|
|
|
210
|
+
| `pom.xml` | `java-spring` | `mvn test` | `mvn compile` |
|
|
211
|
+
| `build.gradle` or `build.gradle.kts` | `java-spring` | `./gradlew test` | `./gradlew build` |
|
|
212
|
+
| `go.mod` | `golang` | `go test ./...` | `go build ./...` |
|
|
213
|
+
| `*.csproj` or `*.sln` | `dotnet` | `dotnet test` | `dotnet build` |
|
|
214
|
+
| `composer.json` | `php-laravel` | `php artisan test` | `composer install` |
|
|
215
|
+
| `pubspec.yaml` | `flutter` | `flutter test` | `flutter build apk` |
|
|
216
|
+
| `angular.json` | `angular` | `npx ng test --watch=false` | `npm run build` |
|
|
217
|
+
| `next.config.*` | `nextjs` | `npx vitest run` | `npm run build` |
|
|
218
|
+
| `package.json` + `nest-cli.json` | `nestjs` | `npm test` | `npm run build` |
|
|
219
|
+
| `package.json` (fallback) | `react` | `npx vitest run` | `npm run build` |
|
|
220
|
+
| `requirements.txt` or `pyproject.toml` | `context-engineering` | `pytest tests/ -v` | `pip install -r requirements.txt` |
|
|
221
|
+
| *(none matched)* | `unknown` | `{{TEST_COMMAND}}` | `{{BUILD_COMMAND}}` |
|
|
222
|
+
|
|
223
|
+
2. Create `{service.path}/.agent/` directory if it does not exist.
|
|
224
|
+
|
|
225
|
+
3. Write `{service.path}/.agent/project-context.yaml`:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
# Auto-generated by /sync — review and update as needed
|
|
229
|
+
tech_stack:
|
|
230
|
+
language: "{detected or from module}"
|
|
231
|
+
framework: "{detected or from module}"
|
|
232
|
+
module: "{module}"
|
|
233
|
+
|
|
234
|
+
conventions:
|
|
235
|
+
test_command: "{test_command}"
|
|
236
|
+
build_command: "{build_command}"
|
|
237
|
+
|
|
238
|
+
paths:
|
|
239
|
+
trace_dir: ".trace"
|
|
240
|
+
lessons_file: ".agent/project-lessons.md" # per-service guardrails (see /learn)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
4. Report:
|
|
244
|
+
- If auto-detected: `✅ Created {service.path}/.agent/project-context.yaml (module: {module}, test: {test_command})`
|
|
245
|
+
- If unknown/placeholder: `⚠️ Created {service.path}/.agent/project-context.yaml — fill in {{TEST_COMMAND}} and {{BUILD_COMMAND}}`
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Step 4 — Check `.gitignore`
|
|
250
|
+
|
|
251
|
+
Check if `.trace/` appears in the umbrella root's `.gitignore` (or `.git/info/exclude`).
|
|
252
|
+
|
|
253
|
+
If missing:
|
|
254
|
+
```
|
|
255
|
+
⚠️ .trace/ is not in umbrella .gitignore
|
|
256
|
+
Add it to prevent accidentally committing generated trace artifacts:
|
|
257
|
+
echo ".trace/" >> .gitignore
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Step 5 — Refresh Living Docs *(umbrella mode only)*
|
|
263
|
+
|
|
264
|
+
*Skip if `services` is empty.*
|
|
265
|
+
|
|
266
|
+
For each service in `services[]`:
|
|
267
|
+
1. Check if `{service.path}/.trace/` directory exists and contains `.tsv` files
|
|
268
|
+
2. If yes → copy TSVs to `{umbrella_root}/.trace/{service-name}/` (create dir if needed)
|
|
269
|
+
|
|
270
|
+
After copying all services, write merged `{umbrella_root}/.trace/trace-report.json`:
|
|
271
|
+
- Aggregate data from each service's `.trace/` TSVs
|
|
272
|
+
- Include `"service"` field per scenario row
|
|
273
|
+
- Recalculate summary totals
|
|
274
|
+
|
|
275
|
+
Print sync result:
|
|
276
|
+
```
|
|
277
|
+
Living Docs → .trace/ synced
|
|
278
|
+
{service-name}: {N} TSVs
|
|
279
|
+
trace-report.json: {total} scenarios across {S} services
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
If no `.trace/` dirs found → `Living Docs: no trace data yet — run /generate-bdd then /generate-code first.`
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Step 6 — Refresh Spec Manifest *(if spec_source present)*
|
|
287
|
+
|
|
288
|
+
*Skip if `setup.spec_source` is absent.*
|
|
289
|
+
|
|
290
|
+
If `spec-manifest.yaml` exists OR `setup.spec_source` is configured:
|
|
291
|
+
- Re-scan `{spec_source}/specs/prd/**/*.md` files
|
|
292
|
+
- Rebuild `spec-manifest.yaml` mapping TICKET-ID → PRD/BDD/tech-doc paths
|
|
293
|
+
- Print: `spec-manifest.yaml refreshed — {N} features indexed`
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Output
|
|
298
|
+
|
|
299
|
+
# Report Footer — Standard Command Output Format
|
|
300
|
+
|
|
301
|
+
Every command report must end with this standard footer section.
|
|
302
|
+
|
|
303
|
+
## Status Badge
|
|
304
|
+
|
|
305
|
+
Choose one based on outcome:
|
|
306
|
+
- `✅ Complete` — all steps succeeded, no issues found
|
|
307
|
+
- `❌ Failed` — command could not complete due to a blocking error
|
|
308
|
+
- `⚠️ Warnings` — completed with non-blocking issues that should be reviewed
|
|
309
|
+
|
|
310
|
+
## Output Artifacts
|
|
311
|
+
|
|
312
|
+
List every file created or modified by this command:
|
|
313
|
+
```
|
|
314
|
+
Output Artifacts:
|
|
315
|
+
{created|updated} {file-path} ({brief description})
|
|
316
|
+
{created|updated} {file-path} ({brief description})
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
If no files were written (e.g., review or analysis commands) → write `Output Artifacts: none (read-only)`.
|
|
320
|
+
|
|
321
|
+
## Next Command Suggestion
|
|
322
|
+
|
|
323
|
+
Suggest the logical next command based on workflow phase:
|
|
324
|
+
|
|
325
|
+
| Current command | Suggest next |
|
|
326
|
+
|-------------------------|-----------------------------------------------|
|
|
327
|
+
| /setup-ai-first | `/define-product` to start your first feature |
|
|
328
|
+
| /define-product | `/generate-prd {product-definition-file}` |
|
|
329
|
+
| /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
|
|
330
|
+
| /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
|
|
331
|
+
| /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 |
|
|
332
|
+
| /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
333
|
+
| /generate-bdd | `/review-context {feature-file}` to verify coverage |
|
|
334
|
+
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
335
|
+
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
336
|
+
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
337
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/generate-tests {UC-ID}` |
|
|
338
|
+
| /generate-tests | `/run-tests {UC-ID}` |
|
|
339
|
+
| /run-tests (passing) | `/review-code {UC-ID}` |
|
|
340
|
+
| /run-tests (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
341
|
+
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
342
|
+
| /smoke-test | Create PR and link to ticket |
|
|
343
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
344
|
+
| /fix-bug | Create PR and link to ticket |
|
|
345
|
+
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
346
|
+
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
347
|
+
| /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
|
|
348
|
+
| /learn | Continue working — lesson applies on next command |
|
|
349
|
+
| /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
|
|
350
|
+
| /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
|
|
351
|
+
|
|
352
|
+
Format the footer as:
|
|
353
|
+
```
|
|
354
|
+
---
|
|
355
|
+
Status : {badge}
|
|
356
|
+
{Output Artifacts block}
|
|
357
|
+
Next : {suggested command with example arguments}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
/sync — {Setup | Update}
|
|
363
|
+
|
|
364
|
+
Git
|
|
365
|
+
✅ git pull — umbrella on branch '{umbrella_branch}'
|
|
366
|
+
✅ submodule sync — .gitmodules config refreshed
|
|
367
|
+
|
|
368
|
+
Submodules (each handled by its current state)
|
|
369
|
+
✅ {spec_source} [spec] — pulled branch '{spec_branch}' ({spec_branch_source}) → {new-sha}
|
|
370
|
+
✋ user-service [active] — on 'feature/FEAT-01' — left untouched, fetched (↓2 behind origin)
|
|
371
|
+
✅ order-service [passive] — aligned to umbrella pointer {sha}
|
|
372
|
+
⚠️ payment-service [dirty] — uncommitted changes, skipped (commit/stash first)
|
|
373
|
+
|
|
374
|
+
Umbrella state
|
|
375
|
+
⚠️ Pointer changed: git add {spec_source} && git commit -m "chore: sync specs"
|
|
376
|
+
(or: ✅ Clean — no commit needed)
|
|
377
|
+
|
|
378
|
+
Tester feedback (pulled this sync)
|
|
379
|
+
📥 1 bug report: BUG-20260608-01 FT-001 [Code]
|
|
380
|
+
1 proposal: FT-001-trailing-spaces → AC2 (pending review)
|
|
381
|
+
(or: 📥 none new this sync)
|
|
382
|
+
→ /fix-bug {BUG-ID} · promote proposal into BDD · or update PRD
|
|
383
|
+
|
|
384
|
+
Service Configs
|
|
385
|
+
✅ user-service — test: mvn test | build: mvn compile
|
|
386
|
+
✅ order-service — test: mvn test | build: mvn compile
|
|
387
|
+
⚠️ payment-service — .agent/project-context.yaml missing
|
|
388
|
+
→ create it so /run-tests works correctly
|
|
389
|
+
|
|
390
|
+
.gitignore
|
|
391
|
+
✅ .trace/ is gitignored
|
|
392
|
+
(or: ⚠️ Add .trace/ to .gitignore)
|
|
393
|
+
|
|
394
|
+
Living Docs
|
|
395
|
+
✅ .trace/ synced — {N} TSVs across {S} services
|
|
396
|
+
(run /validate-traces for full coverage report)
|
|
397
|
+
|
|
398
|
+
Spec Manifest
|
|
399
|
+
✅ spec-manifest.yaml — {N} features indexed
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
Status : ✅ Complete | ⚠️ Warnings
|
|
403
|
+
Output Artifacts: updated .trace/ (umbrella mirror), spec-manifest.yaml
|
|
404
|
+
Next : /validate-traces (full coverage check) | /generate-code {UC-ID} (start coding)
|
|
405
|
+
```
|