Repository navigation
v0.1.39
Twelve improvements from a measured study of 285 recorded runs (128 real ones on three repositories), plus three defects the first real runs of the new code exposed. Every item is pinned by tests (973 in the suite) and written up in docs/KNOWN_ISSUES.md with the evidence.
Fixed
- The worker read its prompt as a source dump and an escaped JSON blob. The substrate's envelope sent the whole of
tasks.pyand the arguments as ASCII-escaped JSON on one line; the pack travelled under the nameguidance. Measured: a median 18 tool calls exploring before the first edit, pack or no pack. Prompts are now rendered as a document (task prompt + one fenced section per input);context,guidanceand thegatecommand travel apart. (promptrender) - The jailed worker reached the user's ssh agent, MCP connectors and sub-agents. Twenty-odd workers with no local toolchain shipped the repository over ssh to compile it elsewhere. The launch policy denies sub-agents, task-list, tool-search, web and plan tools, loads no MCP server, ignores the repo's own settings, disables the browser bridge, and unsets credential-shaped variables for the worker. (
launch) - Any finding rejected the proposal, so most rejections meant nothing. 58% of gate-passing proposals were rejected; the human then accepted 60% of those. Findings now carry a severity; only blocking ones reject, drive rework and block auto-settle; advisories are shown and learned. A rejection naming only advisories is recorded as approved, with a note.
- No run recorded what it cost or which model produced it. Every launch records tokens, cache, cost, turns, API time and the served model; the summary,
--review-report, history andstatusshow them. - A worker reaped at its budget was recorded as an unexplained run failure. 13 attempts of ~915 s read as
run_failed; they now readtimed_outand the retry gets the timeout guidance. optimizehung two minutes per replay case on an inherited stdin (itsinitasked the review-panel question). Replays run with stdin closed;initasks only on a terminal.- A dead login or a spent allowance cost an attempt to discover. An auth preflight resolves the credential before the pack, refreshes a subscription token that would not last the run, and stops on a spent allowance (with its reset time), a dead login, or a stale
~/.claude/.credentials.jsonshadowing a live keychain login — the shape behind the history'sNot logged infailures. - The reviewer read the wrong tree. The proposal is applied into the reviewer's working copy before its CLI starts; custody compares the proposal's files by bytes instead of exempting their paths.
- The planner's targets were the first thing the pack dropped. The pack keeps 15k of its 25k for file content, trims the tree to fit, and places the planner's targets first.
- The worker had no toolchain. Each launch gets its own writable copy of the repo's
jail_seedcaches as an extra writable root of the jail (jail_seed_linksfor caches that must sit in the tree, e.g.node_modules). - Bytecode the worker's own test run left behind became part of the proposal, and its NULs killed the reviewer's launch (
embedded null byte). Build residue is filtered before it is read; a binary file is named, not rendered.
Added
--model,--reviewer-model,--effortand themodelsconfig block: model, effort and fallback per role (worker, reviewer, planner).limits.worker_budget/limits.gate_timeout/limits.max_attemptsin.shepherd-dev.json, with the flags still winning.speculative_review: auto— the reviewer overlaps the gate where this repo's recent gate-pass rate is high;--no-speculative-reviewto force it off.statusreports tokens, cost, models, exploring calls before the first edit and the reviewer's tool calls per run.worker.prompt,worker.launch,worker.init,worker.result,worker.overlay,worker.seedevents in every run's log.
Smoke-tested end to end on a toy repository: worker with zero exploration (2 reads, 2 edits, ran the gate itself, 6 turns), reviewer reading the applied tree and approving, 52 s wall clock, $0.29 as the CLI reported it.