The authoritative maintained source is the repository root
HANDOFF.md.
The content below is included directly during every book build.
Core hardening wave — 2026-10-02
Nested reviewer cwd layout — 2026-10-18
Task ba9b2fb4 addresses the second mxmini canary blocker under owner task
422ce01e: a real reviewer pwd call ends in tmp/claude-997/cwd-ID, which
the old flat-only guard refuses with status 126. The same failure reproduced
with signed Claude 2.1.300, so the temporary version pin was rolled back to
2.1.303. The fix accepts only the observed bounded nested grammar, requires
its existing nonsymlink host directory, recreates the parent only inside the
masked tmpfs, and checks the host target again before resetting cwd. It does
not bind harness temp into the candidate sandbox. Flat paths, command status,
timeouts, stopped-command accounting and descendant cleanup remain enforced.
Exact-source validation, independent review and a real contained reviewer
proof are required before installing the new supervisor. CLI publication fix
48802dc5 is independently tracked and still requires its matching service
and CLI rollout; installing either fix alone does not clear the canary hold.
Private-repository helper checkpoints — 2026-10-18
Task 48802dc5 fixes the blocked mxmini canary discovered under owner task
422ce01e. Candidate and WIP helper routes scan the bundle locally, use the
trusted host helper’s authenticated remote confirmation, validate its exact
receipt, and recheck the clean snapshot. They perform no client remote reads;
the helper retains the authoritative full outgoing-history scan and create-only
publication. Direct checkpoints retain their independent remote verification.
Verification, integration and compatible CLI rollout evidence belongs in those
tasks. Resume the existing Ready canary only after deploying the verified CLI
and clearing its task-specific unsubmitted-launch hold; successful setup still
requires an actual outcome=ok and the ntfy failure-path exercise.
S6 required-check stability sample — 2026-10-05 (workflow off): PASS
Per book/src/docs/integrator-cutover.md “Required-check stability evidence”. Pinned
main 3882ba4b6f121f4cad35f99d2737fb6398d3b26d (re-checked before every rerun and at the
end; unchanged). Push runs: Coordination checks 37117852141, Documentation checks
37117852080. 20 sequential “rerun all jobs” attempts each (14:49-17:28 UTC; no
failed-job-only reruns, no dispatches) on top of attempt 1 ⇒ 21 attempts per required check,
0 non-success, rate 0.0: Linux format, Clippy, and workspace tests 21/21,
Audit locked dependencies 21/21, Pinned mdBook build and local-link validation 21/21
(non-required Native Windows client, CLI, and local runner tests also 21/21; the
launcher-lock test did not fail). integrator-flip-rate.py rc 0, all passed: true.
Evidence outside Git in ~/.local/share/agent-coordinator-autonomy/s6-stability/:
ci-jobs.json, docs-jobs.json (filter=all), flip-rate-report.json, per-attempt
ci-loop.log/docs-loop.log, driver rerun-loop.sh. Note: the docs log’s attempt-19 line
says null because the jobs API lagged the completed run attempt; the run attempt and the job
later read completed/success. The rest of the S6 chain has since completed: live policy
has integration_owner=integrator, and the post-cutover canary (task f92bf97d) is done.
U27 Claude setup-token auth — 2026-10-03 (branch hardening/claude-token-20261003)
Workflow off. The owner proof on oracle-1 (see the planning HANDOFF.md) showed that Claude
2.1.287 refreshes OAuth only after mkdir claude-config/.oauth_refresh.lock, which the
root-owned claude-config denies. Decision U27: agent accounts use claude setup-token.
-
Supervisor:
launch::spawnreads<state>/<role>/claude-tokenand passesCLAUDE_CODE_OAUTH_TOKENto the child only, never intoLaunchCommand.envordescribe. The read ispath_without_symlinks, then anO_NOFOLLOW|O_NONBLOCKopen, then fstat checks (regular file, 1 link, at most 4098 bytes) and a bounded read. The token must be printable non-space ASCII, at most 4096 bytes, and trailing whitespace is trimmed. Nothing binds.credentials.json, and claude-config has no writable path. Preflight requires a root:0440 non-empty token, reports every disallowed claude-config entry, and gives a retired .credentials.jsonits own removal instruction. -
host-setup: shreds a leftover single-link
.credentials.json. It holds an existing token at root:agentc-0440, but only if it is already root-owned; it refuses links and never reads the token (beyond a same-size dummy check). --uninstallzeroes the tokens.next_stepsprints theclaude setup-tokenplussudo install -m 0440 /dev/stdinflow. -
containment-suite: installs a dummy token for a role that has none (root:role 0440) and removes only its own unchanged dummies on exit. A stale dummy left by a killed run is a FAIL. New legs: claude-config write and
mkdir .oauth_refresh.lockdenied, token not writable, no cross-role read, and neither the candidate token file nor the env var is visible. -
Red team: both lanes DISPUTED in round 0 (low severity: an oversized file passed through the read bound, an untested read bound, the first-entry-only report, an lstat/open race; a stale or partial dummy, a non-root token adopted, a vacuous grep probe), all fixed, then CONFIRMED in round 1. Flake seen under mutation load:
push_helper::tests::stale_launch_directories_are_swept_only_when_owned_unlocked_directories(6/6 passes alone). -
oracle-1 root run (2026-10-03, owner-approved): host-setup
APPARMOR_BWRAP=1rc 0 removed both retired logins; pin moved 2.1.287 -> 2.1.288 (host-setup copies the owner’s claude); claude-config holds only the two root seeds. Containment suite rc 0, 101 PASS, no FAIL, NOTE x2 (dummy token), SKIP browser (no staging); dummies removed afterwards. -
Real-token proof on oracle-1 (2026-10-03, Claude 2.1.288): two distinct setup-tokens at root:agentc-
0440 (1 link, 108 B). Suite rc 0, 101 PASS, no NOTE. Auth smoke per role with the token via env: ok, no auth/refresh stderr, claude-config unchanged (seeds only).pwd -Psuffix PASS on 2.1.288 (plain, cd, background; file directly in TMPDIR). Preflight lists no token/claude-config problem (only the missing proof clone/run). Merged to main (3882ba4). -
mxmini root run (2026-10-05, owner, from
3882ba4; release binaries rebuilt first, the old ones predated U27): host-setup rc 0 removed both retired logins; pin 2.1.288 -> 2.1.289 (owner’s claude). Two distinct setup-tokens at root:agentc-0440, 1 link, no newline; auth smoke per role (throwaway CLAUDE_CONFIG_DIR, token via env)okrc 0. Suite rc 0, 90 PASS, no FAIL/NOTE, SKIP push-key (no key) and browser (no staging). The impl token was then pasted into a session transcript, so the owner revoked both new tokens and installed two fresh ones (108 B each, distinct, auth smokeokrc 0 per role). Revocation path (not in the docs): claude.ai web Settings > Claude Code > Authorization tokens; setup-tokens are the rows whose only scope isuser:inference(no device or role shown, so revoke by creation time; trash icon on hover). The retiredclaude auth loginrefresh tokens lived only in the shredded files.pwd -Psuffix re-proof on 2.1.289 (2026-10-05): PASS. Pinned claude run as agentc-rev (setpriv, rev token via env, proxy, throwaway HOME/TMPDIR, loggingCLAUDE_CODE_SHELL_PREFIX): plain,cdand background commands each reached the prefix as one arg ending&& pwd -P >| $TMPDIR/claude-XXXX-cwd(directly in TMPDIR); noenv -isnapshot call through the prefix. Gotcha:--allowedToolsis variadic, so put the-pprompt before it. -
09a2b78TypeSafe main-service-only secret file (wave-plan A-P4): the main unit addsEnvironmentFile=-/etc/agent-coordinator/typesafe.envafterservice.env; backup/maintenance units unchanged; install and backup guides,service.env.exampleand the install smoke updated. Independently CONFIRMED. The out-of-reporelease-next/deploy-pre.shnow aborts before stopping anything unlesstypesafe.envholds a nonempty key and warns ifservice.envstill has a key line (previous copydeploy-pre.sh.pre-typesafe-env). The next deploy therefore needs the user’s VM step first: installtypesafe.env(root:root 0600) with the key, install the new unit, daemon-reload, remove the key line fromservice.env, restart. -
8b24b8eC1 routing resolved as a new phase: literal URL snapshots, rewrite refusal, plus refusal of a configured remote named like a snapshot (the old blocker), ASCII-only host match and exact.gitsuffix. Two repairs, after which the final verifier found no routing bypass. Tests inscripts/ship_routing_test.py(real local Git, mocked transport). -
8c2cdc6exact-ref readback:ls-remotesuffix matching letrefs/heads/a/refs/heads/mainbe read back as main. Pre-existing on main; the user chose to fix it as a separate item. Independently CONFIRMED. -
417dbcaR-P3b.5(d), decision U20: read-only credentials keep their own top-level session but any registration naming a subagent is refused (403) before writes. Full gate on it: fmt, warnings-denied Clippy, 546 tests, zero ignored (r5d-*.log). Independently CONFIRMED. Untested: replay ordering (no test pins the check above the replay branch). -
709d277R-P3b.3, decision U18: Claude reviewer Bash commands run throughCLAUDE_CODE_SHELL_PREFIX= generated$RUN/candidate-shellin a nested bwrap (state dir tmpfs; clone ro; tmp/target/Cargo rw; private$RUN/candidate-homeover$HOME; Claude config ro with login masked; env credentials unset; own pid/ipc/uts/user ns; no nested userns; ro /proc). Reviewer outer keeps userns + rw /proc for nesting; Codex reviewers refused. Two repairs (unpinned inner flags; shared$HOMElet planted.gitconfig/.profilereach Claude Code’s out-of-prefix git/login shell). Final review INCONCLUSIVE; user chose commit and track. Full gate: fmt, Clippy, 550 tests, docs (r3-*.log). One unrelated flake seen once:namespace_teardown_kills_detached_descendants_on_exit_and_wrapper_kill. Open, blocks first live launch (own repair budget): candidate can move the harness’s tracked cwd into shared tmp/target/Cargo dirs; an out-of-prefixgit statusthere could run a candidate filter with the reviewer login (trigger unconfirmed; site gated by CLAUDE_CODE_AUTO_MODE_GIT_STATUS). Fix: candidate-shell resets the cwd file to the clone, plus an instrumented owner run (git shim logging cwd). Also unverified on a real host: prefix applies to background Bash, fd inheritance into the prefix, shell snapshots, UI checks (need U18’s per-run short-lived staging login, not built). -
Gate: ship tests (18), routing tests (36), pinned docs check and py_compile passed; no Rust/Cargo change since the full gate on
0beabe8. Logs:~/.local/share/agent-coordinator-autonomy/core-20261002/followup-*.log. -
One verifier accidentally ran an https
git fetchto github.com; it stopped at the credential prompt. Nothing was pushed. -
Known false refusals by design: https URLs with userinfo (token insteadOf) and ssh→https insteadOf with pushInsteadOf back.
-
6f19eb4R-P3b.3 cwd residual: candidate-shell refuses (126, before running) a command not ending inpwd -P >| <plain file in $RUN/tmp>; after the nested sandbox exits it writes the clone path to that file and returns the command’s status. Candidates get$RUN/candidate-tmpas TMPDIR; the harness’s$RUN/tmpis a throwaway tmpfs inside, so no candidate (incl. background) can rewrite the file.cdno longer persists. Full gate: fmt, Clippy, 554 tests, docs (r3cwd-*.log); two mutations red. Independent red-team CONFIRMED (real-bwrap probe with delayed and setsid writers, dash/bash parsing table, four mutations). Owner-run checks: the pinned CLI’s cwd file is directly in TMPDIR with that suffix, background and snapshot invocations carry it, and no harness file under$RUN/tmpis handed to Bash. Hardening note: the final write follows a symlink, but only the harness can create entries in$RUN/tmp. -
Decision U21 (refines U19): R-P3b.4 uses a supervisor port bridge (
--unshare-net, relay only proxy 3128 and staging 18080 over per-launch Unix sockets); pasta/passt is not installed on mxmini. -
52191ceR-P3b.4 per U21: Claude launches run with--unshare-net; the supervisor relays only the proxy and a verifying reviewer’s loopback staging port (host half: Unix sockets in$RUN/net-> that TCP address, under the firewall; namespace half: hiddennetns-relaylistens on the same ports and runs the harness). Ports must be IPv4 loopback >= 1024; unfaithful loopback staging URLs are refused. Preflight requires a root-owned supervisor binary and runs its relay once. Supervisor is now lib + bin;tests/launch_relay.rsdrives a real wrapped reviewer launch through both halves. Full gate: fmt, Clippy, 566 tests, docs (r4b-*.log). Red-team round 1 DISPUTED (host half untested, silent staging forms, ports < 1024 unbindable); one repair, round 2 CONFIRMED. Residuals: mutants “launch::run skips start_host” and “check skips probe_relay” survive (paths need root-owned binaries) -> add a root containment-suite leg running a reallaunchwhose mock harness reaches the proxy via the relay (check_claude_sandboxcurrently cuts args at the first--, so it never runs the relay). Codex launches keep the host namespace and the firewall ephemeral range. Silent fail-closed staging forms remain (percent-encoded hosts,0.0.0.0,0x). Owner-run: host relay under the real nft rule; Claude Code and Chromium behind the relay. Pre-existing flakenamespace_teardown_kills_detached_descendants...hit once under full parallel load (0/15 both here and at HEAD afterwards). -
f1edaddcontainment-suite relay leg: per role, a realagentc-supervisor --config <tmp> launchthrough a temporary root-owned/opt/agentc/suite-bin.*(copied supervisor + mockclaude; config = the installed one withbin_dirprepended) must reach the proxy via the relay, fail direct egress, and (reviewer) reach the proxy from a candidate command; a stub bin dir (/bin/falsesupervisor) must make preflight reportnamespace relay probe failed. Red-team round 1 DISPUTED (pipefail made the stub check always fail); fixed by capturing preflight output, plus cleanup/error-path fixes; helpers exercised locally with stubs. Docs check passed; no Rust change. Not run: needs root and the new supervisor installed on mxmini (installed one predates the relay), so the firstsudo deploy/agentc/containment-suite.shafter install is the owner step that proves it. Staging relay is not in this leg (no login fixture);tests/launch_relay.rscovers it. -
e47c46fU22 per-run staging session (refines U18): newstaging_login.rs. Afterstate.started, a verifying Claude reviewer launch signs in to staging from the supervisor (login file never enters a sandbox), writes only{url, cookie}to$RUN/verification-session.json(create_new 0600; ro-bind into the candidate sandbox), signs out after the harness (also on spawn/wait failure, and if writing the file fails). Sign-in failure fails the launch. Loopback perrelay::staging_address(direct,.resolveto the relay address); otherwise https via the egress proxy. Reviewer harness gets a tmpfs overrev/verification.verification.jsonnamessession_file(notcredential_file);verify_ui.mjssets the cookie via CDP (form login kept for hand-written descriptions). Gate: fmt, Clippy, 573 tests, 0 ignored, docs (u22r-*.log). Two mutations red (candidate bind, harness hide). Local e2e against a real staging server + Chrome:/me200 with the cookie,verify_uiOK, 401 after sign-out (temporary test, not committed). Red-team round 1 DISPUTED (.localhostmismatch with relay, harness could read logins, http off-host, long functions); repaired; round 2 CONFIRMED. Residuals: no sign-out on panic/SIGKILL (12h session bound); a cookie holder has operator power on staging during the run; staging login rate limit 5/min/user and 10-session cap may bite bursts of reviewer launches; https__Host-cookie via CDP untested; trailing-dot Origin vs the server’s origin check untested. -
598c77aR-P3b.2 phase 1 (U17/U23/U24):coordinator_local::candidate_push, both sides of the per-launch helper protocol (JSON request line + u64 length-prefixed bundle; one JSON reply line with stable refusal codes). The helper checks the pack withindex-pack --strict(git 2.39.5 applies neitherfetch.fsckObjectsnortransfer.fsckObjectsto bundle fetches), imports by OID only, re-scans, and pushes onlyrefs/agent-coordinator/candidates/<task>/<launch>under an intent + lease guard (foreign refs never adopted; intent cleared on definite failure). The outgoing secret scan now also reads raw commit objects (messages, idents, signatures, anyencodingheader) — behaviour change oncheckpoint_candidatetoo, accepted by the main loop. Gate: fmt, Clippy, 598 tests, docs (p2c-*.log). Red team: DISPUTED twice (foreign-ref adoption, reply size, unscanned messages; then encoding-header bypass, stale intent), round 3 CONFIRMED. Residuals: helper repo disk growth (pack stored twice, refused packs kept); first push fetches full prerequisite history; EBCDIC-style re-encoding is obfuscation, not caught. -
bb5294bR-P3b.2 phase 3: withAGENT_COORDINATOR_CANDIDATE_PUSH_SOCKET(absolute path; blank = unset) a code submission refuses--candidate-ref, checks the base commit, pre-scans with the caller’s credential digest (the helper cannot know it), sends, then reads the helper’s ref back (exact commit + tree). Codes: refused (per RefusalCode), connection failure incl. EOF-before-reply → 7 retryable (helper retry is idempotent), pre-send local error → 2, protocol violation → 5. Red team DISPUTED twice (classification, Windows dead code, escapes, env parsing; then EOF-before-reply), round 3 CONFIRMED. Residual: the CLI records any prefixed ref already holding the exact commit (no launch identity client-side; bind server-side if needed); no socket timeout on the client. -
2132b4cR-P3b.2 phase 2:agentc-push serve [--config /etc/agentc/push.toml] --socket --task --launch --work-dir [--known-digest]... [--parent-pid](integrator crate, now lib + 2 bins; examplecrates/integrator/push.example.toml;app_id,installation_id,repositoryrequired). Mints only after a valid preamble, budget burst 3 / 1 per 20 s, token scoped to the repo + contents:write, askpass via self withGIT_CONFIG_PARAMETERS/global/system neutralised and env cleared to PATH/HOME/LANG/LC_ALL, revoked always; refuses root; PDEATHSIG (follows the spawning thread); socket 0660 via a 0700 staging dir + hard link. Red team DISPUTED once (mint per empty connection, inherited Git env, chmod window), round 2 CONFIRMED. Phase 4 must: spawn from a launch-lived thread withenv_clear(), pass--parent-pid, keep socket paths < 108 bytes, remove a stale socket after SIGKILL, and settle one-submission-per-launch (the helper moves its single ref on resubmission). Full gate on the combined tree: fmt, Clippy, 641 tests, 0 ignored, docs (p2f-*.log); one ETXTBSY flake incandidate::shell_testsonce, 3/3 reruns green. -
f55cdbcR-P3b.2 phase 4a, U26 (narrows U24): the helper creates its ref only when absent and never moves it; same-commit retry (incl. intent recovery) accepted; any other commit →candidate_already_published(early, before the bundle, once a lease exists); CLI exit 5. Red team CONFIRMED first round. Lows: a crash after the push but before the lease, plus a foreign deletion, lets a second commit through (X was never acknowledged); corrupt lease reads as absent (fails closed as bundle_invalid); the refusal does not name the published commit. A refused second commit still costs one mint. -
d8a9b80R-P3b.2 phase 4b, U25:agentc-supervisor launch-root(root). Per-launch dir<state_dir>/push/<session>/(push root 0711 root-only;sock/agentc-push:2750; work/agentc-push 0700) — not under$RUNbecauseruns/is 0700 agentc-impl. Helper as agentc-push via setgroups/setgid/setuid in pre_exec (verifies setuid(0) fails), env PATH/LANG/HOME=work,--parent-pid, digests of implementer-ownedcredentials.tomltokens; ≤10 s socket wait; launch child as agentc-impl with--push-socket --task --session-id; SIGTERM→5 s→SIGKILL; dir removed; teardown failures warn and keep the launch’s exit code. Sweep of stale dirs (incl. abandoned.new-*) underpush/.sweepflock. Claude sandbox now masks<state_dir>/pushand<state_dir>/<role>/runs(tmpfs) and binds back only its own socket dir and$RUN. Ref =.../candidates/<task>/<session-id>. Red team: DISPUTED (cross-launch socket reach via leaked session ids; sweep race), then N1 lexical socket path + first-runpush/race; all repaired; full gate fmt, Clippy, 669 tests, 0 ignored, docs (p4bf-*.log). Known gap (documented): Codex implementers run in the host namespace as agentc-impl and can reach concurrent launches’ sockets — run Codex implementers one at a time. Unverified without root: the real uid switch, setgid inheritance onto the socket, agentc-rev refused,host_problemsinsidelaunch_root. A SIGKILLed launch-root leaves the launch child running without its helper (next run sweeps the dir). -
(phase 5, this commit’s parent) host-setup/containment-suite/docs:
agentc-pushaccount strictly checked (uid≠0, not shared with impl/rev/egress, nologin/false, only its own group); binary at/opt/agentc/bin/agentc-push(new default;/usr/local/binis root:staff 2775 on Debian and failsprotected_executable);/var/lib/agentc/pushroot 0711;/etc/agentc/push.tomlroot:agentc-push 0640 written only when absent (App 5168037 / installation 167333814); key chowned to agentc-push 0400 if present (symlink/hardlink refused).--uninstallnow removes only host-setup’s own paths (the integrator survives — previously itrm -rf’d/opt/agentc,/var/lib/agentc,/etc/agentc). Suite push leg uses a non-minting sentinel config. Red team CONFIRMED + L1-L4 hardening. Nothing here has run as root.agentc-pushhas no egress firewall (direct to GitHub).
R-P3b.2 is code-complete. User steps (root): on oracle-1 from this branch:
cargo build --release --locked -p agentc-supervisor -p agentc-integrator -p coordinator-cli,
sudo SUPERVISOR=target/release/agentc-supervisor CLI=target/release/agent-coordinator deploy/agentc/host-setup.sh,
sudo deploy/agentc/containment-suite.sh; same on mxmini (key checks SKIP;
also owes the f1edadd relay leg). Remaining backlog: owner Claude
host/auth/refresh/browser proof (incl. the pwd -P suffix), S6 cutover chain.
-
7b8d3a1R-P3b.5(b)(c) (2026-10-02 late; coordinator workflow still off, local commit only). (b)no_new_privson every harness, preflight--versionand sandbox probe;reaper::reapedmakeslaunchandlaunch-rootchild subreapers that SIGKILL every descendant (pidfd, parent re-checked, whole tree per round) after the harness and before.state-terminal.json, and again if the launch errors. (c)--uninstallretires impl/rev/push accounts first (linger off,pkill -u/-Uwith a final re-check, crontab,atjobs, own files in /tmp, /var/tmp, /dev/shm, userdel), then stopsagentc-egress(Restart=always) before retiring its account, then drops the firewall. Gate: fmt, Clippy, 674 tests, docs,bash -n; mutation controls m1-m5 red. Red team: two DISPUTED rounds, all findings fixed (last one, the egress restart race, fixed after round 2 and verified with shell stubs only). Residual LOW: thereapedcall sites inmain.rs/push_helper.rsare untested wiring. Unverified without root: the whole uninstall path, cross-uid kills fromlaunch-root. Flake seen once:coordinator-clilauncher_lock_excludes_another_launcher_but_allows_native_journal_lock(passed 6 reruns; untouched crate). -
Root runs, 2026-10-02 night (owner-guided, workflow off; branch pushed). Both hosts:
containment-suite.shall checks passed (only SKIP: browser, no staging). mxmini (Debian 12) also ran thef1edaddrelay leg; push-key legs SKIP there (no key). oracle-1 (Ubuntu 26.04, kernel 7.0, AppArmor 5.0.2) passed the push-key legs. Fixes found by the runs:0ae9877install_node exited silently under pipefail without nvm;a72f402opt-inAPPARMOR_BWRAP=1(Ubuntu’sunpriv_bwrapdenies the reviewer’s nested sandboxsys_admin; apriority=local override does not lift it): agentc-only/opt/agentc/bin/bwrap(root:agentc-bwrap 0750, members exactly impl+rev) with its ownagentc-bwrapprofile, plus the suite now expects preflight to refuse Codex reviewers;4ce6b93SIGPIPE- safe primary-group check. Red team: DISPUTED twice, all findings fixed. oracle-1 runs withAPPARMOR_BWRAP=1; re-run host-setup with it after any Bubblewrap upgrade (suite fails on a stale copy). Accepted scope: Codex implementers (unwrapped) can reach the copy, as on Debian. Still unverified: the--uninstallpath as root; cross-uid kills beyond the suite’s legs. Next: owner Claude host/auth proof (incl.pwd -Psuffix), S6 cutover chain.
The user disabled the Agent Coordinator workflow and authorized overnight local implementation with subagents. Cutoff: 2026-10-02 08:00 America/New_York (12:00 UTC). No production changes, credential issuance, rulesets, ownership switch, host root changes or Git pushes are part of this wave.
Integration tree: ~/src/worktrees/agent-coordinator-core, branch
hardening/core-20261002, based on freshly fetched origin/main 1e8aebb.
Each builder has its own agent-coordinator-core-{typesafe,confinement,ship}
worktree, branch and Cargo target directory. The primary owns integration,
checkpoint commits, gates and this handoff. Preserve the planning checkout
~/src/agent_coordinator and existing autonomy/s6 worktree.
User decisions:
- Isolated writable Cargo caches per launch. Under disk pressure, prune expired terminal launch state first; any more efficient fallback must preserve write isolation. Shared writable download caches are not authorized.
- After two evidence-led repair attempts on a disputed phase, record its blocker and continue independent lanes.
- At most three concurrent subagents. Builders: TypeSafe
gpt-6.1-sol/high, Claude confinementgpt-6-astra/xhigh, ship.pygpt-6.1-sol/medium. Fresh verifiers are at least as capable; security verification usesgpt-6-astra/xhigh. The deadline repair reused the idle Astra/xhigh builder; A3 uses Sol/high.
Current phase state:
- A1 concurrency cap (default 4) independently verified after one bounds repair;
249ea62here (d8155bbin its lane). A2 circuit breaker independently verified: three consecutive completed failures open it for 60 seconds, followed by one half-open probe; stale completions cannot alter newer generations.60af14ahere (f20a47din its lane). A3 application-context fallback/order, deterministic recovery and redacted-log tests independently verified and integrated as0beabe8(7649f6ain its lane): 30 library tests, seven integration tests, warnings-denied scoped Clippy, format and pinned docs passed. - B1 per-launch state and terminal-only retention independently verified:
1f8e96ahere (487e2c5in its lane). B2 protected seeds and validation before writes independently verified:1f9063ahere (e44a701in its lane). B3 Claude-only OS write confinement independently verified after one repair:1383e0chere (69a3c75in its lane). It uses bubblewrap, narrow writable mounts, protected seeds, descriptor fencing, a bounded sealed prompt snapshot and descendant cleanup. Codex keeps its existing native sandbox/auth behavior. Supervisor focused gate: 55 tests, warnings-denied Clippy, format, shell syntax and pinned docs passed on Rust 1.98.1. Actual owner-run host containment, authenticated Claude credential refresh and nested browser compatibility remain unverified. Root-owned Claude config parents prohibit temp-file/rename refresh; owner bootstrap must import only the credential file from a separate login dir. Do not treat local mock proofs as operational readiness. - C1 fetched-tip ancestry and exact GitHub repository routing is BLOCKED
after two repair attempts. Do not integrate its uncommitted changes from
agent-coordinator-core-ship. Its 26 tests pass, but an independent real Git resolution probe found that a remote whose name is a saved URL can redirect fetch/push/readback to an unchecked repository without anyurl.*rewrite. Example:remote.publish.url=https://github.com/Checked/Repo.gitandremote.https://github.com/Checked/Repo.git.url=https://github.com/Unchecked/Repo.git.validated_remote("publish")approves Checked while literal URL operations resolve to Unchecked. No actual transport was used in the probe. Earlier repairs fixed GH_HOST, mutable aliases and chained URL rewrites; respect the user retry limit and retain this disputed work for a future phase. - C2 independently verified after one repair and integrated as
70c7c55(06736bbin its clean lane). Default overall Actions deadline is 1800 seconds, appearance window remains 300 seconds, individual queries are capped at 300 seconds and bounded by remaining deadlines. Positive finite huge overrides do not overflow subprocess polling; timeouts name the full SHA and stop final push. Eighteen unit tests and four independent full-flow checks passed. Treeagent-coordinator-core-ship-deadline, branchhardening/ship-deadline-20261002, contains no disputed C1 changes.
Final integration gate on product commit 0beabe8 passed on stable Rust 1.99.0:
format, warnings-denied workspace/all-target Clippy, all 545 workspace tests
(33 suites, zero ignored), locked workspace build, disposable loopback service/CLI
smoke, backup/restore smoke, all 18 shipping deadline tests, pinned mdBook 0.5.4
source/package/local-link checks, and dependency audit (372 dependencies).
The focused phase gates also passed on Rust 1.98.1. No dependency version changed;
Cargo.lock adds the already-resolved libc dependency to the supervisor only.
The gate cleared ambient coordinator configuration and the TypeSafe key; no paid
provider call or production service mutation occurred. Baseline had 502 tests.
Evidence is outside Git under
~/.local/share/agent-coordinator-autonomy/core-20261002/: see
integrated-gate-results.json and integrated-{fmt,clippy,tests,build,smoke,backup-smoke,ship-tests,docs,audit}.log.
The accepted lane worktrees are clean; the disputed routing tree is intentionally
uncommitted. The original S6 tree was preserved. No branches were pushed and no
production deployment or root host change was attempted.
Next session: start with this handoff and git status --short in this integration
worktree. Review git log --oneline origin/main..HEAD and the source diff before
requesting authorization to ship. Do not ship through the disputed routing phase.
Future work needs a new routing phase, TypeSafe main-service-only secret-file
preparation, owner Claude host/authentication/refresh/browser proof, and the
remaining supervisor security decisions. The two-repair cutoff applied to C1;
do not silently resume a third repair in the completed core wave.
S6 cutover and the later supervisor security queue remain separate work. The planning handoff records the 24-hour polling pass but no live candidate evidence.
S6 release 1e8aebb and oracle-1 shadow bootstrap — 2026-09-30
Carried from branch autonomy/s6 (af29aae, 1b3e498); workflow was off then.
- Shipped and deployed: product candidate
1e8aebb(incorporating14e2fda,e042e26,291b680). Fresh-context security review (gpt-6-astra/xhigh) reproduced a false-green drain preflight for expired/revoked ordinary task and review attempts whose recovery is derived rather than persisted; fixed by requiring zerotasks.current_attempt_id, with an expired-task/review regression (five ops tests pass). Live roster revision 3 (linux-validation,documentation,dependency-audit) is mapped to its GitHub job names/paths in.agent-coordinator/roster.toml. - Gate: 502 workspace tests, fmt, warnings-denied Clippy, locked audit, workspace build,
service/CLI smoke, backup/restore smoke, pinned documentation checks, five ops regressions.
CI runs
36662950828and36662950832passed on the exact SHA; release acceptance36663055767passed Linux package/systemd/HTTPS, five-minute load and Windows packaging. - Binaries-only production deploy: all seven preflight counts zero before deploy and after
stop; stop/start 03:23:02–03:23:25 UTC, health 03:23:26; public build identity, backup,
maintenance, transfer and timers verified. Rollback binaries use suffix
-0.1.1-4a72018; snapshots old20260930T032256.016Z-88af7c3f-0b71-4134-8da5-92be7292612f, new20260930T032326.636Z-fdd008a6-28f0-42ed-b119-9aca91aaedb7. Evidence, logs and scripts:~/.local/share/agent-coordinator-autonomy/release-1e8aebb/. - oracle-1 integrator build: ARM64, systemd 259, Rust 1.98.1; clean detached checkout
/home/ubuntu/src/worktrees/agent-coordinator-s6-releaseat1e8aebb; host-nativeagentc-integratorSHA2564018b8cee4e1bda30b64da585fc899bb1b35a0b177b50c508d8f1bb46cce01fa. Owner bootstrap:integrator-host-setup.shwith that binary,~/integrator-shadow.tomlinstalled as/etc/agentc/integrator.toml(root:root 0644), and a read-only integrator-class credential at/etc/agentc/integrator-credentials.toml(root:root 0400; token never in chat or Git). App and coordinator source files are root:root 0400. - Shadow startup: unit running from 2026-09-30 04:28:08 UTC; first target observation
04:28:12 UTC, zero restarts or errors at startup. Journal evidence:
~/.local/share/agent-coordinator-autonomy/release-1e8aebb/shadow-start.log.
Historical S6 implementation checkpoint — 2026-09-29
The user disabled the Agent Coordinator workflow for this session. No service
work was created, claimed or updated. Continue in branch autonomy/s6, worktree
~/src/worktrees/agent-coordinator-s6, based on main 4a72018; keep Cargo
output in this worktree’s target. The autonomy planning handoff/design remain
in ~/src/agent_coordinator on autonomy-plan (fbce216 at session start).
S6 local implementation adds agentc-integrator shadow [--once], a pre-cutover
queue view (?shadow=true, integrator credential only, no live heartbeat),
root-owner host bootstrap, a read-only drain preflight, required-check sample
analysis and the canonical cutover runbook.
Shadow uses separate local state, computes R and reads checks; no service
publication writes, Git pushes or job reruns occur. WouldPush is provisional
(authority_verified=false). Revert computation is still live-only. Missing
rules are logged before cutover; missing roster mappings fail the shadow pass.
Production remains unchanged. S6 is not complete. Required next steps:
- App repository access completed and browser-verified 2026-09-29: App
5127380, installation166293403, now selects onlymarshallr12/agent_coordinator; the test repo is removed. GitHub displayed the saved-update confirmation. U4 App-only push protection passed in the previous session. The App key stays on oracle-1 at/etc/agentc/integrator-app.pem, root-owned0400; never copy it to the workstation. Connect via the user’soracleBash alias;ssh oracle-1does not resolve locally. - Review/ship/deploy S6 service and build the host-native integrator at the
reviewed revision. Owner runs
deploy/agentc/integrator-host-setup.shwith sudo, sets project/config and installs a read-access integrator credential. - Land a target roster mapping the exact service identities to the three GitHub job names/paths in the runbook; the current target has no roster file.
- Run/retain a continuous 24-hour production shadow and a reviewed live candidate test. Collect about 20 all-job attempts per required check on pinned main; each observed non-success rate must be <2%. Then zero drain preflight, owner rulesets, credential replacement, ownership switch and canary. Do not infer any of these from the local regression tests. P3b follows completed S6.
Local verification: 502 workspace tests passed, warnings-denied workspace
Clippy passed, pinned documentation source/package/local-link checks passed,
locked dependency audit passed, four cutover-ops regressions passed, shell
syntax and generated systemd unit validation passed. The rendered runbook was
inspected in Brave. The full workspace build, service/CLI smoke and backup/restore smoke passed
on clean committed candidate 14e2fda; the final focused shadow-queue test also
passed after adding the missing-project check. This record update changes
only documentation. Product code remains locally committed, not pushed or deployed.
Local gate logs use /tmp/agentc-s6-*.log; cutover credentials/evidence stay
outside Git. No remote push or production deployment has occurred.
Implementation handoff — 2026-09-14
MCP-first bootstrap
Startup now prefers a configured authenticated MCP connection and uses the native
CLI as fallback. Public discovery schema 2 separates coordination from local
workstation capabilities and gives explicit missing-client and ownership-safe
transition procedures. MCP’s own instructions no longer require a native launcher.
The native session adopt-mcp command validates and adopts an existing quiescent
MCP session using protected environment values; it never claims or renews work.
CLAUDE.md remains a minimal bootstrap. Deployment/test evidence belongs to the
live service task, not a local task queue.
Service discovery migration
The public info endpoint now embeds the canonical book/src/docs/agent-startup.md
guide as data.agent_startup (schema version 1). It describes portable credential
configuration and native CLI workflows. Private task/project contents remain
behind authentication. CLAUDE.md is a seven-line discovery bootstrap; AGENTS.md
contains only its pointer. Engineering requirements moved to CONTRIBUTING.md.
BACKLOG.md and its book wrapper were removed; historical milestones are in the
implementation-history chapter and pending acceptance criteria remain in the live
service. Agents need no local backlog or handoff to select and claim work.
Validation and deployment evidence will be recorded with the live migration task.
Setup usability follow-up
The two setup usability items and the Copy token investigation are now Code
tasks in the live Agent Coordinator project. Read their current state from the
service; this document is historical context, not the work queue.
The repository binding names project
fe95a6c5-2aad-463f-8446-4366d9a281c7 at https://agents.sithbit.com.
The verified Windows CLI from release run 34891009689 is installed under
%LOCALAPPDATA%/AgentCoordinator/bin; scripts/coordinator.ps1 supplies the
binding and requires an explicit, stable harness session name. The operator
saved the codex-miniair token in protected Windows configuration after manually
copying it. Native CLI authentication, complete orientation, reading all three
tasks, and reading the required-check roster passed on 2026-09-14 without using
admin browser authentication. No task was claimed during setup verification.
CLAUDE.md and AGENTS.md now direct future working sessions to the live service,
automatically selecting and claiming eligible work according to live priorities.
The Copy token investigation was created through the external browser as
4b68f1c7-7ed2-42cb-b8cc-3ce0a1dfaefb; its evidence distinguishes the user’s
manual failure from possible automation clipboard isolation.
Initial operator setup exposed unclear project policy and required-check fields. The live task queue tracks accessible explanatory tooltips, examples, and guidance on matching producer registrations. A second item removes redundant repository identity entry by deriving it from the saved URL while preserving existing identities and shared integration holds. These are pending service task records; the deployed UI is unchanged. Implement and verify the live acceptance criteria before claiming tooltip support.
Google Cloud deployment
The application from deployment commit 019ffb6 is
installed on the agent-coordinator e2-micro VM in sithbit-19b44,
us-east1-b (South Carolina). It has a 30-GB standard persistent boot disk,
deletion protection, 1 GiB swap, and reserved IPv6 2600:1900:4020:671::.
The temporary installation IPv4 address was removed. The earlier empty
central-region VM, disk, address, subnet, and backup bucket were removed.
No unrelated project resources were changed.
The service, Caddy, hourly local backups, daily maintenance, and hourly
download-verified Cloud Storage backup transfer are running. The origin is
live at https://agents.sithbit.com. Cloudflare proxies its AAAA record and
applies Full (strict) TLS through a hostname-specific configuration rule.
Browser Integrity Check is disabled for this API hostname after it blocked
Python clients with error 1010. The administrator is admin;
its initial password is in the operator’s protected local deployment directory,
outside this repository, and was never printed. No repository is enrolled or
bound to this service yet.
Installed package identity from release run 34891009689:
- Archive SHA-256:
199c254e0c52b99eaf932b7a41a7c68c37f777688c5db33c3e921f75cdce6699. - Server SHA-256:
06f10eb72d4a0ac173ed795786048552b31e5c1aee294078afa37714b238e720. - CLI SHA-256:
4ae4d9e3e0e51c2035f4de8ac6676412b45f97064f19edd668645dd66f45b716.
The Linux package build/systemd/HTTPS and native Windows release jobs passed,
as did local Linux package layout/checksum/link checks. Formatting, warnings-
denied Clippy, workspace tests/build, both smoke exercises, native Windows tests,
and dependency audit passed in coordination run 34891009230.
The initial deployment check found the newly published RUSTSEC-2026-0285 in
rustls 0.23.44; deployment commit 019ffb6 updates it to 0.23.45. An earlier
release Windows timing-test failure was not reproduced by the patched runs.
The server binary is byte-identical before and after the client TLS update.
That exact server passed the 30-minute release-size load/restore job in
run 34888396240.
The second run’s redundant load job was cancelled after its Linux and Windows
package jobs passed; the second run is not claimed as an aggregate green run.
This CI workload is not an e2-micro capacity measurement.
Live checks confirmed the rendered browser sign-in page, public HTTPS from
Windows and the VM, administrator login/logout, Secure cookies, CSRF rejection,
unauthenticated project denial, synchronized time, restart health, and IPv6
access to package mirrors and Cloud Storage after public IPv4 removal.
A complete backup was uploaded to the private
sithbit-19b44-agent-coordinator-backups-east bucket, downloaded, and verified.
An independent download on the Ubuntu 24.04 WSL workstation matched SHA-256
552b597b95fd0e7360760235f71073c4f3bf030e3c43fa5ab77b2da0a52e8650 and restored
snapshot 94f708d6-83f6-4f37-a1c3-ca2d8edbb46f into an absent directory in
0.425 seconds, ending at restore_reconciliation. This is an initial,
artifact-free database rehearsal, not a production-size recovery benchmark.
See Google Cloud installation for resources, backup-transfer behavior, and cost limits. Free-tier eligibility depends on total billing-account usage; no zero-cost guarantee is claimed.
Previous implementation acceptance
Backlog items 6.1 (MCP), 6.2 (mdBook), and 7 (native Windows workstation acceptance) are implemented, exercised, and reviewed. The numbered release backlog and hosted-CI validation follow-up are complete. Item 7 used the actual native Windows workstation and a separate Linux workstation; it did not substitute native Windows CI or package inspection for the physical exercise.
Native Windows workstation acceptance
The accepted agent-coordinator 0.1.0 Windows x86-64 CLI from
release run 34459987847
ran natively on workstation MINIAIR against a disposable service on Linux
workstation mxmini through a temporary Cloudflare HTTPS tunnel. The downloaded
Windows archive SHA-256 was
be5e96ec6f8843a63c8be319d9b4f9745f4e0870bebbbc160c2c24f69dc32a1d,
matching its adjacent checksum; the exercised executable SHA-256 was
40240c59aeaf012aba6721f378e9dec57419ceb8833aec0187391c3bccb1111d.
The exercise used distinct Windows and Linux principals and sessions across two
isolated projects. Windows claimed, checkpointed, and submitted project-two work;
a same-principal agent review was rejected, while the independent Linux principal
claimed and approved the exact submission. Project-one work remained isolated.
At a published barrier, both workstations attempted the same project-one task and
revision. Linux obtained generation 2 ownership and Windows received the expected
claim_conflict; Linux checkpointed the result and released the task ready. In a
separate recovery case, Windows checkpointed with a dedicated session, that session
was closed, and Linux inspected and released the retained work without reviving the
Windows session.
Sanitized cross-workstation evidence is retained in
completion commit c017a69.
The encrypted one-time handoff branch was removed after Windows decrypted it. The
disposable public service and tunnel were shut down after acceptance. This proves
the scoped native two-workstation workflow; it is not a production deployment,
permanent public endpoint, hardware attestation, or off-server backup exercise.
MCP completion
The authenticated stateless /mcp endpoint exposes 56 closed, typed tools through
the same guarded REST handlers. Connections, discovery, ping, and receipt replay
never renew ownership. The native mcp-client launcher securely shares one saved
harness session with a trusted foreground MCP client and its native CLI children.
Git, local producers, and binary transfer remain native operations. The launcher
requires an absolute executable path and does not supervise background clients.
No service-side execution or OAuth discovery is introduced.
Candidate cd9a633 passed all 182 local workspace tests, formatting,
warnings-denied Clippy, build, and both smoke exercises. Linux workspace/smoke,
native Windows client/CLI/local-runner tests, and the dependency audit passed in
CI run 34468585302.
The integrated 677253a also passed
CI run 34468821269.
Official SDK tests exercise modern and legacy protocols over real TCP; wire tests
cover revocation, races, policies, shared REST receipts, and generation/lease guards.
See the MCP guide for configuration and compatibility limits.
Documentation completion
Canonical guides, contracts, the plan, and README content now live in book/src.
The original docs/README/PLAN entry paths remain short compatibility links.
Root AGENTS.md, HANDOFF.md, BACKLOG.md, and DURABLE-RECORD.md remain authoritative;
their book chapters include them at build time. Edit those root files directly.
The pinned mdBook 0.5.4 build covers all 35 chapters. Main review verified retained acceptance evidence, proposal/current-status distinctions, source references, rendered internal links and fragments, search, live includes, and desktop/390-pixel phone layout without page overflow or JavaScript errors. Release packages retain bounded Markdown sources and book configuration, without generated HTML.
Package checks passed for layout, checksums, permissions, offline links, explicit member/size limits, and building the book from an extracted archive. The final local structural package used stripped copies of the current local debug binaries; it is documentation validation, not new release-binary or capacity acceptance. Local-file navigation and search also passed with networking disabled.
After the repository became public, hosted validation was retried on main commit
ebf72f7. The pinned mdBook build and documentation checks passed in
documentation run 34487173043.
Linux formatting, warnings-denied Clippy, all workspace tests, the workspace build,
both service/CLI smoke exercises, native Windows client/CLI/local-runner tests,
and the locked dependency audit passed in
coordination run 34487175859.
These runs supersede the earlier failed-to-start billing-blocked attempts; no job
steps ran in those attempts, so they remain historical scheduling failures rather
than test results.
Use mdbook build or python3 scripts/check_docs.py from a source checkout; output
is target/book/index.html. See book maintenance.
The retained Linux acceptance evidence remains
unchanged and identifies its exact accepted package and server. Schema version is
16 and instruction version is 7. No production deployment or actual off-server
transfer is claimed. Host/domain/backup-destination choices remain installation
inputs. Keep separate Cargo targets for concurrent worktrees.