specrails-core 5.6.0 → 6.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.
Files changed (275) hide show
  1. package/README.md +27 -145
  2. package/bin/specrails-core.mjs +12 -554
  3. package/dist/agent-runtime/capabilities.js +0 -1
  4. package/dist/agent-runtime/cli-executor.d.ts +1 -1
  5. package/dist/agent-runtime/cli-executor.js +1 -2
  6. package/dist/agent-runtime/cli-process.js +0 -1
  7. package/dist/agent-runtime/cli.js +3 -4
  8. package/dist/agent-runtime/codex-schema.js +0 -1
  9. package/dist/agent-runtime/compact/architect.d.ts +3 -272
  10. package/dist/agent-runtime/compact/architect.js +8 -9
  11. package/dist/agent-runtime/compact/chat-client.d.ts +3 -3
  12. package/dist/agent-runtime/compact/chat-client.js +1 -2
  13. package/dist/agent-runtime/compact/developer.d.ts +3 -70
  14. package/dist/agent-runtime/compact/developer.js +13 -14
  15. package/dist/agent-runtime/compact/environment.d.ts +4 -5
  16. package/dist/agent-runtime/compact/environment.js +1 -2
  17. package/dist/agent-runtime/compact/exit-code-honesty.d.ts +2 -1
  18. package/dist/agent-runtime/compact/exit-code-honesty.js +0 -1
  19. package/dist/agent-runtime/compact/guarded-loop.d.ts +2 -18
  20. package/dist/agent-runtime/compact/guarded-loop.js +7 -8
  21. package/dist/agent-runtime/compact/prompt-inputs.d.ts +0 -2
  22. package/dist/agent-runtime/compact/prompt-inputs.js +1 -2
  23. package/dist/agent-runtime/compact/reviewer.d.ts +0 -13
  24. package/dist/agent-runtime/compact/reviewer.js +5 -6
  25. package/dist/agent-runtime/compact/step.d.ts +0 -1
  26. package/dist/agent-runtime/compact/step.js +1 -2
  27. package/dist/agent-runtime/compact/test-reachability.js +0 -1
  28. package/dist/agent-runtime/config.js +0 -1
  29. package/dist/agent-runtime/core-host.d.ts +1 -1
  30. package/dist/agent-runtime/core-host.js +1 -2
  31. package/dist/agent-runtime/durable-store.d.ts +0 -1
  32. package/dist/agent-runtime/durable-store.js +1 -2
  33. package/dist/agent-runtime/efficiency-summary.d.ts +2 -2
  34. package/dist/agent-runtime/efficiency-summary.js +1 -2
  35. package/dist/agent-runtime/efficiency-types.js +0 -1
  36. package/dist/agent-runtime/efficiency.js +0 -1
  37. package/dist/agent-runtime/evaluation-corpus.js +0 -1
  38. package/dist/agent-runtime/evaluation.d.ts +2 -1
  39. package/dist/agent-runtime/evaluation.js +1 -2
  40. package/dist/agent-runtime/executor-types.d.ts +1 -1
  41. package/dist/agent-runtime/executor-types.js +0 -1
  42. package/dist/agent-runtime/executors.js +0 -1
  43. package/dist/agent-runtime/gemini-policy.js +0 -1
  44. package/dist/agent-runtime/graph/artifacts.d.ts +1 -1
  45. package/dist/agent-runtime/graph/artifacts.js +1 -2
  46. package/dist/agent-runtime/graph/nodes.d.ts +1 -1
  47. package/dist/agent-runtime/graph/nodes.js +1 -2
  48. package/dist/agent-runtime/graph/review-policy.js +0 -1
  49. package/dist/agent-runtime/graph/roles.d.ts +2 -5
  50. package/dist/agent-runtime/graph/roles.js +2 -8
  51. package/dist/agent-runtime/graph/state.d.ts +1 -1
  52. package/dist/agent-runtime/graph/state.js +0 -1
  53. package/dist/agent-runtime/graph-checkpointer.d.ts +2 -1
  54. package/dist/agent-runtime/graph-checkpointer.js +0 -1
  55. package/dist/agent-runtime/guardrails.d.ts +3 -3
  56. package/dist/agent-runtime/guardrails.js +1 -2
  57. package/dist/agent-runtime/index.d.ts +1 -1
  58. package/dist/agent-runtime/index.js +1 -2
  59. package/dist/agent-runtime/kimi-acp.js +1 -2
  60. package/dist/agent-runtime/kimi-model.d.ts +6 -0
  61. package/dist/agent-runtime/kimi-model.js +12 -0
  62. package/dist/agent-runtime/openai-executor.d.ts +0 -9
  63. package/dist/agent-runtime/openai-executor.js +6 -7
  64. package/dist/agent-runtime/openspec-tool-server.js +1 -2
  65. package/dist/agent-runtime/openspec.d.ts +0 -2
  66. package/dist/agent-runtime/openspec.js +1 -6
  67. package/dist/agent-runtime/prompts.d.ts +4 -3
  68. package/dist/agent-runtime/prompts.js +0 -1
  69. package/dist/agent-runtime/provider-diagnostic.js +1 -2
  70. package/dist/agent-runtime/recovery.js +1 -2
  71. package/dist/agent-runtime/repository-context.d.ts +1 -1
  72. package/dist/agent-runtime/repository-context.js +0 -1
  73. package/dist/agent-runtime/review-context.d.ts +1 -1
  74. package/dist/agent-runtime/review-context.js +0 -1
  75. package/dist/agent-runtime/role-routing.js +0 -1
  76. package/dist/agent-runtime/role-state.js +0 -1
  77. package/dist/agent-runtime/runtime-identity.js +1 -2
  78. package/dist/agent-runtime/tool-event.js +0 -1
  79. package/dist/agent-runtime/verification-plan.d.ts +5 -4
  80. package/dist/agent-runtime/verification-plan.js +1 -2
  81. package/dist/agent-runtime/workflow-types.js +0 -1
  82. package/dist/agent-runtime/workflow.js +0 -1
  83. package/dist/agent-runtime/workspace-tools.d.ts +2 -2
  84. package/dist/agent-runtime/workspace-tools.js +1 -2
  85. package/dist/installer/cli.d.ts +3 -32
  86. package/dist/installer/cli.js +26 -101
  87. package/dist/installer/commands/framework.d.ts +4 -3
  88. package/dist/installer/commands/framework.js +0 -1
  89. package/dist/installer/commands/init.d.ts +4 -25
  90. package/dist/installer/commands/init.js +5 -8
  91. package/dist/installer/phases/framework-lifecycle.d.ts +3 -17
  92. package/dist/installer/phases/framework-lifecycle.js +2 -3
  93. package/dist/installer/phases/install-config.d.ts +7 -8
  94. package/dist/installer/phases/install-config.js +2 -7
  95. package/dist/installer/phases/manifest.d.ts +6 -7
  96. package/dist/installer/phases/manifest.js +2 -7
  97. package/dist/installer/phases/prereqs.d.ts +6 -7
  98. package/dist/installer/phases/prereqs.js +4 -6
  99. package/dist/installer/phases/provider-detect.d.ts +6 -7
  100. package/dist/installer/phases/provider-detect.js +2 -4
  101. package/dist/installer/phases/scaffold.d.ts +9 -10
  102. package/dist/installer/phases/scaffold.js +82 -805
  103. package/dist/installer/util/errors.js +0 -1
  104. package/dist/installer/util/exec.d.ts +3 -2
  105. package/dist/installer/util/exec.js +0 -1
  106. package/dist/installer/util/fs.d.ts +0 -10
  107. package/dist/installer/util/fs.js +1 -2
  108. package/dist/installer/util/git.js +0 -1
  109. package/dist/installer/util/install-transaction.d.ts +2 -2
  110. package/dist/installer/util/install-transaction.js +1 -2
  111. package/dist/installer/util/logger.d.ts +1 -3
  112. package/dist/installer/util/logger.js +0 -1
  113. package/dist/installer/util/paths.js +0 -1
  114. package/dist/installer/util/registry.d.ts +4 -8
  115. package/dist/installer/util/registry.js +2 -3
  116. package/dist/{installer/runtime → pipeline}/pipeline-state.js +0 -3
  117. package/dist/shared/args.d.ts +18 -0
  118. package/dist/shared/args.js +53 -0
  119. package/integration-contract.json +10 -46
  120. package/package.json +3 -10
  121. package/templates/agents/sr-architect.md +15 -310
  122. package/templates/agents/sr-developer.md +15 -269
  123. package/templates/agents/sr-reviewer.md +13 -367
  124. package/templates/codex-skills/rails/sr-architect/SKILL.md +14 -308
  125. package/templates/codex-skills/rails/sr-developer/SKILL.md +14 -201
  126. package/templates/codex-skills/rails/sr-reviewer/SKILL.md +15 -289
  127. package/templates/kimi/specrails/run-skill.mjs +91 -2173
  128. package/bin/tui-installer.mjs +0 -430
  129. package/commands/doctor.md +0 -62
  130. package/dist/agent-runtime/capabilities.js.map +0 -1
  131. package/dist/agent-runtime/cli-executor.js.map +0 -1
  132. package/dist/agent-runtime/cli-process.js.map +0 -1
  133. package/dist/agent-runtime/cli.js.map +0 -1
  134. package/dist/agent-runtime/codex-schema.js.map +0 -1
  135. package/dist/agent-runtime/compact/architect.js.map +0 -1
  136. package/dist/agent-runtime/compact/chat-client.js.map +0 -1
  137. package/dist/agent-runtime/compact/developer.js.map +0 -1
  138. package/dist/agent-runtime/compact/environment.js.map +0 -1
  139. package/dist/agent-runtime/compact/exit-code-honesty.js.map +0 -1
  140. package/dist/agent-runtime/compact/guarded-loop.js.map +0 -1
  141. package/dist/agent-runtime/compact/prompt-inputs.js.map +0 -1
  142. package/dist/agent-runtime/compact/reviewer.js.map +0 -1
  143. package/dist/agent-runtime/compact/step.js.map +0 -1
  144. package/dist/agent-runtime/compact/test-reachability.js.map +0 -1
  145. package/dist/agent-runtime/config.js.map +0 -1
  146. package/dist/agent-runtime/core-host.js.map +0 -1
  147. package/dist/agent-runtime/durable-store.js.map +0 -1
  148. package/dist/agent-runtime/efficiency-summary.js.map +0 -1
  149. package/dist/agent-runtime/efficiency-types.js.map +0 -1
  150. package/dist/agent-runtime/efficiency.js.map +0 -1
  151. package/dist/agent-runtime/evaluation-corpus.js.map +0 -1
  152. package/dist/agent-runtime/evaluation.js.map +0 -1
  153. package/dist/agent-runtime/executor-types.js.map +0 -1
  154. package/dist/agent-runtime/executors.js.map +0 -1
  155. package/dist/agent-runtime/gemini-policy.js.map +0 -1
  156. package/dist/agent-runtime/graph/artifacts.js.map +0 -1
  157. package/dist/agent-runtime/graph/nodes.js.map +0 -1
  158. package/dist/agent-runtime/graph/review-policy.js.map +0 -1
  159. package/dist/agent-runtime/graph/roles.js.map +0 -1
  160. package/dist/agent-runtime/graph/state.js.map +0 -1
  161. package/dist/agent-runtime/graph-checkpointer.js.map +0 -1
  162. package/dist/agent-runtime/guardrails.js.map +0 -1
  163. package/dist/agent-runtime/index.js.map +0 -1
  164. package/dist/agent-runtime/kimi-acp.js.map +0 -1
  165. package/dist/agent-runtime/openai-executor.js.map +0 -1
  166. package/dist/agent-runtime/openspec-tool-server.js.map +0 -1
  167. package/dist/agent-runtime/openspec.js.map +0 -1
  168. package/dist/agent-runtime/prompts.js.map +0 -1
  169. package/dist/agent-runtime/provider-diagnostic.js.map +0 -1
  170. package/dist/agent-runtime/recovery.js.map +0 -1
  171. package/dist/agent-runtime/repository-context.js.map +0 -1
  172. package/dist/agent-runtime/review-context.js.map +0 -1
  173. package/dist/agent-runtime/role-routing.js.map +0 -1
  174. package/dist/agent-runtime/role-state.js.map +0 -1
  175. package/dist/agent-runtime/runtime-identity.js.map +0 -1
  176. package/dist/agent-runtime/tool-event.js.map +0 -1
  177. package/dist/agent-runtime/verification-plan.js.map +0 -1
  178. package/dist/agent-runtime/workflow-types.js.map +0 -1
  179. package/dist/agent-runtime/workflow.js.map +0 -1
  180. package/dist/agent-runtime/workspace-tools.js.map +0 -1
  181. package/dist/installer/cli.js.map +0 -1
  182. package/dist/installer/commands/doctor.d.ts +0 -27
  183. package/dist/installer/commands/doctor.js +0 -615
  184. package/dist/installer/commands/doctor.js.map +0 -1
  185. package/dist/installer/commands/framework.js.map +0 -1
  186. package/dist/installer/commands/init.js.map +0 -1
  187. package/dist/installer/commands/update.d.ts +0 -56
  188. package/dist/installer/commands/update.js +0 -257
  189. package/dist/installer/commands/update.js.map +0 -1
  190. package/dist/installer/commands/v5-migration.d.ts +0 -32
  191. package/dist/installer/commands/v5-migration.js +0 -133
  192. package/dist/installer/commands/v5-migration.js.map +0 -1
  193. package/dist/installer/phases/framework-lifecycle.js.map +0 -1
  194. package/dist/installer/phases/install-config.js.map +0 -1
  195. package/dist/installer/phases/manifest.js.map +0 -1
  196. package/dist/installer/phases/prereqs.js.map +0 -1
  197. package/dist/installer/phases/provider-detect.js.map +0 -1
  198. package/dist/installer/phases/scaffold.js.map +0 -1
  199. package/dist/installer/runtime/kimi.d.ts +0 -84
  200. package/dist/installer/runtime/kimi.js +0 -255
  201. package/dist/installer/runtime/kimi.js.map +0 -1
  202. package/dist/installer/runtime/pipeline-state.js.map +0 -1
  203. package/dist/installer/util/errors.js.map +0 -1
  204. package/dist/installer/util/exec.js.map +0 -1
  205. package/dist/installer/util/fs.js.map +0 -1
  206. package/dist/installer/util/git.js.map +0 -1
  207. package/dist/installer/util/install-transaction.js.map +0 -1
  208. package/dist/installer/util/logger.js.map +0 -1
  209. package/dist/installer/util/paths.js.map +0 -1
  210. package/dist/installer/util/prompts.d.ts +0 -23
  211. package/dist/installer/util/prompts.js +0 -49
  212. package/dist/installer/util/prompts.js.map +0 -1
  213. package/dist/installer/util/registry.js.map +0 -1
  214. package/dist/installer/util/template.d.ts +0 -23
  215. package/dist/installer/util/template.js +0 -60
  216. package/dist/installer/util/template.js.map +0 -1
  217. package/docs/README.md +0 -40
  218. package/docs/agent-runtime-efficiency.md +0 -65
  219. package/docs/agent-runtime.md +0 -393
  220. package/docs/agents.md +0 -315
  221. package/docs/changelog.md +0 -168
  222. package/docs/ci-cd.md +0 -60
  223. package/docs/concepts.md +0 -183
  224. package/docs/customization.md +0 -363
  225. package/docs/deployment.md +0 -234
  226. package/docs/getting-started.md +0 -122
  227. package/docs/installation.md +0 -395
  228. package/docs/local-tickets.md +0 -191
  229. package/docs/migration-guide.md +0 -140
  230. package/docs/playbook-oss-maintainer.md +0 -112
  231. package/docs/playbook-parallel-dev.md +0 -124
  232. package/docs/playbook-product-discovery.md +0 -115
  233. package/docs/plugin-architecture.md +0 -144
  234. package/docs/research/codex-compatibility-analysis.md +0 -365
  235. package/docs/research/mcp-feasibility-analysis.md +0 -382
  236. package/docs/testing/test-matrix-codex.md +0 -130
  237. package/docs/updating.md +0 -89
  238. package/docs/user-docs/cli-reference.md +0 -428
  239. package/docs/user-docs/codex-vs-claude-code.md +0 -23
  240. package/docs/user-docs/core-updates.md +0 -70
  241. package/docs/user-docs/faq.md +0 -146
  242. package/docs/user-docs/getting-started-codex.md +0 -194
  243. package/docs/user-docs/getting-started-kimi.md +0 -423
  244. package/docs/user-docs/installation.md +0 -237
  245. package/docs/user-docs/provider-pipelines.md +0 -96
  246. package/docs/user-docs/quick-start.md +0 -161
  247. package/docs/windows.md +0 -78
  248. package/docs/workflows.md +0 -463
  249. package/schemas/profile.v1.json +0 -207
  250. package/templates/claude-md/CLAUDE-quickstart.md +0 -54
  251. package/templates/claude-md/root.md +0 -50
  252. package/templates/codex-skills/batch-implement/SKILL.md +0 -38
  253. package/templates/codex-skills/implement/SKILL.md +0 -38
  254. package/templates/codex-skills/retry/SKILL.md +0 -16
  255. package/templates/commands/specrails/compat-check.md +0 -271
  256. package/templates/commands/specrails/doctor.md +0 -62
  257. package/templates/commands/specrails/explore-spec.md +0 -173
  258. package/templates/commands/specrails/health-check.md +0 -527
  259. package/templates/commands/specrails/memory-inspect.md +0 -261
  260. package/templates/commands/specrails/opsx-diff.md +0 -419
  261. package/templates/commands/specrails/propose-spec.md +0 -102
  262. package/templates/commands/specrails/refactor-recommender.md +0 -169
  263. package/templates/commands/specrails/telemetry.md +0 -553
  264. package/templates/commands/specrails/why.md +0 -96
  265. package/templates/gemini-commands/batch-implement.toml +0 -37
  266. package/templates/gemini-commands/implement.toml +0 -37
  267. package/templates/gemini-commands/retry.toml +0 -15
  268. package/templates/profiles/default.json +0 -14
  269. package/templates/profiles/kimi-default.json +0 -15
  270. package/templates/rules/layer.md +0 -8
  271. package/templates/runtime/provider-pipeline.md +0 -113
  272. package/templates/security/security-exemptions.yaml +0 -20
  273. package/templates/settings/confidence-config.json +0 -17
  274. package/templates/settings/settings.json +0 -15
  275. /package/dist/{installer/runtime → pipeline}/pipeline-state.d.ts +0 -0
@@ -1,65 +0,0 @@
1
- # Efficient programmatic implementation
2
-
3
- New runs use workflow 5 and instructions 7. Architect, developer and reviewer keep their official OpenSpec workflow: fast-forward, apply and verify. Verification remains deterministic Core execution, not a fourth AI agent. Custom role text does not replace the mandatory scope, response or OpenSpec protocol.
4
-
5
- ## Configuration
6
-
7
- Optional schema-version-1 settings:
8
-
9
- ```json
10
- {
11
- "efficiency": {
12
- "schemaVersion": 1,
13
- "contextMode": "incremental",
14
- "reviewMode": "incremental",
15
- "planning": "proportional",
16
- "acceptDeveloperChecks": true,
17
- "verification": { "maxConcurrency": 1 }
18
- }
19
- }
20
- ```
21
-
22
- These defaults are normalized once at admission and frozen. `full` disables the corresponding adaptive policy. Incremental context requires a compatible session and a transport that explicitly guarantees continuation. Built-in CLI transports currently report continuation as unknown; stateless API and Kimi transports cannot receive a partial packet. They receive full context. A smaller prompt in the offline continuation fixture does **not** imply the same saving on every provider.
23
-
24
- Each role optionally accepts `effort` and one `escalation: { model, effort? }` within the same provider. Query actual installed support with `specrails-core runtime capabilities --config config.json`; this never runs inference. Unknown effort support rejects an explicit value at admission. Omitting effort leaves the provider default. No economic tier is selected automatically.
25
-
26
- Architect escalation is limited to the existing deepen pass. Developer escalation can begin on the third permitted candidate, after two failed outcomes; it adds no attempt to the configured limit. Reviewer escalation repairs malformed responses only, never a valid code rejection. Selected tiers and role session identities persist across interruption. All calls, including repairs, consume the existing budgets.
27
-
28
- ## Checks and evidence
29
-
30
- Host and architect checks form an immutable baseline. Developers can add up to 20 checks per response, with at most 100 effective checks. Reusing a developer key replaces that addition's active revision; omitted additions remain required. A harness contains at most eight UTF-8 source files, 64 KiB each and 256 KiB per proposal. Sources live outside delivery under the run's state directory, not in the product repository. The runtime expands a structured command and exports `SPECRAILS_CHECK_REPO_ROOT` for locating repository files.
31
-
32
- Receipts, acceptance and archive approval bind the candidate and complete verification plan. Source changes, interrupted checks or a newer failure cannot reuse an older green result. A nonterminal continuation rechecks and asks the reviewer to certify the current acceptance criteria; terminal reads do not execute checks. Previously granted archive consent only survives when the candidate, plan and acceptance decisions remain identical.
33
-
34
- Checks default to `policy.reuse: "never"`. Host-only `snapshot-local` reuse requires explicit deterministic/read-only declarations, complete input/toolchain/dependency contents and a proven executable identity. Ignored installed dependencies must be declared; an unchanged lockfile is insufficient. Unknown inputs rerun. Concurrency defaults to one, with a maximum of four. Only contiguous checks in the same host-declared independence group, on distinct repositories with explicit nonoverlapping resources, run together. Missing resources mean unknown; an explicit empty array means no shared resources.
35
-
36
- Read recorded evidence without invoking agents:
37
-
38
- ```sh
39
- specrails-core runtime evidence --context desktop-context.json --limit 25
40
- specrails-core runtime evidence --context desktop-context.json --id EVIDENCE_ID --section stdout
41
- specrails-core runtime evidence --context desktop-context.json --id EVIDENCE_ID --section source --source-id SOURCE_ID
42
- ```
43
-
44
- List responses discover opaque evidence/source IDs and bound pagination cursors. Output pages are bounded; stdout/stderr captures retain at most 1 MiB each, with redaction, hashes and truncation markers. Historical source snapshots remain readable after worktree removal. They describe that execution, not current validity. The same scoped resolver is available to developer/reviewer through API and MCP tools.
45
-
46
- ## Reproducible evaluation
47
-
48
- Build first, then run the actual offline command:
49
-
50
- ```sh
51
- npm run build
52
- node bin/specrails-core.mjs runtime evaluate --output /tmp/specrails-efficiency-evaluation
53
- ```
54
-
55
- Five fixed cases cover static Tetris-like logic, a local feature, a cross-repository contract, verification correction and review correction. Each independent oracle must accept its reference implementation and reject deliberately defective variants. Full and optimized modes use fresh repositories/sessions and identical acceptance gates. The fixed long-context correction must shrink at least 40% without extra invocations. Reports record task, oracle, repository, configuration and runtime identities, failures, sample variation and independent acceptance.
56
-
57
- Offline tokens and zero fixture cost are synthetic. The initial offline run accepted 5/5 cases in both modes and reduced its fixed correction prompt from 4,774 to 1,777 bytes (62.8%). It did not demonstrate lower monetary cost or faster real-provider execution. Repeat after implementation changes; the report records the tested package identity.
58
-
59
- Real evaluation is opt-in only: `runtime evaluate --real --config EXPLICIT_MODELS.json --max-cost-usd BUDGET --output OUTPUT`. Select all models and authorize the aggregate spend first. Unsupported spend limits prevent launch; incomplete billing stops further calls. The report distinguishes same-model from configured routing experiments and evaluates the descriptive target of 20% lower aggregate cost per independently accepted output. Small samples and uncontrolled provider caches do not establish universal quality or savings.
60
-
61
- ## Compatibility and rollback
62
-
63
- A v4 checkpoint requires its original runtime. Never rewrite checksums or substitute a newly installed package. Desktop retains an immutable package and dependency closure per admitted run. Restoring that proven package is the recovery path; an unknown original package cannot be inferred from matching workflow inputs alone. New runtime configuration or package changes affect new runs only.
64
-
65
- This source tree is a development package. Publishing Core and updating Desktop's exact version/integrity lock are separate coordinated release steps; local assembly is not proof that a new version has been published.
@@ -1,393 +0,0 @@
1
- # Programmatic agent runtime
2
-
3
- Core executes implementation as a local TypeScript workflow:
4
-
5
- ```text
6
- architect → developer → verify → reviewer → archive
7
- │ ↑ │ │
8
- │ └──────────┴─────────┘ bounded corrections
9
- └─ investigate once, then ask (or proceed on stated assumptions)
10
- ```
11
-
12
- The workflow is a [LangGraph](https://docs.langchain.com/oss/javascript/langgraph/overview) state graph. LangGraph owns the traversal, the typed state and its reducers, the checkpoint history, dynamic interrupts (approvals and questions) and time travel; Core owns the role reports, the OpenSpec workflow binding, the verification subprocesses, the acceptance evidence, the receipts, budgets, leases and interrupted-write recovery. Provider adapters execute one role and load its official OpenSpec skill through the explicit headless tool binding; they never invoke the retired implementation orchestrator.
13
-
14
- The developer role has the same autonomy the legacy Implement step had: it edits files and runs commands inside its CLI's own sandbox (Claude `--tools default --dangerously-skip-permissions` with nested agents and skills disallowed, Codex `workspace-write`, Gemini `--yolo`, Kimi ACP auto mode), so it can run the project's tests before handing off. The architect reads code and authors change artifacts through confined OpenSpec tools; the reviewer stays read-only. Claude roles load only project settings (`--setting-sources project,local`), so `CLAUDE.md` and `.claude/rules` apply while the user's global memory and plugins do not.
15
-
16
- This page describes the current source implementation, **runtime API 1**, workflow version 4, checkpoint envelope format 2. An older published Core package can have the same major version and lack this export. Build the paired checkout when developing this feature; do not assume `@latest` contains unreleased changes.
17
-
18
- ## Requirements and ownership
19
-
20
- - Node.js **20.19.0+** and Git on macOS or Windows. Individual provider CLIs may require a newer Node release.
21
- - Installed and authenticated Claude, Codex, Gemini or Kimi CLIs for whichever roles use them; alternatively, a reachable OpenAI-compatible endpoint with tool support.
22
- - A frozen execution context and a new change name. Verification commands are optional: configured commands run as given, the architect proposes the project's own checks for repositories that have none, and a repository with no automated check is admitted and recorded as unverified in the receipt.
23
- - `ownership.git: "host"`. The runtime implements and archives; its caller owns worktrees, commits, pushes, pull requests and backlog delivery. It rejects Core-owned Git delivery rather than reporting success while shipping remains pending.
24
-
25
- Specrails, LangGraph and the runtime infrastructure are open source and require no paid orchestration service, tracing backend, Python daemon or database server. Model inference, hardware and existing provider CLIs retain their own costs and license terms. No model download or provider subscription is included.
26
-
27
- ## Configure providers and roles
28
-
29
- Save this as `.specrails/agent-runtime.json`, adapting the verification command to your repository:
30
-
31
- ```json
32
- {
33
- "schemaVersion": 1,
34
- "enabled": true,
35
- "providers": [
36
- { "id": "claude", "kind": "cli", "cli": "claude" },
37
- { "id": "codex", "kind": "cli", "cli": "codex" },
38
- { "id": "gemini", "kind": "cli", "cli": "gemini" },
39
- { "id": "kimi", "kind": "cli", "cli": "kimi" },
40
- {
41
- "id": "local",
42
- "kind": "openai-compatible",
43
- "baseUrl": "http://127.0.0.1:11434/v1"
44
- }
45
- ],
46
- "agents": {
47
- "architect": { "provider": "claude", "maxTurns": 100 },
48
- "developer": { "provider": "codex", "maxTurns": 100 },
49
- "reviewer": { "provider": "gemini", "maxTurns": 100 }
50
- },
51
- "limits": { "maxAttempts": 3, "timeoutMs": 900000 },
52
- "verification": [
53
- { "repositoryId": "app", "command": "node", "args": ["--test"] }
54
- ],
55
- "review": { "minScore": 80, "aspects": { "security": 85 } },
56
- "architect": { "onLowConfidence": "ask" },
57
- "approvalBeforeArchive": false
58
- }
59
- ```
60
-
61
- `verification` may be an empty array. At run time Core builds the effective plan from the configured commands plus the architect's proposals for uncovered repositories; the plan is frozen in the graph state and reused by every verification and resume. When the plan covers no repository at all, the run still passes through task completion and review, and the receipt lists those repositories under `unverifiedRepositories`.
62
-
63
- `review` tightens the review gate. Core's own gate is the floor: overall score at least 70, `security` at least 75, every other aspect at least 60. A lower value is rejected by validation, because the pipeline journal enforces the floor regardless of configuration. The reviewer is told the effective thresholds.
64
-
65
- `architect.onLowConfidence` decides what happens when the architect still reports low confidence after its investigation pass (see [Questions and approvals](#questions-and-approvals)): `ask` (default) pauses the run with the architect's question; `proceed` continues on the assumptions the architect stated, recording `design-confidence.json` as `medium` with `assumed: true` and the original `reportedConfidence`.
66
-
67
- Set any role's `provider` to `kimi` to use Kimi. A CLI role's optional `model` is passed to that provider; omitting it uses the CLI's default. Provider IDs are aliases, so you can configure several endpoints or replace an executor without changing workflow code.
68
-
69
- To use the local endpoint, set the desired role to `{"provider":"local","model":"your-installed-model-id","maxTurns":100}`. The endpoint must support `POST <baseUrl>/chat/completions`, OpenAI-style function tool calls and a final assistant result. Its model must actually be able to use these tools; a chat-only endpoint is insufficient for the developer role. The example port is a placeholder for your own running server.
70
-
71
- For an authenticated endpoint, add `"apiKeyEnv":"MY_MODEL_API_KEY"` to its provider configuration and set that variable in the process launching Core. Omit `apiKeyEnv` when no key is required. URLs cannot contain credentials, query parameters or fragments. Verification commands inherit process credentials; do not put secrets into their persisted `env` overrides.
72
-
73
- The configuration schema is [agent-runtime.schema.json](../schemas/agent-runtime.schema.json). `validateRuntimeConfig()` also checks relationships such as role-to-provider references and the review floors. Runtime configuration is separate from the existing [profile v1 schema](../schemas/profile.v1.json); it does not translate legacy profile routing into programmatic phases.
74
-
75
- ## Run from the CLI
76
-
77
- Use an installed Core package that exposes runtime API 1. For a source checkout, run `npm ci` and `npm run build` in Core, then replace `specrails-core` below with `node /path/to/specrails-core/bin/specrails-core.mjs`.
78
-
79
- Desktop constructs the execution context automatically. For standalone use, create a context JSON with absolute paths:
80
-
81
- ```json
82
- {
83
- "schemaVersion": 1,
84
- "runId": "feature-navigation-01",
85
- "backlogRoot": "/absolute/path/to/app",
86
- "artifactRoot": "/absolute/path/to/app",
87
- "artifactRepositoryId": "app",
88
- "repositories": [
89
- { "id": "app", "name": "App", "path": "/absolute/path/to/app" }
90
- ],
91
- "ownership": { "git": "host", "backlog": "host", "worktrees": "host" },
92
- "specs": [
93
- {
94
- "id": "navigation",
95
- "title": "Keyboard navigation",
96
- "description": "Implement the agreed keyboard navigation behavior.",
97
- "repositoryIds": ["app"],
98
- "acceptanceCriteria": ["Every setting can be reached using the keyboard."]
99
- }
100
- ]
101
- }
102
- ```
103
-
104
- On Windows use absolute paths such as `C:/work/app` or JSON-escaped `C:\\work\\app`. Repository paths must identify existing Git repositories. Multi-repository contexts list every selected repository; `artifactRoot` must be the path of `artifactRepositoryId`. Choose a fresh, portable run ID and a new kebab-case change name. Every acceptance criterion (or the description when a spec has none) becomes a frozen requirement the reviewer must certify.
105
-
106
- ```sh
107
- specrails-core runtime api
108
- specrails-core runtime validate --config .specrails/agent-runtime.json
109
- specrails-core runtime run --context .specrails/context.json --config .specrails/agent-runtime.json --change keyboard-navigation
110
- specrails-core runtime status --context .specrails/context.json
111
- specrails-core runtime resume --context .specrails/context.json --answer "Keep the existing shortcut map"
112
- specrails-core runtime resume --context .specrails/context.json --approve archive
113
- ```
114
-
115
- The commands work in macOS shells and PowerShell; quote paths and answers containing spaces. Verification uses `command` plus an `args` array, not a shell command string. Prefer portable Node/npm commands over Bash scripts when the project supports Windows.
116
-
117
- Run and resume emit JSON lines: `workflow-event` (the durable ledger events), `agent-event` (role narration and tool activity), `verification-output`, `span` (one per finished role attempt, with `traceId`, `spanId`, timing, status and usage, ready for an OpenTelemetry bridge) and a final `runtime-result`. The direct runtime entry point is `dist/agent-runtime/cli.js`; it also emits JSON errors. The main package CLI can report command-validation errors on stderr. Exit codes are `0` for success, `2` for a pause (approval or question pending), and `1` for failure, blocking or cancellation. A successful Core result means implementation, verification, review, acceptance evidence and archive completed; host delivery remains separate.
118
-
119
- `runtime api` returns `{type:"runtime-api",apiVersion:1,coreVersion:"..."}` without invoking providers. Hosts can send a JSON configuration through stdin to `runtime validate --stdin` (maximum 2 MiB), avoiding temporary files and platform-specific shell quoting. It is mutually exclusive with `--config`. Use `runtime status --context <file> --compact` for process/UI integration: it retains the run and trace identities, phase status and visits, `pendingApproval`, `pendingQuestion`, usage, the completion verdict and the acceptance summary while omitting accumulated outputs, history and frozen context. Omit `--compact` for full inspection.
120
-
121
- ## Verification output and correction limits
122
-
123
- The `exit-code-honesty` guardrail catches test harnesses that print failures but exit with code 0. It recognizes complete count summaries (including TAP `# fail N`, Jest/Vitest test totals and Mocha-style counts) and explicit failure markers. Passing test names such as `rethrows non-404 failures` are descriptions, not failure counts. ANSI colors and Windows line endings are normalized; a partial line at the diagnostic tail boundary is discarded. TAP TODO/SKIP results are not treated as ordinary failed tests. A green suite does not erase another suite's explicit failure.
124
-
125
- This is a conservative text diagnostic over the last 16,000 characters of captured output, not a universal parser for every test framework. Test commands must still propagate real failures through their exit status. When the guardrail rejects output, the log includes the matching line so the reported failure can be checked against the runner's results.
126
-
127
- Verification failures return to the fixer. `limits.maxAttempts` bounds fixer invocations (default: 3), after which Core blocks with `Implementation correction limit reached`. An explicit resume grants a fresh budget. If the fixer repeatedly reports no defect, inspect the quoted verification evidence before resuming; rerunning an unchanged command cannot correct a diagnostic false positive.
128
-
129
- ## Questions and approvals
130
-
131
- The graph pauses through LangGraph interrupts; the host resumes it with the matching answer.
132
-
133
- - **Low design confidence.** When the architect reports `low`, Core first asks the same architect session to investigate the code once more and decide from evidence. If confidence is still low, the run pauses with the architect's single blocking question (`pendingQuestion`), the draft proposal is left on disk for inspection, and `resume --answer <text>` re-runs the architect with the answer as authoritative input. With `architect.onLowConfidence: "proceed"` the run continues on the stated assumptions instead of pausing.
134
- - **Archive approval.** With `approvalBeforeArchive: true` the run pauses before archive (`pendingApproval`); `resume --approve archive` grants it. The default is no approval, so a fully autonomous run implements, verifies, reviews and archives without a human in the loop.
135
-
136
- A resumed node collects its answer before doing any work, so the pass that asked the question is never repeated. Approvals and answers are persisted; a granted approval survives interruption, but invalidated candidate evidence clears it.
137
-
138
- ## Recovery and durable state
139
-
140
- State lives below `<backlogRoot>/.specrails/pipeline/<runId>/`:
141
-
142
- | File | Purpose |
143
- | --- | --- |
144
- | `state.json` and `receipts/` | Authoritative Core gates, verification and acceptance evidence |
145
- | `agent-runtime-request.json` | Frozen CLI change name and runtime configuration |
146
- | `agent-workflow/<runId>/checkpoint.json` | One atomic envelope: the host ledger (attempts, receipts, usage, ordered events, pending interrupts) and the complete LangGraph checkpoint history |
147
- | `agent-workflow/<runId>/.lease/` | Exclusive runtime process ownership |
148
-
149
- Resume uses the saved configuration and change. It rejects a different frozen input, Core/instruction identity or workflow definition. Valid completed phases are retained; stale evidence invalidates the affected phase and everything declared after it, and the graph travels back in time to the checkpoint taken right before that phase last ran, so its predecessors' state is exactly what it saw then. The ledger is authoritative for which node runs next: if LangGraph's own position disagrees after a crash, traversal follows the ledger. Once archived, changed evidence requires a new run.
150
-
151
- Correction loops stay cheap: when verification or review sends work back, the developer's previous provider session is resumed with a short correction prompt (Claude `--resume`, Codex `exec resume`, Gemini `--resume`, Kimi `--session`), so the code it wrote and the reasons behind it are already in context. If the session is gone the developer starts a fresh full turn with the same feedback. Unchecked tasks in `tasks.md` are returned to the developer as feedback, not treated as a workflow failure. A run blocked at `limits.maxAttempts` can be resumed explicitly: the resume grants a fresh attempt budget and transition ceiling; visits and history keep the complete record.
152
-
153
- Architect and reviewer replies are validated against a JSON Schema (Claude `--json-schema`, Codex `--output-schema`; other providers are parsed leniently, accepting fenced or prefixed objects). The developer finishes with a structured summary (files, tests, verification run, incomplete tasks) validated the same way; a provider that returns prose instead is recorded as such rather than repaired. An unusable architect or reviewer reply gets one repair turn inside the same session before the phase fails. Omitting the assigned OpenSpec workflow uses that same single repair budget: the role must load and execute its official skill, not merely resend JSON. Sessionless providers receive the full original role prompt for this correction. Evidence from an older role visit cannot satisfy a new invocation.
154
-
155
- ```sh
156
- # Retry a reported failure with the same frozen configuration.
157
- specrails-core runtime resume --context .specrails/context.json
158
-
159
- # After inspecting partial edits, explicitly allow an interrupted write to run again.
160
- specrails-core runtime resume --context .specrails/context.json --recover developer
161
-
162
- # Recheck evidence explicitly; this also invalidates downstream review/archive.
163
- specrails-core runtime resume --context .specrails/context.json --invalidate verify
164
- ```
165
-
166
- Inspect the saved phase and worktree before using `--recover`; it authorizes repeating an effect whose completion was not durably recorded. Dead local process leases can be reclaimed. Live, remote or unverifiable leases are never silently stolen. Do not delete a lease while its process may still be running.
167
-
168
- Cancellation propagates to owned provider and verification processes. Programmatic callbacks must cooperate with `AbortSignal` and finish subprocess cleanup before returning; the engine retains its lease until they settle. A write step that settles after cancellation is recorded as interrupted and requires explicit recovery.
169
-
170
- ## Acceptance evidence
171
-
172
- Core 5.2 requires acceptance evidence before a change can be archived. The runtime produces it without a separate role:
173
-
174
- - The reviewer receives every frozen acceptance criterion with stable coordinates (`specId`, `criterionIndex`) and certifies each one as `met`, `exception`, `blocked` or `pending` with concrete evidence. A reviewer may only accept a non-material exception itself; material scope changes stay `blocked`.
175
- - Core records the verification commands it actually ran as required checks (passed or failed by exit code, with the receipt id as evidence), repositories admitted without a check as unavailable checks, and the reviewer's own inspections as supplementary, never required, checks.
176
- - The report is validated against the frozen scope inside the reviewer turn (a malformed report gets the repair turn), then bound to the exact candidate before the reviewer verdict is recorded. Unresolved requirements or a failed required check block review and archive; the CLI status exposes the reasons.
177
-
178
- ## Budgets and provider capability differences
179
-
180
- | Setting | Behavior |
181
- | --- | --- |
182
- | `agents.<role>.maxTurns` | Bounded role/tool interaction, default 100; provider transports enforce their available turn/tool events |
183
- | `limits.maxAttempts` | Maximum development visits per invocation, including correction cycles, default 3; an explicit resume starts a fresh budget |
184
- | `limits.timeoutMs` | Workflow duration limit and provider timeout; default provider timeout is 15 minutes when omitted |
185
- | `limits.maxTokens` | Rejects missing required usage or an observed overrun; CLI accounting may arrive only after a call |
186
- | `limits.maxCostUsd` | Accepted by the built-in Claude executor through its native dollar limit; rejected by built-in Codex, Gemini, Kimi and OpenAI-compatible executors |
187
-
188
- Do not configure `maxCostUsd` for a mixed-provider run unless every selected custom executor can enforce the requested cap. An observed token limit cannot guarantee that an opaque CLI stops before spending those tokens. Provider spend is accounted the moment each call returns, so a pause or failure after a call never loses it. Unknown usage stays `null`; known spend is tracked as a lower bound, never fabricated as zero. Local endpoints can report zero cost, but absent billing data remains unknown.
189
-
190
- OpenSpec Kimi roles use ACP with the per-session workflow server; non-developer roles retain plan mode with scoped reads and denied writes/terminal operations. Unsupported ACP modes or multi-repository capabilities fail explicitly. Kimi lacks authoritative token accounting, so its built-in executor rejects token and dollar caps. Configure another provider for a role when its installed Kimi version cannot expose the required repository scope.
191
-
192
- Gemini architect/reviewer roles require a CLI that advertises `--admin-policy` (verified with Gemini 0.49). Core supplies a temporary admin policy allowing file reads, listing, glob, grep and the scoped OpenSpec MCP tool; other tools are denied, including shell, writes and mode changes. This policy applies even if user settings disable plan mode or previously approve write tools. Gemini ignores per-run admin policies when system policy files exist, so Core rejects those managed environments before invoking a read-only role; select another provider for these roles or arrange a compatible environment with the system administrator. Older Gemini versions without this policy capability also fail explicitly. Gemini developer roles retain their existing `--yolo` execution.
193
-
194
- ## Embed and extend
195
-
196
- Import the public ESM entry point; TypeScript declarations are included:
197
-
198
- ```ts
199
- import { readFileSync } from 'node:fs'
200
- import { runCoreWorkflow, validateRuntimeConfig } from 'specrails-core/agent-runtime'
201
-
202
- const context = JSON.parse(readFileSync('.specrails/context.json', 'utf8'))
203
- const config = validateRuntimeConfig(JSON.parse(readFileSync('.specrails/agent-runtime.json', 'utf8')))
204
- const controller = new AbortController()
205
- const state = await runCoreWorkflow({
206
- context, config, change: 'keyboard-navigation', signal: controller.signal,
207
- onEvent: event => process.stdout.write(JSON.stringify(event) + '\n'),
208
- onSpan: span => process.stdout.write(JSON.stringify(span) + '\n'),
209
- })
210
- console.log(state.status, state.nextStep, state.pendingQuestion?.question)
211
- ```
212
-
213
- Programmatic hosts retain their input/config and supply the same values with `resume: true`, plus `approve`, `answer`, `recoverInterrupted` or `invalidate` as needed. The CLI additionally creates the frozen request file for you.
214
-
215
- Register an executor directly to add a provider in code. This example registers a private local endpoint with no CLI installation:
216
-
217
- ```ts
218
- import {
219
- ExecutorRegistry, OpenAICompatibleExecutor, runCoreWorkflow,
220
- type RuntimeConfig,
221
- } from 'specrails-core/agent-runtime'
222
-
223
- const registry = new ExecutorRegistry().register('on-prem',
224
- new OpenAICompatibleExecutor({
225
- id: 'on-prem', kind: 'openai-compatible', baseUrl: 'http://127.0.0.1:8080/v1',
226
- }),
227
- )
228
- const config: RuntimeConfig = {
229
- schemaVersion: 1, enabled: true, providers: [],
230
- agents: {
231
- architect: { provider: 'on-prem', model: 'your-installed-model-id' },
232
- developer: { provider: 'on-prem', model: 'your-installed-model-id' },
233
- reviewer: { provider: 'on-prem', model: 'your-installed-model-id' },
234
- },
235
- verification: [{ repositoryId: 'app', command: 'node', args: ['--test'] }],
236
- }
237
- // context is the frozen JSON object from the preceding example.
238
- await runCoreWorkflow({ context, config, registry, change: 'local-navigation' })
239
- ```
240
-
241
- A custom executor implements `AgentExecutor.execute(request): Promise<AgentResult>`. The request contains role, central instructions, allowed roots, model, limits and signal. Return final text and honest `{inputTokens, outputTokens, costUsd}` usage; use `null` for unavailable values. The executor must enforce role permissions and supported limits, own its tool/process cleanup, and throw on incomplete results. `createExecutorRegistry(config, {executors: {alias: executor}})` can replace or supplement configured providers.
242
-
243
- An optional, side-effect-free `validateLimits({maxTokens, maxCostUsd})` method rejects unsupported limits before any role runs. Built-in executors provide this preflight; custom registrations own their capabilities. Core also validates the complete verification command plan against the frozen repository scope before creating a run or invoking providers.
244
-
245
- For a different host workflow, use `runWorkflow()` with a LangGraph state schema and typed nodes:
246
-
247
- ```ts
248
- import { Annotation } from '@langchain/langgraph'
249
- import { runWorkflow } from 'specrails-core/agent-runtime'
250
-
251
- const State = Annotation.Root({ notes: Annotation<string[]>({ reducer: (a, b) => [...a, ...b], default: () => [] }) })
252
- await runWorkflow<typeof State.State>({
253
- directory, runId, input: { change }, workflow: {
254
- id: 'my-host', version: '1', schema: State, entry: 'plan',
255
- nodes: {
256
- plan: { ends: ['build'], run: async () => ({ status: 'succeeded', update: { notes: ['planned'] } }) },
257
- build: { effect: 'write', ends: ['plan'], run: async (state, context) => {
258
- context.reportUsage({ costUsd: 0.1, inputTokens: 10, outputTokens: 5 })
259
- if (state.notes.length < 2) return { status: 'succeeded', next: 'plan' }
260
- context.interrupt({ kind: 'approval', reason: 'Ship it?' })
261
- return { status: 'succeeded', next: null }
262
- } },
263
- },
264
- },
265
- })
266
- ```
267
-
268
- Each node declares its `effect`, optional retry bounds, its possible successors (`ends`) and `run(state, context)`. A result supplies `status`, an optional graph `update` (merged through the schema's reducers), an optional ledger `output` and an optional `next` for conditional routing; `null` completes the workflow. Node names must not collide with state channel names. Nodes pause with `context.interrupt()` and report provider spend with `context.reportUsage()` as it happens. Write retries require `retrySafe: true`; interrupted writes still require explicit recovery. `readWorkflowState(directory, runId)` is read-only. Observer exceptions cannot replay a committed step. The Core nodes themselves are exported as `coreNodes(deps)` for hosts that want to reuse a phase inside another graph.
269
-
270
- ## Tools, specifications and compatibility
271
-
272
- The OpenAI-compatible tool executor exposes scoped listing, literal text search, numbered line reads and a single-file Git diff. Developers additionally have whole-file writing and exact-match patches. It rejects traversal, symlink escapes and protected runtime metadata. It has no model-accessible shell tool; Core owns verification subprocesses, and `get_diff` runs fixed, read-only Git commands with external diff and text conversion disabled. This is a tool policy, not an operating-system sandbox for arbitrary custom executors or external CLIs.
273
-
274
- ### Efficient development and workspace tools
275
-
276
- The programmatic developer runs focused tests while implementing. Core alone runs the complete configured verification plan after the developer returns, and feeds real failures into the correction session. The developer's self-reported checks never replace a Core receipt. This removes the instruction to run the same full suite twice; it does not weaken the final gate. The implement and batch-implement commands now enter this same runtime.
277
-
278
- | Tool | Input | Behavior |
279
- |---|---|---|
280
- | `search_text` | `path`, literal `query`, optional `maxResults` (1–100) | Searches bounded source files; skips generated/dependency directories, protected metadata, symlinks and binary/large files. Returns numbered matches, `skipped` and `truncated`. |
281
- | `read_lines` | `path`, optional one-based `startLine` / `endLine` | Reads up to 500 lines / 48 KiB from a file up to 1 MiB; returns the full-file SHA-256, line count and continuation information. |
282
- | `get_diff` | One file `path` | Shows staged and unstaged changes against HEAD, up to 48 KiB. Reports untracked files without dumping their contents; inspect them with `read_lines`. Requires Git and a HEAD commit. |
283
- | `apply_patch` | `path`, unique nonempty `oldText`, `newText`, optional `expectedHash` | Developer-only atomic replacement of one exact fragment. Rejects ambiguous, absent or stale context. Resulting files remain limited to 256 KiB. |
284
-
285
- These operations do not silently widen a role's write permissions. Ranged reads keep original line endings, so include the original `\r\n` when matching multiline Windows text. Use the returned hash to reject changes made since a read.
286
-
287
- ### Measuring efficiency
288
-
289
- `runtime status` and `runtime-result` include an additive `metrics` object with `schemaVersion: 1`. `runtime status --compact` also includes it under `state.metrics` for Desktop. Desktop shows **Usage and time** on saved runtime executions; older Core versions simply omit it.
290
-
291
- The summary contains `total` and `phases` (architect, developer, verify, reviewer, archive). Each phase reports attempts, measured attempts, wall duration, agent duration, provider calls, tool calls, input/output tokens, reported dollar cost and optional uncached/cache-read/cache-write input counters. Provider and requested-model identifiers are retained per phase; absent model identifiers mean the provider selected its default.
292
-
293
- - Agent time covers the whole executor call, including CLI startup and native tools. It is not an inference-only measurement. Verification time is the `verify` phase duration.
294
- - A provider call means one executor invocation; an API invocation can contain multiple model/tool rounds. Tool calls count observed tool-start events, including failed/denied tools. They are not an independently billed token category.
295
- - Cache counters are subsets of input tokens, not additional tokens. Missing counters or costs remain `null`. No pricing table or estimated discount is applied.
296
- - Failed calls, fallback sessions, repairs and earlier correction attempts remain included. Polling or resuming without another provider call does not add spend. Run totals are cumulative; `invocationUsage` retains its existing meaning of spend in the latest CLI invocation.
297
- - The Core host persists each completed provider call and its reported usage on the current attempt before continuing. A process killed inside an opaque provider call can still lose unreported usage; completed calls are not a hard upper bound on that provider's bill. Older attempts without invocation metadata show incomplete measurements rather than fabricated zeros.
298
- - Total execution duration accumulates active workflow time, excluding time parked for human approval between invocations. Phase time includes phase overhead; do not add agent time to phase time. A phase without an end timestamp has unknown duration.
299
-
300
- Prompt instructions now have version 6. Frozen runs reject an incompatible instruction/runtime identity; finish them with their original Core version or start a new run. New metrics are additive and need no database migration.
301
-
302
- To evaluate the first efficiency changes, select a fixed set of representative tasks and reset each task to the same base revision. Keep provider/model settings and acceptance criteria fixed. Save status JSON for every run, including failures and manual recovery, and compare:
303
-
304
- 1. Total reported spend divided by independently accepted implementations, including failed attempts/runs in the numerator. Separate cohorts with missing billing instead of counting them as free.
305
- 2. Median and p95 active execution time, provider calls, input/output tokens and verification time.
306
- 3. First-pass completion, correction attempts, acceptance-test results, reviewer defects and human changes required before acceptance.
307
-
308
- The metrics do not themselves establish quality or savings. Compare the legacy engine and the new engine on equivalent tasks with the same independent acceptance checks, then evaluate model routing or additional parallelism separately.
309
-
310
- Architect and reviewer responses are structured metadata. The architect authors real OpenSpec delta artifacts using the official fast-forward skill and CLI instructions. Archive uses the real OpenSpec CLI in a staging copy and publishes its merged main specifications with a durable preimage/write journal; it never replaces main specifications with delta text. The developer may update task checkboxes, but changing approved design, task descriptions or specification content invalidates the gates.
311
-
312
- Implementation and batch implementation use this runtime exclusively. Their installed commands are thin entry points; they do not orchestrate provider-native role waves. Profile v1 remains available for other workflows. Desktop stores provider connections globally and role assignments per project; existing connections migrate without discarding endpoints. An admitted run remains bound to its frozen request after settings changes. See the [integration contract](../integration-contract.json) for runtime API and artifact paths, and Desktop's programmatic runtime guide for release pairing and continuation/delivery behavior.
313
-
314
-
315
- ## Official OpenSpec role workflows
316
-
317
- Core depends on OpenSpec **1.4.1** and resolves that package's executable directly, independently of the PATH shim. It generates the official `ff`, `apply` and `verify` skills using the package's own installer in an isolated directory. Version, document hashes, project configuration and change identity are frozen in the checkpoint. Version 3 runs must finish using their original Core or start a new implementation; they are never reinterpreted as deltas.
318
-
319
- The architect loads `openspec-ff-change`, calls `new`, `status` and artifact `instructions`, and writes the artifacts itself through `write_artifact`. The developer loads `openspec-apply-change`, reads the real apply context and updates task checkboxes. The reviewer loads `openspec-verify-change`, inspects code and the real apply context, then reports acceptance evidence. `verify` is not an artifact ID for `openspec instructions`. Questions map to LangGraph interruptions; progress narration replaces provider-specific TodoWrite helpers.
320
-
321
- All current headless adapters explicitly use **official skill-document adaptation**, not a claim of native slash-command activation. The tool returns the exact generated skill; Core does not maintain copies of its templates in prompts.ts. CLI adapters use a local stdio MCP server named `specrails_openspec`; API adapters expose the same implementation as `openspec_workflow`.
322
-
323
- | Transport | OpenSpec binding |
324
- | --- | --- |
325
- | Claude | Explicit per-process MCP configuration; architect/reviewer native tools remain Read/Grep/Glob plus ToolSearch for deferred discovery of the scoped workflow tool. |
326
- | Codex | Process-local MCP configuration with approval of this first-party tool; native read-only or workspace-write sandbox is preserved. |
327
- | Gemini | Temporary settings preserving administrator settings, with an explicit MCP server; read-only admin policy admits only source reads and this workflow tool. Restrictive administrator MCP settings fail admission. |
328
- | Kimi | ACP session MCP forwarding. Plan mode and denied filesystem/shell reverse requests remain for non-developer roles; developer uses auto mode. Unsupported mode/scope capabilities fail explicitly. |
329
- | OpenAI-compatible API | The same confined OpenSpec operations alongside the existing workspace function tools. |
330
-
331
- No global provider configuration is rewritten. Supported planning is currently **repo-local spec-driven**, without local schema overrides. Custom planning homes/schemas fail explicitly; adding one requires conformance tests. The architect's tool cannot edit application code, the developer's artifact tool changes only checkboxes, and the review tool cannot write. Native developer code tools retain their existing provider permissions.
332
-
333
- Advancement requires an observed official skill/instructions tool trace, nonempty planning artifacts, unblocked apply state and strict CLI validation. Existing code verification, frozen-candidate fingerprints and acceptance review still gate completion; a CLI exit code or checked task alone is insufficient. Traces prove tool use and outputs, not perfect semantic compliance by a model.
334
-
335
- Deterministic tests cover the real CLI, real stdio MCP, API function calls, adapter configuration, main-spec merging and interrupted archive recovery. Native model-backed end-to-end certification is a separate check; help/argv tests alone do not establish model behavior or support every installed CLI version.
336
-
337
- For developer and reviewer, the agent’s `load_skill` request also runs the official read-only `status` and `instructions apply` commands and returns their unmodified JSON under `planning`. Successful prerequisite queries are recorded with `via: load_skill`; failed or cancelled loading records no participation. The agent must still read the context files and implement or review according to the official skill. This avoids a redundant model correction solely for an omitted planning query; host validation does not count as role participation.
338
-
339
- Tool activity includes untruncated target paths and an explicit working directory when the provider supplies them. Desktop uses the admitted repository map to label multi-repository actions in persisted logs and narration; unknown targets stay unattributed and role identity does not imply a fixed repository.
340
-
341
- ## Editable role definitions
342
-
343
- Desktop Settings exposes global architect, developer and reviewer task definitions below Provider connections. `runtime prompts` returns the actual Core defaults. Desktop stores overrides in `~/.specrails/runtime-role-prompts.json` and freezes the effective `rolePrompts` map in each new job configuration. Saving or resetting a definition never changes a saved job; resume uses its existing frozen configuration. The optional map supports the three roles only, with nonblank definitions up to 20,000 characters and no null bytes.
344
-
345
- Overrides replace the role task definition across providers. Scope, acceptance evidence, correction feedback, output contracts and the mandatory OpenSpec binding are still assembled by the runtime. Omitted definitions retain the existing factory wording for older saved jobs. Resetting a role removes its global override, so future jobs use the active Core default.
346
-
347
- Codex output schemas use its strict transport format: every property is required and originally optional fields accept null. The adapter restores optional nulls to omitted fields before Core consumes the response. This transport adaptation does not alter frozen role contracts. Provider failures include bounded, credential-redacted diagnostics from structured errors or stderr.
348
-
349
- ## Failed archive recovery diagnostics
350
-
351
- Archive success requires a destination and removal of the staged active change,
352
- not only an exit code of zero. On an aborted OpenSpec validation, the failure
353
- retains bounded CLI output so the host can identify the actual spec or prerequisite
354
- to repair. No writes from an unsuccessful staging pass are published.
355
-
356
- A retry of a failed archive reuses verification and review when their receipts
357
- remain valid. Candidate/environment changes continue to invalidate those receipts
358
- and require verification/review. Compact runtime status includes up to eight
359
- `recentFailures` with step, status, attempt, visit, timestamp and bounded error;
360
- it excludes agent outputs. Hosts should diagnose repeated errors and identify a
361
- changed precondition before retrying, preserving the original worktree.
362
-
363
- ## Scoped recovery API
364
-
365
- Capability `scopedRecovery: 1` exposes `runtime recovery --context <json> --stdin`.
366
- The JSON actions are inspect, history (optional offset), list_files, read_file,
367
- diff, patch and check. File actions require a repositoryId from the frozen context
368
- and a relative path. Patch requires expectedHash, one unique oldText/newText
369
- replacement (16 KiB fragments), operationId UUID and reason. Check accepts only
370
- kind openspec or kind verification with an ID from inspect's registered checks;
371
- no submitted command/argv is accepted. The CLI requires the retained runtime
372
- identity before dispatch. Desktop maps patch to write and check to destructive.
373
-
374
- Recovery holds the workflow lease, rejects archived/completed mutations and
375
- requires explicit acknowledgement of interrupted writes. It reuses WorkspaceTools
376
- for bounded UTF-8 reads/diffs and atomic writes, adds protected-plan and portable
377
- path checks, and records bounded attempts in a separate write-ahead history.
378
- Same operation IDs never blindly rerun; changed requests with an old ID fail.
379
- Interrupted patches reconcile by their after-hash; uncertain checks remain
380
- interrupted. Repeated failed checks require a stated changed precondition.
381
-
382
- Verification checks use the frozen plan and existing scoped receipts with a
383
- 45-second deadline. OpenSpec validation reports must contain successful results,
384
- not merely an exit code of zero. Neither operation grants acceptance or marks
385
- workflow phases complete. Resume remains responsible for the required gates.
386
-
387
- ### Claude Opus selection
388
-
389
- For Claude CLI roles, `model: opus` resolves to `claude-opus-5-5` (Opus 5.5).
390
- Explicit model IDs pass through unchanged, including older generations, and other
391
- providers are unaffected. This applies to base and escalation invocations.
392
- Claude Code owns the native thinking and tool protocol; Core does not send
393
- Anthropic Messages API parameters.