Repository navigation
v0.53.0
Security
@modelcontextprotocol/sdk1.30.0 → 1.32.1 (its OAuth client could send credentials to an authorization server chosen by the MCP server), plus lockfile updates for thefast-uri,ip-address,hono,qs,proxy-addr, andsource-map-jsadvisories;npm auditreports 0 vulnerabilities. CodeQL actions 4.37.7 → 4.38.3;@types/node26.2.0 → 26.6.5;vitest4.1.11 → 5.0.3.- Producer-authored bytes can no longer steer Git. Diff-family commands always run with
--no-textconvand--no-ext-diff; review diffs read attributes from the trusted base with--attr-source=<base>(Git 2.40+, reported bydoctorasgit-too-oldbelow that), so a committed.gitattributescannot hide source as binary; Git calls inside a managed worktree pinGIT_DIR,GIT_COMMON_DIR, andGIT_WORK_TREE, so a rewritten.gitpointer is ignored; and truncated Git output is a failure everywhere through onegitChecked/gitSucceededpair. - On macOS, project verification runs under Seatbelt with a private scratch
TMPDIR, and its evidence recordsconfinement: "macos-seatbelt". The Seatbelt profile denies reads of credential stores under$HOME(.ssh,.aws,.gnupg,.kube,.docker,.netrc,.git-credentials,.config/gh,.config/gcloud,.azure). - Autonomous acceptance is stricter. It requires every executed verification command to have run under a known OS confinement backend (a missing policy record fails closed, so off macOS every decision needs a person), and a plain
delegatecandidate that changes verification inputs — tests, test or build configuration, dependency manifests and lockfiles,.gitattributes/.gitignore/.gitmodules— needs a person too. The decision advisory shown to a human is now exactly the autonomous verdict's reasons. integrateCandidaterefuses an acceptance that names no artifact (a legacy record withoutcandidateManifestHash) withdecision-artifact-mismatchinstead of falling through.- Autopilot honors
CLAUDE_ARCHITECT_DECISION_AUTHORITY=human: it refuses to start (decision-authority-human), refuses to resume a workflow that still promotes, and the promoter records noautopilot-policyacceptance under it. The acceptance is written only after the exact bytes are staged. - A spec's
environmentcan no longer override variables the platform sets (HOME,PATH,TMPDIR, …), and every adapter- or spec-supplied value except absolute paths is redacted from output. - The watchdog keeps the Producer in its process group and escalates SIGTERM to SIGKILL on the whole group when the supervisor dies or the child exits, so grandchildren cannot outlive a run.
bootstrap.mjsignores relativePATHentries when locating Node. - Dependency inheritance runs
cpby absolute path and treats lockfiles over 64 MiB or of different sizes as non-matching. delegation-spec.v1.jsonbounds every array (maxItems), so an oversized spec is rejected at validation.- Review patches in the review snapshot are sanitized (binary payload omitted, redacted), and Git stderr in pipeline errors is redacted.
Changed
-
Plugin renamed
claude-architect→architect. Claude Code now reserves plugin names starting withclaude-, soclaude plugin validaterefused the old name.CLAUDE.mdmoved to.claude/CLAUDE.md, because strict validation rejects it at the plugin root. Install withclaude plugin install architect@claude-architect; commands are/architect:delegate,/architect:codex, and/architect:subagent-driven-delegation, and MCP tools aremcp__plugin_architect_runtime__*. The marketplace maps the old name to the new one. The marketplace name, repository, environment variables, Git ref namespace, and.worktrees/claude-architect/layout are unchanged. -
Protocol 2.0.0 → 3.0.0.
autopilotStartno longer acceptspullRequest, and Autopilot specs and workflow states are v2. Callers pinned to 2.0.0 get an explicitprotocol version mismatchdiagnostic. Run archives are bound to the protocol major, so runs recorded under 2.x are refused as incompatible; decide and integrate them before upgrading. -
Final Branch Report v2: the passing status is
ready-for-human-review, matching the terminal state, instead ofready-to-ship. A v1 report is refused on resume with an explicit version diagnostic. -
Autopilot ends at a final-reviewed local branch. It no longer pushes, opens a draft PR, polls required checks, or marks a PR ready; that belongs to the repository's delivery gate (No Mistakes here). Autopilot Spec v2 drops
shipping, and Workflow State v2 replacesshipping/ciObservationswithbranchand drops thepushing,creating-draft-pr,waiting-required-checks, andmarking-readyphases; v1 specs and states are refused with explicit version diagnostics. Cleanup keeps the reviewed branch and removes only the worktree and the private base ref. -
Promotion commits carry the user's own Git author and committer, dated now, instead of a fixed runtime identity dated 2000-01-01. Autopilot refuses to start without a configured identity (
git-identity-missing). -
One state machine owns an Autopilot workflow:
startbootstraps and then runs the same resume path, and startup recovery reports an abandonedcleaning-upworkflow asresume(thefinalizedisposition is gone) instead of finishing it with a second proof of the same crash window. Finish it withautopilotResume. -
Autopilot reads the remote only at create. Revalidation before each promotion and the final review no longer runs
ls-remoteor re-resolves the remote URL, so a busy upstreammainno longer fails a workflow (remote-base-changedandremote-identity-changedare gone), and the workflow runs offline after create. The local base ref still pins the base. -
Managed worktrees live in each repository's main checkout under
.worktrees/claude-architect/<id>, a self-ignoring namespace recorded in the plugin data root so recovery finds it; the legacy state-directory location is still swept. -
Every pipeline writer, each fixer included, starts in a fresh worktree at the current candidate; its commits are validated and imported into the shared object store before the worktree is removed. A failed promotion now distinguishes a missing candidate commit (
sandbox-violation) from a host failure (environment-defect). -
Optional Jev screen: with
CLAUDE_ARCHITECT_JEV=onandTYPESAFE_API_KEY, an otherwise autonomous acceptance is screened by the TypeSafe API over the redacted patch and changed paths. A concern routes the decision to a person; an outage or clear result leaves the deterministic verdict unchanged. It never grants autonomy. -
Minor and nit findings never block the pipeline gate; every undispositioned blocker or major still requires a human.
-
Weakened-test detection covers Python, Go, Rust, JVM, .NET, and RSpec path conventions and skip markers.
-
Autopilot eligibility is derived directly from the pipeline result, review snapshot, and advisor report, so no self-derived projection is re-checked against itself; a missing candidate is reported as
pipeline result has no candidate. -
The final branch review freezes only the refs it needs (task
logs/transcripts excluded), embeds verification once, and is crash-resumable: evidence files are replaceable, the report is immutable, and a report already published for the same artifact is returned on resume. -
Lock contention during promotion reports
checkout-busyinstead ofbranch-identity-changed. -
The
ls-filesoutput bound is 512 MiB; other Git output stays bounded at 8 MB. -
macOS bound-directory cleanup removes directories in batches of 64 with one
lsofper batch (a 2,040-directory tree went from over 120 s to about 26 s). -
A checkout-lease release failure after a finished integration keeps the result and appends
; checkout lock release failedinstead of discarding it. -
The slice lifecycle moved out of
runPipelineWithLeaseintoSliceRunner(src/pipeline/slice-runner.ts): plan wave, create worktree, launch Producer, freeze, verify, review, compose, release anchor. Run-scoped facts travel as aRunContextvalue instead of a shared closure, sopipeline-runtime.tsfell from 2464 to ~1540 lines and slice behaviour can be exercised without driving a whole pipeline. -
One implementation of the slice phase.
SliceRunner.runsuperseded the callback-drivenrunSlicePhase/SlicePhaseDepspair, which stayed behind as a second routing loop that nothing called but a test suite still exercised — so the suite proved nothing about the code that runs. The superseded loop is deleted and its evidence-isolation and hard-blocker cases now drive the real runner. -
One implementation of the managed-worktree lifecycle.
withManagedWorktreelives besideWorktreeManagerinsrc/runtime/worktree-manager.ts, and the pipeline, the slice runner, and candidate verification all borrow through it — so creation serialization and the cleanup-failure disposition cannot drift apart, and verification worktrees gain thegit worktree addserialization they previously lacked. -
The slice ref namespace has a single declaration (
src/git/ref-namespace.ts). The pipeline wroterefs/claude-architect/slices/while recovery swept the same literal from its own copy; one declaration makes a silent divergence — refs created but never reclaimed — impossible. -
Unified candidate evaluation into
RunDecision(src/runtime/run-decision.ts).readRunDecisionSnapshotloads a run's result, manifest, review snapshot, gate clearance, and decision once and checks their cross-file coherence in one place;evaluatereturns a typedRunVerdict—accepted(autonomous),human-required,rejected,incomplete, orinvalid— replacing the accept-only rule that was written twice, inmcp/server.tsandmcp/tools.ts. The decide path now reads the archive once:loadArchivedRuncarries the snapshot it read, and the provenance resolver judges that snapshot through the pureverdictForrather than re-reading five files per caller. -
pipelineGateClearedis a versioned artifact next toCandidateDecisionV2, with its own canonical schema atruntime/schemas/pipeline-gate-cleared.v1.json. The artifact store validates every durable record against that schema on both read and write, so a malformed clearance is aninvalidverdict with a reason rather than a shape-sniffed warning string, and a record that reached disk malformed never reads back as "absent". -
Acceptance verification takes a named
mode—candidate,composed-slice, orfinal-branch— instead of an injected structural verifier.MODE_STRUCTURAL_FAILURESdeclares the failure classes each mode may report and now drivesstructuralVerify, which skips the work that proves a class the mode cannot report. The pipeline'sIGNORED_STRUCTURAL_FAILURESfilter, the final branch reviewer's substitute verifier and its privatefinalPathAllowedcopy, and the second scope-violation glob inverifyCandidateare all gone: one scope rule, one symlink rule, one manifest recomputation across every mode. -
runPipelineWithLeaseis 345 lines, down from 1048. The increment loop, the review rounds, candidate promotion, the halted-slice path, the salvage and archive paths, and the final gate are named functions over one explicitPipelineRunStatevalue, and each phase returnscontinueor a terminalPipelineResultinstead of writing into a shared closure. Status lines after the slice wave default to the last slice index throughRunContextrather than a pipeline-local emitter. -
ArtifactStoreis descriptor-driven. OneArtifactDescriptorper archived kind names the file, the read validator, the write-side redaction and validation, and the write mode; every typed façade is one line over a sharedreadArtifact/writeArtifactpair, andwriteArtifactis built onPlatformSafety.writeAtomic. Reads go through the same traversal and identity guards asreadEvidence, so no façade carries its own copy of them.tests/runtime/artifact-store-bytes.test.tspins the archive bytes with hashes recorded from the hand-written façades, so the rewrite is proven byte-identical. -
The store is bound to its run once.
ArtifactStorevalidated the run id at construction and then took it again on every read; the read façades (readManifest(),readResult(),readDecision(), …) now take no run id, and theToolArtifactStore,ReviewSnapshotStore,RunDecisionStore, and advisor-stage store interfaces follow. Prune reads each candidate run through a store bound to that run rather than through the caller's. -
RecoveryDependenciesdropsrequestCooperativeTermination,delayMs, andgraceMs, which were retained for input compatibility and did nothing, and takesplatformServiceswhole.recoverStaleRunsno longer rebuilds aPlatformServicesby grafting a caller's three methods onto the selected platform — production code that existed only to complete an incomplete test double. Recovery never took a checkout lease through that object; leases come fromplatformSafety.withRecoveryLease. -
src/runtime/recovery-manager.ts(3,880 lines, nine concerns) is split into one module per concern:recovery-runs,recovery-prune-journal,recovery-quarantine,recovery-worktree-removals,recovery-worktree-sweep, andrecovery-autopilot, over arecovery-sharedleaf.recovery-managerkeeps onlyrecoverStaleRuns, which sequences them. The declarations moved verbatim, and the modules import in one direction. -
CI pins every GitHub Action to a commit SHA with its version as a comment, and pins the Claude Code CLI it installs. A wiring test enforces both.
-
Internal deepening (no protocol or on-disk format change): one Cleanup Journal module owns
cleanup.ndjson; one Checkout Lock module owns every checkout, recovery and cleanup-journal lock under the owned (link-publish, handle-verified) protocol, with transient Windows errors retried inside the deadline; one Candidate Decisions module owns provenance-to-authority mapping, idempotency and conflicts, anchor removal and the integration and Autopilot acceptance checks (MCP handlers only resolve provenance); one Run Evidence loader gives Autopilot's promoter and final reviewer the union of their former evidence checks; one Worktree Transaction module owns the version-1 manifest, phases and replay (the removal coordinator is gone); durable append, exclusive publish and directory move are shared primitives;roleRunneris the only role-run injection seam; Producer adapters are built from descriptors. Two identity checks are stricter than the plan to leave birth-time comparison where it was, both failing closed: live checkout locks now need a locks directory that reports a birth time, as recovery already did, and reportlocks directory lacks stable birth-time identitywhen it does not; and the workflow store's durable write session compares the workflow directory's birth time as well as its device and inode. The cleanup journal's append, which may truncate a torn tail, likewise refuses a runs root without a birth time. On WindowsflushDirectorycannot flush a directory handle and is a no-op, so cleanup-journal and workflow-store writes there fsync the file but not its directory entry.
Fixed
- On Windows, a sliced run in a long worktree path threw
git diff failed: … Filename too longinstead of recording its halt. Git checks whether each revision argument before--names a file, and that check exceededMAX_PATH. Every runtimegit diff,diff-tree,log,rev-list, andshowcall that takes revisions now ends its revisions with--. - A pipeline that failed after its candidate passed verification (review cancelled, fixer or adoption failure, an unexpected error) on an unsliced run used to leave an archive a person could accept and integrate; every terminal exit now goes through one terminal recorder that demotes the result with the failure classification, removes the candidate anchor (except for a verification failure), always writes
pipeline/pipeline-result.json, and releases authority only after its files are written. Crash recovery archives an interrupted unsliced pipeline the same way. - Crash recovery's cleanup-journal appends now go through the same redacting serializer and directory flush as live prunes, and an append after another process crashed mid-write repairs the torn final line first instead of corrupting the journal.
- A checkout-lock release can no longer delete a lock another holder published in its place, and a dead holder's lock left with its temporary record still linked (a crash between publish and cleanup) is reclaimed instead of staying locked across restarts.
- A worktree manifest naming the never-written
creation-root-changedphase is rejected as malformed (recovery fails closed). - Re-sending an identical rejection after its candidate anchor was removed now succeeds against real Git (
show-ref --verifyexits 128 for an absent ref, which the old check misread). - When salvage promoted a candidate and its re-verification then threw, the fallback demoted the pre-promotion attempt and failed to remove the promoted anchor.
- Directory identity checks use exact 64-bit device/inode values, and wherever birth time is compared it is compared exactly (a recorded zero birth time no longer matches a directory that has one); the archive store, run-start records and the workflow store's directory-identity check still compare device and inode only.
- An atomic write whose temporary-file cleanup also fails reports both failures, primary first, instead of swallowing the cleanup error.
- A descriptor-driven Producer adapter with no probe hook reports the edit lane unavailable instead of eligible.
- The rejected decision advisory for a failed pipeline carries the recorded (redacted) failure reason after its classification, not the classification alone.
Removed
- The GitHub shipping adapter (
src/ship/, about 1,190 lines), the Autopilot v1 spec and workflow-state schemas, and thedoctorchecksautopilot-remote-recovery-requiredandautopilot-pr-recovery-required. - Duplicate primitives: ten
errorCode/isMissingcopies (nowsrc/util/errors.ts), three hot-path directory flushes (nowflushDirectory), strict identity comparisons (nowsameDirectoryIdentity), three workflow-store stable-read copies (nowreadSingleLinkFile), about a dozen per-file Git success helpers (nowsrc/git/checked-git.ts), theLOCK_NAME/reclaimLocksaliases, the last sixNodeJS.ErrnoExceptioncasts, and the unusedSpecInvalidError,SpawnFailureError, andworkflowOwnershipClaimsWorktree.
Documentation
- The lane docs name current models. The direct Codex skill defaults to
gpt-6.1-soland lists GPT-6 models (gpt-6.1-sol,gpt-6-astra,gpt-6-sol,gpt-6-luna), with the GPT-5.6 models moved to legacy and themax/ultraeffort rules restated for GPT-6; the README example, the delegate skill's Codex lane default and the presentation templates name GPT-6.1 Sol; the Pi lane givesxai/grok-4.7as an example of the model configured in Pi; the Claude Code lane mapsopus/sonnet/fableto Opus 5.5, Sonnet 5.5 and Fable 5.1; and theclaude-advisoragent names Fable 5.1. AGENTS.md,README.md,docs/SECURITY_MODEL.md,docs/THREAT_MODEL.md,docs/decision-authority.md, the delegate skill, anddocs/autopilot-terminal-states.mddescribe the confinement and verification-input rules for autonomy, the opt-in Jev screen, the.worktrees/layout, the Git 2.40 floor, and Autopilot ending at a local branch handed to No Mistakes.tests/README.mdmaps every test file to the module and exported interface it crosses and lists the tests that reach past an interface, with the disposition of each.docs/README.mdindexes every document underdocs/as current, historical, or superseded, naming the superseding document where one exists.docs/ARCHITECTURE.mdmaps eachAGENTS.mdtrust invariant to exactly one owning subsystem and file;SECURITY_MODEL.md,TRUST_BOUNDARIES.md, andTHREAT_MODEL.mdpoint at that mapping.docs/MARKETPLACE_REVIEW.mdstates edit-lane confinement evidence per lane and platform, and says plainly that no lane has native Windows edit evidence and none is claimed — five of the six lanes are unsupported for editing off macOS becausemacos-seatbeltdeclares no Linux or Windows platform at all.- The delegate skill is 35% shorter (5417 → ~3520 words) with no rule removed: the autopilot and manual lifecycles are one section, the two presentation sections are one, and the sliced pipeline, backgrounded-run monitoring, presentation templates, decision-authority policy, and verification-preflight reference moved to
docs/.subagent-driven-delegationno longer restates the spec-authoring, lane-correlation, and decision rules it shares withdelegate; it points at them.