specrails-core 4.12.0 → 5.0.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/README.md +49 -78
- package/bin/specrails-core.mjs +18 -98
- package/bin/tui-installer.mjs +22 -105
- package/commands/doctor.md +1 -1
- package/dist/installer/cli.js +12 -2
- package/dist/installer/cli.js.map +1 -1
- package/dist/installer/commands/doctor.js +3 -5
- package/dist/installer/commands/doctor.js.map +1 -1
- package/dist/installer/commands/init.js +23 -19
- package/dist/installer/commands/init.js.map +1 -1
- package/dist/installer/commands/update.js +17 -16
- package/dist/installer/commands/update.js.map +1 -1
- package/dist/installer/commands/v5-migration.js +119 -0
- package/dist/installer/commands/v5-migration.js.map +1 -0
- package/dist/installer/phases/install-config.js +3 -6
- package/dist/installer/phases/install-config.js.map +1 -1
- package/dist/installer/phases/manifest.js +2 -6
- package/dist/installer/phases/manifest.js.map +1 -1
- package/dist/installer/phases/prereqs.js +0 -1
- package/dist/installer/phases/prereqs.js.map +1 -1
- package/dist/installer/phases/scaffold.js +38 -148
- package/dist/installer/phases/scaffold.js.map +1 -1
- package/package.json +1 -1
- package/schemas/profile.v1.json +1 -1
- package/templates/agents/sr-architect.md +30 -0
- package/templates/agents/sr-developer.md +21 -8
- package/templates/agents/sr-reviewer.md +44 -31
- package/templates/codex-skills/batch-implement/SKILL.md +9 -32
- package/templates/codex-skills/implement/SKILL.md +61 -143
- package/templates/codex-skills/rails/sr-architect/SKILL.md +38 -20
- package/templates/codex-skills/rails/sr-developer/SKILL.md +29 -10
- package/templates/codex-skills/rails/sr-reviewer/SKILL.md +21 -10
- package/templates/commands/specrails/doctor.md +1 -1
- package/templates/commands/specrails/implement.md +117 -288
- package/templates/commands/specrails/memory-inspect.md +6 -4
- package/templates/commands/specrails/propose-spec.md +1 -1
- package/templates/commands/specrails/refactor-recommender.md +8 -51
- package/templates/commands/specrails/retry.md +12 -48
- package/templates/commands/specrails/telemetry.md +1 -1
- package/templates/gemini-commands/implement.toml +9 -0
- package/templates/profiles/default.json +5 -18
- package/commands/enrich.md +0 -1456
- package/templates/agents/sr-backend-developer.md +0 -91
- package/templates/agents/sr-backend-reviewer.md +0 -152
- package/templates/agents/sr-doc-sync.md +0 -247
- package/templates/agents/sr-frontend-developer.md +0 -85
- package/templates/agents/sr-frontend-reviewer.md +0 -145
- package/templates/agents/sr-merge-resolver.md +0 -195
- package/templates/agents/sr-performance-reviewer.md +0 -186
- package/templates/agents/sr-product-analyst.md +0 -36
- package/templates/agents/sr-product-manager.md +0 -148
- package/templates/agents/sr-security-reviewer.md +0 -191
- package/templates/agents/sr-test-writer.md +0 -176
- package/templates/codex-skills/enrich/SKILL.md +0 -191
- package/templates/codex-skills/merge-resolve/SKILL.md +0 -88
- package/templates/codex-skills/rails/sr-backend-developer/SKILL.md +0 -93
- package/templates/codex-skills/rails/sr-backend-reviewer/SKILL.md +0 -120
- package/templates/codex-skills/rails/sr-doc-sync/SKILL.md +0 -124
- package/templates/codex-skills/rails/sr-frontend-developer/SKILL.md +0 -106
- package/templates/codex-skills/rails/sr-frontend-reviewer/SKILL.md +0 -111
- package/templates/codex-skills/rails/sr-merge-resolver/SKILL.md +0 -156
- package/templates/codex-skills/rails/sr-performance-reviewer/SKILL.md +0 -109
- package/templates/codex-skills/rails/sr-product-analyst/SKILL.md +0 -85
- package/templates/codex-skills/rails/sr-product-manager/SKILL.md +0 -131
- package/templates/codex-skills/rails/sr-security-reviewer/SKILL.md +0 -121
- package/templates/codex-skills/rails/sr-test-writer/SKILL.md +0 -115
- package/templates/commands/specrails/auto-propose-backlog-specs.md +0 -312
- package/templates/commands/specrails/enrich.md +0 -1456
- package/templates/commands/specrails/get-backlog-specs.md +0 -226
- package/templates/commands/specrails/merge-resolve.md +0 -172
- package/templates/commands/specrails/reconfig.md +0 -80
- package/templates/commands/specrails/vpc-drift.md +0 -405
- package/templates/commands/test.md +0 -58
- package/templates/personas/persona.md +0 -43
- package/templates/personas/the-maintainer.md +0 -98
- package/templates/settings/perf-thresholds.yml +0 -25
|
@@ -66,28 +66,14 @@ which openspec && openspec --version
|
|
|
66
66
|
|
|
67
67
|
#### 5. Agent discovery
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
`AVAILABLE_AGENTS` resolves through a single path: **a profile if one is active, otherwise the baseline trio**. There are no modes — the baseline is just the default value the resolution falls back to when no profile is present.
|
|
70
70
|
|
|
71
|
-
#####
|
|
71
|
+
##### Resolve the profile path
|
|
72
72
|
|
|
73
|
-
A profile is active when either condition holds:
|
|
73
|
+
A profile is active when either condition holds (highest precedence first):
|
|
74
74
|
|
|
75
|
-
1.
|
|
76
|
-
2.
|
|
77
|
-
|
|
78
|
-
If condition 1 holds, use `$SPECRAILS_PROFILE_PATH` as the profile path. Otherwise, if condition 2 holds, use `.specrails/profiles/project-default.json`. Otherwise, fall through to **legacy mode**.
|
|
79
|
-
|
|
80
|
-
##### Preflight: `jq` availability (profile mode only)
|
|
81
|
-
|
|
82
|
-
When running in profile mode, `jq` is required to read the profile JSON. Run:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
command -v jq >/dev/null 2>&1 || { echo "[error] 'jq' is required for profile-aware mode. Install with: brew install jq / apt install jq / https://stedolan.github.io/jq/"; exit 1; }
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
##### Profile mode — load, validate, populate
|
|
89
|
-
|
|
90
|
-
Resolve the profile path into `PROFILE_PATH` (highest precedence wins), then read it:
|
|
75
|
+
1. `SPECRAILS_PROFILE_PATH` is set AND points to a readable file. Tools like `specrails-desktop` set this to a job-scoped snapshot.
|
|
76
|
+
2. `.specrails/profiles/project-default.json` exists and is readable.
|
|
91
77
|
|
|
92
78
|
```bash
|
|
93
79
|
if [[ -n "${SPECRAILS_PROFILE_PATH:-}" && -r "${SPECRAILS_PROFILE_PATH:-}" ]]; then
|
|
@@ -95,13 +81,27 @@ if [[ -n "${SPECRAILS_PROFILE_PATH:-}" && -r "${SPECRAILS_PROFILE_PATH:-}" ]]; t
|
|
|
95
81
|
elif [[ -r ".specrails/profiles/project-default.json" ]]; then
|
|
96
82
|
PROFILE_PATH=".specrails/profiles/project-default.json"
|
|
97
83
|
else
|
|
98
|
-
|
|
84
|
+
PROFILE_PATH=""
|
|
85
|
+
fi
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
##### No profile → baseline default
|
|
89
|
+
|
|
90
|
+
When `PROFILE_PATH` is empty, `AVAILABLE_AGENTS` is the baseline trio and there are no per-agent model overrides (each agent uses the `model:` in its own `.md` frontmatter). No profile file is written — the baseline is an in-memory default, honoring the reserved-paths contract (`.specrails/profiles/**` is never created by the pipeline):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
if [[ -z "$PROFILE_PATH" ]]; then
|
|
94
|
+
AVAILABLE_AGENTS="$(printf '%s\n' sr-architect sr-developer sr-reviewer)"
|
|
95
|
+
PROFILE_NAME=""
|
|
99
96
|
fi
|
|
100
97
|
```
|
|
101
98
|
|
|
102
|
-
|
|
99
|
+
##### Profile present → load, validate, populate
|
|
100
|
+
|
|
101
|
+
`jq` is required to read a profile JSON:
|
|
103
102
|
|
|
104
103
|
```bash
|
|
104
|
+
command -v jq >/dev/null 2>&1 || { echo "[error] 'jq' is required to read a profile. Install with: brew install jq / apt install jq / https://stedolan.github.io/jq/"; exit 1; }
|
|
105
105
|
PROFILE="$(cat "$PROFILE_PATH")"
|
|
106
106
|
```
|
|
107
107
|
|
|
@@ -149,14 +149,20 @@ if [[ "$IS_LAST" != "true" ]]; then
|
|
|
149
149
|
fi
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
Populate `AVAILABLE_AGENTS` from the profile
|
|
152
|
+
Populate `AVAILABLE_AGENTS` from the profile. The three baseline agents are **hard-required**: if a baseline agent's file is missing, STOP. A **non-baseline** agent whose file is missing is **warned and skipped** — this is how a pre-v5 profile that still references a removed agent (e.g. `sr-frontend-developer`) degrades gracefully:
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
|
-
AVAILABLE_AGENTS="
|
|
156
|
-
for id in $
|
|
157
|
-
[[ -f ".claude/agents/$id.md" ]]
|
|
158
|
-
|
|
155
|
+
AVAILABLE_AGENTS=""
|
|
156
|
+
for id in $(jq -r '.agents[].id' <<<"$PROFILE" | sort); do
|
|
157
|
+
if [[ -f ".claude/agents/$id.md" ]]; then
|
|
158
|
+
AVAILABLE_AGENTS="$AVAILABLE_AGENTS$id"$'\n'
|
|
159
|
+
elif [[ "$id" == "sr-architect" || "$id" == "sr-developer" || "$id" == "sr-reviewer" ]]; then
|
|
160
|
+
echo "[error] Core agent $id not found. Run npx specrails-core update to reinstall."; exit 1
|
|
161
|
+
else
|
|
162
|
+
echo "[warn] profile references agent '$id' but no agent file exists — skipping (removed in v5; use a custom-* agent)"
|
|
163
|
+
fi
|
|
159
164
|
done
|
|
165
|
+
AVAILABLE_AGENTS="$(printf '%s' "$AVAILABLE_AGENTS" | sed '/^$/d')"
|
|
160
166
|
```
|
|
161
167
|
|
|
162
168
|
Also store per-agent model overrides and the orchestrator model for use in later phases:
|
|
@@ -176,13 +182,12 @@ done < <(jq -r '.agents[] | [.id, (.model // "null")] | @tsv' <<<"$PROFILE")
|
|
|
176
182
|
# Routing rules (array), consumed by Phase 3b.
|
|
177
183
|
ROUTING="$(jq '.routing' <<<"$PROFILE")"
|
|
178
184
|
|
|
179
|
-
PROFILE_MODE="profile"
|
|
180
185
|
PROFILE_NAME="$(jq -r '.name' <<<"$PROFILE")"
|
|
181
186
|
```
|
|
182
187
|
|
|
183
|
-
##### Apply per-agent model overrides (profile
|
|
188
|
+
##### Apply per-agent model overrides (only when a profile declares them)
|
|
184
189
|
|
|
185
|
-
Claude Code's Agent tool determines a subagent's model from the `model:` line in the agent's `.md` frontmatter at invocation time — there is no per-call model parameter. When a profile
|
|
190
|
+
Claude Code's Agent tool determines a subagent's model from the `model:` line in the agent's `.md` frontmatter at invocation time — there is no per-call model parameter. When a profile declares model overrides, rewrite each agent's frontmatter `model:` value in-place to match `AGENT_MODEL[$id]`.
|
|
186
191
|
|
|
187
192
|
This rewrite is safe because:
|
|
188
193
|
- Multi-feature runs execute in **isolated git worktrees** (`isolation: worktree`), so each rail mutates its own copy of `.claude/agents/` without cross-rail contention.
|
|
@@ -195,7 +200,7 @@ for id in "${!AGENT_MODEL[@]}"; do
|
|
|
195
200
|
file=".claude/agents/$id.md"
|
|
196
201
|
[[ -f "$file" ]] || continue
|
|
197
202
|
# Rewrite the first `model:` line within the frontmatter block (lines between the
|
|
198
|
-
# first two `---` separators). Use
|
|
203
|
+
# first two `---` separators). Use awk with portable syntax (macOS + Linux).
|
|
199
204
|
awk -v new="$model" '
|
|
200
205
|
BEGIN { in_fm=0; done=0 }
|
|
201
206
|
/^---$/ { in_fm = !in_fm; print; next }
|
|
@@ -207,42 +212,21 @@ done
|
|
|
207
212
|
|
|
208
213
|
If a profile does not declare `model` for a given agent (the field is optional), that agent's frontmatter is left untouched.
|
|
209
214
|
|
|
210
|
-
#####
|
|
211
|
-
|
|
212
|
-
If no profile is active, scan the agents directory exactly as before:
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
AVAILABLE_AGENTS="$(ls .claude/agents/sr-*.md 2>/dev/null | sed 's|.*/||;s|\.md$||' | sort)"
|
|
216
|
-
PROFILE_MODE="legacy"
|
|
217
|
-
PROFILE_NAME=""
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Per-agent model overrides are empty in legacy mode — subagent invocations inherit the `model:` value from each agent's `.md` frontmatter. Routing in Phase 3b uses the hardcoded legacy rules.
|
|
221
|
-
|
|
222
|
-
##### Agent roles (both modes)
|
|
215
|
+
##### Agent roles
|
|
223
216
|
|
|
224
|
-
The pipeline
|
|
217
|
+
The pipeline ships exactly three first-party agents. Any additional agent comes from an active profile that declares a user-owned `custom-*` agent (with routing) — the installer never ships or manages non-core agents.
|
|
225
218
|
|
|
226
219
|
| Agent | Role | Required? | Phase(s) affected |
|
|
227
220
|
|-------|------|-----------|-------------------|
|
|
228
221
|
| sr-architect | Architecture & design | **Core** (always present) | 3a |
|
|
229
222
|
| sr-developer | Full-stack implementation | **Core** (always present) | 3b |
|
|
230
|
-
| sr-reviewer |
|
|
231
|
-
|
|
|
232
|
-
| sr-product-manager | Product exploration | Optional | 1 |
|
|
233
|
-
| sr-test-writer | Test generation | Optional | 3c |
|
|
234
|
-
| sr-doc-sync | Documentation sync | Optional | 3d |
|
|
235
|
-
| sr-frontend-developer | Frontend implementation | Optional | 3b (routing) |
|
|
236
|
-
| sr-backend-developer | Backend implementation | Optional | 3b (routing) |
|
|
237
|
-
| sr-frontend-reviewer | Frontend review | Optional | 4b |
|
|
238
|
-
| sr-backend-reviewer | Backend review | Optional | 4b |
|
|
239
|
-
| sr-security-reviewer | Security analysis | Optional | 4b |
|
|
240
|
-
| sr-performance-reviewer | Performance analysis | Optional | 4b |
|
|
223
|
+
| sr-reviewer | Quality gate (correctness, tests, security, performance) | **Core** (always present) | 4b |
|
|
224
|
+
| custom-* | Profile-declared specialist | Optional — only when an active profile lists it | per profile routing |
|
|
241
225
|
|
|
242
226
|
**Gate rules** (applied throughout the pipeline):
|
|
243
|
-
-
|
|
244
|
-
-
|
|
245
|
-
-
|
|
227
|
+
- The three baseline agents are the source of truth for the non-profile default; a profile's `agents[]` (baseline + any `custom-*`) is the source of truth when a profile is active. Agents not in `AVAILABLE_AGENTS` are unavailable regardless of what is on disk.
|
|
228
|
+
- If a `custom-*` agent routed by the profile is not in `AVAILABLE_AGENTS` (e.g. skipped above), that routing target is dropped — the task falls through to the profile's `default: true` rule.
|
|
229
|
+
- If a core agent is missing, **STOP** and print: `[error] Core agent <name> not found. Run npx specrails-core update to reinstall.`
|
|
246
230
|
|
|
247
231
|
### Summary
|
|
248
232
|
|
|
@@ -256,7 +240,7 @@ Print a setup report:
|
|
|
256
240
|
| OpenSpec | ok | ... |
|
|
257
241
|
| Dependencies | ok | ... |
|
|
258
242
|
| Test runner | ok | ... |
|
|
259
|
-
| Agents | N
|
|
243
|
+
| Agents | N available | baseline: 3/3, custom (profile): M |
|
|
260
244
|
```
|
|
261
245
|
|
|
262
246
|
**Pass `TEST_CMD`, `BACKLOG_AVAILABLE`, and `AVAILABLE_AGENTS` forward** — all later phases must use these.
|
|
@@ -287,6 +271,7 @@ Before parsing input, scan `$ARGUMENTS` for control flags:
|
|
|
287
271
|
- If `--confidence-override "<reason>"` is present in `$ARGUMENTS`:
|
|
288
272
|
- Set `CONFIDENCE_OVERRIDE_REASON=<reason>` (the quoted string immediately following `--confidence-override`)
|
|
289
273
|
- Strip `--confidence-override` and the reason before further parsing.
|
|
274
|
+
- The one flag bypasses BOTH confidence gates: the architect's design-confidence gate (Phase 3a.3) and the reviewer's score gate (Phase 4b-conf).
|
|
290
275
|
|
|
291
276
|
If none of these flags is present: `DRY_RUN=false`, `APPLY_MODE=false`, `CONFIDENCE_OVERRIDE_REASON=""`. Pipeline runs as normal.
|
|
292
277
|
|
|
@@ -301,13 +286,13 @@ Initialize conflict-tracking variables:
|
|
|
301
286
|
**If the user passed a text description** (e.g. `"add feature X"`):
|
|
302
287
|
- **Single-feature mode**. Derive a kebab-case change name.
|
|
303
288
|
- Set `SINGLE_MODE = true`. No worktrees, no parallelism.
|
|
304
|
-
-
|
|
289
|
+
- Go directly to Phase 3a.
|
|
305
290
|
|
|
306
291
|
**If the user passed ticket references** (e.g. `#85, #71` or `#1, #2`):
|
|
307
292
|
- Fetch each ticket from `.specrails/local-tickets.json` at `tickets["{id}"]`.
|
|
308
293
|
- Extract area, value, effort, and feature details from each ticket body.
|
|
309
294
|
- If only 1 ticket: set `SINGLE_MODE = true`.
|
|
310
|
-
-
|
|
295
|
+
- Go directly to the confirmation table.
|
|
311
296
|
|
|
312
297
|
#### Phase 0 snapshot capture
|
|
313
298
|
|
|
@@ -392,8 +377,6 @@ Write the initial state file:
|
|
|
392
377
|
"phases": {
|
|
393
378
|
"architect": "pending",
|
|
394
379
|
"developer": "pending",
|
|
395
|
-
"test-writer": "<'pending' if sr-test-writer ∈ AVAILABLE_AGENTS, else 'skipped'>",
|
|
396
|
-
"doc-sync": "<'pending' if sr-doc-sync ∈ AVAILABLE_AGENTS, else 'skipped'>",
|
|
397
380
|
"reviewer": "pending",
|
|
398
381
|
"ship": "pending",
|
|
399
382
|
"ci": "pending"
|
|
@@ -430,27 +413,15 @@ When a phase completes or fails, update `PIPELINE_STATE_PATH`:
|
|
|
430
413
|
|
|
431
414
|
If `PIPELINE_STATE_AVAILABLE=false`: skip all state updates silently.
|
|
432
415
|
|
|
433
|
-
**If the user passed area names
|
|
416
|
+
**If the user passed area names** (no concrete issue/spec):
|
|
434
417
|
- Check for open backlog issues. If found, filter and pick top 3.
|
|
435
|
-
- If none,
|
|
418
|
+
- If none, STOP with: `[input] No backlog issue or spec resolved from the given area(s). Product exploration was removed in v5 — pass a backlog issue number or a feature description/spec.`
|
|
436
419
|
|
|
437
420
|
---
|
|
438
421
|
|
|
439
|
-
## Phase 1:
|
|
422
|
+
## Phase 1 & 2: (removed in v5)
|
|
440
423
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
If `sr-product-manager` is not installed, skip Phase 1 and Phase 2 entirely. Print: `[phase-1] sr-product-manager not installed — skipping exploration. Proceeding with provided input.`
|
|
444
|
-
|
|
445
|
-
For each area, launch a **sr-product-manager** agent (`subagent_type: sr-product-manager`, `run_in_background: true`).
|
|
446
|
-
|
|
447
|
-
Wait for all to complete. Read their output.
|
|
448
|
-
|
|
449
|
-
## Phase 2: Select
|
|
450
|
-
|
|
451
|
-
**Only runs if Phase 1 ran.**
|
|
452
|
-
|
|
453
|
-
Pick the single idea with the best impact/effort ratio from each exploration. Present to user and wait for confirmation.
|
|
424
|
+
Product exploration and idea selection were driven by `sr-product-manager`, which is not shipped in v5. The pipeline works from concrete inputs — backlog issues or a feature description/spec passed to the command — and proceeds directly from Phase 0 to Phase 3a. If you want product discovery, run it as a separate step and feed the resulting spec/issue into `/specrails:implement`.
|
|
454
425
|
|
|
455
426
|
## Phase 3a.0: Pre-architect conflict check
|
|
456
427
|
|
|
@@ -575,6 +546,42 @@ Quick-check each architect's artifacts:
|
|
|
575
546
|
|
|
576
547
|
**Pipeline state:** update `architect` → `done`. If any architect agent failed (skipped area): update `architect` → `failed` with error context `"sr-architect failed for: <area-names>"`.
|
|
577
548
|
|
|
549
|
+
### 3a.3 Design confidence gate
|
|
550
|
+
|
|
551
|
+
Implementation is the expensive phase — it only runs on designs the architect actually trusts. For each feature, read:
|
|
552
|
+
|
|
553
|
+
```
|
|
554
|
+
${SPECRAILS_REPO_DIR:-.}/openspec/changes/<name>/design-confidence.json
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
- **File missing** (pre-gate architect output): print `[design-confidence] Warning: design-confidence.json not found for <name>. Proceeding without gate.` and continue — backward compatible.
|
|
558
|
+
- **`confidence: "high"` or `"medium"`**: print `[design-confidence] <name>: <level>. Proceeding.` and continue to Phase 3b.
|
|
559
|
+
- **`confidence: "low"`**:
|
|
560
|
+
- If `CONFIDENCE_OVERRIDE_REASON` is non-empty: print `[design-confidence] Override accepted for <name>. Reason: <CONFIDENCE_OVERRIDE_REASON>. Proceeding.` and continue.
|
|
561
|
+
- Otherwise **HALT this feature before any implementation cost is paid.** Print:
|
|
562
|
+
|
|
563
|
+
```
|
|
564
|
+
## Design Confidence Gate: BLOCKED — <name>
|
|
565
|
+
|
|
566
|
+
The architect could not form a confident design.
|
|
567
|
+
|
|
568
|
+
**Reason:** <reason>
|
|
569
|
+
|
|
570
|
+
**Blocking question:** <blocking_question>
|
|
571
|
+
|
|
572
|
+
### Next Steps
|
|
573
|
+
1. Answer the question above (edit the ticket description or refine the spec), then re-run `/specrails:implement`.
|
|
574
|
+
2. Or, to accept the risk and implement the architect's best interpretation:
|
|
575
|
+
`/specrails:implement #N --confidence-override "reason"`
|
|
576
|
+
|
|
577
|
+
No implementation, git, or backlog operations were performed for this feature.
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
- **Pipeline state:** `developer` → `skipped`, `failed_phase` = `architect`, `error_context` = `"design confidence low: <blocking_question>"`.
|
|
581
|
+
- In multi-feature mode, a `low` on one feature halts only that feature — the others continue normally. Halted features appear in the Phase 4e report with Status `BLOCKED (confidence)`.
|
|
582
|
+
|
|
583
|
+
The OpenSpec artifacts the architect produced are intentionally left in place — the answered question turns them into a resumable starting point, not waste.
|
|
584
|
+
|
|
578
585
|
## Phase 3b: Implement
|
|
579
586
|
|
|
580
587
|
### Pre-flight: Verify Bash permission
|
|
@@ -585,6 +592,8 @@ Before launching any developer agent, run a trivial Bash command to confirm Bash
|
|
|
585
592
|
|
|
586
593
|
**Read reviewer learnings:** Check `.claude/agent-memory/sr-reviewer/common-fixes.md` and include in developer prompts.
|
|
587
594
|
|
|
595
|
+
**Test-execution economy:** every developer prompt MUST include this reminder: *"Per-task test runs are SCOPED to the test file(s) the task touches. The full suite runs exactly once, at your validation gate. The reviewer owns the pipeline's authoritative full CI run."*
|
|
596
|
+
|
|
588
597
|
#### Dry-Run: Redirect developer writes
|
|
589
598
|
|
|
590
599
|
**If `DRY_RUN=true`**, include the following in every developer agent prompt:
|
|
@@ -619,11 +628,11 @@ Produce three sets: `FRONTEND_TASKS`, `BACKEND_TASKS`, `OTHER_TASKS`.
|
|
|
619
628
|
|
|
620
629
|
**Step 2 — Route tasks to developer agents:**
|
|
621
630
|
|
|
622
|
-
Routing
|
|
631
|
+
Routing has a single path. When **no profile** is active, every task goes to `sr-developer` — `DEVELOPER_ROUTING = { sr-developer: <all tasks> }`. When a **profile** is active, apply its `ROUTING` rules (below), which may direct some tasks to profile-declared `custom-*` agents.
|
|
623
632
|
|
|
624
|
-
##### Profile
|
|
633
|
+
##### Profile routing
|
|
625
634
|
|
|
626
|
-
|
|
635
|
+
Apply `ROUTING` rules in their array order. For each task, collect its tag set (the layer tags from Step 1 plus any explicit `[tag]` markers in tasks.md). The first rule whose `tags` array intersects the task's tag set wins. The terminal `default: true` rule catches tasks matched by no earlier rule.
|
|
627
636
|
|
|
628
637
|
Example (pseudocode):
|
|
629
638
|
|
|
@@ -655,29 +664,14 @@ assigned_agent_for_task() {
|
|
|
655
664
|
}
|
|
656
665
|
```
|
|
657
666
|
|
|
658
|
-
Produce `DEVELOPER_ROUTING` from the per-task decisions, grouping by assigned agent.
|
|
659
|
-
|
|
660
|
-
##### Legacy mode (`PROFILE_MODE=legacy`)
|
|
661
|
-
|
|
662
|
-
When no profile is active, evaluate available developer agents in `AVAILABLE_AGENTS` and apply these hardcoded rules in priority order:
|
|
667
|
+
Produce `DEVELOPER_ROUTING` from the per-task decisions, grouping by assigned agent. If a rule routes a task to an agent that is **not** in `AVAILABLE_AGENTS` (e.g. a `custom-*` agent that was warned-and-skipped in Phase -1 because its file is missing), that routing target is dropped and the task falls through to the terminal `default: true` rule (which resolves to a baseline agent). Do not STOP for a missing non-baseline target — graceful degradation is intentional.
|
|
663
668
|
|
|
664
|
-
|
|
665
|
-
|-----------|-------------------|------|
|
|
666
|
-
| ALL tasks are frontend-only AND `sr-frontend-developer` ∈ `AVAILABLE_AGENTS` | **sr-frontend-developer** | Single agent for all tasks |
|
|
667
|
-
| ALL tasks are backend-only AND `sr-backend-developer` ∈ `AVAILABLE_AGENTS` | **sr-backend-developer** | Single agent for all tasks |
|
|
668
|
-
| Mix of frontend + backend tasks AND both layer-specific developers available | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for `OTHER_TASKS` | Parallel agents per layer |
|
|
669
|
-
| Frontend tasks exist AND `sr-frontend-developer` available, but no backend-specific developer | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-developer** for remaining | Parallel agents |
|
|
670
|
-
| Backend tasks exist AND `sr-backend-developer` available, but no frontend-specific developer | **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for remaining | Parallel agents |
|
|
671
|
-
| No layer-specific developers available (fallback) | **sr-developer** | Single agent for all tasks |
|
|
672
|
-
|
|
673
|
-
Store the result as `DEVELOPER_ROUTING`: a map of `{agent_id: [task_list]}`.
|
|
674
|
-
|
|
675
|
-
##### Routing trace (both modes)
|
|
669
|
+
##### Routing trace
|
|
676
670
|
|
|
677
671
|
After computing `DEVELOPER_ROUTING`, optionally emit a trace line to aid debugging:
|
|
678
672
|
|
|
679
673
|
```
|
|
680
|
-
[phase-3b] routing decision:
|
|
674
|
+
[phase-3b] routing decision: profile=${PROFILE_NAME:-none} agents=[list]
|
|
681
675
|
```
|
|
682
676
|
|
|
683
677
|
**Step 3 — Print routing decision:**
|
|
@@ -687,16 +681,15 @@ After computing `DEVELOPER_ROUTING`, optionally emit a trace line to aid debuggi
|
|
|
687
681
|
|
|
688
682
|
| Agent | Tasks | Reason |
|
|
689
683
|
|-------|-------|--------|
|
|
690
|
-
| sr-
|
|
691
|
-
|
|
|
692
|
-
| sr-developer | Task 5 | Mixed layer (config + infra) |
|
|
684
|
+
| sr-developer | Task 1, Task 2 | Default (no profile / default rule) |
|
|
685
|
+
| custom-api-dev | Task 3 | Profile routed [backend] tasks here |
|
|
693
686
|
```
|
|
694
687
|
|
|
695
|
-
Also store `DEVELOPER_AGENTS_USED` (the set of developer agent IDs actually launched) —
|
|
688
|
+
Also store `DEVELOPER_AGENTS_USED` (the set of developer agent IDs actually launched) — reported in the Phase 4e summary.
|
|
696
689
|
|
|
697
690
|
#### Launch modes
|
|
698
691
|
|
|
699
|
-
For each entry in `DEVELOPER_ROUTING`, launch the assigned developer agent using its `subagent_type` (`sr-developer
|
|
692
|
+
For each entry in `DEVELOPER_ROUTING`, launch the assigned developer agent using its `subagent_type` (`sr-developer` or a profile-declared `custom-*` developer) with its task subset.
|
|
700
693
|
|
|
701
694
|
**If `SINGLE_MODE` and only one agent in routing**: Launch in the main repo, foreground.
|
|
702
695
|
**If `SINGLE_MODE` but multiple agents in routing**: Launch agents sequentially in the main repo (one at a time, foreground), passing only their assigned tasks.
|
|
@@ -717,84 +710,14 @@ Only after the LAST background agent sends its completion notification, emit the
|
|
|
717
710
|
| <feature-a> | sr-developer | 64 | 8m 02s |
|
|
718
711
|
| <feature-b> | sr-developer | 50 | 7m 35s |
|
|
719
712
|
|
|
720
|
-
All N developers complete. Proceeding to Phase
|
|
713
|
+
All N developers complete. Proceeding to Phase 4.
|
|
721
714
|
```
|
|
722
715
|
|
|
723
716
|
This prevents stale "still waiting" text from appearing as the terminal result when the job completes.
|
|
724
717
|
|
|
725
718
|
**Pipeline state:** update `developer` → `done`. Also update `implemented_files` in the state file with the complete list of files created or modified by the developer agent(s). If developer failed: update `developer` → `failed` with error context `"<agent-id> failed: <exit code or error description>"`.
|
|
726
719
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
**Guard:** If `sr-test-writer` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3c] sr-test-writer not installed — skipping test generation.` Update pipeline state: `test-writer` → `skipped`. Proceed to Phase 3d.
|
|
730
|
-
|
|
731
|
-
Launch a **sr-test-writer** agent (`subagent_type: sr-test-writer`) for each feature immediately after its developer completes.
|
|
732
|
-
|
|
733
|
-
Construct the agent invocation prompt to include:
|
|
734
|
-
- **IMPLEMENTED_FILES_LIST**: the complete list of files the developer created or modified for this feature
|
|
735
|
-
- **TASK_DESCRIPTION**: the original task or feature description that drove the implementation
|
|
736
|
-
|
|
737
|
-
### Launch modes
|
|
738
|
-
|
|
739
|
-
**If `SINGLE_MODE`**: Launch a single sr-test-writer agent in the foreground (`run_in_background: false`). Wait for it to complete before proceeding to Phase 4.
|
|
740
|
-
|
|
741
|
-
**If multiple features (worktrees)**: Launch one sr-test-writer agent per feature, each in its corresponding worktree (`isolation: worktree`, `run_in_background: true`). Wait for all sr-test-writer agents to complete before proceeding to Phase 4.
|
|
742
|
-
|
|
743
|
-
### Dry-run behavior
|
|
744
|
-
|
|
745
|
-
**If `DRY_RUN=true`**, include in every test-writer agent prompt:
|
|
746
|
-
|
|
747
|
-
> IMPORTANT: This is a dry-run. Write all new or modified test files under:
|
|
748
|
-
> .claude/.dry-run/\<feature-name\>/
|
|
749
|
-
>
|
|
750
|
-
> Mirror the real destination path within this directory. After writing each file, append an entry
|
|
751
|
-
> to .claude/.dry-run/\<feature-name\>/.cache-manifest.json using:
|
|
752
|
-
> {"cached_path": "...", "real_path": "...", "operation": "create"}
|
|
753
|
-
|
|
754
|
-
### Failure handling
|
|
755
|
-
|
|
756
|
-
If a test-writer agent fails or times out:
|
|
757
|
-
- Record `Tests: FAILED` for that feature in the Phase 4e report
|
|
758
|
-
- Continue to Phase 4 — the sr-test-writer failure is non-blocking
|
|
759
|
-
- Include in the reviewer agent prompt: "Note: the sr-test-writer failed for this feature. Check for coverage gaps."
|
|
760
|
-
|
|
761
|
-
**Pipeline state:** update `test-writer` → `done` (or `failed` with error context `"sr-test-writer timed out or errored"`). Failure does not block the pipeline.
|
|
762
|
-
|
|
763
|
-
## Phase 3d: Doc Sync
|
|
764
|
-
|
|
765
|
-
**Guard:** If `sr-doc-sync` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3d] sr-doc-sync not installed — skipping doc sync.` Update pipeline state: `doc-sync` → `skipped`. Proceed to Phase 4.
|
|
766
|
-
|
|
767
|
-
Launch a **sr-doc-sync** agent (`subagent_type: sr-doc-sync`) for each feature after its tests are written.
|
|
768
|
-
|
|
769
|
-
Construct the agent invocation prompt to include:
|
|
770
|
-
- **IMPLEMENTED_FILES_LIST**: the complete list of files the developer created or modified for this feature
|
|
771
|
-
- **TASK_DESCRIPTION**: the original task or feature description that drove the implementation
|
|
772
|
-
|
|
773
|
-
### Launch modes
|
|
774
|
-
|
|
775
|
-
**If `SINGLE_MODE`**: Launch a single sr-doc-sync agent in the foreground (`run_in_background: false`). Wait for it to complete before proceeding to Phase 4.
|
|
776
|
-
|
|
777
|
-
**If multiple features (worktrees)**: Launch one sr-doc-sync agent per feature, each in its corresponding worktree (`isolation: worktree`, `run_in_background: true`). Wait for all sr-doc-sync agents to complete before proceeding to Phase 4.
|
|
778
|
-
|
|
779
|
-
### Dry-run behavior
|
|
780
|
-
|
|
781
|
-
**If `DRY_RUN=true`**, include in every doc-sync agent prompt:
|
|
782
|
-
|
|
783
|
-
> IMPORTANT: This is a dry-run. Write all new or modified doc files under:
|
|
784
|
-
> .claude/.dry-run/\<feature-name\>/
|
|
785
|
-
>
|
|
786
|
-
> Mirror the real destination path within this directory. After writing each file, append an entry
|
|
787
|
-
> to .claude/.dry-run/\<feature-name\>/.cache-manifest.json using:
|
|
788
|
-
> {"cached_path": "...", "real_path": "...", "operation": "create|modify"}
|
|
789
|
-
|
|
790
|
-
### Failure handling
|
|
791
|
-
|
|
792
|
-
If a doc-sync agent fails or times out:
|
|
793
|
-
- Record `Docs: FAILED` for that feature in the Phase 4e report
|
|
794
|
-
- Continue to Phase 4 — the sr-doc-sync failure is non-blocking
|
|
795
|
-
- Include in the reviewer agent prompt: "Note: the sr-doc-sync agent failed for this feature."
|
|
796
|
-
|
|
797
|
-
**Pipeline state:** update `doc-sync` → `done` (or `failed` with error context `"sr-doc-sync timed out or errored"`). Failure does not block the pipeline.
|
|
720
|
+
> **Note (v5):** dedicated test-writing (`sr-test-writer`) and doc-sync (`sr-doc-sync`) phases were removed. Tests and documentation are part of each OpenSpec task and are produced by `sr-developer`; the reviewer's TDD and spec-completeness checklist enforces them. A profile may reintroduce equivalent stages via `custom-*` agents with routing.
|
|
798
721
|
|
|
799
722
|
## Phase 4: Merge & Review
|
|
800
723
|
|
|
@@ -890,40 +813,15 @@ After all features are processed, print the preliminary report:
|
|
|
890
813
|
- <file> (features: <a>, <b> — conflicting section: "<heading>")
|
|
891
814
|
```
|
|
892
815
|
|
|
893
|
-
**Step 5a:
|
|
894
|
-
|
|
895
|
-
If `sr-merge-resolver` is not installed, print: `[smart-merge] sr-merge-resolver not installed — skipping merge conflict resolution agent. Fix conflicts manually.` and skip to Step 5b.
|
|
816
|
+
**Step 5a: Conflict handling** (orchestrator-owned; skip if `SINGLE_MODE=true` or `DRY_RUN=true`)
|
|
896
817
|
|
|
897
|
-
If `MERGE_REPORT.requires_resolution` is non-empty:
|
|
818
|
+
There is no dedicated resolver agent. The built-in section-aware / `patch --forward` merge above IS the only resolution path. If `MERGE_REPORT.requires_resolution` is non-empty after the merge, the orchestrator does not guess:
|
|
898
819
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
Build `CONTEXT_BUNDLES` from the features in `MERGE_ORDER`:
|
|
904
|
-
```
|
|
905
|
-
{ "<feature-a>": "${SPECRAILS_REPO_DIR:-.}/openspec/changes/<feature-a>/context-bundle.md", "<feature-b>": "${SPECRAILS_REPO_DIR:-.}/openspec/changes/<feature-b>/context-bundle.md" }
|
|
906
|
-
```
|
|
820
|
+
- Leave the conflict markers in place in the affected files.
|
|
821
|
+
- **Halt the affected features** — do not proceed to Phase 4c (git/PR) for any feature whose files still carry conflict markers. Independent features with no unresolved conflicts continue normally.
|
|
822
|
+
- Print: `[merge] N file(s) have unresolved conflict markers — halting the affected feature(s). Resolve manually, then re-run.`
|
|
907
823
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
Construct the `sr-merge-resolver` agent prompt with:
|
|
911
|
-
- `CONFLICTED_FILES`: all file paths in `MERGE_REPORT.requires_resolution`
|
|
912
|
-
- `CONTEXT_BUNDLES`: the map above
|
|
913
|
-
- `CONFIDENCE_THRESHOLD`: from config or default (70)
|
|
914
|
-
- `RESOLUTION_MODE`: from config or default (`auto`)
|
|
915
|
-
- `REPORT_PATH`: `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<first-feature-in-MERGE_ORDER>/merge-resolution-report.md`
|
|
916
|
-
|
|
917
|
-
Launch the **sr-merge-resolver** agent (`subagent_type: sr-merge-resolver`, foreground, `run_in_background: false`). Wait for it to complete.
|
|
918
|
-
|
|
919
|
-
Read `MERGE_RESOLUTION_STATUS` from the agent's output (`CLEAN`, `PARTIAL`, or `UNRESOLVED`).
|
|
920
|
-
|
|
921
|
-
**Post-resolution: update MERGE_REPORT**
|
|
922
|
-
|
|
923
|
-
For each file in `MERGE_REPORT.requires_resolution`:
|
|
924
|
-
- Re-scan the file for remaining `<<<<<<<` markers.
|
|
925
|
-
- If none remain: move the file from `requires_resolution` → `auto_resolved` (with note: `smart-resolver`).
|
|
926
|
-
- If markers remain: keep in `requires_resolution`.
|
|
824
|
+
Files in `requires_resolution` MUST appear in the Phase 4e final report so the user sees exactly what to fix.
|
|
927
825
|
|
|
928
826
|
**Step 5b: Emit final merge report**
|
|
929
827
|
|
|
@@ -945,7 +843,7 @@ Pipeline will continue. Fix remaining conflicts before the reviewer runs CI.
|
|
|
945
843
|
Resolution report: openspec/changes/<feature>/merge-resolution-report.md
|
|
946
844
|
```
|
|
947
845
|
|
|
948
|
-
If `MERGE_REPORT.requires_resolution` is now empty: print `All conflicts resolved
|
|
846
|
+
If `MERGE_REPORT.requires_resolution` is now empty: print `All conflicts resolved.` and omit the "Requires Manual Resolution" section.
|
|
949
847
|
|
|
950
848
|
**Step 6: Clean up worktrees** (skip if `DRY_RUN=true`)
|
|
951
849
|
|
|
@@ -953,91 +851,23 @@ If `MERGE_REPORT.requires_resolution` is now empty: print `All conflicts resolve
|
|
|
953
851
|
git worktree remove <worktree-path> --force
|
|
954
852
|
```
|
|
955
853
|
|
|
956
|
-
Pass `MERGE_REPORT` to the Phase 4b reviewer agent prompt, listing any files in `requires_resolution`.
|
|
957
|
-
|
|
958
|
-
### 4b. Layer Dispatch and Review
|
|
959
|
-
|
|
960
|
-
#### Step 1: Layer Classification
|
|
961
|
-
|
|
962
|
-
Before launching any reviewer, classify `MODIFIED_FILES_LIST` into layer-specific file sets.
|
|
963
|
-
|
|
964
|
-
**Frontend files** — a file is frontend if any of these conditions match:
|
|
965
|
-
- Extension is one of: `.jsx`, `.tsx`, `.vue`, `.svelte`, `.css`, `.scss`, `.sass`, `.less`, `.html`, `.htm`
|
|
966
|
-
- Extension is `.js` or `.ts` AND path contains one of: `components/`, `pages/`, `views/`, `ui/`, `client/`, `frontend/`, `app/`
|
|
967
|
-
- Path starts with: `public/`, `static/`, `assets/`
|
|
968
|
-
|
|
969
|
-
Set `FRONTEND_FILES` = files matching frontend rules.
|
|
970
|
-
|
|
971
|
-
**Backend files** — a file is backend if any of these conditions match:
|
|
972
|
-
- Extension is one of: `.py`, `.go`, `.java`, `.rb`, `.php`, `.rs`, `.cs`, `.sql`
|
|
973
|
-
- Extension is `.js` or `.ts` AND path contains one of: `server/`, `api/`, `routes/`, `controllers/`, `services/`, `models/`, `db/`, `backend/`
|
|
974
|
-
- Path is under: `migrations/`, `alembic/`, `db/migrate/`
|
|
975
|
-
|
|
976
|
-
Set `BACKEND_FILES` = files matching backend rules.
|
|
977
|
-
|
|
978
|
-
**Overlap rule:** a file may appear in both `FRONTEND_FILES` and `BACKEND_FILES` (e.g., a Next.js API route at `pages/api/`). Both reviewers will scan it independently.
|
|
979
|
-
|
|
980
|
-
#### Step 2: Determine which reviewers to launch
|
|
981
|
-
|
|
982
|
-
A layer reviewer is launched when **both** conditions are met:
|
|
983
|
-
1. There are files to review for that layer (file classification) **OR** the corresponding layer developer was used in Phase 3b (`DEVELOPER_AGENTS_USED`)
|
|
984
|
-
2. The reviewer agent is installed (`∈ AVAILABLE_AGENTS`)
|
|
985
|
-
|
|
986
|
-
| Reviewer | Launch condition | Skip reason |
|
|
987
|
-
|----------|-----------------|-------------|
|
|
988
|
-
| sr-frontend-reviewer | (`FRONTEND_FILES` non-empty OR `sr-frontend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No frontend files + no frontend developer used, or not installed |
|
|
989
|
-
| sr-backend-reviewer | (`BACKEND_FILES` non-empty OR `sr-backend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No backend files + no backend developer used, or not installed |
|
|
990
|
-
| sr-security-reviewer | Installed | Not installed |
|
|
991
|
-
| sr-performance-reviewer | Installed | Not installed |
|
|
992
|
-
|
|
993
|
-
If a reviewer is skipped, set its report variable to `"SKIPPED"` and note the reason.
|
|
994
|
-
|
|
995
|
-
#### Step 3: Launch Layer Reviewers in Parallel
|
|
996
|
-
|
|
997
|
-
Launch all applicable layer reviewers in parallel (`run_in_background: true`), using the corresponding `subagent_type` for each (`sr-frontend-reviewer`, `sr-backend-reviewer`, `sr-security-reviewer`, `sr-performance-reviewer`):
|
|
998
|
-
|
|
999
|
-
**sr-frontend-reviewer** (`subagent_type: sr-frontend-reviewer`, if applicable per Step 2):
|
|
1000
|
-
- Pass `FRONTEND_FILES_LIST`: the list of files in `FRONTEND_FILES`
|
|
1001
|
-
- Pass `PIPELINE_CONTEXT`: brief description of what was implemented
|
|
1002
|
-
|
|
1003
|
-
**sr-backend-reviewer** (`subagent_type: sr-backend-reviewer`, if applicable per Step 2):
|
|
1004
|
-
- Pass `BACKEND_FILES_LIST`: the list of files in `BACKEND_FILES`
|
|
1005
|
-
- Pass `PIPELINE_CONTEXT`: brief description of what was implemented
|
|
1006
|
-
|
|
1007
|
-
**sr-security-reviewer** (`subagent_type: sr-security-reviewer`, if applicable per Step 2):
|
|
1008
|
-
- Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
|
|
1009
|
-
- Pass `PIPELINE_CONTEXT`: brief description of what was implemented
|
|
1010
|
-
- Pass the exemptions config path: `.claude/security-exemptions.yaml`
|
|
1011
|
-
|
|
1012
|
-
**sr-performance-reviewer** (`subagent_type: sr-performance-reviewer`, if applicable per Step 2):
|
|
1013
|
-
- Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
|
|
1014
|
-
- Pass `PIPELINE_CONTEXT`: brief description of what was implemented
|
|
1015
|
-
|
|
1016
|
-
Wait for all launched layer reviewers to complete before proceeding to Step 4.
|
|
1017
|
-
|
|
1018
|
-
Parse status lines from each completed reviewer:
|
|
1019
|
-
- `FRONTEND_REVIEW_STATUS: ISSUES_FOUND` or `CLEAN` → set `FRONTEND_STATUS`
|
|
1020
|
-
- `BACKEND_REVIEW_STATUS: ISSUES_FOUND` or `CLEAN` → set `BACKEND_STATUS`
|
|
1021
|
-
- `SECURITY_STATUS: BLOCKED | WARNINGS | CLEAN` → set `SECURITY_BLOCKED=true` if `BLOCKED`, otherwise `false`
|
|
1022
|
-
|
|
1023
|
-
If a layer reviewer fails or times out: set the relevant report variable to `"ERROR: reviewer did not complete"` and continue.
|
|
1024
|
-
|
|
1025
|
-
#### Step 4: Launch Generalist Reviewer
|
|
854
|
+
Pass `MERGE_REPORT` to the Phase 4b reviewer agent prompt, listing any files in `requires_resolution`.
|
|
1026
855
|
|
|
1027
|
-
|
|
856
|
+
### 4b. Review
|
|
1028
857
|
|
|
1029
|
-
|
|
1030
|
-
- `BACKEND_REVIEW_REPORT`: full output of backend-reviewer (or `"SKIPPED"`)
|
|
1031
|
-
- `SECURITY_REVIEW_REPORT`: full output of security-reviewer
|
|
858
|
+
There is a single reviewer, `sr-reviewer`. It owns every review dimension — correctness, TDD/spec completeness, code quality, **security**, and **performance** — scaled to what the change actually touches (its checklist covers all of them). There are no separate layer-reviewer passes.
|
|
1032
859
|
|
|
1033
|
-
|
|
1034
|
-
-
|
|
860
|
+
Construct the reviewer's invocation prompt with:
|
|
861
|
+
- `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
|
|
862
|
+
- `PIPELINE_CONTEXT`: a brief description of what was implemented
|
|
863
|
+
- `MERGE_REPORT`: any files still in `requires_resolution` (multi-feature runs)
|
|
864
|
+
- The security-exemptions config path: `.claude/security-exemptions.yaml` (if present)
|
|
865
|
+
- Full CI commands (reference material for its scoped-first verification policy — the reviewer runs diff-scoped tests plus fast static checks, escalating to one full pass only when its own fixes warrant it; the developer's Phase 4 full pass is the baseline)
|
|
1035
866
|
- Cross-feature merge issue checks
|
|
1036
867
|
- Instruction to record learnings to `common-fixes.md`
|
|
1037
868
|
- Instruction to archive completed changes via OpenSpec
|
|
1038
|
-
- The three layer report variables substituted into the `[injected]` slots in the reviewer agent template
|
|
1039
869
|
|
|
1040
|
-
|
|
870
|
+
The reviewer emits `SECURITY_STATUS: BLOCKED | WARNINGS | CLEAN`. Set `SECURITY_BLOCKED=true` if `BLOCKED`, otherwise `false`.
|
|
1041
871
|
|
|
1042
872
|
**The security gate (blocking ship on `SECURITY_STATUS: BLOCKED`) is enforced in Phase 4c.** Do not apply it here.
|
|
1043
873
|
|
|
@@ -1407,7 +1237,6 @@ Include the shipping mode in the report:
|
|
|
1407
1237
|
|
|
1408
1238
|
## Error Handling
|
|
1409
1239
|
|
|
1410
|
-
- If a sr-product-manager fails: skip that area, continue with others
|
|
1411
1240
|
- If a sr-architect fails: skip that area, report the failure
|
|
1412
1241
|
- If a sr-developer fails: report which phase it failed at
|
|
1413
1242
|
- If the sr-reviewer finds unfixable issues: report them, push what works
|
|
@@ -122,12 +122,14 @@ If `AGENT_FILTER` is set (single-agent mode), show the full content of each file
|
|
|
122
122
|
|
|
123
123
|
## Phase 4: Orphan Detection
|
|
124
124
|
|
|
125
|
-
An **orphaned** memory directory is one whose agent name does not correspond to a known
|
|
125
|
+
An **orphaned** memory directory is one whose agent name does not correspond to a known agent.
|
|
126
126
|
|
|
127
|
-
Known
|
|
128
|
-
`sr-architect`, `sr-developer`, `sr-
|
|
127
|
+
Known agent names (check for exact match):
|
|
128
|
+
`sr-architect`, `sr-developer`, `sr-reviewer`
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
Any directory whose name begins with `custom-` is a user- or profile-owned agent and is **never** orphaned — treat the `custom-` prefix as known.
|
|
131
|
+
|
|
132
|
+
For each directory in `AGENT_DIRS`, check whether its `AGENT_NAME` is in the known list (or carries the `custom-` prefix). Collect non-matching directories as `ORPHANED_DIRS`.
|
|
131
133
|
|
|
132
134
|
If `ORPHANED_DIRS` is non-empty, print:
|
|
133
135
|
|