0.5.0 - 2026-09-14
The v0.5.0 reliability work. Migration notes:
docs/migration-0.5.md; rationale:
docs/plan-v0.5.md.
Breaking
request_permissionsis advertised only indangerousmode. Outside it
the tool can only answerELICITATION_UNSUPPORTED, which is where roughly
60% of its observed calls went. It stays callable when hidden, so a direct
call still gets that same answer rather thanUnknown tool. The registry
holds 19 tools;safeandtrustedadvertise 18 anddangerousadvertises
19. A client that hardcodes the catalog must readtools/list.- The
write_generated_or_ignoredpermission kind is removed from the
request_permissionsschema. It was an enum value no code path requested or
granted. read_filemodel text now opens with a banner —
[Showing lines 1-40 of 40 revision=…]— on every read, not only a
truncated one.apply_changesneeds that revision and most clients forward
only the text.structuredContent.contentis unchanged.exec_command's defaulttimeout_msis now 300000 (was 30000).
timeout_msalways meant total process lifetime, but the old default was
shorter than an install or a build, so a command backgrounded by the yield
was killed shortly after the call returned.yield_time_msstill defaults to
10000 and the 600000 maximum is unchanged.
Added
apply_changes, a line-addressed editing tool. Each change names an
action (create,write,edit,delete,move,copy) and a path.
Existing targets use therevisionread_filereported.writeis an
upsert and may omit it when creating a missing path;createasserts absence.
Nothing has to match textually, and a file that changed since it was read is
refused withREVISION_MISMATCHinstead of being overwritten. A path may
appear once per call.read_filereports arevision, a SHA-256 of the whole file computed
during the pass that already streams it, so no second read can disagree with
the bytes the model saw.--workspace-mutation=structured-onlyand repeatable--write-path,
off by default. Structured-only makes the workspace read-only for
exec_commandunder Landlock, leavingapply_patchandapply_changesas
the only way in. Experimental: it breaks any command that writes into the
tree unless that directory is allowlisted. Also settable as
CODING_TOOLS_MCP_WORKSPACE_MUTATIONandCODING_TOOLS_MCP_WRITE_PATHS;
the effective policy and whether it is enforced appear inserver_infoas
workspace_mutation_policy. Full enforcement requires Landlock ABI 3 or
newer, and missing in-workspace write directories are created before rules
are installed.idempotency_keyonapply_patchandapply_changes. Replaying a key
with the same arguments returns the recorded result instead of doing the work
twice, so a lost response is safe to retry. A key names one request: it is
recorded with a fingerprint of the arguments that earned it, reusing it for
different arguments isIDEMPOTENCY_KEY_REUSEDrather than a replay of work
that was never done, and adry_runresult is never recorded at all. The
runtime keeps one 64-entry LRU of(tool, key)results across both tools,
not a separate cache per tool.- A repeat-failure circuit breaker. The third byte-identical call that
would produce the same deterministic error is refused with
REPEATED_CALL_BLOCKED. Changing any argument gives the revised call a fresh
budget; a successful write, including a move whose hunks were already
present, clears the breaker entirely. The first terminal observation of each
command_idfromexec_command,write_stdin,read_output, or
kill_commandalso clears it when that command could write: in unrestricted
mode, under an unenforced structured-only policy, through a configured write
path, or after Landlock setup failed open. Later observations of the same
command do not clear it again.IDEMPOTENCY_KEY_REUSEDis excluded because
its repair is a new key. - Per-tool
outputSchemaintools/list, replacing one generic envelope. - A real-task evaluation harness under
benchmarks/agent_eval/, which runs
the same tasks and prompt through an agent's native tools and through this
server and scores both on pass rate, first-attempt success, rounds to green,
regressions, and wall time. See
docs/agent-evaluation.md. Its gates are
release-announcement criteria, not merge criteria.
Changed
apply_patchlocates hunks with forward text anchors.@@ <context>
advances a language-agnostic search cursor; it does not infer function or
block boundaries.*** End of Filealso participates in placement.- Patch matching is graded — exact, then ignoring trailing whitespace, then
ignoring indentation width — and the grade actually used is reported in
match_quality, so a downgrade is visible rather than silent. - A successful patch returns evidence:
changed_ranges, a per-file
revision, andtotal_lines. These are evidence only;apply_patchstill
takes norevisionargument, because its context lines are already its
optimistic check. - A failed patch returns repair data: the hunk index, nearby numbered text,
and candidate match positions, so the next attempt can be aimed. - A patch whose changes are already present reports
already_applied
instead of failing, when the result is locatable: an exact or
trailing-whitespace match of a block that carries a context line, or a
multi-line addition. A context-free single line that happens to occur
somewhere in the file is a coincidence, not a completed edit, and still
fails withPATCH_CONTEXT_NOT_FOUND. A*** Move to:that actually
relocates the file remains a write and reportsalready_applied: falseeven
when every hunk was already present. apply_patchnow follows Codex primary-path and overwrite semantics. An
operation's primary path may appear only once in an envelope, including
aliases such asa.txtand./a.txt.Add Filemay replace an existing
file,Move tomay replace an existing destination, and distinct source
files may move to the same destination in order, with the later write
winning.apply_changescompares paths after resolving them, soa.txtand
./a.txtare one path: naming both isINVALID_ARGUMENTrather than a
silent overwrite reported as two applied changes.git_diffincludes untracked files by default, so a file created by
apply_patchis visible. Passinclude_untracked: falsefor the old
behavior.- Telemetry counts operations truthfully. A command that exits nonzero,
times out, or dies on a signal is no longer recorded as a successful tool
call; its terminal outcome is counted once rather than again on every
exec_command,write_stdin,read_output, orkill_commandobservation;
and consecutive failures are tracked per (tool, error code) rather than in
one global slot any tool's success could reset. A 0.5.0 dashboard is not
comparable to an earlier one. check_exec_environmentwarns on non-Linux hosts that there is no
Landlock and therefore no filesystem confinement.server_infodiscloses the output retention TTL and the completed-command
cap, which docs/limitations.md points callers at.- Project instructions now tell a model to prefer
apply_changesand
apply_patchoverexec_commandfor file edits. - The runtime contract now states that
patch_lockserializes patches within
one server process only; two servers on one workspace are protected by the
pre-commit baseline recheck alone.
Fixed
- Chained patch operations retain staged file state. A newly moved
destination can be updated, deleted, or moved again in the same envelope,
and a laterAdd Fileoverwrite preserves its staged executable mode.
Repeated destination writes keep the first baseline, so an intervening
external edit raisesPATCH_CONFLICTinstead of being overwritten. apply_changesno longer doubles carriage returns in CRLF replacement
content. Replacement text now normalizes LF, CRLF, and CR separators before
the file's original line-ending convention is restored, so returned
total_linesandchanged_rangesstay consistent with a subsequent
read_file.@@ <context>now follows Codex-style forward-cursor semantics. Missing
anchors fail instead of being ignored, matching never jumps back before the
anchor/current cursor, top-level and brace-based code are not rejected by
indentation heuristics, and pure-addition hunks validate their anchor before
appending at EOF.- Move evidence and breaker invalidation now follow actual staged
mutations. Moves that change paths retain an explicit source deletion in
affected_files, and successful workspace-mutation invalidation is derived
from committed staged actions rather than compressed display evidence. - Move mode preservation now survives later content reversion. A staged
file is considered unchanged only when both its content and mode match the
original destination baseline, so an executable source moved over a
non-executable destination keeps its executable bit even if later patch
operations restore the destination's original bytes. - Whole-file
apply_changesevidence now reports line counts consistently.
Rewriting identical content reports zero additions/removals, and replacement
ranges count removed lines from the original file. Bare-CR content is also
counted with the same universal-newline rules asread_filewithout
rewriting the user's bytes. - The long-running PTY compliance test now polls the bounded terminal stream
for final child output instead of assuming input echo and process output
arrive in one response. - Cloudflare local
.dev.vars*and.env*files remain ignored after the
control-plane move toinfra/cloudflare/. - Release-gate tests now distinguish unavailable Landlock/PTY host capabilities
from product behavior and no longer race the 16-command concurrency limit
while testing completed-command retention. - Regenerated
uv.lockfrom the v0.5.0 release metadata, including the current
mcpandPyYAMLdevelopment dependencies. The release checker now rejects
a checked-in uv lock whose project version or dev dependency set has drifted
frompyproject.toml.
Other
- Moved the source-checkout tunnel launchers to
integrations/tunnels/so user-facing runtime integrations no longer live under repository-maintenance scripts. The previously documentedscripts/tunnel.shentry point remains as a compatibility wrapper. - Organized repository-owned components by responsibility: the npm launcher now lives in
packages/npm-launcher/, the Cloudflare sandbox control plane ininfra/cloudflare/sandbox-control/, and promo-video sources inmedia/promo-video/.