specrails-core 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +103 -310
  2. package/bin/specrails-core.mjs +3 -1
  3. package/dist/installer/cli.js +4 -0
  4. package/dist/installer/cli.js.map +1 -1
  5. package/dist/installer/commands/framework.js +64 -49
  6. package/dist/installer/commands/framework.js.map +1 -1
  7. package/dist/installer/commands/init.js +102 -66
  8. package/dist/installer/commands/init.js.map +1 -1
  9. package/dist/installer/commands/update.js +80 -74
  10. package/dist/installer/commands/update.js.map +1 -1
  11. package/dist/installer/commands/v5-migration.js +14 -0
  12. package/dist/installer/commands/v5-migration.js.map +1 -1
  13. package/dist/installer/phases/framework-lifecycle.js +2 -0
  14. package/dist/installer/phases/framework-lifecycle.js.map +1 -1
  15. package/dist/installer/phases/scaffold.js +191 -258
  16. package/dist/installer/phases/scaffold.js.map +1 -1
  17. package/dist/installer/runtime/pipeline-state.js +801 -0
  18. package/dist/installer/runtime/pipeline-state.js.map +1 -0
  19. package/dist/installer/util/exec.js +6 -1
  20. package/dist/installer/util/exec.js.map +1 -1
  21. package/dist/installer/util/fs.js +11 -2
  22. package/dist/installer/util/fs.js.map +1 -1
  23. package/dist/installer/util/install-transaction.js +246 -0
  24. package/dist/installer/util/install-transaction.js.map +1 -0
  25. package/dist/installer/util/registry.js +20 -0
  26. package/dist/installer/util/registry.js.map +1 -1
  27. package/docs/ci-cd.md +57 -0
  28. package/docs/user-docs/codex-vs-claude-code.md +23 -151
  29. package/docs/user-docs/core-updates.md +70 -0
  30. package/docs/user-docs/provider-pipelines.md +53 -0
  31. package/integration-contract.json +179 -66
  32. package/package.json +5 -2
  33. package/templates/agents/sr-developer.md +9 -11
  34. package/templates/agents/sr-reviewer.md +26 -33
  35. package/templates/codex-skills/batch-implement/SKILL.md +58 -244
  36. package/templates/codex-skills/implement/SKILL.md +136 -338
  37. package/templates/codex-skills/rails/sr-architect/SKILL.md +7 -0
  38. package/templates/codex-skills/rails/sr-developer/SKILL.md +13 -0
  39. package/templates/codex-skills/rails/sr-reviewer/SKILL.md +39 -5
  40. package/templates/codex-skills/retry/SKILL.md +37 -117
  41. package/templates/commands/specrails/batch-implement.md +16 -288
  42. package/templates/commands/specrails/implement.md +62 -1057
  43. package/templates/commands/specrails/retry.md +22 -314
  44. package/templates/gemini-commands/batch-implement.toml +28 -40
  45. package/templates/gemini-commands/implement.toml +55 -114
  46. package/templates/gemini-commands/retry.toml +21 -0
  47. package/templates/kimi/specrails/run-skill.mjs +51 -2
  48. package/templates/runtime/provider-pipeline.md +55 -0
@@ -1,44 +1,74 @@
1
1
  {
2
- "schemaVersion": "3.2",
2
+ "schemaVersion": "4.0",
3
3
  "providers": {
4
4
  "claude": {
5
- "enrichCommand": "/specrails:enrich",
6
- "enrichArgs": ["--from-config"],
7
- "updateCommand": "/specrails:enrich",
8
- "updateArgs": ["--update"],
5
+ "updateCommand": "update",
9
6
  "cli": {
10
- "initArgs": [],
11
- "enrichArgs": ["--dangerously-skip-permissions", "--output-format", "stream-json", "-p", "/specrails:enrich"],
12
- "enrichFromConfigArgs": ["--dangerously-skip-permissions", "--output-format", "stream-json", "-p", "/specrails:enrich --from-config"]
7
+ "initArgs": [
8
+ "init",
9
+ "--yes",
10
+ "--provider",
11
+ "claude"
12
+ ],
13
+ "updateArgs": [
14
+ "update",
15
+ "--provider",
16
+ "claude"
17
+ ]
18
+ },
19
+ "initCommand": "init",
20
+ "workflows": {
21
+ "implement": "/specrails:implement",
22
+ "batch-implement": "/specrails:batch-implement",
23
+ "retry": "/specrails:retry"
13
24
  }
14
25
  },
15
26
  "codex": {
16
- "enrichCommand": "$enrich",
17
- "enrichArgs": ["--from-config"],
18
- "updateCommand": "$enrich",
19
- "updateArgs": ["--update"],
27
+ "updateCommand": "update",
20
28
  "cli": {
21
- "initArgs": [],
22
- "enrichArgs": ["exec", "run enrich"],
23
- "enrichFromConfigArgs": ["exec", "run enrich --from-config"]
29
+ "initArgs": [
30
+ "init",
31
+ "--yes",
32
+ "--provider",
33
+ "codex"
34
+ ],
35
+ "updateArgs": [
36
+ "update",
37
+ "--provider",
38
+ "codex"
39
+ ]
40
+ },
41
+ "initCommand": "init",
42
+ "workflows": {
43
+ "implement": "$implement",
44
+ "batch-implement": "$batch-implement",
45
+ "retry": "$retry"
24
46
  }
25
47
  },
26
48
  "gemini": {
27
- "enrichCommand": "/specrails:enrich",
28
- "enrichArgs": ["--from-config"],
29
- "updateCommand": "/specrails:enrich",
30
- "updateArgs": ["--update"],
49
+ "updateCommand": "update",
31
50
  "cli": {
32
- "initArgs": [],
33
- "enrichArgs": ["-p", "/specrails:enrich", "--output-format", "stream-json"],
34
- "enrichFromConfigArgs": ["-p", "/specrails:enrich --from-config", "--output-format", "stream-json"]
51
+ "initArgs": [
52
+ "init",
53
+ "--yes",
54
+ "--provider",
55
+ "gemini"
56
+ ],
57
+ "updateArgs": [
58
+ "update",
59
+ "--provider",
60
+ "gemini"
61
+ ]
62
+ },
63
+ "initCommand": "init",
64
+ "workflows": {
65
+ "implement": "/specrails:implement",
66
+ "batch-implement": "/specrails:batch-implement",
67
+ "retry": "/specrails:retry"
35
68
  }
36
69
  },
37
70
  "kimi": {
38
- "enrichCommand": "/skill:specrails-enrich",
39
- "enrichArgs": ["--from-config"],
40
- "updateCommand": "/skill:specrails-enrich",
41
- "updateArgs": ["--update"],
71
+ "updateCommand": "update",
42
72
  "cli": {
43
73
  "binary": "node",
44
74
  "providerBinary": "kimi",
@@ -69,89 +99,172 @@
69
99
  "windowsPromptTransport": "For the standard npm kimi.cmd/bat shim, prompt bytes travel over stdin to a fixed Node bootstrap which restores process.argv before importing Kimi; native executables fail above a 30000 UTF-16 command-line budget.",
70
100
  "initialActivationTelemetry": "Visible prompt parity only; the external materializer cannot emit Kimi-private skill.activated/origin telemetry.",
71
101
  "cancellation": "Single-skill mode forwards SIGINT/SIGTERM/SIGHUP to its direct Kimi child. Role-wave mode forwards each termination signal to every live Kimi child and waits for aggregate completion; the embedding host remains responsible for platform process-tree teardown.",
72
- "initArgs": [],
73
- "enrichArgs": [".kimi-code/specrails/run-skill.mjs", "--skill", "specrails-enrich", "--model", "k3"],
74
- "enrichFromConfigArgs": [".kimi-code/specrails/run-skill.mjs", "--skill", "specrails-enrich", "--model", "k3", "--args", "--from-config"],
75
- "resumeArgs": ["--session=<session-id>"],
76
- "notes": "CLI-only integration. enrichCommand/updateCommand are interactive Kimi TUI syntax only. Headless callers must execute binary + enrichArgs; plain `kimi -p \"/skill:...\"` is literal prompt text in Kimi 0.27 and does not activate a skill. The managed Node runner materializes the upstream user-slash prompt, then launches external Kimi with stream-json and no shell. Generated multi-role workflows use one bounded role-wave file so context never enters shell source and parallel roles cannot race on request paths. Do not start kimi web/server; authenticate once with `kimi login`."
102
+ "initArgs": [
103
+ "init",
104
+ "--yes",
105
+ "--provider",
106
+ "kimi"
107
+ ],
108
+ "resumeArgs": [
109
+ "--session=<session-id>"
110
+ ],
111
+ "notes": "CLI-only provider execution. Installation/update uses the deterministic Core CLI above. Headless workflows use the managed Node skill runner, never literal /skill text in kimi -p. Role waves await every child and preserve frozen Core execution context. Authenticate once with kimi login.",
112
+ "updateArgs": [
113
+ "update",
114
+ "--provider",
115
+ "kimi"
116
+ ],
117
+ "workflowArgs": [
118
+ ".kimi-code/specrails/run-skill.mjs",
119
+ "--skill",
120
+ "<skill-id>",
121
+ "--model",
122
+ "<model-id>",
123
+ "--args",
124
+ "<arguments>"
125
+ ]
126
+ },
127
+ "initCommand": "init",
128
+ "workflows": {
129
+ "implement": "/skill:specrails-implement",
130
+ "batch-implement": "/skill:specrails-batch-implement",
131
+ "retry": "/skill:specrails-retry"
77
132
  }
78
133
  }
79
134
  },
80
135
  "tiers": {
81
- "quick": {
82
- "description": "Template-based install with minimal defaults. No AI codebase analysis. Agents are functional immediately.",
83
- "enrichFlag": "--quick",
84
- "checkpoints": ["base_install", "agent_selection", "agent_generation"],
136
+ "standard": {
137
+ "description": "Deterministic installation of the core agents, provider workflows and required skills. No model invocation or enrichment.",
138
+ "checkpoints": [
139
+ "base_install",
140
+ "agent_generation",
141
+ "command_generation"
142
+ ],
85
143
  "requiresEnrich": false
86
- },
87
- "full": {
88
- "description": "Full AI-powered install. Analyzes codebase, generates VPC personas, creates personalized agents.",
89
- "enrichFlag": "--from-config",
90
- "checkpoints": ["codebase_analysis", "vpc_discovery", "persona_synthesis", "agent_generation", "command_generation"],
91
- "requiresEnrich": true
92
144
  }
93
145
  },
94
146
  "configSchema": {
95
147
  "file": ".specrails/install-config.yaml",
96
148
  "version": 1,
97
149
  "fields": {
98
- "version": "number schema version, currently 1",
99
- "provider": "string claude | codex | gemini | kimi",
100
- "tier": "string full | quick",
101
- "agents.selected": "string[] unique lowercase kebab-case agent ids to install (1-64 characters)",
102
- "agents.excluded": "string[] unique lowercase kebab-case agent ids to skip; must not overlap agents.selected",
103
- "models.preset": "string balanced | budget | max; resolved within the selected provider catalog",
104
- "models.defaults.model": "string exact provider model id or configured alias (overrides preset; Kimi: 1-128 characters matching [A-Za-z0-9][A-Za-z0-9._/:-]*; default: k3)",
105
- "models.overrides": "Record<safe-agent-id, string> exact per-agent provider model ids or configured aliases with the same provider-specific validation (highest priority)"
150
+ "version": "number \u2014 schema version, currently 1",
151
+ "provider": "string \u2014 claude | codex | gemini | kimi",
152
+ "tier": "Deprecated legacy string, tolerated and ignored; all installs use deterministic placement.",
153
+ "agents.selected": "string[] \u2014 unique lowercase kebab-case agent ids to install (1-64 characters)",
154
+ "agents.excluded": "string[] \u2014 unique lowercase kebab-case agent ids to skip; must not overlap agents.selected",
155
+ "models.preset": "string \u2014 balanced | budget | max; resolved within the selected provider catalog",
156
+ "models.defaults.model": "string \u2014 exact provider model id or configured alias (overrides preset; Kimi: 1-128 characters matching [A-Za-z0-9][A-Za-z0-9._/:-]*; default: k3)",
157
+ "models.overrides": "Record<safe-agent-id, string> \u2014 exact per-agent provider model ids or configured aliases with the same provider-specific validation (highest priority)"
106
158
  }
107
159
  },
108
160
  "checkpoints": {
109
- "base_install": "Templates and directory structure copied",
110
- "agent_selection": "Agent list finalized from config or TUI",
111
- "codebase_analysis": "Codebase language/framework/architecture detected",
112
- "vpc_discovery": "VPC personas researched and drafted",
113
- "persona_synthesis": "Final persona files written",
114
- "agent_generation": "All selected agents generated with placeholders filled",
115
- "command_generation": "All workflow commands installed and configured"
161
+ "base_install": "Runtime prerequisites and artifact workspace resolved",
162
+ "agent_generation": "Core agents and selected custom roles placed",
163
+ "command_generation": "Workflow commands, required skills and installation manifest verified"
116
164
  },
117
165
  "modelPresets": {
118
166
  "balanced": {
119
167
  "scope": "claude",
120
168
  "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
121
- "defaults": { "model": "sonnet" },
169
+ "defaults": {
170
+ "model": "sonnet"
171
+ },
122
172
  "overrides": {}
123
173
  },
124
174
  "budget": {
125
175
  "scope": "claude",
126
176
  "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
127
- "defaults": { "model": "haiku" },
177
+ "defaults": {
178
+ "model": "haiku"
179
+ },
128
180
  "overrides": {}
129
181
  },
130
182
  "max": {
131
183
  "scope": "claude",
132
184
  "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
133
- "defaults": { "model": "sonnet" },
134
- "overrides": { "sr-architect": "opus", "sr-product-manager": "opus" }
185
+ "defaults": {
186
+ "model": "sonnet"
187
+ },
188
+ "overrides": {
189
+ "sr-architect": "opus",
190
+ "sr-product-manager": "opus"
191
+ }
135
192
  }
136
193
  },
137
194
  "providerModelCatalogs": {
138
195
  "kimi": {
139
196
  "default": "k3",
140
- "models": ["k3", "kimi-for-coding", "kimi-for-coding-highspeed"],
197
+ "models": [
198
+ "k3",
199
+ "kimi-for-coding",
200
+ "kimi-for-coding-highspeed"
201
+ ],
141
202
  "presets": {
142
- "balanced": { "defaults": { "model": "k3" }, "overrides": {} },
143
- "budget": { "defaults": { "model": "k3" }, "overrides": {} },
144
- "max": { "defaults": { "model": "k3" }, "overrides": {} }
203
+ "balanced": {
204
+ "defaults": {
205
+ "model": "k3"
206
+ },
207
+ "overrides": {}
208
+ },
209
+ "budget": {
210
+ "defaults": {
211
+ "model": "k3"
212
+ },
213
+ "overrides": {}
214
+ },
215
+ "max": {
216
+ "defaults": {
217
+ "model": "k3"
218
+ },
219
+ "overrides": {}
220
+ }
145
221
  },
146
222
  "cliAliasPrefix": "kimi-code/",
147
223
  "reasoningEfforts": {
148
- "k3": ["low", "high", "max"]
224
+ "k3": [
225
+ "low",
226
+ "high",
227
+ "max"
228
+ ]
149
229
  },
150
230
  "note": "Install config and profiles retain exact ids or safe custom aliases. Preset names do not imply Claude aliases for Kimi. Process launch prefixes only the three documented official short ids with kimi-code/; every custom alias that matches the published model grammar passes through unchanged."
151
231
  }
152
232
  },
153
233
  "legacyCompat": {
154
234
  "setupCommandAlias": false,
155
- "note": "The Node-native installer ships /specrails:enrich only. Existing repos should prune any leftover /specrails:setup alias during re-install or update."
235
+ "enrichCommand": false,
236
+ "note": "Core 5 installs directly. Legacy config tier is tolerated; enrich, --quick and --lite are removed. Hosts must negotiate schema 4 deterministic lifecycle."
237
+ },
238
+ "lifecycle": {
239
+ "mode": "deterministic",
240
+ "requiresEnrich": false,
241
+ "initCommand": "init",
242
+ "updateCommand": "update",
243
+ "minimumCoreMajor": 5,
244
+ "removedCommands": [
245
+ "enrich"
246
+ ],
247
+ "removedFlags": [
248
+ "--quick",
249
+ "--lite"
250
+ ]
251
+ },
252
+ "execution": {
253
+ "schemaVersion": 1,
254
+ "contextEnv": "SPECRAILS_EXECUTION_CONTEXT",
255
+ "context": "Absolute JSON file: runId, backlogRoot, backlogPath?, artifactRoot, artifactRepositoryId, repositories[{id,name,path,baseSha?}], ownership{git,backlog,worktrees:host|core}, specs[{id,title,description,repositoryIds?,acceptanceCriteria?}]",
256
+ "runtime": ".specrails/runtime/pipeline.mjs",
257
+ "operations": [
258
+ "init",
259
+ "status",
260
+ "phase",
261
+ "verify",
262
+ "archive-check",
263
+ "preview",
264
+ "apply-preview"
265
+ ],
266
+ "statePath": "<backlogRoot>/.specrails/pipeline/<runId>/state.json",
267
+ "verification": "Successful argv-based commands captured by the runtime, bound to frozen scope, candidate files and relevant execution environment. Unknown or stale evidence cannot pass archive.",
268
+ "hostOwnership": "Host worktrees are used directly; host git/backlog are not mutated by Core delivery."
156
269
  }
157
270
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specrails-core",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "Provider-independent AI agent workflow system for Claude Code, Codex, Gemini CLI, and Kimi Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -61,7 +61,10 @@
61
61
  "test:watch": "vitest",
62
62
  "test:coverage": "npm run build && vitest run --coverage",
63
63
  "dogfood": "npm run build && node bin/specrails-core.mjs init --yes",
64
- "prepack": "npm run build"
64
+ "prepack": "npm run build",
65
+ "test:scripts": "node --test scripts/release-utils.test.mjs",
66
+ "check:package": "npm run build && node scripts/verify-package.mjs",
67
+ "ci": "npm run typecheck && npm run test:scripts && npm run test:coverage && npm run check:package"
65
68
  },
66
69
  "dependencies": {
67
70
  "@inquirer/prompts": "^7.0.0",
@@ -50,17 +50,15 @@ You are a polyglot engineer with extraordinary depth in:
50
50
 
51
51
  You don't just write code that works — you write code that is elegant, maintainable, testable, and performant.
52
52
 
53
- ## Repository location (read first)
53
+ ## Frozen execution handoff
54
54
 
55
- Your working directory may NOT be the user's source repository. The user's source code, `openspec/**`, the project `CLAUDE.md`, `.claude/rules/`, and `.git` all live under **`${SPECRAILS_REPO_DIR:-.}`** (the env var is set by the spawner to the repo path; when it is unset it defaults to `.`, i.e. the current directory byte-identical to a classic in-repo run).
55
+ Read the supplied absolute SPECRAILS_EXECUTION_CONTEXT. Preserve frozen specs/acceptance, run/change and selected repository IDs. Every source path is resolved against its task's repository; only a single selected root has an implicit target. Never refetch scope or mutate host-owned Git, backlog or worktrees.
56
56
 
57
- Concretely:
58
- - **Every openspec read/write** targets `${SPECRAILS_REPO_DIR:-.}/openspec/...`.
59
- - **Every source-file edit** named in `tasks.md` uses repo-relative paths (e.g. `src/foo.ts`); resolve and edit them as `${SPECRAILS_REPO_DIR:-.}/<path>` so the change lands in the real repo, not the working directory.
60
- - **CI / build / test commands** run from inside the repo — `cd "${SPECRAILS_REPO_DIR:-.}"` (or run them with that as the working directory) before invoking them.
61
- - **Convention scans** of the project `CLAUDE.md` and `.claude/rules/` read from `${SPECRAILS_REPO_DIR:-.}`.
57
+ SPECRAILS_REPO_DIR points to artifactRoot for `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<specName>/` and the official apply workflow. Source edits/test cwd use their own repository paths; framework workspace, backlogRoot and artifactRoot can differ.
62
58
 
63
- Run-state directories you write to during a run `.claude/agent-memory/`, `.claude/pipeline-state/` are NOT repo-resident; leave them relative to the working directory.
59
+ Coordinator owns phase transitions. Keep workers foreground, collect terminal results and resume unchecked tasks without discarding completed implementation.
60
+
61
+ Execute checks through `node "${SPECRAILS_PIPELINE_RUNTIME:-.specrails/runtime/pipeline.mjs}" verify --request <stateDir/checks.json>`. Requests contain kind (scoped/full) and commands with repositoryId, command, args, explicit cwd and optional env/timeoutMs. Use scoped repair requests, then one final full request covering every selected repo after aggregate task completion. Runtime captures actual evidence; never hand-write a PASS receipt. Requests/notes belong under stateDir.
64
62
 
65
63
  ## Your Mission
66
64
 
@@ -93,7 +91,7 @@ You MUST follow Test-Driven Development. This is non-negotiable. The cycle is: *
93
91
  - Read the OpenSpec change spec thoroughly
94
92
  - Read referenced base specs
95
93
  - Read layer-specific CLAUDE.md files ({{LAYER_CLAUDE_MD_PATHS}})
96
- - **Read recent failure records**: Check `.claude/agent-memory/failures/` for JSON records where `file_pattern` matches files you will create or modify. For each matching record, treat `prevention_rule` as an explicit guardrail in your implementation plan. If the directory does not exist or is empty, proceed normally — this is expected on fresh installs.
94
+ - **Read recent failure records**: Check `<stateDir>/notes/failures/` for JSON records where `file_pattern` matches files you will create or modify. For each matching record, treat `prevention_rule` as an explicit guardrail in your implementation plan. If the directory does not exist or is empty, proceed normally — this is expected on fresh installs.
97
95
  - Identify all files that need to be created or modified
98
96
  - Understand the data flow through the architecture
99
97
 
@@ -220,7 +218,7 @@ You MUST run ALL of these checks after implementation — **once, at the Phase 4
220
218
 
221
219
  ## Explain Your Work
222
220
 
223
- When you make a significant implementation decision, write an explanation record to `.claude/agent-memory/explanations/`.
221
+ When you make a significant implementation decision, write an explanation record to `<stateDir>/notes/explanations/`.
224
222
 
225
223
  **Write an explanation when you:**
226
224
  - Chose an implementation approach over a plausible alternative
@@ -236,7 +234,7 @@ When you make a significant implementation decision, write an explanation record
236
234
  **How to write an explanation record:**
237
235
 
238
236
  Create a file at:
239
- `.claude/agent-memory/explanations/YYYY-MM-DD-developer-<slug>.md`
237
+ `<stateDir>/notes/explanations/YYYY-MM-DD-developer-<slug>.md`
240
238
 
241
239
  Use today's date. Use a kebab-case slug describing the decision topic (max 6 words).
242
240
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sr-reviewer
3
- description: "Use this agent as the final quality gate after developer agents complete implementation. It reviews all code changes, runs the exact CI/CD checks, fixes issues, and ensures everything will pass in the CI pipeline. Launch once after all developer worktrees have been merged into the main repo.\n\nExamples:\n\n- Example 1:\n user: (orchestrator) All developers completed. Review the merged result.\n assistant: \"Launching the reviewer agent to run CI-equivalent checks and fix any issues.\"\n\n- Example 2:\n user: (orchestrator) Developer agent finished implementing. Verify before PR.\n assistant: \"Let me launch the reviewer agent to validate the implementation matches CI requirements.\""
3
+ description: "Use this agent as the final quality gate after developer agents complete implementation. It reviews all code changes, runs the exact CI/CD checks, fixes issues, and ensures everything will pass in the CI pipeline. Launch once on the complete candidate in the selected repository roots.\n\nExamples:\n\n- Example 1:\n user: (orchestrator) All developers completed. Review the merged result.\n assistant: \"Launching the reviewer agent to run CI-equivalent checks and fix any issues.\"\n\n- Example 2:\n user: (orchestrator) Developer agent finished implementing. Verify before PR.\n assistant: \"Let me launch the reviewer agent to validate the implementation matches CI requirements.\""
4
4
  model: sonnet
5
5
  color: red
6
6
  memory: project
@@ -43,9 +43,15 @@ Leave empty to review all areas with equal weight.
43
43
 
44
44
  Do not proceed with any review work until specName is confirmed.
45
45
 
46
- ## Repository location (read first)
46
+ ## Frozen execution and receipt handoff
47
47
 
48
- Your working directory may NOT be the user's source repository. The user's source code, `openspec/**`, and `.git` all live under **`${SPECRAILS_REPO_DIR:-.}`** (the spawner sets the env var to the repo path; unset defaults to `.`, i.e. byte-identical to a classic in-repo run). Read the change spec from `${SPECRAILS_REPO_DIR:-.}/openspec/...`, and run every CI / build / test / `git` command from inside the repo `cd "${SPECRAILS_REPO_DIR:-.}"` (or use it as the working directory) before invoking them. (The archive Skill resolves `openspec/**` itself; only your own on-disk verification reads need the prefix.)
48
+ Read supplied immutable SPECRAILS_EXECUTION_CONTEXT and exact specName. Preserve frozen requirements, selected repository IDs/paths and ownership; never select the newest artifact directory or another backlog.
49
+
50
+ SPECRAILS_REPO_DIR points to artifactRoot for `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<specName>/`. Source inspection, fixes and test cwd follow each task's repository ID. Do not mutate host-owned Git/backlog/worktrees.
51
+
52
+ Inspect managed runtime status --json. Reuse the developer's full receipt only when verification.valid is true and its commands cover required checks. Execute scoped/full requests via `node "${SPECRAILS_PIPELINE_RUNTIME:-.specrails/runtime/pipeline.mjs}" verify --request <stateDir/checks.json>`. Requests include kind and structured repositoryId/command/args/cwd; edits require one fresh final full receipt. No baseline PASS proves missing acceptance.
53
+
54
+ Coordinator owns phase transitions. Normal review returns acceptance/security evidence and canonical confidence before archive authorization.
49
55
 
50
56
  ## Your Mission
51
57
 
@@ -130,41 +136,30 @@ After running CI checks, also review for:
130
136
  - Search for any lines matching `- [ ]` (hyphen, space, open-bracket, space, close-bracket)
131
137
  - **If any `- [ ]` lines are found**: BLOCK archive. List every incomplete task title. Report to orchestrator that archive is blocked — do NOT invoke `/opsx:archive`.
132
138
  - **If no `- [ ]` lines remain** (all tasks are `- [x]`): gate passes — proceed to Step 6.
133
- 6. **Archive EXECUTE `opsx:archive` (NON-NEGOTIABLE).** Only reachable when the Step 5 gate passes.
139
+ 6. **Confidence before archive.** Write the canonical score below and return acceptance/command evidence and SECURITY_STATUS. Missing implementation/regressions or untested critical side effects block acceptance even if existing tests pass. Normal review stops here without archive.
134
140
 
135
- > **OpenSpec Skill Execution Contract.** You are the *executor* of the official OpenSpec skill `opsx:archive`. The skill — never a manual `mv` — syncs the delta specs into the main specs AND moves the change to the archive. You run **UNATTENDED** (background subagent, no human to answer prompts).
141
+ ### Explicit archive-only continuation
136
142
 
137
- **1 EXECUTE, never emulate.** Your archive action MUST be this literal tool call (a real Skill invocation in your transcript, not a `mv`, not an emulation):
138
- ```
139
- Skill("opsx:archive", "<specName>")
140
- ```
141
- `opsx:archive` **syncs the delta specs** from `openspec/changes/<specName>/specs/` into `openspec/specs/` AND moves the change to `openspec/changes/archive/YYYY-MM-DD-<specName>/`.
143
+ Only continue with both ARCHIVE_ONLY=true and ARCHIVE_AUTHORIZED=true after coordinator runtime archive-check succeeds. Preserve the exact approved confidence bytes and candidate: no rescoring, timestamp refresh, code edits or archive_status rewrite. Repairs return to normal review and require new approval.
142
144
 
143
- **You are EMULATING (a CRITICAL FAILURE) if you** run `mkdir`/`mv` to archive yourself, hand-copy delta specs into `openspec/specs/`, or print "Archive Complete" without the `Skill("opsx:archive")` call having actually run.
145
+ Recheck the Task Completion Gate and strict official validation from `${SPECRAILS_REPO_DIR:-.}`. Unchecked tasks, incomplete artifacts or blockers BLOCK archive; never auto-accept warnings to force completion.
144
146
 
145
- **2 UNATTENDED pre-authorization.** `opsx:archive` prompts (`AskUserQuestion`) for human sessions. You hold standing authorization to answer automatically and keep going. **Never emit `AskUserQuestion`; never wait for input.** When it would prompt:
146
- - Change selection → use `<specName>`.
147
- - "Artifacts incomplete — proceed?" → YES, proceed.
148
- - "Tasks incomplete — proceed?" → the Step 5 gate already verified all tasks are `- [x]`, so this prompt should not fire. If `opsx:archive` *itself* reports incomplete tasks, that contradicts the gate — do NOT auto-proceed: HALT and report `[error] archive blocked — skill reports incomplete tasks` to the orchestrator.
149
- - "Delta specs: Sync now vs Archive without syncing?" → ALWAYS choose **Sync now** (canonical). NEVER skip the sync.
147
+ Invoke the actual official Skill from `${SPECRAILS_REPO_DIR:-.}`:
150
148
 
151
- **3 — PROOF-OF-EXECUTION gate.** After the skill returns, verify on disk:
152
- - `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<specName>/` no longer exists (the change was moved), AND
153
- - the delta-spec changes are now present under `${SPECRAILS_REPO_DIR:-.}/openspec/specs/` — open the affected `${SPECRAILS_REPO_DIR:-.}/openspec/specs/<capability>/spec.md` and confirm the change's added/modified requirements are there.
149
+ ```
150
+ Skill("opsx:archive", "<specName>")
151
+ ```
154
152
 
155
- If the move happened but the specs were NOT synced (the classic *simulated-archive* symptom), recover canonically **never hand-copy**:
156
- - a. Invoke `Skill("opsx:sync", "<specName>")` (the official sync skill) and re-verify.
157
- - b. If the change was not moved at all, re-invoke `Skill("opsx:archive", "<specName>")` once.
158
- - c. If specs are still not synced after that, HALT and report `[error] archive incomplete — delta specs not synced` to the orchestrator. Do NOT treat the change as done and do NOT fake it with manual file ops.
153
+ Verify `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<specName>/` moved to its matching archive with unchanged confidence. Verify affected `${SPECRAILS_REPO_DIR:-.}/openspec/specs/<capability>/spec.md` contains synced requirements. Do not emulate with filesystem copies/moves. Official failure remains resumable.
159
154
 
160
- **4 Execution receipt.** Finish with an `## OpenSpec Skill Execution Receipt` section stating the exact `Skill("opsx:archive", …)` (and any `Skill("opsx:sync", …)`) calls you made, the archive path the change moved to, and the `openspec/specs/**` files that now reflect the synced deltas.
155
+ Return exact Skill calls and resulting paths as the OpenSpec Skill Execution Receipt. Coordinator records archive done; do not rewrite confidence after the move.
161
156
 
162
157
  ## Write Failure Records
163
158
 
164
159
  After completing the review report, for each distinct failure category found (one record per class of failure, not per instance):
165
160
 
166
- 1. Create a JSON file at `.claude/agent-memory/failures/<YYYY-MM-DD>-<error-type-slug>.json`.
167
- 2. Populate all fields using the schema in `.claude/agent-memory/failures/README.md`.
161
+ 1. Create a JSON file at `<stateDir>/notes/failures/<YYYY-MM-DD>-<error-type-slug>.json`.
162
+ 2. Populate all fields using the schema in `<stateDir>/notes/failures/README.md`.
168
163
  3. Write `root_cause` based on what you observed — be specific, include file and line if known.
169
164
  4. Write `prevention_rule` as an actionable imperative for the next developer: "Always...", "Never...", "Before X, do Y".
170
165
  5. Set `file_pattern` to the glob that best matches where this failure class appears.
@@ -185,7 +180,7 @@ Do NOT write a record when:
185
180
 
186
181
  ### Idempotency
187
182
 
188
- Before writing a new record, scan `.claude/agent-memory/failures/` for any existing file where `error_type` matches and `prevention_rule` is substantively identical. If found, skip — do not create duplicates for the same known pattern.
183
+ Before writing a new record, scan `<stateDir>/notes/failures/` for any existing file where `error_type` matches and `prevention_rule` is substantively identical. If found, skip — do not create duplicates for the same known pattern.
189
184
 
190
185
  ## Output Format
191
186
 
@@ -233,7 +228,7 @@ The `SECURITY_STATUS:` line is MANDATORY and machine-parsed by the orchestrator
233
228
 
234
229
  ## Explain Your Work
235
230
 
236
- When you make a non-trivial quality judgment, write an explanation record to `.claude/agent-memory/explanations/`.
231
+ When you make a non-trivial quality judgment, write an explanation record to `<stateDir>/notes/explanations/`.
237
232
 
238
233
  **Write an explanation when you:**
239
234
  - Applied a lint rule fix that has non-obvious reasoning
@@ -249,7 +244,7 @@ When you make a non-trivial quality judgment, write an explanation record to `.c
249
244
  **How to write an explanation record:**
250
245
 
251
246
  Create a file at:
252
- `.claude/agent-memory/explanations/YYYY-MM-DD-reviewer-<slug>.md`
247
+ `<stateDir>/notes/explanations/YYYY-MM-DD-reviewer-<slug>.md`
253
248
 
254
249
  Use today's date. Use a kebab-case slug describing the decision topic (max 6 words).
255
250
 
@@ -273,7 +268,7 @@ Optional sections: `## Why This Approach`, `## Alternatives Considered`, `## See
273
268
 
274
269
  ## Confidence Scoring
275
270
 
276
- After completing all CI checks and fixes, you MUST produce a confidence score. This is non-optional. Write the score file before reporting your results.
271
+ During normal review, after checks/fixes and BEFORE archive, you MUST produce a confidence score. Write it before normal review returns. Archive-only continuations preserve it byte-for-byte.
277
272
 
278
273
  ### What to assess
279
274
 
@@ -295,9 +290,7 @@ Score semantics:
295
290
 
296
291
  ### How to derive the change name
297
292
 
298
- The change name is the kebab-case directory under `${SPECRAILS_REPO_DIR:-.}/openspec/changes/` that was active during this review. It is typically provided in your invocation prompt by the orchestrator. If not provided explicitly, find it by listing `${SPECRAILS_REPO_DIR:-.}/openspec/changes/` and identifying the directory most recently modified.
299
-
300
- If the change name cannot be determined: write the score with `"change": "unknown"` and `"overall": 0`, and populate every `notes` field with an explanation of why the name could not be determined.
293
+ Use required specName and verify it matches the journal. Never infer identity by modification time or write an unknown score. Missing/mismatched identity blocks review.
301
294
 
302
295
  ### Output file
303
296