Rust CLI and runtime foundation for a local-first multi-agent coding orchestrator.
The owned Coding Agent Manager source is included with its desktop application and a native core build. Its separate lockfiles and build instructions keep it independent of the orchestrator's Cargo package. Account-backed MACO execution and a shared account authority are still being integrated.
This project is a local-first control plane for coordinating multiple coding agents against one Git repository. It is designed to isolate work in disposable Git worktrees, reserve edit boundaries with path claims, run validation, collect agent output, and eventually integrate LLM-backed coding agents without letting provider-specific behavior bypass the local safety model.
The goal is not only to call an LLM. The goal is to make parallel coding work reviewable and recoverable:
- understand the repository before splitting work
- assign each agent a clear set of files or directories
- run each agent in an isolated worktree
- prevent overlapping edits through shared path claims
- collect diffs, summaries, validation results, and patches
- preview merge candidates, review them under integration authority, and apply them with conflict reporting
maco init, maco repo, maco llm, and maco supervise plan stay local, including on Windows. maco supervise run needs Linux. The process must already sit in a delegated systemd user manager (user@<uid>.service on the unified cgroup v2 hierarchy). Windows refuses writable-runtime admission before spawn.
Operator command sequence for that host, including Codex and Grok: operator quickstart.
That Linux host also needs:
- an owner-private
/run/user/<uid>directory (current uid, mode0700) - root-owned, non-writable, executable
systemd-run,systemctl,sh,env,sleep,stat, andfindmntat/usr/bin,/bin, or/run/current-system/sw/bin - logical
codexat/usr/bin/codex,/bin/codex, or/run/current-system/sw/bin/codex(root-owned, executable, not group- or world-writable, not a symlink). Catalog preflight runscodex debug modelswith a 30-second limit MACO_CAM_AUTHORITY_SOCKETleft unset for default CAM discovery
Without a CAM authority service (both the implicit socket and its maco parent absent), MACO uses the local CAM registry selection if one exists; otherwise Codex uses $CODEX_HOME/auth.json or ~/.codex/auth.json (a non-symlink regular file). An installed CAM authority service at /run/user/<uid>/maco/account-authority.sock is used and must be healthy; see packaging.
Reviewed machine-global.json (version 1). The root named by --machine-global-runtime-root-id is an existing canonical directory inside /run/user/<uid>. state_root is a different owner-private 0700 directory and does not overlap that root. The config file is current-user-owned, has one hard link, and is not group- or world-writable.
{
"version": 1,
"state_root": "/run/user/1000/maco-task/state",
"roots": [
{
"id": "runtime",
"path": "/run/user/1000/maco-task/runtime",
"protected_paths": [],
"quarantine_grace_seconds": 86400
}
]
}1000 is the operator uid. Create both directories before launch. goal.md is the goal file read by --from-goal.
maco supervise run --runtime codex --repo . --run-id one-task \
--from-goal goal.md --codex-bin codex \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --json
maco supervise collect one-task --repo . --jsonThe durable report is .maco/o2/runs/one-task/reports/supervisor-final.json. supervise run exits successfully only when its printed cascade has follow_up_cascade_success set to true; otherwise it exits with supervise run failed.
The current implementation covers a local-first command-line slice:
-
maco initinitializes a Git repository. -
maco worktree create <agent-id>derives the capability-bound repository cleanliness input at command start: creation proceeds only when the primary repository is observed clean, and a dirty primary fails with the required remedy. -
maco worktree listlists verified registered agent worktrees.maco worktree pendingis a strict existing-only authenticated reader: absent state returns an empty list, while transitional or invalid state is refused without creating locks, migrating, scavenging, recovering, or writing. -
maco worktree remove <agent-id> --forceperforms explicitly authorized cleanup of authenticated managed state; non-force removal is temporarily disabled. -
maco worktree gcremoves clean, inactive managed worktrees while retaining branch refs, protects tracked changes and unapproved untracked-only lanes plus active leases/claims, supports an exact repeatable untracked-path allowlist for reviewed full-lane cleanup, offers a liveness-checked target-only mode that retains lanes and branches, removes retainedtarget/build artifacts by default, supports dry-run and max-age/max-count/apparent-byte retention filters, reports estimated reclaimable and reclaimed bytes, and routes unregistered leftover directories through recoverable machine-global quarantine. -
maco worktree sweep --workspace <path>discovers both workspace-managed.maco/worktrees/<repo>roots and exact repository-local<repo>/.worktreesroots, then aggregates the existing per-root GC reports. It is dry-run by default; removal requires--apply, an unresolved repository is reported as a typed per-root failure without aborting later roots, and a total discovery miss is reported separately from an inspected root with nothing to reclaim. -
SyncCoordinatorprovides an in-memory exclusive path-claim layer for local agent coordination. -
maco sync claim <agent-id> <path>...records durable exclusive path claims. -
maco sync release <token>releases one durable claim. -
maco sync release-agent <agent-id>releases all claims for an agent. -
maco sync owner <path>reports the owner of a path, if one exists. -
maco sync statuslists active durable claims. -
Remote GitHub CAS coordination is opt-in: without
maco sync coordination configure, sync claims stay local-only.maco sync coordination configure <repo-relative-config>validates live GitHub repository/issue identity and journal-branch protection, then persists a frozen authenticated selection (not raw operator JSON).maco sync coordination statusis read-only.maco sync coordination disableclears the selection and refuses while local claims, pending coordination operations, or remote active owners/reservations exist. Shared-effect journal reconciliation still requires a separate production verifier; configuring remote mode does not enable it. -
maco repo mapprints a read-only repository file map with coarse file categories and Git status while excluding runtime-only.macooutput and local.agents/temp,.agents/storage, and.agents/livecoordination data. -
maco repo map --semanticbuilds a parser-backed Rust semantic map for modules, symbols, impls, imports, public re-exports, module declarations, import dependencies, and parse errors. -
maco repo query symbol <name>andmaco repo query path <path>search the semantic Rust map. -
maco repo query risk --path <path> --jsonreports touched symbols, dependency impacts, and impacted files for changed Rust paths. -
maco coord preview/claim/status/release/release-agentprovides standalone repo-local semantic intent coordination for paths, modules, and symbols without automatic task planning. -
maco orchestrate validate <plan-file>validates a local JSON orchestration plan. -
maco orchestrate run <plan-file>runs a local JSON orchestration plan. Verified assignment creation derives the capability-bound repository cleanliness input before creating managed worktrees; a dirty primary repository fails with the required remedy. -
maco orchestrate resume <checkpoint-file>authenticates the repository-bound v3 journal, validates repository HEAD, plan snapshot, worktree metadata, path boundaries, and claims, then reruns validation/capture for completed commands without rerunning those commands. -
maco worktree diffcollects a registered agent worktree diff and uses active sync claims when--claimis omitted. -
maco orchestrate collectreads a prior JSON run summary and builds merge candidates with validation reports from agent summaries. -
maco merge preview --jsoncaptures the review artifact required before primary-worktree integration. After that complete preview receives authority review,maco merge applyaccepts either the unchanged full preview JSON or an extracted one-fieldfreshness_watermarkJSON object through--reviewed-watermark; it otherwise refuses before primary mutation. Both commands retain the dirty-primary, stale-base, unclaimed-edit, candidate-bound validation, and apply-check safety reports. Their JSON reports also include advisory semantic classification for overlapping symbols, impls, modules, imports, signatures, and dependent files. Both commands accept external validation JSON with--validation-report;--require-validationaccepts passed reports only when their envelope contains the exact currentcandidate.validation_binding(or a passedmerge apply --validation-command). -
After the required preview review,
maco merge applywith--validation-command <command>and--reviewed-watermark <unchanged-preview.json>validates a temporary merged candidate before mutating the primary worktree. A command failure or a recursive candidate-state change, including an initialized or uninitialized submodule change, blocks the apply and leaves the primary worktree unchanged. -
maco pr previewchecks whether an agent worktree or--from-branchtask branch is ready to publish without contacting a forge. -
maco pr publish --forge fake|githubturns a safe agent worktree result into a local agent-worktree commit when validation is not required, or publishes a committed--from-branchtask branch through the same gates.--squash-onto <base>builds a deterministic import commit on a disjoint base lineage, and--exclude <path>refuses referenced-but-missing exclusions. Publication re-previews the exact candidate before either emitting a deterministic fake PR URL or, with explicit--forge github, publishing an OID-bound remote ref and verifying the resulting GitHub receipt. A durable transaction journal reconciles a lost push orghresponse when the same command is rerun. With--require-validation, publication is a two-stage workflow: commit or preview first, validate that exact binding, then publish with the bound envelope. -
maco issue previewredacts issue bodies without creating anything. -
maco issue create --forge fake|githubcreates a deterministic fake issue URL locally or, with explicit--forge github, shells out togh issue create. -
maco live status,maco live validate,maco live apply,maco live heartbeat,maco live release, andmaco live override-releaseexpose and safely mutate repo-local Markdown claim liveness for active, blocked, ready-for-review, handoff, and done work. -
maco llm providersandmaco llm prompt-previewexpose the provider-neutral prompt boundary without network calls. -
maco agent runexecutes one agent assignment in an isolated managed worktree. Verified assignment creation derives the capability-bound repository cleanliness input before creating the worktree; a dirty primary repository fails with the required remedy. -
maco supervise plan <task-or-plan-file>normalizes the existing plain-text task or JSON plan form, whilemaco supervise plan --from-goal <file>explicitly decomposes a high-level goal/spec into a validated full supervisor plan. -
maco supervise run <task-or-plan-file>andmaco supervise run --from-goal <file>accept the same mutually exclusive positional-plan or high-level-goal inputs assupervise plan, then execute the resulting validated plan through the live supervisor gates. Optional--role-categorystamps every assignment (and nested worker assignment) asselection_source=operator_override; omitting it keeps automatic selection derived from the plan role. Resume of an existing run refuses a new--role-category. A loadable plan sniffsassignment.runtimeand otherwise defaults to Codex;--from-goal,--literal-goal, missing, and unparsable plans require explicit--runtime. Baremaco <instruction>injects--runtime codex. Normalized planning-phase Codex children receive a read-only workspace and read-only access to their own Git worktree metadata in both the outer systemd containment and inner Codex permission profile. Only their exact private final-message staging root is writable. Authored plans may declare a terminalrole: "researcher"with explicitrole_category: "read_only_researcher". Researcher assignments use a distinctResearcherReport, have no nested assignments or mechanical duty, and currently require Codex on Linux in a managed read-only worktree in either phase. They retain their own model binding (general-judgment minimum), claims, scheduling dependencies and parent audit, including subject coverage for a successful zero-diff result. Reports must attest read-only execution and no further delegation; reported or observed changes are rejected. Other runtimes and primary-worktree execution are refused. Generated goal/provider lowering does not emit Researchers. For source packets, an operator-authored Researcher assignment may declare"source_inputs": [{"path": "review-packets/source.diff", "sha256": "<64 lowercase hex digits>"}]. These are exact, non-hidden, repo-relative regular files already present in the selected managed snapshot, not parent-machine paths. Prepare/commit the packet in the chosen source snapshot before launching; an untracked packet in a different checkout is unavailable. No files are copied automatically and prose paths grant no mounts. At most eight nonempty files of 1 MiB each are accepted; duplicate paths, traversal, symlinks, hard-link aliases, unknown fields (including writable access), and hash mismatches are refused. The parent checks the snapshot, then reads each entire file with the actual read-only child confinement profile before provider dispatch and revalidates identity/content before release. The probe and target mount private copies of the same verified bytes at each declared path; later host-side in-place writes cannot replace the packet visible to the target. A verified, quiescent local-only input refusal releases the unused provider reservation asNotStarted. Unverified helper ownership remains conservative and cannot authorize cleanup or acceptance.researcher_input_receiptsin the private execution artifact record path, SHA256, byte count, file identity and profile visibility. Receipts establish preparation only; the Researcher must still inspect the substantive source and pass the existing independent acceptance gates. A prelaunch refusal has no provider launch evidence; it is not an observed zero-token response. Source inputs cannot be declared by nested Workers and do not change credential, network, write, delegation or publication authority. Legacy plans without this optional declaration retain their behavior; only explicitly declared packets receive this prelaunch guarantee. Execution-phase implementation children retain native workspace-write and their existing bounded writable Git metadata; the optional app-server duplex reviewer is not their release path. Writable access to the primary checkout remains fail-closed because Codex cannot force a blocking client callback for every in-sandbox action. The command requires--machine-global-configand--machine-global-runtime-root-idso private runtime output-staging cleanup cannot silently take the unbound deletion bypass. The private staging directory is created beneath that exact reviewed runtime root, not an independently discovered per-user runtime directory. It still acquires the repository-cleanliness capability and creates capability-bound managed child worktrees before that safety gate. External child sessions receive the three report contracts as individually validated read-only files in both sandbox layers; their schema directory and run-artifact parent are not exposed. Parent review-lens sessions receive only the auditor contract. The in-process Fake runtime executes the same depth, claim, journal, review-lens, economics, KPI, and final primary-integrity gates without launching an external executable; its successful output is always non-publishable.maco supervise plan/status/collectremain available. The supervisor scheduler launches opt-in O1 child orchestrators through the Codex CLI in isolated child worktrees under an O2 supervisor, with conservative network-bound fan-out as the default. Admission composes that ceiling with configured provider quota and measured/configured host capacity, and launches hierarchy-ready assignments concurrently only while their normalized claim scopes are disjoint;--max-concurrent-children 1is the explicit serial opt-out. Overlapping scopes are never admitted together. The swarm-health cascade circuit breaker from Issue #24 is the admission safety backstop for this higher default: a trip stops pending admissions and drains active assignments without weakening the resource or claim gates. Each child is instructed to readAGENTS.mdand project-local.agentsguidance before acting, use Codex native SubAgent/delegated-worker mechanisms for terminal worker/researcher assignments when available, preserve the O1/O2 subprocess launch boundary of the outer verified MACO sandbox with verified systemd cgroup ownership evidence plus the fixedmaco_external_codexinner permission profile, enable goals and multi-agent support only for the supervisor role, leave O1/O2 hierarchy and enforced audit gates to MACO/Codex CLI subprocess workflows, report peer-O2 escalation candidates instead of taking them over, and preserve structured reporting without applying worker changes to the primary worktree automatically. -
maco supervise statusreports durable supervisor run artifact state without launching workers or applying changes. -
maco supervise collectemits the versioned lifecycle-awaresupervisor_collect_reportcontract and preserves the same no-automatic-primary-apply boundary. Finalized output flattens the complete supervisor-final fields for compatibility; active, resumable, uncertain, interrupted, and inconsistent-finalized snapshots explicitly advertisefinal_report_available: falseand use<unavailable-until-finalized>instead of an empty or invented plan path. -
maco supervise artifacts list/latest/pruneinspects or prunes durable supervisor run artifacts. -
maco consult askasks a terminal read-only cross-runtime consultant for advisory help, using deterministic fake mode by default or an explicit Codex/Claude-compatible executable when selected. Consultant runs write local artifacts under.maco/consult/runs/<run-id>/: parent-owned files live intrusted/, while a real external result is isolated underincoming/. -
maco consult artifacts list/latest/pruneinspects or prunes durable consultant run artifacts. -
User-directed / out-of-band O2 roots may write durable run state under
.maco/o2-autopilot/runs/<run-id>/(STATE.tsv,HEARTBEAT.tsv,NEXT_O2_TASKS.tsv, event streams, andSUMMARY.md). The root O2 is out-of-band and is not counted against autonomous depth. That path is a run store, not a shipped launcher; in-repo agents must not add.agents/scripts/o2-autopilot. -
maco <instruction>is the live local-first entrypoint: a bare instruction routes into supervised goal/spec (supervise run --literal-goal). Usemaco supervise plan/run/status/collectfor authored plans or--from-goalfiles, andmaco inbox scan/run/status/collect/watchfor the fake-first reaction loop. Inbox still uses the autopilot library path; it does not restore the retired CLI. -
maco autopilot planandmaco autopilot runare retired and fail closed withautopilot plan/run is retired; use literal instruction routing: maco <instruction>. Remaining query and artifact commands aremaco autopilot status/collectandmaco autopilot artifacts list/latest/prune. Historical reports remain under.maco/autopilot/runs/<run-id>/. Autopilot never publishes, merges, or applies a result to the primary worktree. -
maco artifacts prune --family <family>applies one retention policy to any authenticated run store, the external O2 driver store, legacy workspace inbox runs, or direct.maco/program-*logs. Policies can combine count, age, and apparent-byte ceilings and always report byte totals. -
maco review pr <number|url>emits an independent fake structured review report by default, withci_reaction_supported=false. -
maco inbox scan/run/status/collect/watchprovides a fake-first reaction loop for issue intake, pull request review feedback, and failing CI checks, converting safe inbox items into Autopilot repair plans without network access or automatic merge by default.inbox runaccepts optional rolling-quota ceilings--max-rolling-tokens,--max-rolling-cost-usd, and--rolling-window-seconds. -
maco inbox intake --pr <positive-u64>invokes the authenticated production producer for one exact provider-observed GitHub pull request. The command accepts only the PR number, repository path, optional Codex executable, and the conventional JSON-output flag; provider and trust evidence are resolved internally. -
maco inbox workspace scan/run/watchsupervises the same inbox loop across a workspace JSON of repositories.scanreports per-repository intake without launching Autopilot;runandwatchexecute the same per-repository inbox path used bymaco inbox run. -
maco inbox artifacts list/latest/pruneinspects or prunes durable inbox run artifacts. -
Bounded GitHub PR repair under operator review policy is two-phase:
maco inbox runmay finish withawaiting_original_pr_update_grantafter autopilot produces a validated candidate C, an independent per-feedback disposition audit, and durable pending repair artifacts. It does not update the original PR or imply feedback is addressed. Phase two is explicit:maco inbox resume-repair --run-id <id> --item-index <n> --grant <file>loads the authenticated pending bundle, appliesmaco pr update-existingwith the operator grant, observes head C on the provider, and advances the review-state journal. -
maco evaluation rungenerates deterministic fake model-mix fixture results from a versioned manifest and digest-bound plan.maco evaluation experimentruns the same goal/spec under multiple profiles through isolated Fake supervise.maco evaluation rescorere-scores a stored results document under a named objective profile without overwriting the stored file. Real providers remain refused. -
maco eval-harness runcompletes a declared role mix through the local fake provider. Version 2 manifests are routed to the Issue #26 v2 operator path;maco eval-harness run-v2always parses that version-2 manifest schema, and the current version-2 run path emits result/schema v3. Result/schema v1 and v2 remain historical; v3 was necessary because fully closing the permissive v2 schema would be breaking. Real network providers are refused; current v3 output is not production-eligible. -
maco optimizer library|preference|replayinspects the starter policy library, operator preference profiles, and stored decision replay snapshots. It does not launch supervise or change production model defaults. -
maco scope serveis a localhost-only observability backend.maco scope eventappends one disclosure-safe external orchestration event. Neither command launches supervise or mutates source trees. -
maco agents listinspects live MACO-launched agent process records.maco agents stopstops one unambiguous process or every process in one explicitly selected run.
Operators with repository-local owner authority can queue authenticated corrective input and related steering actions against registered in-flight assignments. The request file must already name the run, assignment, action id, actor, action, and deadline; the CLI does not invent those fields.
Use the actual run and assignment IDs. Replace the example deadline with the current Unix millisecond timestamp plus the requested timeout, at most 300,000 milliseconds:
{
"version": 1,
"action_id": "act-operator-001",
"run_id": "run-supervise-001",
"assignment_id": "task-worker-001",
"actor": { "kind": "operator", "agent_id": "operator" },
"action": {
"type": "inject_corrective_input",
"message": "Stop editing README.md; finish the CLI wiring only."
},
"deadline_unix_ms": 0
}Examples:
maco steer submit steer-request.json --repo .
maco steer evidence run-supervise-001 --repo . --json
maco steer sweep run-supervise-001 --repo .Delivered means the action was authenticated and queued. For Grok ACP corrective input, Acknowledged is recorded after the corrective prompt's correlated terminal response; task success and model compliance require their own evidence. The CLI does not print signing keys or MAC material.
Grok ACP sessions launched with lifecycle identity consume corrective input. The in-process Fake API also supports corrections. Other runtime transports currently support cancellation without a corrective-input consumer. Cancellation targets registered child processes across runtimes. Review and merge authority are unchanged.
Implemented local foundations:
- Result collection, merge preview, and guarded application of agent-worktree patches after an authorized preview review.
- Parser-backed Rust repository maps for modules, symbols, impls, imports, and dependency edges, plus semantic risk reports for changed paths.
- Retained local orchestration internals with dependency scheduling, path claims, timeouts,
per-agent validation, repo-level validation, run ids, checkpoint writes,
safe checkpoint resume, and guarded
reuse=reset. - Provider-neutral LLM adapter boundaries with deterministic fake-provider
tests; public
maco agent runexecutes the localfakeprovider in an isolated managed worktree. Real network providers remain planned and are refused until configured.
Known limitations and roadmap for 0.3.0:
- Semantic merge conflict classification is advisory and Rust-only. It is bounded by parser-map coverage and reports degraded confidence when a conflict path cannot be resolved; Git safety checks remain authoritative.
- Goal/spec planning now proposes independent supervisor assignments with path and Rust semantic scopes. The proposal remains conservative and Rust-first; richer semantic planning, broader language adapters, and automatic refinement remain post-0.3.0 work. Runtime claim gates remain authoritative.
- PR and issue publication are intentionally narrow. The fake forge is
deterministic and local-only. GitHub publication is opt-in with explicit
--forge githuband shells out to localgitandgh; tests cover the fake adapter without network access. Remote push, PR creation, and the post-create receipt check are not one globally atomic operation; the durable receipt supports detection and retry reconciliation rather than claiming cross-service atomicity. The supervise-backed Autopilot spine does not call either forge; legacyforge_modeplan data is inert there. Inbox intake keeps deterministic fake data as the default; GitHub inbox scanning is selected only with an explicit GitHub source. Issue triage metadata remains minimal. - Real LLM providers remain post-0.3.0 roadmap work and must be opt-in, explicitly approved, and covered by additional invariant tests.
- Semantic-map caching and broader language adapters are post-0.3.0 roadmap work after the Rust path is stable.
- Automatic merge remains intentionally absent. Autopilot can record
auto_merge=trueas a request, but always reportsauto_merge_performed=falseand leaves human review and merge as the next action.
Network-facing LLM behavior should remain optional. The default development and test workflow should continue to run without provider credentials.
Durable sync state is shared through the Git common metadata directory. Current
claims live in the repository-authenticated authenticated-claims-state-v1
snapshot namespace; claims.json is retained only as a signed version-3
retirement tombstone that makes legacy version-2 writers fail closed.
maco state migrate --repo . --json is a non-mutating dry-run for legacy
maco/state data. maco state migrate --repo . --apply --json is the explicit
offline apply path. Migration refuses active known kernel locks, unexpected
entries, links, non-owner files, oversized state, malformed JSON, or invalid
legacy checksums before changing anything. Apply holds all legacy consumer
locks, hardens the state root to 0700 and files to 0600, then records
claims, semantic intents, and the optional managed-worktree registry (including
an explicit missing entry) in a signed generation-one manifest. An
owner-private transaction outside the state root makes a crash between chmod
and manifest publication forward-recoverable; ordinary pre-publication errors
restore original modes, and successful apply writes an idempotent audit
receipt.
Checksum-less version-1 claims.json has no cryptographic provenance that MACO
can verify. Recover it only after taking the repository offline and independently
verifying both the file's origin and its exact bytes. The digest pins the
operator-reviewed bytes; it does not authenticate who created them or make
untrusted claims trustworthy. MACO still validates the strict claims-v1
structure and repository-relative paths, rejects a digest mismatch, and records
the operator-attested unauthenticated-import provenance in the signed migration
manifest.
Use this procedure only for the exact failure where the reviewed current
development binary reports an authenticated claims physical journal that is not
anchored by any signed logical state, while the legacy claims.json is the
checksum-less version-1 state independently reviewed by the operator. Do not
use it for a different inventory, authentication, rollback, or incomplete
initialization error.
The repository must remain offline for the entire procedure: stop every MACO
writer and verify that none can restart. Do not delete, replace, or "repair"
claims.lock; a lock error is a reason to abort. Run the commands below from
one Bash session, replace the two absolute placeholders, and stop on every
unexpected result:
set -euo pipefail
umask 077
unset GIT_DIR GIT_WORK_TREE GIT_COMMON_DIR GIT_INDEX_FILE
unset GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES
REPO=/absolute/path/to/repository
REPO=$(realpath -e -- "$REPO")
DEV=/absolute/path/to/reviewed-current-dev-maco
PINNED_PATH="$REPO/.agents/scripts/maco"
test -x "$PINNED_PATH"
test -f "$PINNED_PATH"
test ! -L "$PINNED_PATH"
PINNED=$(realpath -e -- "$PINNED_PATH")
COMMON=$(git -C "$REPO" rev-parse --path-format=absolute --git-common-dir)
COMMON=$(realpath -e -- "$COMMON")
STATE="$COMMON/maco/state"
ORPHAN="$STATE/authenticated-claims-state-v1"
RECOVERY_BASE="$COMMON/maco/offline-recovery"
test -x "$DEV"
mv --version | grep -F 'GNU coreutils' >/dev/null
mv --no-copy --help >/dev/null
test -d "$STATE"
test -d "$ORPHAN"
test ! -L "$ORPHAN"
test -f "$STATE/claims.json"
test ! -L "$STATE/claims.json"
test ! -L "$RECOVERY_BASE"
install -d -m 0700 -- "$RECOVERY_BASE"
test ! -L "$RECOVERY_BASE"
RECOVERY=$(mktemp -d "$RECOVERY_BASE/issue33.XXXXXXXX")
chmod 0700 -- "$RECOVERY"
test "$(stat -c %a -- "$RECOVERY")" = 700First prove the current failure. Both fixed fragments must occur in stderr; a successful command or any other error is outside this procedure:
set +e
"$DEV" sync status --repo "$REPO" --json \
>"$RECOVERY/dev-before.stdout" \
2>"$RECOVERY/dev-before.stderr"
DEV_STATUS=$?
set -e
test "$DEV_STATUS" -ne 0
grep -Fq "authenticated snapshot physical journal '" \
"$RECOVERY/dev-before.stderr"
grep -Fq "is not anchored by any signed logical state" \
"$RECOVERY/dev-before.stderr"The development command acquires the live persistent kernel lock before reporting the inventory error. Bind that lock's identity and copy the exact plaintext claims bytes before invoking the pin:
test -f "$STATE/claims.lock"
test ! -L "$STATE/claims.lock"
LIVE_CLAIMS_LOCK_ID=$(stat -c '%d:%i:%s:%f:%h' -- "$STATE/claims.lock")
cp -- "$STATE/claims.json" "$RECOVERY/claims-v1.reviewed.json"
chmod 0600 -- "$RECOVERY/claims-v1.reviewed.json"
cmp -s -- "$STATE/claims.json" "$RECOVERY/claims-v1.reviewed.json"The registry pin must never run against the live repository: its legacy
create-new PID lock is incompatible with the live persistent kernel lock and
could otherwise fail on or remove a stale parseable claims.lock. Instead,
create an isolated throwaway Git repository under the owner-private recovery
directory, prove that it has a different Git common directory, and give it only
the copied plaintext claims-v1. For this incident, the exact reviewed wrapper
has SHA-256
93b76ebff318fb75e44f8ce48b5b48b4bad5435045d9fe736c4e1fc587a0d814.
Its own project-root resolution must bind it to REPO, and its manifest path
must resolve inside the reviewed attached checkout. That checkout must be
commit 373550870f9986224bc8b57a9b13019a3da02516 with a clean index and
worktree, including no untracked files. The commit reads and writes plaintext
claims-v1 and contains no authenticated-claims journal writer. Its isolated
output therefore proves only which copied plaintext claim view it interpreted;
it does not prove that the captured orphan journal was emitted by that pin.
PINNED_WRAPPER_SHA256=93b76ebff318fb75e44f8ce48b5b48b4bad5435045d9fe736c4e1fc587a0d814
test "$(sha256sum -- "$PINNED" | cut -d ' ' -f 1)" \
= "$PINNED_WRAPPER_SHA256"
PINNED_WRAPPER_ID=$(stat -c '%d:%i:%s:%f:%h' -- "$PINNED")
PINNED_PROJECT_ROOT=$(cd -- "$(dirname -- "$PINNED")/../.." && pwd -P)
test "$PINNED_PROJECT_ROOT" = "$REPO"
PINNED_CHECKOUT=$(realpath -e -- \
"$PINNED_PROJECT_ROOT/.agents/external/multi-agent-coding-orchestrator")
test "$(realpath -e -- \
"$PINNED_PROJECT_ROOT/.agents/external/multi-agent-coding-orchestrator/Cargo.toml")" \
= "$PINNED_CHECKOUT/Cargo.toml"
test "$(realpath -e -- "$(git -C "$PINNED_CHECKOUT" rev-parse --show-toplevel)")" \
= "$PINNED_CHECKOUT"
PINNED_HEAD=$(git -C "$PINNED_CHECKOUT" rev-parse --verify 'HEAD^{commit}')
printf '%s\n' "$PINNED_HEAD" >"$RECOVERY/pinned-head.txt"
test "$PINNED_HEAD" = 373550870f9986224bc8b57a9b13019a3da02516
git -C "$PINNED_CHECKOUT" status --porcelain=v1 \
--untracked-files=all --ignore-submodules=none \
>"$RECOVERY/pinned-checkout-status.before"
test ! -s "$RECOVERY/pinned-checkout-status.before"
PINNED_STAGE="$RECOVERY/pinned-plaintext-stage"
test ! -e "$PINNED_STAGE"
git init --quiet -- "$PINNED_STAGE"
PINNED_STAGE_COMMON=$(git -C "$PINNED_STAGE" \
rev-parse --path-format=absolute --git-common-dir)
PINNED_STAGE_COMMON=$(realpath -e -- "$PINNED_STAGE_COMMON")
test "$PINNED_STAGE_COMMON" != "$COMMON"
test "$(stat -c %d -- "$PINNED_STAGE_COMMON")" \
= "$(stat -c %d -- "$RECOVERY")"
PINNED_STATE="$PINNED_STAGE_COMMON/maco/state"
test ! -L "$PINNED_STATE"
install -d -m 0700 -- "$PINNED_STATE"
test ! -L "$PINNED_STATE"
cp -- "$RECOVERY/claims-v1.reviewed.json" "$PINNED_STATE/claims.json"
chmod 0600 -- "$PINNED_STATE/claims.json"
cmp -s -- \
"$RECOVERY/claims-v1.reviewed.json" \
"$PINNED_STATE/claims.json"
CARGO_NET_OFFLINE=true \
CARGO_INCREMENTAL=0 \
CARGO_TARGET_DIR="$RECOVERY/pinned-cargo-target" \
"$PINNED" sync status --repo "$PINNED_STAGE" --json \
>"$RECOVERY/pinned-claims-view.json" \
2>"$RECOVERY/pinned-claims-view.stderr"
test ! -e "$PINNED_STATE/claims.lock"
test "$(stat -c '%d:%i:%s:%f:%h' -- "$PINNED")" = "$PINNED_WRAPPER_ID"
test "$(sha256sum -- "$PINNED" | cut -d ' ' -f 1)" \
= "$PINNED_WRAPPER_SHA256"
test "$(git -C "$PINNED_CHECKOUT" rev-parse --verify 'HEAD^{commit}')" \
= "$PINNED_HEAD"
git -C "$PINNED_CHECKOUT" status --porcelain=v1 \
--untracked-files=all --ignore-submodules=none \
>"$RECOVERY/pinned-checkout-status.after"
test ! -s "$RECOVERY/pinned-checkout-status.after"
cmp -s -- \
"$RECOVERY/pinned-checkout-status.before" \
"$RECOVERY/pinned-checkout-status.after"
cmp -s -- "$STATE/claims.json" "$RECOVERY/claims-v1.reviewed.json"
test "$(stat -c '%d:%i:%s:%f:%h' -- "$STATE/claims.lock")" \
= "$LIVE_CLAIMS_LOCK_ID"
jq -e 'type == "object" and .version == 1
and (.next_token | type == "number")
and (.claims | type == "array")' \
"$RECOVERY/claims-v1.reviewed.json" >/dev/null
jq -e 'type == "array"' "$RECOVERY/pinned-claims-view.json" >/dev/null
jq -S '.claims' "$RECOVERY/claims-v1.reviewed.json" \
>"$RECOVERY/raw-claims.sorted.json"
jq -S '.' "$RECOVERY/pinned-claims-view.json" \
>"$RECOVERY/pinned-claims.sorted.json"
cmp -s -- \
"$RECOVERY/raw-claims.sorted.json" \
"$RECOVERY/pinned-claims.sorted.json"
jq '.next_token' "$RECOVERY/claims-v1.reviewed.json"The last command only displays next_token: it is not present in the pinned
status array and must be reviewed separately with the entire copied claims-v1
file.
Inventory and hash every entry in the orphan namespace before changing its
active path. The inventory includes type, mode, ownership, size, device, inode,
link count, path, and symlink target; the hash list covers every regular file.
The -P and -xdev boundaries prevent following links or crossing a mounted
filesystem. Abort if any visited entry is nevertheless on another device.
inventory_tree() {
(
cd -- "$1"
find -P . -xdev \
-printf '%y\t%m\t%U\t%G\t%s\t%D\t%i\t%n\t%P\t%l\0' |
LC_ALL=C sort -z
)
}
hash_tree() {
(
cd -- "$1"
find -P . -xdev -type f -print0 |
LC_ALL=C sort -z |
xargs -0r sha256sum -z --
)
}
ORPHAN_DEVICE=$(stat -c %d -- "$ORPHAN")
while IFS= read -r -d '' ENTRY; do
test "$(stat -c %d -- "$ENTRY")" = "$ORPHAN_DEVICE"
done < <(find -P "$ORPHAN" -xdev -print0)
inventory_tree "$ORPHAN" >"$RECOVERY/orphan.inventory.before"
hash_tree "$ORPHAN" >"$RECOVERY/orphan.sha256.before"
sync -f -- "$RECOVERY"The prerequisite checks above require GNU Coreutils mv with --no-copy.
Prove the orphan namespace and recovery directory are on the same filesystem,
then atomically quarantine the complete namespace with one rename. --no-copy
makes a failed rename fail closed instead of falling back to copy-and-delete.
Do not copy individual journals or synthesize a locator. The quarantined
namespace is forensic evidence and must never be adopted, re-anchored, restored
into active state, or used as migration input.
test "$(stat -c %d -- "$ORPHAN")" = "$(stat -c %d -- "$RECOVERY")"
test "$(stat -c %d -- "$STATE")" = "$(stat -c %d -- "$RECOVERY")"
QUARANTINED="$RECOVERY/authenticated-claims-state-v1"
test ! -e "$QUARANTINED"
mv --no-copy -T -- "$ORPHAN" "$QUARANTINED"
test ! -e "$ORPHAN"
sync -f -- "$STATE" "$RECOVERY"
inventory_tree "$QUARANTINED" >"$RECOVERY/orphan.inventory.after"
hash_tree "$QUARANTINED" >"$RECOVERY/orphan.sha256.after"
cmp -s -- \
"$RECOVERY/orphan.inventory.before" \
"$RECOVERY/orphan.inventory.after"
cmp -s -- \
"$RECOVERY/orphan.sha256.before" \
"$RECOVERY/orphan.sha256.after"
sync -f -- "$RECOVERY"If any command after the rename fails, keep all writers offline and leave the quarantine in place for investigation; do not automatically move it back.
Manually inspect the complete claims-v1.reviewed.json, including
next_token, agent ids, tokens, and every path. Compute the digest independently
of MACO, paste the reviewed lowercase value, and verify it against both the
review copy and the still-active plaintext file:
sha256sum -- "$RECOVERY/claims-v1.reviewed.json"
read -r -p "Paste the reviewed lowercase SHA-256: " EXPECTED
test "${#EXPECTED}" -eq 64
case "$EXPECTED" in
*[!0-9a-f]*) exit 1 ;;
esac
test "$(sha256sum -- "$RECOVERY/claims-v1.reviewed.json" | cut -d ' ' -f 1)" \
= "$EXPECTED"
test "$(sha256sum -- "$STATE/claims.json" | cut -d ' ' -f 1)" \
= "$EXPECTED"
cmp -s -- "$STATE/claims.json" "$RECOVERY/claims-v1.reviewed.json"Run the attested migration with the reviewed development binary. Dry-run must
report ready or already_applied; apply must report applied or
already_applied:
"$DEV" state migrate --repo "$REPO" \
--acknowledge-unauthenticated-claims-v1 \
--expected-claims-v1-sha256 "$EXPECTED" \
--json >"$RECOVERY/migration-dry-run.json"
jq -e '.mode == "dry_run"
and (.status == "ready" or .status == "already_applied")' \
"$RECOVERY/migration-dry-run.json" >/dev/null
"$DEV" state migrate --repo "$REPO" --apply \
--acknowledge-unauthenticated-claims-v1 \
--expected-claims-v1-sha256 "$EXPECTED" \
--json >"$RECOVERY/migration-apply.json"
jq -e '.mode == "apply"
and (.status == "applied" or .status == "already_applied")' \
"$RECOVERY/migration-apply.json" >/dev/nullFinally, let the development binary create/open the new authenticated claims
snapshot from the signed claims-v1 migration, compare its claims to the pinned
plaintext view, and inspect worktree cleanup without removing anything. A
legitimate dry-run can report eligible worktrees, targets, or orphan directories,
so require only dry_run == true and review every reported entry rather than
requiring zero counts.
"$DEV" sync status --repo "$REPO" --json \
>"$RECOVERY/dev-claims-after.json"
jq -e 'type == "array"' "$RECOVERY/dev-claims-after.json" >/dev/null
jq -S '.' "$RECOVERY/dev-claims-after.json" \
>"$RECOVERY/dev-claims-after.sorted.json"
cmp -s -- \
"$RECOVERY/pinned-claims.sorted.json" \
"$RECOVERY/dev-claims-after.sorted.json"
"$DEV" worktree gc --repo "$REPO" --dry-run --json \
>"$RECOVERY/worktree-gc-dry-run.json"
jq -e '.dry_run == true' "$RECOVERY/worktree-gc-dry-run.json" >/dev/null
inventory_tree "$QUARANTINED" >"$RECOVERY/orphan.inventory.final"
hash_tree "$QUARANTINED" >"$RECOVERY/orphan.sha256.final"
cmp -s -- \
"$RECOVERY/orphan.inventory.before" \
"$RECOVERY/orphan.inventory.final"
cmp -s -- \
"$RECOVERY/orphan.sha256.before" \
"$RECOVERY/orphan.sha256.final"
sync -f -- "$STATE" "$RECOVERY"Review the migration, sync-status, and GC reports and keep the full quarantine before resuming writers. Never run the registry-pinned writer against the live repository at any point; its only permitted invocation is against the isolated pre-migration staging repository above. After migration, resume only the reviewed development binary. The new authenticated claims snapshot is supported by the attested claims-v1 migration; the captured orphan journal remains unanchored and unadopted. Neither its writer provenance nor its authorization as the current logical state was established. The wrapper checks bind the reviewed script bytes, its project root, its resolved manifest, and the clean pinned source checkout before and after the isolated invocation. They do not independently attest Cargo, rustc, cached dependencies, or the wider toolchain, and they do not defend against a hostile same-UID process racing and restoring checked paths during execution; the exclusive offline operator boundary remains a prerequisite.
The first open of each migrated claims, semantic-intent, or managed-worktree consumer performs a recoverable retirement transaction while holding its legacy kernel lock. It copies the exact signed-manifest legacy bytes into a bounded owner-private sidecar, binds both original and sidecar identities and digests in an HMAC intent, atomically replaces the legacy filename with a pending version-3 tombstone, publishes the full authenticated snapshot, and then activates the tombstone and removes the sidecar. Crashes before the tombstone leave only the old state; crashes after it recover forward from the signed sidecar, while old writers always reject version 3. Migration dry-run and repeated apply verify the original signed manifest entry, active tombstone, exact authenticated snapshot locator, every held legacy consumer lock, and the identity-bound transaction root before and after producing a result, without adopting a tombstone on first use.
The typed authenticated-state foundation uses immutable HMAC-chained journals,
signed atomic heads, and full-lifecycle instance locks. Snapshot stores add a
signed stable locator containing the active journal identity, absolute
generation and token, and retained prior terminal anchors. Rollover publishes a
signed prepared intent before its candidate journal can exist, publishes and
authenticates the replacement generation, then atomically switches that
locator. A bounded physical-journal inventory rejects a signed old-locator
replay that leaves newer evidence present; a prepared pre-switch crash either
recovers forward from the bound candidate or leaves the old locator
authoritative. Old journals remain present and are verified on open. A missing
locator, a substituted or deleted retained journal, an unbound physical
journal, or locator replay beyond the single-record crash window fails closed.
Snapshot inventory is namespace-wide: every signed logical locator and pending
initialization/rollover intent contributes to one bounded union of physical
journals. Namespace-specific quotas bound logical stores, total root entries,
and retained physical journals; the external-effect namespace permits 4,096
logical source-action stores within its larger finite root budget. Capacity is
checked before a new logical store or rollover candidate is created. Reaching a
quota fails closed and requires operator archival or other explicit manual
intervention; MACO does not auto-delete exactly-once receipts or retry the
external effect to recover capacity.
Managed-worktree snapshots retain only active incarnations. Retired nonce lease
files are queued with signed inode identities and scavenged only after an
exclusive lock proves them inactive; active, foreign, or rebound lease paths
are never unlinked. Effect WALs likewise publish a durable
planned record before returning to a caller and require the ordered
planned -> started -> observed -> completed reconciliation sequence.
Every authenticated namespace must be registered in the first-key consumer registry before it can be created. The entire sensitive state root must also be masked from every untrusted child process; authentication does not compensate for exposing its key. Local HMAC evidence detects partial mutation and rollback relative to retained current evidence, but no local design without an external monotonic anchor can detect a coherent restoration of every artifact needed to form an older mutually consistent namespace (its locator, tombstone, journals, heads, and transaction evidence), or restoration of an older key/epoch and all state authenticated by it as one whole snapshot.
Semantic coordination adds a typed blackboard of structured intents, not
free-form agent chat. Durable semantic state is repo-local in the Git common
metadata directory's authenticated-semantic-state-v1 snapshot namespace, so
the primary worktree and linked agent worktrees see the same planning state.
The legacy semantic_intents.json pathname is only the signed retirement
tombstone.
Hard path claims remain the write boundary. Semantic intents sit earlier in the workflow as a planning and coordination layer: blocking conflicts can prevent an intent from being claimed, while advisory conflicts can warn about likely overlap without reserving files. MVP semantic analysis is Rust-only.
maco coord preview agent-a --path src/lib.rs --symbol WorktreeManager --repo . --json
maco coord claim agent-a --path src/lib.rs --module crate::worktree --repo . --json
maco coord status --repo . --json
maco coord release <token> --repo . --json
maco coord release-agent agent-a --repo . --jsonOrchestration opts in with --semantic-coordination off|warn|block; the
default is off.
Orchestration commands, validation commands, and opt-in provider-proposed shell
commands are trusted local shell commands. maco isolates work with Git
worktrees and path-claim checks, but it is not an OS or filesystem sandbox.
Path claims enforce Git-visible repository changes; they do not prevent a
trusted command from reading or writing arbitrary local filesystem paths.
File-backed CLI inputs are opened as bounded regular files without following links in any path component. Multiply linked files, special files, and inputs that exceed their command-specific size or structural limits are refused before worktrees, claims, or run artifacts are created. Repository discovery for task planning, prompt excerpts, repository maps, and Autopilot dirty-state checks is also depth-, entry-, path-, byte-, and time-bounded. Prompt excerpt paths must be repository-relative; a missing path or directory may still be named as a claim scope, but neither is read as prompt content.
maco machine-global coordinates paths outside Git repositories without making
arbitrary absolute paths claimable. Every invocation requires an explicit
--config file; MACO never infers a root from HOME, repository location,
pathname spelling, or process environment. The config file is bounded, strict
version-1 JSON opened without following links in any path component. Its own
path, state_root, and every declared root must be existing, exact canonical
absolute paths. The config file itself must be a current-user-owned,
single-link regular file that is not group- or world-writable. state_root
must be an owner-private 0700 directory and must not intersect a declared
root. Declared roots may not overlap one another. Unknown fields, . or ..
components, symbolic links, non-canonical spellings, and changed root
identities fail closed. On Linux, the state root and every declared root are
also bound to their statx mount id. Duplicate filesystem identities are
rejected. Two configured paths on the same device but different mounts are
rejected conservatively as possible bind aliases; paths on one mount retain the
component-aware overlap check. An existing coordinate whose parent or leaf
crosses away from its declared root's mount is refused.
{
"version": 1,
"state_root": "/srv/maco-machine-global-state",
"roots": [
{
"id": "runtime-sessions",
"path": "/run/user/1000/maco/runtime-sessions",
"protected_paths": [
{
"coordinate": {
"root_id": "runtime-sessions",
"relative": "active"
},
"retryability": "not_retryable"
}
],
"quarantine_grace_seconds": 86400
}
]
}The config is the reviewed authority ceiling. Commands carry a root id and a
strict root-relative path. Privacy-safe structured success, status, and typed
denial JSON omits configured absolute roots; local diagnostic errors may
identify a configured path for operator repair. Containment uses path
components, so state does not contain state-backup. An absolute value
supplied to retention --path is refused as an undeclared destructive target
and its GateDenial contains only a fingerprint. Claim conflicts and
destructive intersections report privacy-safe root-id-relative coordinates. A
denied --json command emits the typed GateDenial object on standard output
and exits unsuccessfully.
maco machine-global claim repair-agent \
--root-id runtime-sessions \
--path active/session-42 \
--correlation repair-42 \
--config /etc/maco/machine-global.json \
--json
maco machine-global owner \
--root-id runtime-sessions \
--path active/session-42/cache \
--config /etc/maco/machine-global.json \
--json
maco machine-global status \
--config /etc/maco/machine-global.json \
--json
maco machine-global release repair-agent <claim-token> \
--config /etc/maco/machine-global.json \
--jsonSuccessful claim output contains a random bearer token needed for release.
status and owner deliberately return redacted claim summaries without
tokens. Keep the config bytes stable while durable state exists: changing the
reviewed config causes the store to refuse reinterpretation of existing state.
Independent repositories coordinate when they use the same config and
state_root. The owner-private state envelope checksum detects accidental or
partial corruption; it is not authentication against a hostile same-UID
process that can rewrite the state and checksum coherently.
Retention accepts the complete target set up front and checks every source and
hidden quarantine sibling against active claims, configured protected paths,
and other active retention reservations before the first rename. Current
retention targets are existing directories on Linux. Each accepted target is
atomically renamed beside its original pathname to a hidden
.maco-quarantine-v1-* sibling, which keeps the move on the same filesystem.
The returned operation records the root-relative source, hidden sibling name,
deterministic .maco-delete-v2-* purge-cleanup sibling, inode identity,
quarantine time, purge deadline, and a random operation token. The source,
quarantine, and cleanup coordinates are all reserved and preflighted. Status
reports omit the token.
maco machine-global retention quarantine cleanup-agent \
--root-id runtime-sessions \
--path expired/session-17 \
--path expired/session-18 \
--correlation retention-2026-07-30 \
--config /etc/maco/machine-global.json \
--json
maco machine-global retention restore cleanup-agent <operation-id> \
--correlation restore-session-17 \
--config /etc/maco/machine-global.json \
--json
maco machine-global retention purge cleanup-agent <operation-id> \
--token <operation-token> \
--correlation purge-session-17 \
--config /etc/maco/machine-global.json \
--jsonRestore uses an atomic no-replace rename and refuses an occupied or rebound original path. Restore intentionally requires the recorded owner but not the purge bearer token, so an operator can recover after a crash that occurred before the token was returned; the full live-claim and protected-path preflight still applies. Purge requires the operation owner and bearer token, uses MACO's trusted system clock, refuses before the configured positive grace period, and reruns the complete claim/protected-path preflight before permanent removal. Purge completes a mount-confined link/special-file audit while the tree still has its restorable quarantine name. It then moves the tree to its recorded cleanup sibling, repeats the identity- and mount-confined audit, and only then deletes the verified tree. Resuming an already-renamed cleanup residue starts with the same audit at that cleanup name. If a quarantine or cleanup pathname is unavailable, collides, cannot be renamed, is full, or cannot be safely inspected, the operation fails closed. MACO never falls back to direct deletion or a cross-filesystem copy. A multi-target I/O failure can leave an explicitly recorded partially quarantined operation. Quarantine does not resume such an operation: restore it to a consistent source layout, then start a fresh quarantine attempt.
Machine-global enforcement is cooperative. A destructive path is protected only when the caller opens the same reviewed configuration and state root, declares the target under the correct root ID, and performs the mutation through the gate. This is not syscall interposition and is not a host-wide guarantee: a hand-run shell command, a directly launched agent, or an arbitrary child process can still modify or delete data without consulting MACO.
merge arbitrate requires --machine-global-config and
--machine-global-runtime-root-id. Its external-agent output staging cleanup is routed
through the machine-global gate. An intersecting active claim produces the existing
typed GateDenial, leaves the staging directory in place, and makes the run
non-publishable. An allowed cleanup is quarantined; the public run record carries only
the retention operation ID, while the purge token remains in a mode-0600 private
receipt beside the JSON log. This is a launch-time obligation for that orchestrator
path, not protection against commands launched outside it.
supervise run requires the same --machine-global-config and
--machine-global-runtime-root-id pair. Every child-orchestrator launch and every
parent acceptance-auditor review-lens launch carries that binding to its private
output-staging cleanup. Missing programmatic bindings fail before verified dispatch;
the CLI rejects missing or partial pairs. Cleanup denials remain typed GateDenial
values and preserve the staged directory. Nested workers and the child-side advisory
auditor run inside the enclosing child session rather than as separate host
ExternalAgentCommand launches, so the child-orchestrator staging gate covers that
session's host output staging.
worktree gc accepts --machine-global-config,
--machine-global-worktree-root-id, and --machine-global-correlation as one
all-or-none binding. A destructive run that discovers unregistered directories refuses
before touching those directories when the binding is absent. With the binding, GC
collects the complete orphan set and sends it through one machine-global quarantine
preflight before the first directory moves. A denial leaves every orphan in place and
is returned in the existing typed GateDenial envelope. The GC report carries the
public retention operation ID only; it does not serialize the bearer purge token.
The audit was performed from mutation sinks outward, rather than from cleanup command
names inward. It enumerated direct filesystem removal, descriptor-relative unlink,
rename/replacement, truncating/open-for-write operations, the safe-state recursive
removal and quarantine wrappers, Git worktree/reference mutation, spawned command or
systemd cleanup, explicit Rust Drop implementations, and dependency-owned RAII
destructors such as tempfile::TempDir. Each production caller's target was then
traced to one of:
repository worktree, separate Git common directory, managed external worktree root,
private runtime/temp root, user-selected output root, or machine-global state/config
root. Finally, CLI path-bearing arguments and generic child-process destinations were
cross-checked against that sink inventory. Test-only mutation fixtures were excluded
only after locating their enclosing test module, rather than by filename or keyword.
The current cleanup/retention audit is:
| Path | Gate status | Reason and attribution boundary |
|---|---|---|
Unregistered direct-child directories found by worktree gc |
Routed | These may be nonempty arbitrary external directories and therefore match the destructive incident shape; treating routing as optional would be unjustified. GC requires an explicit reviewed binding when such targets exist, preflights the complete orphan set, quarantines allowed targets, and reports a typed denial plus logical actor maco-worktree-gc when refused. |
| Pre-worktree final reservation and staging setup rollback/recovery/finalization | Known transactional bypass, attributed | These paths exist before the child is a repository worktree, but they are not adopted retention targets: MACO creates the exclusive reservation and authenticated create intent, binds the exact inode, removes only a still-empty reservation/staging root, and preserves changed, nonempty, or unbound paths for manual recovery. Final replacement accepts only the verified clean staged worktree. Routing these transaction-internal names into retention quarantine would break the idempotent create protocol rather than protect pre-existing data. While retained, the authenticated operation records agent, phase, root/path identity, and branch; each direct mutation also emits its fixed operation label with process_attribution=not_process_observable. |
| Machine-global state-root lock/state/temp maintenance | Known infrastructure bypass | The state root is deliberately disjoint from declared data roots: the gate must lock and replace its own bounded authenticated state before it can evaluate a claim, so recursively gating that state is ill-founded. State writes and temp cleanup are identity-bound, bounded, and lock-fenced. The fixed private state root and filenames identify the machine-global subsystem, but successful bootstrap/temp cleanup is not durably process-observable. Retention purge is not included in this bypass: it rechecks the gate and retains its owner, operation ID, coordinates, identities, and final purged phase. |
External-agent output staging used by merge arbitrate or supervise run |
Routed | Creation resolves the explicitly declared root ID first and places the private staging directory beneath that exact reviewed machine-global runtime root. Cleanup revalidates the same directory/root binding. Supervise applies the binding to child-orchestrator and parent review-lens auditor launches; review-lens temporary Git workspaces therefore reach this same runtime-staging cleanup path. Refusals use GateDenial; allowed operations use the existing retention record. |
Parent review-lens isolated Git workspaces under /tmp/maco-review-lens-* |
Known process-owned ephemeral bypass | tempfile creates an unpredictable, exclusively owned directory for one lens; no operator, sibling agent, or caller supplies or adopts its path. TempDir::drop recursively removes that leaf, so this is a distinct deletion from the routed /run/user/<uid> output staging. Its hazard is materially weaker than shared staging, while routing it through the runtime-root binding would misrepresent an independently created /tmp leaf as part of that reviewed root. The supervisor run and lens identity provide logical context while their artifacts remain, but successful Drop cleanup is not durably process-observable. Any change that accepts a caller path or permits adoption must route the cleanup instead of relying on this exception. |
| External-agent output staging used without a machine-global binding by other entrypoints | Known bypass, attributed | supervise run and merge arbitrate do not take this path. For callers that genuinely lack a reviewed binding, completed cleanup records actor=maco-external-agent, operation=delete_private_output_staging, the reason, and process_attribution=not_process_observable in the serialized run; early Drop cleanup emits the same actor/operation marker before deletion. This identifies the cooperative bypass without claiming process-level observation. |
| External-agent staging setup rollback | Known empty-directory bypass, attributed | If exclusive output reservation fails, setup emits actor=maco-external-agent, operation=delete_empty_output_staging_setup_rollback, and process_attribution=not_process_observable before removing only the newly created, still-empty staging directory. No external data was accepted into that directory. |
Bounded worktree-status crash scavenging under /tmp/maco-worktree-status-<uid> |
Known bypass | It removes only identity-bound, bounded files from MACO's per-user status root, but no reviewed root configuration is available at that call site. The call site and per-user root identify the subsystem; the deleting process is not durably observed. |
Merge private-runtime orphan scavenging and close cleanup under /run/user/<uid> or /tmp/maco-runtime-<uid> |
Known bypass | Runtime teardown and orphan recovery must also work before a repository/configuration is available. Owner records carry PID, process start time, boot ID, and runtime kind while present, but successful deletion removes those records; this is not durable deletion attribution. |
Orchestrator cleanup of user-selected --patch-dir and --checkpoint-dir reservations |
Known bypass | Exclusive leaf reservation prevents overwrite, but cleanup is still direct because these optional roots are not declared machine-global roots. The enclosing run, agent, and reservation identify the logical actor while present; process-level deletion attribution is not durable. |
| Reviewer program/view cleanup in the private runtime root | Known bypass | These are current-run private runtime files and cleanup must work without a reviewed machine-global configuration. The run/reviewer context identifies the logical actor while records remain; successful Drop cleanup is not durably attributed. |
| Process-runner and pinned-exec systemd unit/runtime/descriptor cleanup | Known bypass | systemd can remove RuntimeDirectory content outside the Rust cleanup path, so the machine-global API cannot wrap every deletion without changing the runtime ceiling. Unit, runtime, and actor metadata provide operational context, not universal process-observable attribution. |
| Publication secret-buffer zeroing in the private runtime root | Known intentional overwrite | The overwrite is identity-checked secret erasure, not retention. Publication/run context identifies the logical actor, but the erasure is not process-observable after the fact. |
| Repository Git-common maintenance: authenticated snapshots, state migration/journals and effect ledgers, repository lock records, and managed-worktree metadata | Known bypass | A separate Git directory can place this authenticated repository state physically outside a worktree. Cleanup and overwrite are bounded to identity-checked leaves under repository-bound locks, but these paths must also work before a machine-global config is supplied. Signed intents, journals, repository identity, and run/operation IDs provide logical attribution where retained; successful temp/intent cleanup is not durable process attribution. |
| Process-runner tee destinations | Conditional capability surface | Current production callers use repository/run-local destinations. Any future caller that supplies an external destination must route it through the gate or add it here as a reasoned, attributable bypass. |
Repository-local retention is outside this machine-global audit: artifact pruning under
.maco, live-claim cleanup under .agents, supervise reporting artifacts, and deletion
of a managed worktree's own files operate inside a repository worktree. Git-common
metadata for those operations is covered separately above because it may use a separate
Git directory.
The retention API currently supports directory retention only on Linux. Coordinate comparison assumes case-sensitive filesystem spelling; case-insensitive or casefolded alias behavior is not established as supported, so such roots should not be declared. The mount policy is intentionally conservative and does not claim to detect every conceivable physical alias.
Default linked worktrees are created inside the repository at the stable path
.maco/worktrees/<sanitized-repo-name>/<agent-id>. This keeps generated lanes and
their Cargo config in the existing runtime-owned area without exempting manual
.worktrees content from primary integrity checks. An explicit --worktree-root
still overrides the root. Implicit default creation registers only
/.maco/worktrees/<sanitized-repo-name>/ in checkout-local Git info/exclude
before creating lanes. Conflicting operator negations and unadmitted local Git
config indirection are refused without changing the exclude file. Explicit
--worktree-root paths remain caller-controlled and receive no automatic ignore.
Existing lanes are not moved or migrated: to keep creating lanes in the old
layout, pass --worktree-root ../.maco/worktrees/<repo-name> with the original
sanitized repository group name. Pass that same root to GC or lifecycle commands
when selecting the old root explicitly. Without an explicit root, GC still
considers authenticated registered lanes across roots, but searches for
unregistered leftovers only under the new default. Completed task branches can be
cleaned with maco worktree gc; branch refs remain available for later
recreation, while dirty, claimed, or leased worktrees are left in place.
Runtime artifacts are local operator evidence, not source files. Autopilot,
inbox, and supervisor runs write under .maco/.../runs/<run-id>/; generated run
ids are collision checked, and an explicit --run-id is refused when that run
directory already exists. Use each command family's nested artifact helpers to
inspect or prune that family's run directories:
cargo run -- autopilot artifacts list --repo . --json
cargo run -- autopilot artifacts latest --repo . --json
cargo run -- autopilot artifacts prune --repo . --keep 10 \
--max-age-seconds 2592000 --max-total-bytes 2147483648 \
--unfinalized-grace-seconds 604800 --dry-run --json
cargo run -- inbox artifacts list --repo . --json
cargo run -- supervise artifacts latest --repo . --json
cargo run -- consult artifacts list --repo . --jsonThe repository-level command reaches stores that have no nested producer command. Its accepted families and roots are:
--family |
retained items |
|---|---|
autopilot |
.maco/autopilot/runs/<run-id> |
consult |
.maco/consult/runs/<run-id> |
inbox |
.maco/inbox/runs/<run-id> |
supervise |
.maco/o2/runs/<run-id> |
o2-autopilot |
.maco/o2-autopilot/runs/<run-id> |
inbox-workspace |
.maco/inbox-workspace/runs/<run-id> legacy residue |
program |
each direct .maco/program-* directory, including its logs/ |
For example, preview program-log retention without touching the real store:
cargo run -- artifacts prune --family program --repo . --keep 3 \
--max-age-seconds 2592000 --max-total-bytes 1073741824 \
--unfinalized-grace-seconds 604800 \
--acknowledge-external-writers-stopped --dry-run --jsonCount, age, total-byte, and unfinalized-grace ceilings are independent
maximums: an item is a candidate when any applicable ceiling is exceeded.
Thus an abandoned unfinalized run expires after its grace even when fewer than
--keep runs exist. Ordering uses the newest bounded descendant activity time,
so appends to an active transcript refresh its age. --max-total-bytes counts
apparent regular-file bytes; the JSON report
includes per-item bytes, age_seconds, and selected_by, plus
scanned_bytes, inventory-snapshot retained_bytes, planned
projected_retained_bytes, would_reclaim_bytes for dry-run, and actual
reclaimed_bytes for apply. Refused trees may change concurrently after their
snapshot, so these are not filesystem quota measurements. A dry-run never
counts planned deletion as actual reclamation.
Fresh marker-missing runs are pinned for --unfinalized-grace-seconds (seven
days by default). A held authenticated writer lock also pins a run regardless
of age. Once a marker-missing run is both selected, older than the grace, and
idle, retention rechecks its identity, byte count, activity, and finalization
state before using the same identity-bound quarantine and no-follow deletion
path as finalized runs. A present but invalid finalization marker remains
refused unless --reclaim-unverifiable explicitly puts it under the same
grace, idle-lock, identity, activity, and state rechecks. This opt-in bounds
abandoned corrupt runs without silently treating damaged evidence as a normal
crash. External and legacy stores have no cooperative writer lock, so both
dry-run and apply refuse their candidates unless
--acknowledge-external-writers-stopped is supplied. That acknowledgement,
the grace, and refreshed descendant activity form the active-run boundary;
the acknowledgement must not be supplied while a same-UID writer can mutate
the store. Marker-missing legacy runs inside authenticated roots also require
this acknowledgement when their cooperative writer lock file is absent.
Retention deliberately does not compress transcripts in this version. A
finalized authenticated file is immutable because its exact path, length, and
digest are covered by the finalization MAC; rewriting it as gzip would destroy
the evidence contract. External journals can still be append targets and have
no common rotation handshake. The report therefore records
compression_strategy: none_requires_writer_migration, counts
compressible_log_bytes, and reports compressed_bytes: 0. Compression needs
a writer-side, crash-safe format migration rather than an in-place prune
rewrite. The reusable ArtifactRetentionPolicy, prune_runs_with_policy, and
prune_artifacts_with_policy APIs are consumed by the opt-in worktree lifecycle
scheduler described below. Its aggregate dry-run reports artifact and worktree
reclamation together before either store is changed.
maco consult ask is a read-only second-opinion path for stuck agents. It does
not create worktrees, claim paths, apply patches, or mutate repository files.
The fake runtime is the default and needs no network or external binaries:
cargo run -- consult ask \
--repo . \
--question "Why is this validation failing after the worker change?" \
--context-path README.md \
--jsonReal runtime adapters are explicit and local-process only. Codex consultant mode uses a read-only sandbox and does not enable goals or multi-agent worker delegation:
cargo run -- consult ask \
--repo . \
--runtime codex \
--consultant-bin codex \
--question-file consult-question.md \
--context-path src/supervise.rs \
--jsonClaude consultant mode is currently refused before launch because MACO cannot
enforce an equivalent inner read-only permission contract. Supplying an
executable does not weaken that refusal. Selecting runtime: claude-code or
runtime: gemini-cli on a supervise assignment is accepted, but writable
managed-worktree launch stays refused under their current capability values
because release requires verified native side-effect confinement. Writable
primary-worktree release uses the separate
blocking_pre_action_callback == All gate. The command form below demonstrates
the expected fail-closed consultant response; it does not launch Claude.
cargo run -- consult ask \
--repo . \
--runtime claude \
--consultant-bin claude \
--question "What narrow fix should I inspect next?" \
--context-path tests/supervise_cli.rs \
--jsonFor execution-phase Codex launches in a managed linked worktree, MACO grants
read-write access only to that worktree's own per-worktree Git directory.
Planning-phase launches bind that same directory read-only. The common Git
allowlist is read-only: objects/, refs/, config, packed-refs,
info/exclude, and optional shallow. The primary HEAD, index, and
config.worktree, MACO common state, and peer worktree entries are not exposed.
The same exact allowlist applies to the outer process confinement and the inner
Codex filesystem policy; primary merge, apply, and publish gates remain in force.
Launch fails closed when Git markers or allowlisted metadata contain symlinks,
hard-link aliases, special files, or object alternates. Recreate the launch
repository with git clone --no-hardlinks and without --reference before
retrying; MACO does not repack the primary repository as remediation.
Consultant advice is advisory evidence only. It does not override project rules, assigned ownership, validation requirements, review gates, or merge gates.
Durable project guidance under .agents/docs, .agents/skills, and
.agents/workflows may appear in repository maps. Local-only agent scratch
state under .agents/temp, .agents/storage, and .agents/live is excluded
from repository maps, semantic maps, and task-path proposal helpers.
Agent execution and repository mapping currently require Linux with a delegated
systemd user manager. Native Windows and macOS builds are compile-portability
targets, not full runtime support. On Windows, use a configured WSL2 Linux
environment for coding workflows; the native maco scope serve command can
serve the local monitoring UI at http://127.0.0.1:7878.
Install maco once as a machine-global binary. Do not invoke it through a
per-repository cargo run wrapper around a pinned checkout. See
docs/PACKAGING.md for the install, update, and version
contract.
On Nix:
nix profile install path:$PWD#maco
maco --versionOn hosts without Nix:
cargo install --locked --path . --bin maco
maco --versionmaco --version prints the package version and the compile-time source identity, the exact lines are documented in docs/PACKAGING.md, and after install maco runs from any working directory.
The authoritative local environment for CI parity is the repository's Nix development shell:
nix develop path:$PWDIt provides the Rust toolchain selected by rust-toolchain.toml, including
Clippy and rustfmt, plus the Python interpreter used by the
repository-portability gate. An ambient system toolchain is not evidence of CI
parity.
Run the CI-equivalent Linux and repository-portability gates with:
export CARGO_INCREMENTAL=0
nix develop path:$PWD -c rustc --version --verbose
nix develop path:$PWD -c cargo --version --verbose
nix develop path:$PWD -c cargo clippy --version
nix develop path:$PWD -c python3 -m unittest discover -s scripts/tests -p 'test_*.py'
nix develop path:$PWD -c python3 scripts/check_repository_portability.py
nix develop path:$PWD -c cargo fmt --all -- --check
nix develop path:$PWD -c cargo check --locked --all-targets
nix develop path:$PWD -c cargo clippy --locked --all-targets -- -D warnings
nix develop path:$PWD -c cargo test --locked --all-targetsFull verification is a one-shot sweep, so CI and this recipe disable Cargo's
incremental cache; ordinary edit/build cycles retain Cargo's default incremental
behavior. This reproduces the Linux CI toolchain and tracked-path portability
gate. It cannot compile or link target-specific code on actual macOS or Windows runners.
Before treating a branch as fully CI-green, push it or open a draft pull request
and wait for both the macos-latest and windows-latest portable-build jobs;
a draft pull request is the cheapest honest way to close that residual gap.
GitHub-hosted Linux runners do not provide the delegated systemd user manager
required by strict containment. Containment-dependent lib tests and CLI
integration tests share the same cgroup probe and print one SKIP <test>: <reason> line when that manager is absent. CI runs plain
cargo test --locked --all-targets; tests decide at runtime whether to execute.
A Linux runner inside a delegated user manager runs the complete suite.
The Nix development shell also pins the supply-chain tools through
flake.lock. Audit the exact Cargo lockfile and enforce the repository policy
with:
nix develop path:$PWD -c cargo audit --deny warnings
nix develop path:$PWD -c cargo deny --locked check -D warnings advisories bans licenses sourcesThe path:$PWD flake reference addresses the current worktree explicitly. The
flake exports the installable maco package and apps outputs documented in
docs/PACKAGING.md, plus the development shell used by
these gates. Release contents of the Cargo package remain selected
independently by Cargo, whose package manifest excludes .agents, .github,
.maco, and AGENTS.md.
cargo fetch --locked is the explicit online boundary for Rust dependencies in
a fresh checkout. Once that checksum-verified closure is present in the Cargo
cache, the build can be repeated without dependency resolution or network
access:
cargo fetch --locked
cargo check --locked --offline --all-targetsThe Nix shell pins the Rust/native toolchain, while Cargo.lock pins crates.io
versions and checksums. The Cargo configuration forces the checksum-verified
libgit2 and zlib sources from that closure instead of ambient system copies.
Dependency unification removes foldhash and therefore needs no Zlib license
exception for that crate. Separately, the vendored libz-sys@1.1.28 build
embeds stock zlib: deny.toml records its combined crate/native license
expression and accepts Zlib only for that exact crate version.
The project does not keep a separate crate mirror or RustSec database snapshot,
so a completely empty machine still needs the explicit fetch steps before
offline verification.
Run the bounded Criterion suite with:
cargo bench --no-run
cargo benchEvery case in benches/coordination.rs owns an isolated, committed
tempfile plus git2 repository fixture. Fixture construction and public-API
success probes run outside the timed loops. The groups measure:
claim_acquire_release: persistedSyncStoreclaim plus release for one path by token and a four-path claim by agent.claim_contention: two disjoint successful claim/release cycles started together, and an overlapping ownership handoff that completes two successful claim/release cycles.claim_concurrency_disjoint: successful disjoint claim/release throughput at bounded thread counts of 1, 4, and 8.repository_queries: public small-repository inventory scan, semantic scan, and semantic risk query over a precomputed map.worktree_lifecycle_s: Git-native managed-worktreecreate→list_managed_verified→remove(force=true)on the small (S, four tracked files) fixture at concurrency 1 and 4 with disjointagent_ids.cargo benchalso attempts concurrency 8; Criterion--test/cargo test --benchskip that 8-way stampede. PublicWorktreeManager::createalready derives cleanliness on a clean repository.merge_preview: claim plus a committed single-path worktree diff, thenpreview_merge_apply_with_evidencewith validation off, concurrency 1, on S and medium (M, 128 tracked ~1 KiB files) fixtures.merge_review_apply_s: preview → reviewed-watermark → apply with gates satisfied, concurrency 1 on S. Apply uses the production merge CLI (the publicapply_merge_resultentrypoint remains fail-closed and is not called).worktree_list_quiescent_s:list_managed_verifiedwith N∈{1,4} already created worktrees on S (the timed path is list, not concurrent create).envelope_probes(optional, not extra factorial cells): eight threads overlapping the same claim path; a fifth concurrent create while four lanes remain.
The suite uses 10 samples, a 300 ms warm-up, and a 700 ms measurement window per
case so a complete local run stays modest. Wall time and throughput come from
that Criterion window. Per-operation p50/p95/p99 are empirical nearest-rank
latencies from Instant-timed production-API calls (including probe and
warmup), printed on stderr. p50 requires n≥1, p95 requires n≥20, and p99
requires n≥100; otherwise the tail is UNAVAILABLE. A Criterion bootstrap
confidence bound is not an operation-latency percentile and is not used as
p95/p99. Those host numbers document one local run; they are not universal CI
timing thresholds. Success and failure counts are printed on stderr for
envelope cells (including warmup). Optional post-hoc .git/maco byte totals
may be printed after lifecycle probes. Lock wait/hold time is UNAVAILABLE (no
public KernelStateLock hooks). Each run prints OS, architecture,
rustc --version, and a best-effort filesystem identity; keep those host
results distinct. Linux ntfs3 profile sweeps, a standalone
classify_semantic_conflicts microbench, and Continuity-scale commits/sec
remain out of scope.
Measured host baseline (2026-09-22): cargo bench --locked --bench coordination
on Linux x86_64, rustc 1.94.1 (e408947bf 2026-03-25), ext4 tempfile fixtures,
inside a delegated systemd user manager (systemd-run --user --scope -p Delegate=yes). Native Windows cannot open these production APIs (verified
no-follow safe-root handles are unsupported on that platform). Supported
lifecycle range on this host is concurrency 1 and 4 on S. Concurrency 8 is
outside the supported envelope: Criterion collection hit managed_worktrees.lock
after 60s (create failed for life-0: timed out after 60 seconds waiting for kernel state lock .../managed_worktrees.lock; success=78 failure=2 on that
cell). Do not treat the 8-way Criterion times as a successful envelope. Merge
preview/review/apply and quiescent list completed with zero failures.
Observed operation latencies (nearest-rank; p95/p99 UNAVAILABLE when n is too small):
- lifecycle S workers=1: success=12 failure=0; post-probe
.git/maco65432 bytes; Criterion wall[5.9822 s, 7.0107 s, 8.1983 s], throughput[0.1220, 0.1426, 0.1672]elem/s. create n=12 p50_ms=5232.062 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE; list_managed_verified n=12 p50_ms=18.748 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE; remove n=12 p50_ms=652.780 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE. - lifecycle S workers=4: success=48 failure=0; post-probe
.git/maco360107 bytes; Criterion wall[24.631 s, 27.628 s, 31.779 s], throughput[0.1259, 0.1448, 0.1624]elem/s. create n=48 p50_ms=16569.574 p95_ms=24741.802 p99_ms=UNAVAILABLE; list_managed_verified n=48 p50_ms=3410.007 p95_ms=13104.932 p99_ms=UNAVAILABLE; remove n=48 p50_ms=1203.899 p95_ms=3378.728 p99_ms=UNAVAILABLE. - lifecycle S workers=8: OUTSIDE_SUPPORTED_ENVELOPE (60s
managed_worktrees.locktimeout). Not a supported cell. - merge preview S: Criterion wall
[1.6473 s, 1.6675 s, 1.6903 s], throughput[0.5916, 0.5997, 0.6071]elem/s;preview_merge_apply_with_evidencen=12 p50_ms=1661.717 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE. - merge preview M: Criterion wall
[1.6273 s, 1.6577 s, 1.6914 s], throughput[0.5912, 0.6033, 0.6145]elem/s;preview_merge_apply_with_evidencen=12 p50_ms=1650.938 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE. - merge review+apply S: success=12 failure=0; Criterion wall
[18.015 s, 18.110 s, 18.204 s], throughput[0.0549, 0.0552, 0.0555]elem/s; cli_merge_preview n=12 p50_ms=3018.834 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE; cli_merge_apply n=12 p50_ms=15080.524 p95_ms=UNAVAILABLE p99_ms=UNAVAILABLE. - quiescent list S n=1: Criterion wall
[3.8873 ms, 3.9278 ms, 3.9607 ms], throughput[252.48, 254.60, 257.25]elem/s; list_managed_verified n=348 p50_ms=3.839 p95_ms=4.728 p99_ms=5.758. - quiescent list S n=4: Criterion wall
[7.0835 ms, 7.2776 ms, 7.7223 ms], throughput[129.49, 137.41, 141.17]elem/s; list_managed_verified n=142 p50_ms=7.303 p95_ms=12.318 p99_ms=16.823. - optional probe same-path claim ×8: probe success=1 failure=7 (expected overlap refusal); Criterion round success=14 failure=98 including warmup.
- optional probe fifth create with four retained: Criterion wall
[5.3359 s, 6.0819 s, 6.9577 s], throughput[0.1437, 0.1644, 0.1874]elem/s.
DEFERRED / UNAVAILABLE: This envelope does not publish:
- Linux
ntfs3filesystem-profile sweeps; - a standalone crate-private
classify_semantic_conflictsmicrobench; - Continuity or any custom VCS;
- KernelStateLock wait/hold instrumentation;
- paid-provider benches;
- brittle universal CI timing thresholds. OS/filesystem identity stays attached to the local Criterion report instead;
- 8-way managed-worktree lifecycle as a supported cell on this host.
Artifact notice for this README section: this section itself documents only provisional deterministic fake evidence over a hand-authored plan. This section is ineligible evidence for production use, production economics, or any production/default model decision.
tests/fixtures/model_mix_evaluation is the phase-A contract for the Issue #26
model-mix evaluation harness. The records are deterministic fake evidence
generated by src/evaluation.rs; no provider, supervisor, held-out command, or
hand-authored plan was executed to produce them. Cost-shaped values are
synthetic fixture data rather than prices.
The version-1 experiment fixture set contains (the current results/summary wire schema is version 4; version 3 remains the pre-objective-selection readable legacy):
hand-authored-plan-v1.jsonexplicitly identifies itself as a provisional hand-authored plan used only to generate deterministic fake evidence. It is ineligible for production use or production/default decisions. It is inert input whose exact bytes are bound by the manifest's SHA-256 digest.manifest-v1.jsonexplicitly identifies itself as a provisional manifest for deterministic fake evidence over that hand-authored plan. It is ineligible for production use or production/default decisions. The strictEvaluationManifestbinds the goal, declared base commit, plan digest, wall-time and dispatch limits, held-out commands, three repetitions, and every complete role/model profile.runs-v1.jsonexplicitly identifies itself as provisional deterministic fake run evidence over that hand-authored plan. It is ineligible for production use or production/default decisions. The strictEvaluationResultssnapshot uses fake seed 26; its 12 synthetic runs cover four profiles and retain fake success, failure, and timeout outcomes. Every repetition records synthetic dispatch, error, usage, cost, wall-time, churn, conflict, diff, held-out, and review values. Per-role usage is explicitly serialized assynthetic_fake(RoleUsageObservation::SyntheticFake), never process-observed. Result validation rejects synthetic dispatch or wall-time values above the manifest limits and rejects missing, unexpected, or over-256-byte execution error evidence.summary-v1.jsonexplicitly identifies itself as a provisional deterministic fake summary over that hand-authored plan. It is ineligible for production use or production/default decisions. The strictEvaluationSummaryprojection contains validated synthetic aggregates and a synthetic cost-versus-quality Pareto frontier. Its quality axis retains held-out validation, breadth, and anti-shortcut components, so test pass rate, LOC, or low cost alone cannot stand in for quality. Integral metric and quality means are exact machine-readable rationals withtotalandcountfields, including when the total is not divisible by the number of repetitions.supervisor-final-execution-v2.jsonis a synthetic, shape-compatible bounded projection of asupervisor-final.jsonenvelope carrying execution/economics schema v2. The harness consumes assignment lifecycle counts, configured and achieved concurrency, the explicit policy-observation marker, every role's resolved model and reasoning effort, and aggregate usage/cost. Its pairedsupervisor-final-execution-v1-legacy.jsonfixture proves that configured values from an older report are not substituted for missing observations.
Results schema v3 added a separate execution_telemetry_comparability value
on each same-repetition dispatch comparison. Schema v4 is the current scored
wire: it requires canonical objective_scoring provenance and is the family
maco evaluation rescore --family evaluation accepts. Resolved model/effort
differences remain dispatch-selection evidence; assignment, fan-out, and usage
differences remain execution-telemetry evidence and do not masquerade as a
model-selection difference. A report without economics schema v2, complete
resolved role bindings, achieved mean concurrency, or complete aggregate usage
is explicitly incomparable. Legacy results schema v2 remains readable and
maps a missing execution comparison to incomparable; no missing count, width,
model, effort, token, or cost is defaulted to zero or to a configured value.
Phase A does not establish Issue #26 requirement-4 observed
isolated-repository-state comparability. It checks consistency among declared
manifest inputs and generated fixture fields only, with status
not_established_deferred_to_phase_b. Its declared_inputs_digest is not an
observed checkout, worktree, tree, HEAD, or dirty-state fingerprint, and it
cannot detect genuine repository-state divergence. Observing and refusing
non-equivalent isolated starting states through the real goal-to-integration
path is deferred to Phase B and Issue #22.
Actual real-model executions, observed isolated-worktree identity, and any production/Pareto conclusion remain Issue #26 Phase B. That phase is currently blocked on Issue #77's writable end-to-end real-provider path; the Phase-A adapter and fixtures do not claim that a provider executed the recorded model slug.
The runner entry point itself requires the exact supplied plan bytes, binds
them to the manifest digest, and validates them before a deterministic fake run
can begin. Invalid or unlabelled input returns
EvaluationError::InvalidHandAuthoredPlan; a digest mismatch returns
EvaluationError::HandAuthoredPlanBindingMismatch. Plan validation is not an
optional caller-side preflight.
Validate the typed fixture contract and exact deterministic snapshot without running a supervisor, provider, or held-out command:
cargo test evaluation::tests --libThe ignored regeneration test is an explicit maintainer action:
cargo test evaluation::tests::regenerate_committed_evaluation_fixtures \
-- --ignored --exactThe same fixture generator is also the maco evaluation run CLI. It still
generates deterministic fake evidence from a versioned manifest and a
digest-bound hand-authored plan; it does not inspect the repository or execute
a provider, supervisor, or held-out command. --execution defaults to
deterministic-fake. --allow-real-provider acknowledges a future real
provider path and is still refused by the current runner.
maco evaluation experiment runs the same goal/spec under multiple profiles
through isolated Fake supervise by default. Real-provider execution is a
separate opt-in tuple described below; omitting any required input still
refuses before artifact reservation or provider calls.
maco evaluation experiment <manifest.json> --execute-held-out --repo <artifact-owner> --json
explicitly opts into executing each declared held-out argv against a separate
contained copy of each candidate. The parent holds the existing candidate write
lease, checks the captured candidate before and after validation, and binds the
observations into the independent parent review request. Nonzero exits and
candidate mutations fail validation; unavailable containment/executables,
cancellation, deadlines and unexecuted commands are unknown. Every required
command must pass before the held-out validation can pass.
This mode emits evaluation_experiment_observations_v3; legacy experiment result
versions and the default command behavior are unchanged. By default its candidates
still come from Fake generation over a synthetic README containing the goal/spec,
with the same baseline commit/tree for every profile and repetition. With
--execute-held-out, paired --source-repo PATH and --base-commit FULL_OID
materialize each profile/repetition from that exact commit/tree in a private
temporary repository; the flags are refused without --execute-held-out and
never infer evaluated source from --repo. --repo owns evidence storage and
is not the evaluated source. The existing owner-private
.maco/o2/runs/<unique-run-id> artifact store retains the full manifest, exact
profile/repetition/run/baseline/candidate/argv bindings, dispatch admissions,
observations and authenticated review/report copies before temporary repositories
are removed. Existing artifact size/file limits apply. Finalization authenticates
the retained run; interrupted runs remain unfinalized, unknown and nonpublishable.
This mode never resumes or replays their commands.
Manifest max_dispatches counts admitted child/auditor invocations and held-out
commands per profile/repetition. The declared wall-time limit is checked before
each dispatch and bounds the command timeout; candidate preparation and cleanup
retain the existing bounded local-Git/guardian behavior. These observations do
not fabricate assertion counts, tokens, prices, confidence or quality scores.
Production and named-default eligibility remain false.
One opt-in command connects the existing held-out parent-validation path to a
non-Fake runtime. It does not establish measured quality, cost, or
named-default eligibility. Every flag below is required together; credentials,
retention roots, and the executable are never inferred from --source-repo.
--repo remains the artifact owner.
maco evaluation experiment <manifest.json> \
--execute-held-out \
--execution real-provider \
--allow-real-provider \
--source-repo <evaluated-git-repo> \
--base-commit <full-40-character-oid> \
--provider-plan <plan-outside-source-repo> \
--runtime <grok|cursor|codex|claude-code|gemini-cli> \
--runtime-bin <explicit-executable> \
--machine-global-config <reviewed-config> \
--machine-global-runtime-root-id <reviewed-root-id> \
--repo <artifact-owner> \
--json--provider-plan is the operator-owned supervisor plan. It must live outside
the evaluated source repository, declare exactly one assignment, and must not
declare generated follow-ups, execution_target, or evidence-only re-audit
controls. The frozen original plan bytes and full parsed document (consultant,
plan metadata, assignment metadata) are retained; only profile role_models are
overlaid per run and revalidated. Each manifest profile supplies those
role_models; observation manifests accept one profile (comparison manifests
still require two). Profile unavailable_model_fallback must not be
LocalDeterministicFake. The parent still executes held-out argv against
contained candidates and retains authenticated evidence.
--runtime-bin must exactly match the configured operator adapter executable
for the requested runtime (options.codex_bin for Codex; MACO_GROK_BIN for
Grok; MACO_<RUNTIME>_BIN for other adapter subprocess runtimes). Mismatch is
refused before artifact reservation and rechecked before every external launch
(including auditors).
Grok parent interaction protocol is selected only by the operator environment
variable MACO_GROK_INTERACTION_PROTOCOL. Exact values are
headless_streaming_json (default when unset) and acp_stdio. Any other value
is refused while the supervisor loads worker and auditor adapter config, before
usable launch; it is not coerced to the default. MACO_GROK_ARGS cannot replace
Grok's immutable safety argv. acp_stdio renders contained
grok agent --no-leader … stdio. Observed model and effort are client-resolved
parent session evidence after session/set_model, not backend attestation.
Writable managed-child launch retains the legacy exact typed contract for
grok-4.6/xhigh. The standard grok-4.7/xhigh typed writable contract is
supported only with headless_streaming_json. The Issue #604 publication gate
is implemented. Grok 4.7 ACP writable admission stays off pending Linux
credential-confined, account-bound managed acceptance in Issue #616. Native
Grok CLI 1.0.40's current ACP identity format can be parsed from the tagged
set-model ack and from currentValue on the session/set_config_option
response. The source wire contract is _meta.outputSchema. A corrected native
Windows CLI 1.0.40 check returned structuredOutput {"accepted":true}; the
earlier _meta.jsonSchema key was a client defect, not a provider limitation.
That receipt is not MACO Linux containment proof, and choosing acp_stdio
does not elevate 4.7 capabilities, with or without an output schema. Select 4.7 explicitly with a role_models entry whose
model is grok-4.7 and whose reasoning_effort is xhigh. That selection
also requires --prior-data containing a dated admissible 4.7 prior and an
eligible operator capability row; see Operator prior data for a supervise
run. Without both, selection fails
closed. Runtime catalogue membership alone does not bypass dated selector
quality/cost gates. The advertised grok-4.7-build-fast CLI slug has no typed
writable contract, is not treated as a public-API model, and is not selected
automatically. The standard 4.7 release documents low through xhigh effort and
a 500k context window, but MACO's writable boundary remains the narrower xhigh
streaming-JSON contract. See the Grok 4.7 announcement
and developer documentation.
Known native cost is a repository microunit equivalent of provider
costUsdTicks (100000 microunits per USD), not a billed quota. Live writable
ExternalGrok credential confinement and remaining compatibility gates stay
unproven. No live managed MACO 4.7 acceptance is claimed. No benchmark,
pricing inference, quality prior, or default-model migration is claimed; the
historical 4.6 terminal seed remains unchanged. This is not production economics and does not close issue 149.
--additional-runtime-bin RUNTIME=ABSOLUTE_EXECUTABLE is optional and repeatable.
It does not replace --runtime / --runtime-bin, which remain required and still
select the parent supervisor. Each additional entry is an explicit launch
allowlist binding for a distinct non-Fake runtime. The operator caller plan and
role_models are not rewritten except for the existing per-profile overlay.
Unknown runtimes, Fake, empty or relative executables, duplicate additional
runtimes, and a duplicate of the primary runtime are refused before artifact
reservation. Declared executables are canonicalized and frozen before
reservation; later launches must match that frozen path and invocation shape.
This is not unrestricted runtime substitution and is not live acceptance of
mixed-runtime quality, cost, or named-default evidence. Actual runtime admission
(catalog, account, confinement, and the matching operator MACO_*_BIN
configuration) remains required.
Example: parent Codex auditor with an explicit Grok worker executable. Replace
the placeholders with reviewed local paths; do not infer them from
--source-repo.
maco evaluation experiment <manifest.json> \
--execute-held-out \
--execution real-provider \
--allow-real-provider \
--source-repo <evaluated-git-repo> \
--base-commit <full-40-character-oid> \
--provider-plan <plan-outside-source-repo> \
--runtime codex \
--runtime-bin <codex-executable> \
--additional-runtime-bin grok=<grok-executable> \
--machine-global-config <reviewed-config> \
--machine-global-runtime-root-id <reviewed-root-id> \
--repo <artifact-owner> \
--jsonreal_provider_execution observation values: not_requested (legacy/default),
requested_unknown (opt-in without parent launch evidence),
launch_attempted (target_launch_attempted only; not success), and
native_runtime_result_captured (publishable parent-held output_last_message
from the trusted runner, not child JSON self-report). real_provider_executed
is true only for native_runtime_result_captured, not for failed
login/quota/spawn or launch-only evidence. Quality, cost, and confidence stay
unknown (null); production, economic, and named-default eligibility stay
false.
cargo run -- evaluation run tests/fixtures/model_mix_evaluation/manifest-v1.json \
--plan-file tests/fixtures/model_mix_evaluation/hand-authored-plan-v1.json --jsonmaco eval-harness run <manifest.json> completes each declared role mix
through the local fake provider and records mix plus per-role outcomes. Version
1 manifests use the v1 local-fake path. Version 2 manifests are routed to the
Issue #26 v2 operator path. maco eval-harness run-v2 <manifest.json> always
parses the version-2 manifest schema and refuses a v1 document. Both commands
accept --json. Their current version-2 run output uses result/schema v3;
result/schema v1 and v2 remain historical. Version 3 was necessary because
fully closing the permissive v2 schema would be breaking. Real network
providers are refused. A v2 provider_request of
real_provider fails closed: omitting the explicit opt-in is
RealProviderOptInRequired, and allow_real_provider=true is still
RealProviderUnavailable. The v2 local fake path emits current machine-readable
comparable results (schema eval_harness_comparable_fake_results_v3) with
production_eligible=false and does not write cwd artifacts.
cargo run -- eval-harness run tests/fixtures/eval_harness/manifest-v2.json --json
cargo run -- eval-harness run-v2 tests/fixtures/eval_harness/manifest-v2.json --jsonReal-provider experiments are a strict future opt-in boundary. A future runner must require an explicit operator choice of provider and models, obtain credentials outside committed fixtures, start every repetition from a freshly verified equivalent isolated state, retain failures rather than filtering them, and write new evidence without replacing phase-A fixtures. The v1 phase-A schema and fake harness exercise unsuccessful-result retention and bounded limit/outcome observability only; they do not execute Issue #22 or a real provider. Merely having credentials or real-looking model labels must never opt in.
Phase B remains required: once the Issue #22 path is available, one command must rerun every profile and repetition from the bound goal and base through goal-to-integration, use the v1 outcome and dispatch-count fields, enforce the same limits and held-out grading contract, and emit schema-compatible run and Pareto results without replacing these phase-A fixtures. The phase-A fixtures do not claim that command exists. Gate-policy/classifier corpus experiments remain separate and depend on the Issue #28 production broker path.
Supervisor routing accepts a named, versioned objective profile. The built-in
maco-default-objective-v1 profile preserves the existing quality weighting
exactly: held-out validation 50%, breadth 25%, and anti-shortcut quality 25%.
Its tradeoff weights preserve the current cost-first selector behavior. The
profile contains no switch-cost term.
Repository-specific profiles may be declared only in the fixed repository-root
file maco-objective-profiles.json. MACO opens that file through its bounded,
no-follow repository-local reader and rejects symlinks, path aliases, unsupported
schema versions, unknown fields, duplicate profile IDs, invalid names, and
weights that are out of range or do not sum to 100. The CLI never accepts an
alternate profile-file path.
Selection precedence is --objective-profile NAME over the authored
objective_profile plan field over the built-in default. Both maco supervise plan and maco supervise run expose the flag; the plan command records the
request in its normalized output, while the run command resolves the effective
profile once against the discovered repository before selector initialization.
Unknown profile names and invalid override files fail before child dispatch.
Retries and budget degradation reuse that frozen resolution instead of reading
mutable configuration again.
New supervisor-final.json reports retain the resolved profile under
role_economics_profile.resolved_objective_profile, including its immutable
ID, version, built-in or repository-override source, content hash, quality
weights, and every effective tradeoff weight. Older reports remain readable;
the generated schema requires this evidence for newly finalized reports.
Verified supervisor runs also write parent-owned child-attempt records under
selection-attempts/ in the existing authenticated run artifact. Initial
selection freezes eligible finalized same-repository history and records its
source digests and exclusions in each selector decision; retries reuse that
snapshot. Only exact-bound real attempts with observed execution identity,
parent-reviewed result, and complete attributable attempt costs can affect
numeric selector outcomes. Current live invocation telemetry does not establish
provider-resolved model identity or per-attempt cost, so those fields remain
unknown and current attempt records do not change numeric scores.
Supervisor routing interprets the default 100%-monetary profile as the exact legacy selector baseline. Nonzero retry/rework and human-review weights are supported as explicit monetary cost-proxy adjustments, proportional to their weights relative to the nonzero monetary baseline. They are not retry rates, review load, or independent observations. A nonzero quota weight fails closed because this branch has no typed, contract-backed per-runtime quota evidence; a nonzero latency weight likewise fails closed because it has no typed per-candidate observed or predicted latency evidence. Missing evidence is never scored as numeric zero.
The 50/25/25 quality decomposition is frozen for evaluation-side consumers;
supervisor selector hard quality and authority gates remain unchanged and
non-weightable. Operator profile selection and immutable review evidence are
live. Historical rescoring of stored evaluation documents is available as
maco evaluation rescore and does not overwrite the stored results file. The
GUI tracked by #152 remains planned.
maco evaluation rescore re-scores a validated stored results document under a
different named objective profile. The stored file is never overwritten. The
command requires:
- a positional manifest path matching the selected family
--results <file>for the stored document--family evaluation|experiment--objective-profile <name>resolved from the repository override file or the built-in profiles- optional
--repo(default.) used only to resolve that named profile - optional
--json
--family evaluation expects stored EvaluationResults schema v4 plus an
EvaluationManifest. --family experiment expects stored ExperimentResults
schema v2 plus an ExperimentManifest. Missing --results, --family, or
--objective-profile, and an unknown family name, fail at argument parsing.
Unknown profile names fail before scoring. The JSON envelope records
kind=historical_rescore, the original and applied profile bindings, the
complete original stored document, and only the preference-bearing selection
recomputed from the stored preference-free Pareto evidence.
cargo run -- evaluation rescore tests/fixtures/model_mix_evaluation/manifest-v1.json \
--results tests/fixtures/model_mix_evaluation/runs-v1.json \
--family evaluation --objective-profile maco-default-objective-v1 --jsonWhen a supervisor plan supplies no role_models override, MACO selects the
named provisional-phase-a-hybrid-effort-v1 profile. Every role's ordinary
default model binding is the single standard slug gpt-5.6-sol; cheaper model
tiers are not availability substitutes in the default profile. The effort
fallbacks remain xhigh for the supervisor, child orchestrator, and auditor,
medium for workers, and high for the gate classifier. A per-role
role_models entry can still replace authored role data, but the acceptance
gate and review-auditor hard floors remain enforced.
Each default role selection retains the ordered-catalog data shape and typed
resolution observations. Its ordinary availability models list is empty, so
the default path never silently substitutes a cheaper slug. The separately
named budget_degrade_models list remains available only to the typed
mechanical-Worker degradation ladder. MACO consults the authenticated runtime
catalog once; when gpt-5.6-sol is present, every default role resolves to it.
The chain is ordinary plan/profile data and round-trips without a code-shape change:
{
"model": "gpt-5.6-sol",
"reasoning_effort": "xhigh",
"unavailable_model_fallback": {
"ordered_catalog_chain": {
"models": [],
"budget_degrade_models": ["gpt-5.6-terra", "gpt-5.6-luna"],
"on_exhausted": "runtime_default"
}
}
}The compatibility name all-frontier-v1 remains available when a plan supplies
the public all_frontier_role_models() data explicitly. Historical execution
telemetry using provisional-phase-a-hybrid-model-tier-v2 remains readable,
but newly finalized reports use the effort-only name.
An assignment may select a typed reasoning_effort value (minimal, low,
medium, high, xhigh, max, or ultra). Missing assignment values use
the role fallback. The selected task effort applies to child, nested-worker,
gate-classifier, and review-auditor duties; gate-classifier duties clamp at
high and review-auditor duties clamp at xhigh. The clamp is retained as
resolution_observation=hard_floor_clamped rather than silently rewriting the
authored request.
The availability fallback order and the economics downgrade order are distinct
data. models answers which advertised model may substitute when the primary
is absent. budget_degrade_models is a monotone cheaper-tier list consulted for
an explicitly mechanical Worker assignment after a run crosses a soft budget
ceiling or when the scheduler observes the low-difficulty mechanical trigger;
an arbitrary plan fallback is never assumed to be cheaper.
The scheduler consumes BudgetAction::Degrade before admitting new work, but
never lowers a child-orchestrator, gate, or auditor judgment binding. Worker
degradation is available only when every Worker in that assignment declares a
typed mechanical_duty. The scheduler first selects a distinct,
runtime-advertised, authority-eligible model from the requested plan's Worker
budget_degrade_models, then lowers Worker effort on the next applicable rung,
and only then halves the remaining fan-out bound (never below one). If the
Worker ladder has no eligible target, the model rung refuses explicitly and
does not advance to fan-out. A hard ceiling still halts new dispatch and drains
already-started assignments. Concurrent admission waits until each newly
spawned assignment has either committed its child budget reservation or
completed without one, so the next policy decision cannot race past an
invisible reservation.
mechanical_duty accepts apply_explicit_text_replacement,
run_preselected_command, format_preselected_files,
enumerate_declared_artifacts, or validate_against_fixed_schema. Omission is
fail-closed for Worker model and effort degradation; mixed marked/unmarked
Worker assignments retain their ordinary role bindings.
Every applied rung is retained in
role_economics_profile.execution.budget_degradations with the assignment ID,
typed trigger (budget_pressure or low_difficulty_mechanical), budget reasons,
the Worker binding before and after the change, and the full effective child
model, effort, and fan-out. The assignment selection ledger projects the
resulting Worker model and effort without rewriting judgment-role rows.
observation=admission_policy_resolved deliberately says that this is
scheduler admission evidence; commands_run remains the process evidence for
a dispatch that actually started. When assignments use different mechanical
Worker bindings, the aggregate Worker role binding is marked
assignment_specific instead of claiming one model or effort for the whole
run.
maco supervise run accepts the same per-supervisor-run
hard ceilings:
--max-tokens(--max-total-tokensalias)--max-cost-usd(--max-total-cost-usdalias)--max-duration-seconds(--max-total-duration-secondsalias)
Token, cost, and duration values must be finite positive values. Token and cost
flags tighten an authored or goal-derived plan's run_budget values by taking
the minimum. If the resulting hard ceiling is below a plan soft threshold, the
soft threshold is clamped to the hard ceiling. Duration likewise composes with
run_budget.max_duration_seconds by taking the minimum and stops new admission
once elapsed time reaches the bound. The effective limits, elapsed seconds, and
remaining duration are retained in supervisor-final.json. When any CLI ceiling
is supplied, the run budget ledger also retains the original plan and CLI
values under run_budget.sources so the override is visible independently of
the composed limits.
maco supervise run and maco inbox run also accept optional workspace rolling-quota ceilings:
--max-rolling-tokens--max-rolling-cost-usd--rolling-window-seconds
A rolling quota is bound only when at least one of --max-rolling-tokens or
--max-rolling-cost-usd is set; --rolling-window-seconds alone does not
create a quota. Values must be finite and positive. When a ceiling is set and
the window is omitted, the window defaults to 86400 seconds (24 hours). These
ceilings apply across supervise/autopilot runs in the workspace rolling
ledger; they are distinct from the per-run --max-tokens / --max-cost-usd /
--max-duration-seconds flags. maco inbox run exposes the same three rolling
flags for inbox Autopilot dispatches and rejects the per-run supervise
ceilings.
Inbox item work that still uses the autopilot library path propagates the per-run limits to its source and generated follow-up supervise dispatches. Completed run-budget results also update MACO's authenticated rolling workspace ledger; in-flight reservations remain local to the run.
maco supervise run accepts an optional
--quota-config REPO_RELATIVE_FILE. The path is resolved inside --repo with
no symlink traversal, and the bounded JSON file is parsed with unknown fields
denied. When the flag is omitted, admission and selection retain their existing
behavior.
The file declares operator-known entitlements. MACO does not call provider billing, quota, rate-limit, or pricing endpoints: availability and marginal cost come only from this config plus completed results in the authenticated workspace ledger. For example, this source pool may degrade only to the exact declared alternative. Prices are operator-declared config evidence, never live quotes:
{
"version": 1,
"pools": [
{
"runtime": "codex",
"account": "operator-primary",
"pool_kind": "subscription_included",
"window": "calendar_month",
"nominal_capacity": { "units": 1000000 },
"rate_limits": { "max_concurrent_sessions": 2 },
"exhaustion_behavior": "degrade",
"declared_list_price_microunits": 1000,
"authorized_alternatives": [
{
"runtime": "cursor",
"account": "operator-backup",
"window": "calendar_month"
}
]
},
{
"runtime": "cursor",
"account": "operator-backup",
"pool_kind": "metered",
"window": "calendar_month",
"nominal_capacity": "unknown",
"rate_limits": { "max_concurrent_sessions": 1 },
"exhaustion_behavior": "fail_closed",
"declared_list_price_microunits": 5000
}
]
}A bounded source at zero remaining capacity obeys its configured behavior.
fail_closed refuses dispatch. degrade considers only exact
authorized_alternatives, and each alternative must still pass catalog,
runtime, authority, policy, and publication gates; if none remains eligible,
selection refuses. Debug overrides cannot bypass quota exhaustion. The selected
pool state and exhaustion decision are retained as typed selection provenance
and assignment-ledger evidence. max_concurrent_sessions also tightens the
resolved scheduler fan-out.
maco supervise run --prior-data REPO_RELATIVE_FILE accepts one bounded,
strict JSON snapshot owned by the operator. Its top-level fields are
schema_version: 1, dataset_id, revision, published_on, models, and
capability_policy. Each models entry uses the ModelPrior shape shown in
src/selection/data/priors-2026-08-07.json;
capability_policy uses the existing ModelCapabilityPolicy shape with id,
version, source, and dated model evidence rows. The path must be inside
--repo; symlinks, traversal, hard-linked leaves, oversized files, unknown
fields, duplicate models, and malformed dates or evidence are refused.
This feature requires Unix component-wise path confinement (including WSL);
native Windows refuses --prior-data and continuation of a run containing
prior data. Legacy runs without prior data retain their existing behavior.
The snapshot may add or update dated model priors. Bundled objective
calibration, model prohibitions, role and long-context vetoes, and judgment
effort floors remain binding. A newly advertised model needs both a dated
prior and an eligible operator capability row before execution admission;
unknown models receive no inferred quality, cost, or authority. This source is
operator-declared prior evidence, distinct from MACO's authenticated
parent-reviewed attempt outcomes. MACO archives the exact source and effective
policy with each run, records their digests in selector provenance, and uses
that same policy in selection and dispatch. A finalized continuation reuses
its authenticated snapshot and refuses changed --prior-data; an unfinalized
run with prior data must first be finalized before continuation.
On the production Codex path, the no-override child-orchestrator and auditor
commands are constructed with the profile's explicit model and resolved
assignment effort. Worker selection remains declarative data in the child
orchestrator prompt because nested workers are not launched as separately
process-observable commands; it is not per-worker model or usage evidence. The
supervisor entry completes the reported role profile rather than claiming that
the running supervisor launches itself. The gate_classifier entry currently
has only the deterministic-fake evaluation boundary described above; Issue
#28's writable production gate remains deferred.
Before a verified Codex run schedules any assignment, MACO invokes the trusted
system Codex CLI's non-bundled codex debug models command exactly once. The
preflight requires a validated auth.json, runs in the contained parent-Codex
network profile with a private HOME and CODEX_HOME, bounds and validates the
JSON catalog, and rechecks both the auth source and executable identity after
the command. Explicit custom executables never receive auth or provider network
access. Missing auth, a failed/nonzero command, unsafe containment, truncated or
malformed output, an empty catalog, duplicate slugs, or invalid slug syntax
fails closed before any child or auditor dispatch.
Exact slug membership in that immutable per-run catalog determines availability
for child and auditor command construction. A present slug remains explicit in
argv. An absent slug is unavailable, so the configured fallback is applied
before budget reservation and spawn-event dispatch:
| Configured fallback | Known-unavailable behavior |
|---|---|
runtime_default |
Clear the explicit model while preserving the configured reasoning effort, allowing the runtime to choose its default model. |
fail_closed |
Refuse the selection rather than dispatch with another model. |
local_deterministic_fake |
Use the deterministic local fallback only with the Fake runtime; reject it for Codex. |
The Fake runtime performs no catalog command and treats configured provider models as unavailable, so its declared local fallback remains local. The Codex CLI can return an in-memory or cached catalog when an online refresh fails; therefore membership is runtime-advertised availability at preflight time, not proof of a fresh entitlement check or a guarantee that a later provider launch will succeed. MACO does not retry by cycling model names.
The single-slug model binding follows the evidence-backed cost-per-accepted-task
decision. Assignment-level effort matching is operationally selected but has
not yet been evaluated with real-provider resolved-effort telemetry, so the
combined profile remains production_eligible=false. Genuine Issue #26
evidence is required before its effort policy can be qualified for production
or revised on empirical grounds.
Automatic routing includes a conservative objective-profile cost when a role changes model or runtime after an earlier assignment in the same supervisor run. The built-in profile configures 10,000 microunits for a model change on the same runtime and 25,000 microunits for a runtime change. Initial selection, staying on the exact runtime/model pair, and changing only reasoning effort on that same pair configure and charge zero. The effort-only case is deliberately zero because this contract models runtime/model re-priming rather than every assignment parameter change.
These defaults are inferred operating policy, not measured transition
telemetry. Operators can tune them through the existing versioned objective
profile. The charged term is normalized inside the existing checked
cost-per-accepted-task objective as
ceil(configured switch cost × 10,000 / candidate posterior-quality basis points).
It therefore generally differs from the configured value unless candidate
quality is 10,000 basis points. Malformed values, zero-quality normalization,
intermediate or result overflow, and total-score overflow fail closed. The state
boundary is the previous assignment for the same role in the current supervisor
run, not process-global or cross-run mutable state.
Serialized selection evidence records the previous choice in the normalized input and records each candidate's typed transition, configured switch cost, charged switch term, and checked total score. The selected choice and runner-up scores repeat the transition and charged term, so the finalized supervisor artifact can reconstruct why staying or switching won.
This bounded Issue #201 increment does not implement measured transition fitting, replay correction, oscillation telemetry or alarms, or safe-set policy promotion. It also does not recreate Issue #150's profile loader, repository override, or command-line override surface.
Linux is the fully supported security-sensitive runtime path. macOS and Windows
adapters cover portable Git, process, and state operations, but commands that
depend on Linux-only primitives such as renameat2, descriptor-confined review
views, or systemd containment return an explicit unsupported-platform error.
They do not silently fall back to weaker path or process checks. The Nix flake
evaluates Linux and Darwin development shells; Windows builds require a separate
Rust target/toolchain and are not provided by this flake.
Install the composing primary-worktree guard only after the canonical v5
human-authorship pre-push dispatcher is present in Git's default hooks
directory:
maco worktree guard install --repo .
maco worktree guard verify --repo .
maco worktree guard uninstall --repo .Install and verify require the active outer dispatcher to match the canonical
v5 bytes and exact 0755 mode. Every installed worktree-guard hook repeats
that check before repository or branch decisions and before invoking a
preserved hook. Re-running install safely upgrades an exactly intact guard
installed by the previous v3 payload, preserving its recorded prior-hook
backups; arbitrary or ambiguous payload, mode, state, or staged-file drift is
still refused. uninstall completes that same exact legacy upgrade before it
restores the recorded backups.
For an ordinary push, push-time refusal exists only while Git executes an outer
pre-push dispatcher that reaches the nested worktree guard. If all executable
bits are removed from the outer hook, Git skips it. If the outer hook is
replaced by an executable script that omits the nested invocation, Git runs
only that replacement; the nested guard and all other checks normally reached
through the dispatcher are bypassed for that push.
maco worktree guard verify detects either form of outer drift. Another
installed guard hook that Git still executes, such as pre-commit or
pre-merge-commit, also detects it. These checks provide defense in depth
against accidental or partial drift, not tamper-proof enforcement by local
hooks.
Inspect a repository:
cargo run -- repo map --repo . --json
cargo run -- repo map --semantic --repo . --json
cargo run -- repo megafile query --repo . --json
cargo run -- repo megafile seed --repo . --json
cargo run -- repo megafile query src/lib.rs --repo . --json
cargo run -- repo query symbol WorktreeManager --repo . --json
cargo run -- repo query path src/worktree.rs --repo . --json
cargo run -- repo query risk --path src/worktree.rs --repo . --jsonrepo map and repo megafile query are read-only. In particular, querying an
uninitialized repository reports initialized=false and does not create an
authentication key, state directory, lock, or telemetry snapshot. Size
telemetry is written only by the explicit repo megafile seed command. The
sampler is language-agnostic: it reads bounded regular repository files and
records bytes and physical lines, including binary files, without requiring a
Rust parser. The authenticated report exposes the bounded retained event
history as records plus current per-path assessments; events include size
samples, claims, merge collisions, and accepted decompositions.
All megafile thresholds are configurable with --file-bytes, --file-lines,
--growth-bytes, --growth-lines, --claim-count, --collision-count, and
--activity-window-records. When none is supplied, the JSON calibration is
bootstrap_provisional: the defaults are operating starting points, not
empirically calibrated policy. Any override labels the assessment
configured. Before using megafile blocking or decomposition acceptance in a
real run, operators must review authenticated telemetry produced by real
repository activity and revise the provisional values with explicit configured
thresholds; bootstrap values are not production acceptance criteria. Continue
revising configured values when later real-run size, claim, or collision data
shows that the calibration no longer represents the repository. History is
bounded to 16,384 logical records and authenticated
snapshot storage is also bounded; older logical events are evicted, so this is
operational recent history rather than an indefinite audit archive.
Managed worktree creation derives a capability-bound repository cleanliness input at command start and creates a linked worktree when the primary is observed clean. A dirty primary fails with the required remedy before the worktree is created:
cargo run -- worktree create agent-a --repo . --json
cargo run -- worktree create agent-b --repo . --gc-max-count 10 --gc-max-age-seconds 604800 --json
cargo run -- worktree create task-r2 --repo . \
--supersede-retry-predecessor --apply-retry-supersession \
--o2-launch-retention-defaults --jsonList worktrees:
cargo run -- worktree list --repo .Dry-run lifecycle cleanup for completed managed worktrees and retained Rust build artifacts:
cargo run -- worktree gc --repo . --dry-run --json
cargo run -- worktree gc --repo . --dry-run \
--allow-untracked-path TASK.md --json
cargo run -- worktree gc --repo . --targets-only --dry-run --json
cargo run -- worktree gc --repo . --targets-only
cargo run -- worktree gc --repo . \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-worktree-root-id worktrees \
--machine-global-correlation scheduled-worktree-gc \
--max-count 10 --max-age-seconds 604800 --max-total-bytes 10737418240 --json
cargo run -- worktree gc --repo . \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-worktree-root-id worktrees \
--machine-global-correlation manual-worktree-gc \
--keep-targetsGC classifies tracked changes separately from untracked-only paths. Tracked
changes always protect the lane. Untracked-only lanes are also protected by
default and report their complete bounded path set; full-lane cleanup is
eligible only when every such path exactly matches a repeatable
--allow-untracked-path <repo-relative-path> value. This is an exact path list,
not a glob or blanket ignore, and is bounded to 128 entries and 64 KiB in
aggregate because a workspace sweep copies it into each per-root report.
Repository-ignored files are included in this classification and need the same
exact authorization. Only documented MACO runtime categories (target/,
.maco/, .maco-cache/, and the .agent[s] temp/storage/live roots) remain
separately disposable. An
untracked file may be a worker's only copy of real output. Apply mode repeats
the bounded status classification immediately before journaling full-lane
removal and protects the lane if a new tracked or unapproved untracked path
appeared. GC removal records the exact, platform-lossless clean or untracked-path
classification and the target's absent/present filesystem identity in its
authenticated recovery journal, then revalidates both immediately before
quarantine. New explicit removals record a distinct origin. Explicit --force
bypasses dirtiness but never target liveness; a legacy operation with no origin
is always ambiguous in every unfinished recovery phase and cannot continue until
the operator reruns the explicit force-removal command to reauthorize it. That
command replaces the pending branch-deletion choice with its current explicit
choice rather than inheriting a stale journal value. GC also keeps
worktrees with
active MACO execution leases or active path claims for the same agent id.
Without retention filters, every eligible inactive managed worktree is selected
for removal. --max-total-bytes adds a size dimension to --max-count and
--max-age-seconds: after age/count exclusions, GC walks eligible lanes from
newest to oldest and retains the newest prefix whose combined apparent size is
within the byte budget. Protected or otherwise ineligible lanes are not charged
to that retention budget, so it is not a global on-disk ceiling. Apparent size
is filesystem metadata length, not allocated blocks or a promise about physical
disk space, and sums descendants only rather than the lane root inode itself.
The report exposes the
apparent bytes considered and estimates for bytes reclaimable and actually
reclaimed; full-lane estimates already include target/, while target-only
estimates count only target/, so they are not double-counted. Sizing is a
bounded, descriptor-relative, non-symlink-following walk; Linux additionally
confines the walk to the lane's exact mount. A timeout, limit, unsupported
platform, invalid target binding, or other sizing failure reports
size_measurement_failed and protects that lane instead of guessing. Retained
clean worktrees keep the checkout but lose their target/ directory unless
--keep-targets is set. A second pass prunes
unregistered direct-child directories left under the managed worktree root. A
destructive second pass requires the three-part machine-global binding above, treats
all discovered orphans as one preflight set, and uses recoverable quarantine rather
than direct deletion. Dry-run discovery remains non-mutating and does not require the
binding.
The byte counters cover authenticated managed lanes and managed target/
cleanup only; orphan quarantine is reported by orphan counts and is not included
in the byte estimates. Creation-time size retention reserves the newly created
lane before considering older lanes. If that new lane alone exceeds the budget,
it remains reserved and the effective byte allowance for older lanes is zero.
--targets-only removes eligible target/ directories while retaining every
managed lane, branch, untracked file, and registered association. Because it is
a separate operation, it rejects --keep-targets, every retention filter
(including --max-total-bytes),
untracked-path allowances, and machine-global orphan-cleanup bindings, and it
does not run orphan pruning. Tracked changes, active claims, and active leases
still protect the target; an untracked-only lane does not require an allowlist
because the lane and its files remain. On Linux, every target deletion scans a
bounded /proc snapshot for same-user processes. Explicit CARGO_TARGET_DIR
values are resolved in the process's own view: absolute paths through
/proc/<pid>/root and relative paths through /proc/<pid>/cwd. Canonical path
containment and bounded ancestor identity checks in both directions detect
aliases across mount namespaces without assuming textual path equality. Process
paths retain their /proc/<pid>/root access path for identity checks. Observer
canonical-path comparisons are used only when the process and observer mount
namespace identities match; a different namespace relies on rooted filesystem
identities and incomplete evidence is unknown. The
detector also parses bounded process command lines for split and --name=value
forms of Cargo's --target-dir and --manifest-path and rustc's --out-dir.
An explicit output under the target is live; a manifest inside the lane with no
explicit output protects the default Cargo target. The fallback association
scan always runs, even after a readable environment or command line has no
explicit target: a cargo/rustc/rustdoc/sccache-like process with a cwd inside
the lane protects the default Cargo target, while a process cwd, executable,
or readable file descriptor inside the target is live. File descriptors are
read with readlink; recognized non-filesystem pipe, socket, anon_inode,
and synthetic memfd or dmabuf targets are skipped, while deleted filesystem
links under the target still protect it. Environment, command-line, cwd,
executable, file-descriptor, bound, read, or timeout failures are unknown, not
clear for a possible build process. Linux user-manager helpers, non-build
systemd user services, and non-build processes with a readable command line but
an unreadable mount namespace are skipped because they do not execute build
work themselves; any cargo/rustc descendant remains a separately scanned
process. A live match is reported as live_target; an incomplete,
oversized, timed-out, or unreconciled scan is reported as
target_liveness_unknown, and both refuse deletion. Reports include bounded
typed PID, source, and cause evidence in JSON and human output.
The target directory's filesystem identity is bound before the liveness probe.
Target-only deletion passes that expected identity into the handle-relative tree
remover, and full-lane deletion rechecks it immediately before recording the
removal operation. Replacement is reported as target_identity_changed and the
lane is retained. The same protections apply to a target included in full-lane
removal. Recovery from a prepared removal rebinds the source, refuses any GC
target absent/present or identity change, reruns the real liveness detector for
every target including explicit-force removals, and revalidates the exact GC
dirtiness state before quarantine. On non-Linux platforms the detector conservatively reports
unknown, so target deletion remains disabled until a native detector is
implemented. These checks run at the removal boundary to narrow the race, but a
non-cooperating process can still start or create output after the final check.
Sweep every repository group beneath one workspace. The first command is a
dry-run because workspace sweeps never remove anything unless --apply is
explicitly supplied:
cargo run -- worktree sweep --workspace /exact/path/to/workspace --json
cargo run -- worktree sweep --workspace /exact/path/to/workspace \
--apply --max-count 10 --max-age-seconds 604800 --json
cargo run -- worktree sweep --workspace /exact/path/to/workspace \
--apply --keep-targetsThe sweep authenticates grouped roots at the exact creation default
<repo>/.maco/worktrees/<sanitized-repo-name> and the legacy parent-workspace
<repo-parent>/.maco/worktrees/<sanitized-repo-name> layout. It also recognizes
the exact canonical manual .worktrees child of either the workspace repository
itself or a direct repository child; custom per-creation roots have no persisted
repository-level configuration to discover. The aggregate report identifies
each root kind and distinguishes roots that were inspected from roots skipped
before GC and roots whose GC attempt failed. discovery_status is
no_roots_discovered for a total miss and roots_discovered even when every
inspected root has zero actions; human output prints an explicit warning for the
former. Each root includes its resolved repository when available, a typed
failure when resolution or GC fails, and its nested GC summary. A failure in one
root does not stop later roots from being inspected. Retention flags and
--keep-targets are passed independently to each discovered root, so
--max-count and --max-total-bytes are per-root limits and dirty worktrees or
lanes with active leases or claims remain protected. Existing machine-global quarantine gates
also remain in force; the sweep does not weaken them. A workspace-managed group
is associated only with one of those exact grouped roots. A primary that is the
workspace itself is admitted only for its exact new default group; the parent
workspace still discovers legacy groups and each direct child's new default.
<repo>/.maco/worktrees itself is not adopted as a lane root, and the sweep does
not search deeper repository descendants.
Repository-local dry-runs also preview healthy Git-registered lanes that predate
the authenticated MACO worktree registry. A stale linked-worktree child cannot
override the exact primary-repository association used to discover that root.
When the host cannot open legacy MACO state safely, the root remains a typed
failed result, but the nested dry-run report still classifies registered lanes
and exposes exact untracked paths, byte estimates, merge state, and target
liveness. The fallback status probe is read-only and ignores ignored files, like
ordinary git status; it exists only to make legacy lanes visible. It never
grants apply-mode removal authority: destructive sweep still requires a valid
authenticated MACO binding and safe private state.
Run the repository-local lifecycle scheduler only with the automation features
that the operator intends to inspect. The scheduler is dry-run by default, and
every feature is off by default, so the bare command preserves the existing
manual worktree gc and artifact-prune behavior:
cargo run -- worktree lifecycle --repo . --json
cargo run -- worktree lifecycle --repo . \
--auto-reap-merged --trunk-ref refs/heads/main \
--retry-successor issue-65-r2 \
--startup-reconciliation --o2-launch-retention --json
cargo run -- worktree lifecycle --repo . --apply \
--auto-reap-merged --trunk-ref refs/heads/main \
--startup-reconciliation \
--destructive-reconciliation \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-worktree-root-id worktrees \
--machine-global-correlation lifecycle-2026-08-12 --jsonThe report aggregates worktree classification/reclamation, startup
reconciliation, and scheduled artifact retention into one human summary or one
JSON document. --apply is required before any enabled lifecycle action can
mutate state. Merged and retry-predecessor lanes still pass through the ordinary
GC cleanliness, exact untracked-path allowlist, size, target-liveness, active
lease, active claim, and machine-global quarantine guards. Retry derivation is
from the exact --retry-successor <AGENT_ID>; both generations must have live,
verified authenticated bindings under one root and one canonical branch
family. A missing, stale, or ambiguous generation is reported and retained.
Worktree creation can invoke that same classifier with
--supersede-retry-predecessor; destructive reaping remains a separate
--apply-retry-supersession opt-in once capability-bound production creation
is available.
Merged-lane automation requires an exact local reference such as
--trunk-ref refs/heads/main. It never treats an arbitrary current or detached
HEAD as trunk, and it re-resolves ancestry at the deletion boundary. An apply
backed by the required reviewed preview only applies a patch to the primary
checkout and does not advance the trunk reference. An apply using
--auto-reap-merged, --trunk-ref ..., and
--reviewed-watermark <unchanged-preview.json> therefore reports a
just-applied lane as unmerged. After the integration commit or fast-forward, a
finalization rerun classifies and, with --apply-auto-reap, reaps the fully
merged lane. The post-reap Git prune pass is limited to the exact selected lane;
unrelated stale registrations are counted as protected and left intact.
The --o2-launch-retention profile schedules only the actual O2-launch run
store: it keeps the newest 10 runs and gives idle unfinalized artifacts a
seven-day grace. Managed worktree metadata has no trustworthy O2-origin tag, so
this flag deliberately does not broaden worktree deletion to every managed
lane. Merged-lane retention is independently explicit through
--auto-reap-merged, --trunk-ref, and the worktree age/count/apparent-byte
limits. Artifact count/grace can be overridden with --artifact-keep and
--artifact-unfinalized-grace-seconds; artifact age and apparent-byte ceilings
are also available. Artifact safety decisions are
never inferred: --reclaim-unverifiable and
--acknowledge-external-writers-stopped are separately named opt-ins and are
rejected unless --o2-launch-retention schedules artifact pruning. Do not
acknowledge stopped external writers while any same-UID writer may still append
to that store.
Startup reconciliation distinguishes authenticated records whose expected
directory or Git registration is missing, exact authenticated stale Git
registrations, and direct on-disk lane directories that are present under a
known or explicitly selected managed root but deregistered. Detection and reporting require
--startup-reconciliation. Destructive resolution requires all three of
--startup-reconciliation, --destructive-reconciliation, and --apply, and
then remains subject to authenticated identity, pending-operation recovery,
active claims, active execution leases, and apply-boundary state rechecks.
Missing-both records are forgotten without deleting their preserved branch;
an exact missing-path Git registration is pruned individually. Present
deregistered directories are never deleted directly: they require the reviewed
machine-global config/root/correlation binding and move into recoverable
quarantine. Unauthenticated Git registrations, duplicate names across roots,
and other unverifiable findings fail closed and remain visible in the aggregate
report.
Perform explicitly authorized force cleanup and delete a MACO-owned branch:
cargo run -- worktree remove agent-a --repo . --force --delete-branchClaim paths for an agent:
cargo run -- sync claim agent-a src README.md --repo . --json
cargo run -- sync claim agent-b src/large.c --repo . --file-lines 2000 --claim-count 4 --jsonClaims remain backward compatible at the top-level JSON fields and also return
the typed claim and warnings fields. A threshold crossing is warn-only at
claim time; it does not weaken or bypass the exclusive claim gate. The
authenticated claim is committed first and its claim-frequency event is then
written to the authenticated megafile history. If that second write fails, the
command fails closed and states that the claim token remains durable; inspect
sync status and explicitly release that token before retrying instead of
blindly creating a second claim. The event journal is observability only and is
not a megafile authority.
Check the current owner for a path:
cargo run -- sync owner src/lib.rs --repo .List active claims:
cargo run -- sync status --repo . --jsonRelease one claim by token:
cargo run -- sync release 1 --repo .Release all claims for an agent:
cargo run -- sync release-agent agent-a --repo .Run a local orchestration plan:
{
"default_timeout_seconds": 600,
"worktree_reuse_policy": "clean",
"repo_validation_commands": [
{
"name": "repo smoke",
"command": "cargo test",
"timeout_seconds": 300
}
],
"agents": [
{
"id": "agent-a",
"paths": ["src"],
"command": "cargo test",
"validation_commands": [
{
"name": "agent fmt",
"command": "cargo fmt -- --check",
"timeout_seconds": 60
}
],
"env": {
"RUST_BACKTRACE": "1"
}
},
{
"id": "agent-b",
"paths": ["README.md"],
"depends_on": ["agent-a"],
"timeout_seconds": 60,
"command": "printf '# Updated\\n' > README.md"
}
]
}cargo run -- orchestrate validate plan.json --json
cargo run -- orchestrate run plan.json --repo . --jobs 2 --patch-dir .maco/patches --reuse clean --run-id demo --checkpoint-dir .maco/checkpoints --json
cargo run -- orchestrate resume .maco/checkpoints/demo.json --repo . --plan-file plan.json --jobs 2 --patch-dir .maco/patches --jsonThe orchestrator validator checks that plan paths do not overlap, dependencies
are known and acyclic, commands are non-empty, and timeouts are positive.
Verified orchestrate run derives the capability-bound repository cleanliness
input before assignment worktrees are created; a dirty primary repository is
refused with the required remedy. Execution
creates or reuses a linked worktree for each agent id according to
worktree_reuse_policy or CLI --reuse, claims all requested paths before
running commands, runs dependency-ready agents up to --jobs, and releases
claims at the end. A failed agent skips only its transitive dependents;
independent branches continue. Dependency edges control execution order and
failure propagation only: predecessor edits are not injected into a dependent
agent's worktree, which starts from the captured run base. Use --keep-claims
to leave acquired claims active for debugging.
clean is the default reuse policy, required requires existing clean
worktrees, fresh refuses existing worktrees, and reset moves a clean,
unclaimed stale worktree to the current primary HEAD while refusing dirty,
untracked, or actively claimed worktrees.
Run summaries include command status, duration, timeout state, changed paths,
unclaimed changed paths, captured stdout/stderr summaries, candidate bindings,
and optional patch paths. Each agent's validation_commands sees that agent's
bound candidate state. A validation command that changes Git-visible candidate
state fails validation, even when the command otherwise exits successfully.
--patch-dir writes the already captured per-agent binary patch against the run
base, the primary HEAD captured for that run.
Repo-level validation materializes the exact successful, non-overlapping agent patch set in plan order into a disposable managed worktree based on the captured run base; it never runs against or writes the primary worktree. The summary and checkpoint bind this target to the base object id, combined diff digest, changed paths, candidate count, and patch sizes. Repo validation also fails if it mutates that materialized state. A run with no candidate changes records and validates an explicit base-only target.
Patch and checkpoint output roots are created owner-private when absent. An
existing root must be owned by the current user with mode 0700; output leaves
are 0600, single-link regular files. Roots overlapping a child worktree are
refused, and patch/checkpoint writes retain descriptor capabilities instead of
reopening post-child paths.
maco orchestrate resume <checkpoint-file> treats the external JSON file only
as a bounded repository-locator/reference envelope. Its repository binding and
MAC are verified before the journal run id, plan path, or saved state becomes
authoritative. The owner-private v3 journal lives under the repository common
directory, holds a full-lifecycle exclusive run lock, and uses immutable,
contiguous, previous-MAC-linked records plus an authenticated durable head.
This detects mutation, truncation, duplication, and reordering relative to the
current authenticated head. The guarantee depends on the owner-private state
root remaining secret and being hidden from child processes; without an
external monotonic anchor it cannot detect rollback to an older coherent
record prefix and matching authenticated head under the same key, nor
restoration of an entire older valid key, journal, and head snapshot by an
attacker who obtained them.
Resume also requires the filename, repository, primary HEAD, plan snapshot, and
worktree bindings to match. A command_started record without a durable
completion is an uncertain outcome and is never retried automatically. A
completed command carries an exact worktree-state binding; resume compares the
live state to it, reruns validation, and recaptures the candidate without
rerunning the command. Completed candidates and repo validation are recaptured
and rerun before success is restored. Unauthenticated checkpoint v1/v2 files
are refused with guidance to start a new v3 run.
Collect and preview agent output:
cargo run -- worktree diff agent-a --repo . --json
cargo run -- worktree diff agent-a --repo . --claim src --full-diff --json
cargo run -- orchestrate collect summary.json --repo . --json
cargo run -- merge preview agent-a --repo . --claim src --json
cargo run -- merge preview agent-a --repo . --claim src --validation-report validation.json --json
cargo run -- merge preview agent-a --repo . --claim src --require-validation --validation-report validation.json --json
cargo run -- merge preview agent-a --repo . --claim src/large.c --block-megafiles --jsonEvery CLI apply uses a mandatory three-stage workflow:
- Run
merge preview --jsonwith the source, target, claims, validation evidence, megafile policy, decomposition evidence, and force choices intended for the apply, and redirect the complete JSON output to a file outside the repository. - Have a reviewer with the project's integration authority inspect that entire file. Do not edit, regenerate, truncate, or replace it after review.
- Run
merge applywith the corresponding options and pass either that same unchanged file or a one-field JSON object containing its unchanged nestedfreshness_watermarkthrough--reviewed-watermark. Extraction does not replace or precede the authority review of the complete preview.
For example, validate external evidence, review the complete captured preview, then apply only that reviewed candidate:
REVIEWED_PREVIEW="$(mktemp)"
cargo run -- merge preview agent-a --repo . --claim src \
--validation-report validation.json --json > "$REVIEWED_PREVIEW"
# Stop here for the required authority review of the complete file.
cargo run -- merge apply agent-a --repo . --claim src \
--validation-report validation.json \
--reviewed-watermark "$REVIEWED_PREVIEW" --jsonCandidate validation, merged-lane reaping, megafile decomposition, and force options use the same preview-review-apply sequence. Each example below requires the authority review at the marked stop before its apply command:
REVIEWED_PREVIEW="$(mktemp)"
cargo run -- merge preview agent-a --repo . --claim src \
--require-validation --validation-command "cargo test" --json \
> "$REVIEWED_PREVIEW"
# Stop here for authority review; leave the file unchanged.
cargo run -- merge apply agent-a --repo . --claim src \
--require-validation --validation-command "cargo test" \
--reviewed-watermark "$REVIEWED_PREVIEW" --json
REVIEWED_PREVIEW="$(mktemp)"
cargo run -- merge preview agent-a --repo . --claim src \
--auto-reap-merged --trunk-ref refs/heads/main --apply-auto-reap --json \
> "$REVIEWED_PREVIEW"
# Stop here for authority review; leave the file unchanged.
cargo run -- merge apply agent-a --repo . --claim src \
--auto-reap-merged --trunk-ref refs/heads/main --apply-auto-reap \
--reviewed-watermark "$REVIEWED_PREVIEW" --json
REVIEWED_PREVIEW="$(mktemp)"
cargo run -- merge preview split-large-c --repo . \
--claim src/large.c --claim src/large/ --block-megafiles \
--decomposition-target src/large.c \
--decomposition-run-id issue19-split-large-c --json \
> "$REVIEWED_PREVIEW"
# Stop here for authority review; leave the file unchanged.
cargo run -- merge apply split-large-c --repo . \
--claim src/large.c --claim src/large/ --block-megafiles \
--decomposition-target src/large.c \
--decomposition-run-id issue19-split-large-c \
--reviewed-watermark "$REVIEWED_PREVIEW" --json
REVIEWED_PREVIEW="$(mktemp)"
cargo run -- merge preview agent-a --repo . --claim src \
--force-dirty-primary --force-stale-base --force-unclaimed-edits --json \
> "$REVIEWED_PREVIEW"
# Stop here for authority review; leave the file unchanged.
cargo run -- merge apply agent-a --repo . --claim src \
--force-dirty-primary --force-stale-base --force-unclaimed-edits \
--reviewed-watermark "$REVIEWED_PREVIEW" --jsonThe nested v2 freshness watermark embeds the reviewed target primary HEAD,
index, and worktree state; source agent identity and HEAD; candidate snapshot
and diff; and a SHA-256 identity that binds the complete base preview. The
top-level review_intent, which is included in that base-preview digest, binds
the exact ordered candidate validation commands, the
require-validation-after-command choice, and the lifecycle/reap choices. After
the complete preview receives authority review,
--reviewed-watermark accepts either that unchanged full output or an extracted
one-field object containing its unchanged nested watermark. Apply re-captures
current state only to compare it with that evidence. The recapture is not an
implicit reviewed preview. Missing, malformed, stale, or substituted evidence
is refused before the primary worktree is mutated, including a different
complete preview for an otherwise unchanged candidate. A raw top-level
watermark object is not accepted.
All public Rust direct-apply wrappers fail closed before repository access.
Mutation requires guarded CLI loading of a previously emitted, reviewed full
preview or a one-field object containing its nested freshness_watermark.
The current merge preview --json and merge apply --json producer contracts
are v2. Mandatory exact review binding changes both the wire shape and
accepted behavior, so it is a breaking correction rather than a compatible v1
extension. Review-evidence refusal envelopes carry an unambiguous top-level
version: 2; ordinary matched apply reports remain disjoint and carry their
v2 base preview instead of a top-level refusal version. The v1 merge-preview
and merge-apply schemas remain historical contracts only. Repository-map,
semantic, and supervisor contracts retain their existing documented versions,
while the current evaluation producer emits v3; v1 and v2 remain historical
contracts because closing the contract required breaking changes.
After review evidence is accepted, merge apply still refuses dirty primary
worktrees, stale agent bases, unclaimed edits, validation failures, and apply
conflicts unless the matching explicit force flag is passed. Apply-check failures
themselves are still blocking unless --force-apply-conflicts allows a
successful three-way apply check.
Megafile merge policy is also warn-only by default. safety.megafile_warnings
contains the authenticated threshold assessments without changing readiness.
--block-megafiles makes threshold-crossing changed paths blocking. For CLI
schema compatibility this policy currently reuses the existing
excluded_reference ApplyBlocker; its ApplyBlockerDetail is unambiguous:
the exact paths, a megafile-specific message, available validation
reports/commands, and a megafile_decomposition next-safe operation are
included, while safety.megafile and safety.megafile_warnings carry the
typed assessment. A future dedicated megafile_threshold_exceeded blocker
would require a coordinated versioned update of all exhaustive blocker
consumers.
merge preview never records a collision. During
merge apply --reviewed-watermark <unchanged-preview.json>, after the reviewed
preview is accepted, apply records paths when its direct check detects a
collision, including the direct-check failure that is allowed to continue via a
successful opt-in three-way check. That write uses the authenticated durable
megafile store before a blocked merge decision is returned. An authenticity or
persistence failure aborts the decision and never turns a blocked merge into an
apply.
gate_denial::GateDenial is the versioned public envelope for passing a gate
denial to correction consumers. It carries a typed reason family, derived
retryability, canonical verified owner/path context, a typed GateCheckSource,
a responsible route, and a typed non-executable next-safe operation. The public
source discriminator distinguishes claim acquisition, budget admission, auditor
and future approval review, validation, primary drift, Git apply check, merge
scope, validation binding and state, sandbox policy, containment, primary
integrity, and external side effects without parsing prose. Reason/source
mismatches are rejected by both constructors and validated deserialization.
The public budget-admission reason carries a BudgetAdmissionDenial drawn from
a finite, value-free set: new_dispatch_stopped, missing_cost_estimate,
hard_token_ceiling, or hard_cost_ceiling. Numeric limits, reservations, and
consumption remain in the structured run-budget report instead of becoming part
of the denial's stable identity. Every budget-admission denial is not_retryable,
routes to the child or controller, and derives
NextSafeOperation::ReviewRunBudgetAndStartNewRun
(review_run_budget_and_start_new_run on the serialized surface). A new run
may start only after the budget or scope is corrected.
Sandbox denials carry the existing SandboxDenialEvidence type without a second
schema. Its evidence-level retryability is reporting data, not execution
authority: GateDenial::from_sandbox_denial always fails closed as
not_retryable and escalates sandbox policy. A future retry would require a
separate trusted supervisor-created execution context that this module does not
provide. Containment failure, primary-integrity failure, and ambiguous or
completed external effects are also unconditionally non-retryable.
Merge callers should adapt ApplyBlockerDetail or ApplyBlocker before
flattening anything to prose and must supply the trusted typed source check. The
adapter uses only blocker kind, blocked disposition, failed check status,
source, and canonical paths. Reviewer messages, validation diagnostics,
validation commands, and the legacy free-text next_safe_operation are never
inputs to corrective-prompt rendering.
Routing is explicit and fixed:
| Denial family | Responsible route |
|---|---|
| Pre-launch claim-acquisition conflict | Planner or parent |
| Budget admission | Child or controller |
| Auditor or validation repair | Child or controller |
Merge remediation, including unclaimed_edits |
Integration controller |
The dedicated from_claim_conflict constructor creates the pre-launch
claim-conflict family with its typed narrow-or-replan operation. Merge-phase
ApplyBlocker::UnclaimedEdits is merge remediation and never routes to the
planner/parent.
Containment and sandbox escalation also route to the child/controller. Primary-integrity and external-side-effect reconciliation route to the integration controller. Corrective prompts contain only fixed policy vocabulary plus validated canonical identities and JSON-quoted repository-relative paths.
The stable denial ID is a deterministic SHA-256 identity of envelope version, typed reason, typed source check, and canonical verified context. It deliberately excludes the correction-correlation ID. Issue 28 lifecycle consumers should therefore dedupe the same denied condition by stable denial ID while using the separately validated correction-correlation ID to associate events with one correction attempt. Starting a new correction lifecycle changes the correlation ID, not the stable denial ID; changing the reason, source check, or verified context changes the stable ID.
--decomposition-target never self-authorizes decomposition work. It must be
paired with --decomposition-run-id naming a verified finalized supervise
artifact. That run must be real/publishable and accepted successful, and its
accepted O1 id must equal the merge candidate agent id. The exact candidate,
supervisor, O1, and successful typed worker files_changed sets must all equal
the target plus the completion's normalized non-empty replacement_paths.
The worker completion must match the accepted child aggregation and supervisor
final decomposition_candidates, while the parent-launched accepted read-only
auditor must cover the worker and every candidate path. This reuses the
authenticated finalized artifact reader; an arbitrary JSON report, unfinished
run directory, fake run, bare target, mismatched agent, or unrelated extra edit
is rejected.
The worker and child cannot self-assert the content identity. After path, journal, and diff inspection, the supervisor uses the isolated two-matching candidate snapshot gate to derive the full candidate validation binding (primary HEAD, agent HEAD, merge base, agent id, and raw-diff object id), writes that binding into the normalized completion evidence before launching the parent auditor, and re-captures it after the auditor. A missing capture or any content, path, or base change across that review fails the run before finalization.
Merge independently re-captures the current candidate under the same isolated
two-matching snapshot gate and requires its full canonical binding to equal the
supervisor-derived binding in the authenticated finalized run. Thus changing
target or replacement bytes after review is rejected even when the exact path
set and run id are reused. The exact target must also be modified smaller than
its primary candidate base or deleted. Every evidence-bound replacement must
be a new regular file absent from that base and non-empty in the candidate.
Only those evidence-bound replacement paths are recorded; ordinary changed
paths cannot be relabeled as decomposition output. The target also must be the
exact authenticated threshold-crossing path and have an exact (not merely
ancestor) path claim. All ordinary dirty-primary, stale-base, claim,
validation, review, and apply gates remain in force; verified evidence bypasses
only its target's opt-in megafile policy blocker. An
accepted_decomposition history event is written only after the primary patch
was successfully applied. A blocked/failed/no-op candidate cannot create it.
If the post-apply authenticated write fails, the command reports that the merge
was already applied and must not be retried blindly. The accepted event starts
a new activity/size epoch; run a later explicit seed to establish the new file
size baseline.
When an apply check reports overlapping paths, both commands add
safety.semantic_conflicts to the existing JSON report. The parser-backed Rust
map identifies touched symbols, impls, modules, imports, and signature changes;
the existing semantic risk query supplies dependency impacts and impacted
files. Import-only and conservative formatting-only overlaps are low risk.
advisory=true means this classification never changes readiness or force
behavior. degraded, confidence, and notes expose unsupported paths, parse
errors, or bounded truncation instead of presenting an unresolved overlap as a
confident classification.
Validation failures are considered when validation reports are supplied from
collected run summaries or from direct --validation-report JSON files.
External validation JSON may be a single report, an array, an object with
validation,
validations, or reports, or an orchestration summary with per-agent
validation. Those legacy forms remain useful as advisory evidence, but they are
unbound and do not satisfy --require-validation. Required external
evidence must use an envelope whose validation_binding is copied verbatim
from the current preview and whose reports contains a passed report:
{
"validation_binding": {
"version": 1,
"agent_id": "agent-a",
"primary_head": "<40-character object id or null>",
"agent_head": "<40-character object id or null>",
"merge_base": "<40-character object id or null>",
"diff_oid": "<40-character object id>"
},
"reports": [
{ "name": "cargo test", "status": "passed", "paths": ["src"] }
]
}For merge preview, copy candidate.validation_binding; for pr preview,
copy preview.candidate.validation_binding. Any candidate, HEAD, base, or diff
change invalidates that envelope. --require-validation also blocks when
validation evidence is missing, only not_run, only skipped, or failed
without a bound passed report. JSON readiness details distinguish validation_missing,
validation_not_run, validation_skipped, and validation_failed, include
related paths when available, and report the next safe operation.
After the exact preview is authority-reviewed and supplied with
--reviewed-watermark, merge apply --validation-command <command> creates an
independent standalone temporary repository for each command. It materializes
the reviewed base through a private Git directory and controlled object
alternate, applies the agent diff, and runs the command there before applying
anything to the primary worktree. A failed command blocks the apply. A
successful command is also
rejected if it changes the candidate's HEAD, index, tracked files,
non-ignored untracked files, or recursive submodule state. For an initialized
submodule, checking records the .git marker identity plus the recursive
repository fingerprint, so ignored build output is outside the comparison. For
an uninitialized submodule, a bounded raw-path fallback detects initialization,
marker removal, or checkout deletion. That fallback fails closed if it exceeds
8,192 entries, 64 MiB total content, or 16 MiB for one file. Candidate capture
uses the same entry, total-content, and single-file limits before it writes new
temporary objects; Git stdin and output are bounded separately and an exceeded
limit fails closed. The tool does not initialize or fetch submodules during this
check. Repository-index fingerprints likewise use a 64 MiB no-follow bounded
read and require a stable real regular file owned by the current user, with one
link and no group/world write permission.
The races addressed by the merge and publication boundary are concrete: a
candidate can change while validation runs, another local process can start a
merge or publication, a branch can move between preview and push, and GitHub can
create a pull request even when the local gh process loses its response.
Ambient Git repository, config, trace, filter, and temporary-directory variables
can also redirect an otherwise read-only command. Candidate capture therefore
uses a private Git directory, private index, private object directory, and a
verified alternate to the repository's object database. It does not read the
real repository's local or worktree config, global config, info/attributes, or
info/exclude; external clean/process filters, external diff drivers, textconv,
hooks, and the ext transport are unavailable in that context. Worktree
.gitattributes and .gitignore still apply when their behavior does not depend
on omitted private config. This deliberately excludes repository-local and
global ignore/attribute rules from candidate meaning; move any review-relevant
rule into the tracked worktree files.
Temporary state uses an owner-only runtime below /run/user/<uid> or a 0700
child of the canonical root-owned sticky temporary directory. This also handles
Darwin's usual /tmp symlink by validating its canonical target. Candidate
capture, candidate validation, publication Git, and private gh directories
carry a versioned 0600 owner record with PID, process-start identity, Linux
boot identity, creation time, kind, and a name-bound nonce. A persistent,
single-link runtime-root lock serializes bounded scanning, reservation
publication, and normal cleanup without unlinking the lock inode. After a crash,
the next entry reclaims only a dead or PID-reused owner whose record and file
identity still match. Interrupted reservations at each owner-record publication
stage are recognizable under that lock. Corrupt, foreign, symlinked, or
unverifiable entries are retained per directory and counted diagnostically;
they do not authorize deletion or turn one entry into a global scan failure.
The scan and deletion walks have direct-directory, entry, and depth limits.
On Unix, cleanup stays anchored to no-follow directory descriptors and uses
fstatat/unlinkat, refuses a device transition before descending, and never
follows a symlink or hard link outside the managed directory. Platforms without
that handle-relative cleanup backend refuse private temporary-context creation;
Windows therefore fails closed before creating one rather than relying on a
verify-then-path-delete sequence.
Internal git and gh commands resolve only through the fixed
/run/current-system/sw/bin, /usr/bin, or /bin entries, then verify the
canonical executable and its ancestors are root-owned and non-writable. An
arbitrary PATH entry is never a candidate, including a directly named
immutable Nix store output whose build provenance is not established. User Nix
profiles and Homebrew therefore fail closed at this boundary.
Every merge validation, local Git, network Git, and gh child has a finite total
deadline, bounded stdin/output, and required process-tree containment. Success is
accepted only after the runner proves its owned process tree empty. On Linux this
requires a trusted user systemd manager and cgroup v2; Windows uses a Job Object,
but trusted Windows Git/gh executable and ACL resolution is not implemented,
so Git-dependent paths still fail closed there. Required containment currently
has no strict Darwin backend, so Git-dependent merge/publication paths fail
closed on Darwin rather than silently using process-group compatibility. These
controls prevent a completed command from leaving a delayed child. They do not
make a trusted validation command an adversarial filesystem sandbox while it is
running.
Safety-sensitive crate-internal direct launches can additionally bind the
entry executable before the systemd start gate opens. That opt-in path records
the source device, inode, mode, length, and SHA-256 digest; authenticates the
bounded launch descriptor against the digest fixed in the transient unit's
argument vector; copies the verified image into a sealed Linux memory file; and
executes the sealed descriptor instead of reopening the source pathname. Script
launches pin and seal both the script and its native shebang interpreter.
Dispatcher shebangs such as env/env -S, native loader hooks, and common
shell/language startup hooks are refused. Bootstrap requires the currently running
maco executable and every path ancestor to be root-owned and non-writable to
the invoking user, so cargo run, development outputs, and user-local installs
fail closed for this authority. Ordinary shell and direct commands do not opt in
and retain their existing behavior. This pins the entry images, not their
dynamic-library or language-module dependency closure.
Candidate validation additionally starts from a cleared environment with a fixed
root-owned system PATH, private HOME, TMP*, and XDG directories, and an
empty private global Git config. Shell startup hooks, provider credentials,
proxy/custom-CA routing, SSH-agent state, and ambient user configuration are not
inherited. Captured validation diagnostics are bounded and redact registered
credential, authentication, cookie/session, proxy/CA, and shell-startup values
before they enter a validation report.
Merge apply with the required reviewed preview evidence and PR publication share
a kernel-managed advisory lock on the stable repo-common file
.git/maco/state/repository-mutation.lock. The file is not deleted when the
operation finishes; closing or crashing the process releases the kernel lock.
Its typed owner record contains the operation, PID, process-start identity when
available, nonce, and creation time for diagnostics. The owner record does not
decide whether the lock is live. A locked malformed record is refused, while an
unlocked stale record is replaced by the next lock holder.
Validation evidence remains bound to the exact candidate snapshot described
above. Git and GitHub publication use a unique OID-derived remote ref and push
the reviewed lowercase object ID with a create-only lease. External publication
accepts only a bounded, canonical https://host/repository/path(.git) origin;
GitHub identities and selectors are stored and checked as exact canonical
host/owner/repository values.
HTTP, SSH, SCP, Git helpers, URL userinfo, query/fragment credentials, escapes,
and relative paths are refused. Local and file:// bare remotes also fail
closed: a concurrent same-UID process could otherwise alter the remote config
during receive-pack, after preflight but before a hook or helper decision.
Network Git runs against a private bare context. The real repo-common
maco/state, primary/source worktrees, repo-common object database, and sibling
runtimes are masked. An observation-only ls-remote context has an empty object
database. Before a push, trusted offline code walks the exact reachable closure
of the reviewed commit and copies only those commit, tree, and blob objects into
the private object database. The walk has object-count, aggregate-byte, commit-
and tree-depth bounds; rejects self/duplicate parents and commit cycles; and
does not traverse gitlinks into another repository. The private database is
rewalked and enumerated to prove that it contains the same closure, no extra
object, and no Git/http alternate before it is exposed read-only to the network
child. Source stores containing Git/http alternates, promisor metadata, or
partial-clone configuration are refused before materialization. The child receives a
cleared, exact environment and a fixed trusted git; proxy, custom CA, askpass,
credential helpers, tracing, HOME, SSH-agent, and ambient Git config inputs are
absent. On Linux the effective unit must prove PrivateNetwork=no, exactly
AF_INET AF_INET6, bounded resources, exact mounts, and masked same-user IPC
sockets. Other platforms fail closed until an equivalent verified backend
exists.
HTTPS authentication is token-only. github.com accepts no explicit port or
canonical :443 (which is normalized away), and accepts GH_TOKEN or
GITHUB_TOKEN. Any enterprise authority, including a non-default port or a
localhost/private endpoint, must first be explicitly allowlisted by an exact
canonical GH_HOST or GITHUB_HOST value; an unapproved authority is rejected
before any token variable is read. An approved enterprise authority accepts
GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN. If both permitted host or
token variables are present they must be identical. The token is never placed
in argv, the child environment, reports, or journals. A private 0600 config binds Authorization: Basic base64("x-access-token:" + token) to the exact canonical repository URL,
requires TLS verification, disables redirects, proxies, askpass, and credential
helpers, and is rebound read-only. Its path/open-file identity, owner, mode,
single-link count, bounded exact bytes, and containing runtime identity are
checked immediately before and after every command. Raw and encoded token forms
are redacted from bounded output. On normal success and ordinary error returns,
config erasure is an explicit fallible step: the same inode is overwritten,
synced, reread as zero bytes, and only then is the private runtime closed; token
and remote-binding scratch buffers are also cleared before release. A process
crash cannot promise memory or file overwriting, so any residue remains in an
owner-only runtime with a PID/process-start/boot-bound owner record and is
handled by the bounded dead-owner scavenger on the next private-runtime entry.
GitHub publication requires an explicit expected creator login in
GH_EXPECTED_AUTHOR or GITHUB_EXPECTED_AUTHOR before token selection; bot
logins such as release-bot[bot] are accepted when named exactly. Each
source-backed external effect derives a stable SHA-256 identity from its effect
transport provider (git or github), source provider, exact host-qualified
repository, source action revision, and operation; source-less
effects additionally bind their exact target and payload. The PR branch and
hidden version-2 maco-external-effect marker are deterministically derived
from that identity;
run IDs, agent IDs, attempts, and random values do not affect them. Publication
observes the remote head and exact base OIDs before PR creation, reads the
resulting PR with gh pr view, and requires exact title, marker-bound body,
creator login, headRefOid, baseRefOid, head/base branch, same head-repository
owner/name, isCrossRepository=false, open state, and draft/ready value before persisting
any PR receipt fields or advancing the receipt phase. A PR already present for
the unique branch before this transaction records a create attempt is treated
as a front-run and rejected. After a recorded create attempt, crash/lost-response
reconciliation adopts only a receipt satisfying the same hidden marker and all
of those provenance fields.
The HTTPS origin is also parsed into a bound host/owner/repository identity.
Every gh pr and gh issue call receives that explicit host-qualified
--repo;
gh receives a private 0600 hosts.yml and an explicit environment allowlist
containing only OS/locale essentials, fixed PATH, GH_CONFIG_DIR, and disabled
prompts; token variables are not inherited. HOME, Git config, proxy, custom CA,
ambient repository, debug, pager, and forced-TTY routing are absent. Its current
directory is that private config runtime, while repo state and source/primary
worktrees are masked. Config identity and bytes are rechecked around every
allowlisted PR/issue subcommand. The receipt URL must identify the same bound
repository and exact PR or issue number.
Publication observes the remote head and base again after that receipt. A
mismatch is reported as blocked rather than published.
Git pushes, GitHub PRs, GitHub issues, and inbox source comments use an
authenticated repository-local effect WAL with planned, started,
observed, and completed phases. started is durable immediately before the
provider call. Recovery from started performs lookup only and proceeds only
for exactly one marker-bound receipt; zero, multiple, or failed lookups require
manual reconciliation and never resend. observed and completed receipts are
re-fetched and checked against the exact repository, object ID, URL, operation,
marker, target, payload, and provider-specific provenance; source-backed effects
also bind the source provider, canonical host, repository selector, and source
action revision separately from the effect transport. A deleted, closed, or
mutated remote object therefore blocks without another provider call.
Immediately before a new effect, the complete source freshness snapshot must
still match. After a source comment changes volatile updatedAt, recovery uses
the stable action revision so the comment can be adopted without weakening
title/body/label/head/base checks. Comment discovery reads every bounded REST
page and then exact-views each marker candidate; truncation or bounds failure is
fail closed.
The effect WAL bounds each record and enforces finite namespace-wide logical store, root-entry, and retained-journal quotas. It deliberately performs no automatic garbage collection or retry of exactly-once effects. Reaching capacity fails closed. Any operator-managed archival or recovery must preserve the authenticated receipt evidence; deleting that evidence can forfeit the exactly-once guarantee.
The new path does not create plaintext records under
.git/maco/state/publication-transactions/. If any legacy plaintext publication
journal entry exists, publication stops with an explicit signed-migration
requirement and neither adopts, signs, overwrites, nor deletes it. This is an
intentional seam for a future migration command. The JSON
publication_receipt remains a public summary of the verified remote result;
the authenticated effect WAL is the recovery authority.
These checks do not make Git hosting operations globally atomic. Another actor
can still move or delete a remote object after a completed re-verification. A
later run detects that change and blocks rather than recreating the effect. The
repo-common lock coordinates this tool's local operations only, and journal
durability still depends on the underlying filesystem. Managed paths reject
pre-existing symlinks (and Windows reparse points), but path-based checks do not
claim protection from a hostile same-user process replacing components during
the check; this boundary coordinates non-adversarial concurrent local actors.
Even with the required reviewed preview evidence,
merge apply --reviewed-watermark <unchanged-preview.json> does not run project
checks after a successful primary apply, so release managers should run final
verification after accepting changes. With --json, a blocked apply emits a
machine-readable report with readiness blockers, blocker details, and related
paths before exiting with an error.
Preview and publish agent worktree changes as a pull request:
cargo run -- pr preview agent-a --repo . --claim README.md --json
cargo run -- pr preview agent-a --repo . --claim README.md --require-validation --validation-report validation.json --json
cargo run -- pr publish agent-a --repo . --claim README.md --forge fake --json
cargo run -- pr publish agent-a --repo . --claim README.md --forge fake --require-validation --validation-report validation.json --json
cargo run -- pr publish agent-a --repo . --claim README.md --forge github --ready --json
cargo run -- pr preview --from-branch task/docs --repo . --json
cargo run -- pr publish --from-branch task/docs --repo . --forge fake --require-validation --validation-report validation.json --json
cargo run -- pr publish --from-branch task/docs --squash-onto main --exclude .agents --repo . --forge fake --jsonmaco pr preview uses the same merge-preview gates as merge apply and never
pushes or creates a pull request.
maco pr publish --forge fake|github refuses dirty-primary, stale-base,
unclaimed-edit, validation, and apply-check blockers.
maco pr preview|publish --from-branch <task-branch> uses the same gates for a
committed primary task branch instead of a managed agent worktree. When
--claim is omitted in branch mode, all changed paths in the branch candidate
are treated as the reviewed publication scope; pass --claim to keep the
unclaimed-edit gate narrow.
An existing same-repository GitHub PR can instead receive an explicit update
from a committed task branch. This path does not run from Inbox, create another
PR, merge, or post a comment. The task branch commit C must descend from the
exact observed PR head B; the primary checkout may be at a different commit.
Candidates changing private .agents or .agent context, managed-worktree
stores, or repository runtime paths anywhere in their new commit history are
refused because this command updates the remote branch without an exclusion step.
Place a version-1 operator grant in an owned, non-symlink regular file outside
the repository (Unix only). Its complete JSON shape is:
{
"version": 1,
"repository": {
"provider_id": "github",
"canonical_locator": "github.com/owner/repo",
"provider_repository_id": {"provider_id": "github", "kind": "repository", "stable_id": "node:sha256:<sha256 of raw repository node_id>"}
},
"pull_request_number": 123,
"pull_request_id": {"provider_id": "github", "kind": "item", "stable_id": "node:sha256:<sha256 of raw PR node_id>"},
"head_ref": "refs/heads/original-pr-branch",
"expected_head_oid": "<40-character lowercase B>",
"base_ref": "refs/heads/main",
"expected_base_oid": "<40-character lowercase observed base>",
"candidate_oid": "<40-character lowercase C>",
"approved_actor_id": {"provider_id": "github", "kind": "actor", "stable_id": "node:sha256:<sha256 of raw user node_id>"},
"approved_actor_login": "approved-login"
}The node:sha256: values are the lowercase SHA-256 of the raw GitHub node
ID bytes, not the node ID itself or a Git commit ID. Obtain the repository,
PR, and authenticated user node_id fields through independently authorized
GitHub observation; the grant must not be generated from child plans or Inbox
feedback. The operator also pins agentFiles.approvedGitHubLogin in the
repository's Git config, and the authenticated account must match both pins.
Supply current base/head refs and OIDs from that same PR. The grant is exact
per candidate and per invocation; changing it requires a fresh preview and
validation.
maco pr preview-update --repo . --from-branch task/fix --grant-file /private/pr-update.json --json
maco pr update-existing --repo . --from-branch task/fix --grant-file /private/pr-update.json --validation-report /private/validation.json --json
preview-update is local and read-only. Copy its
candidate_validation_binding into the validation envelope's
validation_binding field, with at least one independently passed report in
reports as shown above. update-existing rechecks that exact B-to-C binding,
the full grant bytes, canonical origin, approved actor, PR/node/ref/base/head,
and remote ref before an authenticated write-ahead record permits one
nonempty-old-OID compare-and-swap push. It reports success only after both the
same PR and remote ref independently read back at C. A lost response or crash
is reconciled from the authenticated record; an ambiguous started update never
blindly retries the push. A changed PR, ref, actor, base, or remote head is a
refusal requiring a new operator decision. A corrected explicit grant or
validation can follow a pre-start refusal while every earlier authenticated
effect remains Planned; any earlier Started effect at the same original head
must first reconcile its exact plan and cannot be replaced by a new plan.
--squash-onto <base> builds a deterministic import commit whose parent is the
named local base branch and whose tree is the task branch snapshot, so PR
publication works even when the task branch and base branch have disjoint
history. --exclude <path> removes repository-local agent context from that
published snapshot. Publication refuses with an excluded_reference blocker if
the remaining tree still refers to an excluded path, for example from
Cargo.toml or a Rust mod declaration.
With --require-validation, use this exact two-stage workflow:
- Commit the candidate in the agent worktree and leave it clean.
- Run
maco pr preview ... --jsonand validate that exact committed snapshot. - Copy
preview.candidate.validation_bindingverbatim into the envelope shown above and add the passed validation report. - Run
maco pr publish ... --require-validation --validation-report <envelope>.
Required worktree publication never creates an internal commit, because doing so
would change the binding after review. A dirty required worktree candidate is
blocked with the commit -> preview -> validate -> publish recovery sequence.
Branch --squash-onto and --exclude previews build the same deterministic
import commit that publish will recheck, so the validation binding remains
stable across the two-stage flow. Without --require-validation, publish may
commit safe uncommitted changes in the agent worktree only, but it re-previews
the clean commit and checks it again immediately before external publication.
The fake forge returns deterministic
fake://pr/... URLs and never uses the network. GitHub publication runs only
when --forge github is passed and shells out to local git and gh using the
transaction and verification sequence above.
Preview and create issues:
cargo run -- issue preview --title "Bug title" --body "API_TOKEN=secret" --json
cargo run -- issue preview --title "Bug title" --body-file issue.md --forge github --json
cargo run -- issue create --title "Bug title" --body-file issue.md --label bug --forge fake --json
cargo run -- issue create --title "Bug title" --body-file issue.md --label bug --forge github --jsonmaco issue preview redacts secret-looking body assignments and reports
created=false. maco issue create --forge fake|github uses the deterministic
local-only fake forge or, with explicit --forge github, shells out to
gh issue create through the same contained, allowlisted process boundary.
Issue triage is intentionally minimal: title, body, and labels. Unlike PR
publication, issue creation does not yet have a write-ahead receipt or retry
reconciliation protocol; if the remote creates an issue but the response is
lost, an operator retry can duplicate it. Treat an ambiguous issue-create result
as a manual reconciliation point.
Inspect and refresh live work claims:
cargo run -- live status --repo . --json
cargo run -- live validate --repo . --json
cargo run -- live apply ../claim-drafts/claim-id.md --repo . --by owner-id --json
cargo run -- live heartbeat claim-id --repo . --by owner-id --json
cargo run -- live release claim-id --repo . --by owner-id --status done --reason "claim completed" --json
cargo run -- live override-release claim-id --repo . --by project-owner --reason "stale claim owner unavailable" --jsonmaco live status reports each claim's owner, status, owned files, lock state,
and liveness. active and blocked claims are treated as locks. A claim is
stale when its heartbeat, updated timestamp, or date fallback is older than its
configured stale-after window. maco live validate reports missing or malformed
claim fields. The existing claim directory is bound without changing its
permissions. It accepts at most 256 entries: canonical .md claim files plus
the optional CLAIM_TEMPLATE.md and empty .maco-live-claims.lock control
files. Every entry is read without following links, with a 64 KiB per-file
limit, strict UTF-8 and bounded filename, line, field, timestamp, owner, path,
and item-count grammar. Links, hard links, special files, nested directories,
unsupported extras, and any invalid claim make the board fail closed.
All reads and mutations hold the same stable board lock and compare the sorted
entry names plus each entry's identity and bytes before accepting a snapshot.
Component-aware ancestor/equality overlap between active or blocked owned
paths is a board validation error. Canonical crash residue from the atomic
claim writer is scavenged under that lock; unknown or malformed residue is
left in place and refused for manual inspection.
Supported owner mutation flows are apply, heartbeat, and release.
apply is create-only: an existing claim ID is always refused, including after
that claim reaches a terminal state. Change scope by releasing or handing off
the prior claim, then submit a new claim ID. A draft must describe a fresh
active initial generation with one matching Claim header and Claim ID, an
owner exactly matching --by, equal canonical UTC Created, Updated, and
Heartbeat values no more than five minutes old, and no pre-existing audit
log. Old, future, terminal-state, and audit-replay drafts fail closed.
The draft parent and leaf are bounded and opened through a no-follow parent
descriptor. Their identity and content are rebound to the same observation as
the claim board; drafts inside or aliasing the board, hard links to board
entries, and ancestor-link replacement are refused. The proposed whole board
must remain valid and free of active path overlap. heartbeat is limited to
active or blocked claims and requires --by to exactly match the recorded
owner. override-release is also limited to those states and requires a claim
that is provably stale; a fresh, future-dated, or otherwise unknown liveness
result is refused. Its required --by value is an audited actor label, not an
authentication credential, and --reason is bounded and rejects
control-character injection. release requires the exact recorded owner and
moves the claim to done or handoff; override-release is the audited
stale-claim administrative exception.
Supported API operations coordinate through the stable board lock. On Linux,
create uses renameat2(RENAME_NOREPLACE) and existing-claim mutations prefer
an exchange CAS that checks the exchanged old inode and bytes and rolls back a
refused generation. Filesystems that specifically report exchange as
unsupported use a recoverable no-replace transaction instead: the old and new
identities, content digests, and unchanged whole-board generation are bound into
an old-generation residue, and the next lock-held board open rolls back or
finalizes only an exact known crash state. Other exchange failures remain
fail-closed. Direct edits below .agents/live/claims/ are unsupported: the lock
and CAS narrow cooperating API races, but do not claim complete exclusion or
detection of a non-cooperating same-UID process holding and editing a file
descriptor across the operation. Audit growth is compacted into a bounded
digest entry, and heartbeat writes reserve release headroom. Mutation timestamps
always use the process's real system clock and refuse future/rollback heartbeat
generations; public --now injection is available only for the observational
status and validate commands.
Preview the local LLM boundary without credentials or network access:
cargo run -- llm providers --json
cargo run -- llm prompt-preview task.md --agent-id agent-a --path src/lib.rs --repo . --jsonRun a deterministic local fake-provider proposal in an isolated worktree:
{
"summary": "update README",
"commands": [
{
"command": "printf '# Updated\\n' > README.md",
"working_directory": null,
"purpose": "implement"
}
],
"patches": [],
"notes": []
}cargo run -- agent run task.md --agent-id agent-a --path README.md --fake-proposal proposal.json --validation "cargo test" --repo . --jsonThe retained agent runner accepts only the local fake provider and executes
in an isolated managed worktree after deriving the capability-bound
repository-cleanliness input. Other provider names are refused. It renders
the same provider-neutral prompt boundary used by llm prompt-preview.
Provider-proposed shell commands are disabled by default: the command above
reports a refusal for the proposed printf command and tells you to rerun with
--allow-provider-commands if you trust the proposal. Patch-only fake proposals
can run without that opt-in. When command execution is explicitly allowed,
the retained agent runner applies fake-provider proposed patches and commands inside the
agent worktree, runs provider-proposed and CLI-supplied validation commands,
collects a merge candidate and preview, reports path-boundary violations, and
releases durable claims unless --keep-claims is supplied. Real network
providers remain unconfigured by default.
cargo run -- agent run task.md --agent-id agent-a --path README.md --fake-proposal proposal.json --allow-provider-commands --validation "cargo test" --repo . --jsonRun an opt-in supervisor-of-orchestrators plan:
# goal.md
- Update the README examples.
- Update `src/cli.rs` and the `PlanSuperviseArgs` contract.
- Add focused coverage in `tests/supervise_cli.rs`.{
"version": 1,
"task": "coordinate README and Rust follow-up work",
"max_depth": 2,
"max_child_assignments": 2,
"max_child_retries": 0,
"child_timeout_seconds": 600,
"assignments": [
{
"id": "docs-child",
"phase": "execution",
"assigned_paths": ["README.md"],
"worker_assignments": [
{
"id": "docs-worker",
"assigned_paths": ["README.md"]
}
]
},
{
"id": "rust-child",
"phase": "execution",
"assigned_paths": ["src/lib.rs"],
"semantic_symbols": ["WorktreeManager"],
"worker_assignments": [
{
"id": "rust-worker",
"assigned_paths": ["src/lib.rs"],
"semantic_symbols": ["WorktreeManager"]
}
]
}
]
}# Explicitly decompose a high-level goal/spec:
cargo run -- supervise plan --from-goal goal.md --repo . --json
# Preserve the positional form for either plain-text tasks or authored JSON plans:
cargo run -- supervise plan supervisor-plan.json --repo . --json
# Selects the default Codex runtime and uses native workspace-write in managed worktrees:
cargo run -- supervise run supervisor-plan.json --repo . --run-id supervise-demo \
--codex-bin codex \
--quota-config config/operator-quota.json \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --json
# Operator role-category override recorded as selection_source=operator_override:
cargo run -- supervise run supervisor-plan.json --repo . --run-id supervise-role \
--runtime fake --role-category non_delegating_terminal_worker \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --json
# Decompose the goal and execute that same validated plan through the live gates:
cargo run -- supervise run --from-goal goal.md --repo . \
--run-id supervise-goal-demo --runtime codex --codex-bin codex \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --json
# Explicit serial opt-out:
cargo run -- supervise run supervisor-plan.json --repo . --run-id supervise-serial \
--codex-bin codex --max-concurrent-children 1 \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --json
cargo run -- supervise status supervise-demo --repo . --json
cargo run -- supervise collect supervise-demo --repo . --json
cargo run -- supervise artifacts latest --repo . --jsonMachine consumers of supervise collect should resolve the exact Draft
2020-12 contract from its schema field. Version 1 currently identifies
schemas/supervisor-collect-report-v1.schema.json; the newly finalized report
contract remains schemas/supervisor-final-report-v1.schema.json. Both tracked
supervisor contracts are compared as complete JSON values against the Rust
generator, and the final-report contract denies unknown properties recursively
through command, gate, follow-up, traceability, breaker, review-report, claim,
and semantic-intent records.
supervise plan and supervise run each require exactly one input source. The
positional TASK_FILE keeps its existing contract: valid JSON is normalized as
an authored supervisor plan, and other UTF-8 text is treated as a task
specification.
--from-goal <FILE> is mutually exclusive with the positional input and always
treats the bounded UTF-8 file as a high-level goal/spec, even if its contents
happen to be valid JSON.
supervise run accepts optional --role-category. Omitted
keeps automatic selection derived from the plan role. When set, the CLI stamps
every assignment and nested worker_assignments entry with that category and
selection_source=operator_override before launch. Accepted values are
delegating_coordinator, non_delegating_terminal_worker,
read_only_researcher, and read_only_review_auditor (hyphen aliases are
accepted). Unknown names fail at argument parsing, before repository access.
Resume of an existing supervise run refuses --role-category; the frozen
categories from the original launch remain in force. The override does not
bypass role-authority admission: a weak-model coordinator remains a typed
refusal.
supervise run persists launch preflight evidence under
preflight/ (git status, repository map, sync status, and in-process runtime
probe outcomes, each with an explicit success/failure marker). It also appends
an operator heartbeat ledger at liveness/heartbeat.jsonl and writes
SUMMARY.md at finalization. A second launch targeting the same repository
refuses while another live supervise or autopilot process is still registered;
stale leftover records are reported without blocking. --force-live-run is
launch-only and does not authorize killing, interrupting, reverting, or
discarding another run.
Managed child worktrees remain the default. An authored plan can opt one
assignment into the existing primary checkout only by declaring an exact-file
scope and the operator separately passing --allow-primary-worktree:
{
"version": 1,
"task": "update one local deployment file",
"max_child_retries": 0,
"max_gate_corrections": 0,
"execution_target": {
"kind": "primary_worktree",
"claim_paths": ["local/deploy.txt"]
},
"assignments": [{
"id": "local-deploy",
"phase": "execution",
"assigned_paths": ["local/deploy.txt"],
"worker_assignments": []
}]
}cargo run -- supervise run primary-plan.json --repo . \
--run-id bounded-primary-deploy --allow-primary-worktree \
--codex-bin codex \
--machine-global-config /exact/path/to/machine-global.json \
--machine-global-runtime-root-id runtime --jsonThe declaration and flag are a double opt-in; either one without the other is
refused before run artifacts or claims are created. This deliberately small
mode accepts one assignment, 1-16 disjoint exact files below a top-level
directory, an aggregate snapshot of at most 1 MiB, and an exact match between
claim_paths and assigned_paths. It rejects . and top-level scopes,
directories, symlinks, missing parent directories, .git overlap, retries,
gate corrections, generated follow-ups, evidence-only re-audit, licensed
breakage, and decomposition evidence.
The supervisor acquires the ordinary durable path claim before checking the
scope and holds it through child execution and parent audit. Git-visible dirty
state in a declared file is refused even with --allow-dirty-primary; an
existing ignored/local-only file is permitted only after its exact bytes and
mode are captured as the baseline. During and after the run, changes to HEAD,
the index, or any path outside the exact declared files fail integrity gates.
Claims are released on success and failure. Supervisor-owned findings in both
the child report and final report state primary_worktree intent and list the
declared scope, and accepted changes already reside in the primary checkout—no
managed-worktree merge step exists.
This opt-in does not relax the existing external-Codex containment, machine-global retention, primary-target pre-action review, or acceptance gates. In particular, the primary-writable coverage gate still refuses release when no universal blocking callback exists; managed-worktree native workspace-write admission does not authorize this mode. The fake runtime does not execute a primary-worktree target.
Goal/spec planning fragments the source and emits one nested subtree per
disjoint workstream: a depth-2 read-only planning root followed by a depth-3
execution child with a real parent_assignment_id. Generated execution children
are direct, non-delegating MACO Worker assignments with no nested
worker_assignments; the MACO parent schedules them through the existing terminal
worker execution and review path. Every normalized assignment
carries a required typed phase; schedule identity and flattened index are
validated before that authority is consumed at launch. Every recursive
assignment must declare planning or execution. Omitted, mixed
present/absent, null, and unknown phases are rejected rather than inheriting
writable execution authority. The execution child keeps
the proposed assigned_paths and any parser-backed Rust
semantic_symbols and semantic_modules. These are proposed path claims and
semantic intents; supervise run still acquires and enforces the authoritative
runtime claims. Fragments whose scopes overlap are coalesced, and the complete
proposal is checked for cross-subtree path, module, and symbol disjointness
before the validated plan is emitted or any child can launch.
Exact Rust symbol matches take precedence over broader module-file and module
declaration matches. This keeps a shared module root or other large declaration
file from transitively coalescing otherwise independent implementation files.
Assignments that genuinely edit different symbols in the same file still
coalesce: writable ownership and merge validation are file-granular, so
sub-file ownership would not be a sound concurrency boundary. Authored plans
that set max_child_assignments to 1 while one assignment contains multiple
independent path or worker scopes emit a
planning_width_pinned_to_one validation warning; the structured warning is
also available from the planning API for run-report telemetry.
Library callers may opt into provider-backed proposal through
propose_task_decomposition_with_optional_provider. With no provider, that API
uses the same deterministic heuristic planner described above. With a provider,
the response must be a recursive ProviderRecursiveTaskPlan (or a flat
ProviderTaskPlan, accepted as a forest of leaves) JSON object in the existing
provider-neutral WorkProposal.summary; commands and patches are rejected.
Deterministic validation is authoritative: inventoried file paths, fragment
coverage, depth/width bounds, exact internal-node fragment unions, concurrent
branch disjointness, and completed-scope protection are checked before a
proposal is accepted. A TaskPlanningSession can feed completed/failed
assignments, coverage gaps, and bounded notes into at most two provider re-plan
attempts. Invalid responses and failed provider calls count against that cap.
Validated sessions lower through
supervisor_plan_from_task_planning_session and can be bound to one future
authenticated supervise run for feedback re-planning. Internal provider tree nodes
remain read-only planning assignments; provider leaves become direct terminal
Worker assignments with their original scope and schedule identity. Explicit
user-authored plans retain their declared roles and nested workers. The local
FakeProvider exercises this boundary; no network provider is configured or selected by
supervise, so the CLI remains heuristic/offline by default.
The emitted document is directly usable as a supervisor plan and preserves
lowering traceability through top-level spec_fragment_ids, per-assignment
spec_fragment_ids, and assignment_schedule. Unmatched fragments appear as
coverage_gaps instead of disappearing. After execution, the final report's
assignment_traceability connects those fragments and assignments to produced
changed paths and candidate diff bindings; missing reports, no-change results,
and missing diff bindings add runtime coverage gaps.
Depth is plan data. Authored plans may use recursive child_assignments up to
their configured max_depth (currently 2 through 32), and normalization records
each assignment's parent_assignment_id, depth, and flattened index. The
scheduler validates that graph in parent-before-child order and admits a
descendant only after its parent has produced an accepted successful outcome
and released its assignment resources. A failed parent suppresses its
descendants transitively without stopping unrelated roots. Every node that is
actually admitted follows the ordinary assignment path: managed worktree
creation, path claims, semantic coordination, hierarchy-parented journal
events, child and worker reports, candidate inspection and binding,
review-auditor evidence, traceability, resource release, and final acceptance.
Admission uses validated assignment ids and parent links rather than generated
name suffixes or a fixed tree depth, leaving the schedule representation
available for future runtime-appended nodes.
Zero-work plans fail closed. Goal/spec input with no repository path, Rust
module, or Rust symbol match returns an actionable error asking for a concrete
scope. The older Issue #14 description's claim that supervise run silently
succeeded with an empty assignment list was already stale before this CLI
surface: supervisor plan validation already rejected an empty assignments
array. The run path continues to use that library validation and does not
reimplement a second empty-plan check.
maco supervise run has a default Codex runtime and admits writable production
execution only inside a verified managed child worktree. Its file-entry path
acquires the repository-cleanliness capability used to create that worktree,
claims each assignment's paths, records semantic coordination metadata when the
plan requests it, and writes structured logs and reports under the run
directory. Managed-worktree Codex uses native workspace-write execution under
the outer confinement boundary; the Issue 28 universal-review coverage gate
remains mandatory for a writable primary-checkout target. The in-process Fake
runtime executes the same depth, claim, journal, review-lens, economics, KPI,
and final primary-integrity gates without launching an external executable;
its successful output is always non-publishable.
Child/model final-message bytes are confined to incoming/; normalized child
reports and supervisor-final.json are parent-owned under reports/. A live
external child requires two distinct writable artifact capabilities in both the
outer and native sandboxes: the descriptor-held incoming report/journal root,
and the private final-message staging root beneath the reviewed machine-global
runtime root. Neither is source-workspace authority. Release must fail closed
unless both exact capabilities are verified; the parent retains descriptors
for bounded reads and atomic final writes.
The full local report schemas remain the authoritative acceptance gate. Codex
receives a derived, provider-compatible output schema that omits unsupported
conditional keywords and supervisor-owned authority fields, including the
review-lens aggregate. The parent still validates every collected final message
against the full local contract and computes its own review evidence before
acceptance.
Worker prompts also include a structured execution journal path under
incoming/worker-journals/<worker-id>.jsonl. Terminal workers append JSONL
records with command, cwd, start_timestamp, end_timestamp, and
changed_paths; the supervisor imports them into
logs/workers/<child-id>/<worker-id>.jsonl and rejects material mismatches
against WorkerReport evidence, assigned paths, or the supervisor-inspected Git
diff.
Each Codex CLI child orchestrator is instructed to read AGENTS.md and
project-local .agents guidance before acting. The generated prompt contract is
user-directed root O2 -> autonomous O2 supervisor -> O1 child orchestrator ->
terminal worker/researcher/review-auditor. Human-invoked agents are treated as
the user-directed root O2: they are out-of-band supervisors, can launch several
bounded autonomous O2 supervisors, and are not counted against autonomous
task_depth. Workers, researchers, and review auditors are terminal. Workers
must attest no_further_delegation=true in their WorkerReport, and review
auditors must attest it in their AuditorReport. Embedded worker prompt
templates begin with ROLE: TERMINAL_WORKER; embedded review auditor prompt
templates begin with ROLE: REVIEW_AUDITOR; both must be passed to terminal
sessions without preamble. Native SubAgent/delegated-worker use is limited to
lightweight terminal worker and researcher roles; O1 child orchestrators must
not bind O1 or O2 roles to native SubAgent sessions. Durable roles use canonical
role names only; runtime labels belong in the runtime bridge and AGENT_LABEL,
never in ROLE. O1 child orchestrators must not spawn peer O2 supervisors;
when they discover newly large cross-cutting problems, they report peer-O2
escalation candidates upward in their structured report instead of taking those
scopes over. The user-root O2 or an autonomous O2 durable queue may then launch
bounded peer O2 supervisors as separate MACO/Codex CLI subprocess scopes.
Long-running O2 supervision is durable run state, not one expanding LLM context.
Autonomous O2 runs carry context through STATE.tsv, HEARTBEAT.tsv,
queue.tsv, NEXT_O2_TASKS.tsv, task prompts, captured final messages,
event streams, and SUMMARY.md under .maco/o2-autopilot/runs/<run-id>/.
O1/O2 subprocess orchestration uses MACO's verified outer process-tree and
side-effect boundary plus verified systemd cgroup ownership evidence and the
fixed maco_external_codex inner permission profile. Goals and multi-agent
features are enabled only for the supervisor role; inner model-generated
network access remains disabled. Nested O2/O1 subprocess chains must go through
the same validated MACO launch path instead of invoking a raw Codex process or
selecting a broader sandbox mode. Within that boundary, an O1 assigned a
managed child worktree uses native workspace-write and launches supplied
terminal worker templates through runtime-native SubAgent support; it does not
switch to app-server merely because an optional duplex reviewer is present.
Before each such writable launch, the parent revalidates the managed disposable
worktree binding, the exact authenticated held-claim token and paths, and the
runtime's verified native side-effect confinement together. A successful
decision is persisted as strict, parent-owned private evidence at
assignments/<assignment>.attempt-<n>.worktree-writable-admission.json, with
its matching schema under schemas/; primary-worktree targets never receive
this admission record and continue through the universal callback gate.
Managed-worktree Codex runs through the native CLI workspace-write path under
the ordinary contained process runner. It does not require the optional hosted
duplex reviewer and therefore does not select app-server for normal isolated
child execution. Issue 28's crate-internal, line-oriented app-server transport
is retained for the stricter primary-writable review boundary. Its protocol
handler receives only a bounded borrowed session after executable validation,
containment attachment, lifecycle registration, tee setup, and the start gate;
it cannot obtain or retain Child, raw stdio handles, or an uncontained
Command. The writable app-server configuration selects
approvals_reviewer="user"; the upstream auto_review mode remains experiment
evidence only.
The live Codex 0.144.4 schema exposes client callbacks for approval requests
that Codex chooses to surface. AskForApproval has no mode that forces every
in-sandbox read, write, destructive operation, or tool action through the
client. Consequently, approval callbacks alone cannot prove universal
review-before-action, including for sensitive reads, and a static filesystem
sandbox cannot distinguish an allowed claimed write from a forbidden delete
of that same path. MACO therefore refuses writable primary-checkout release
before starting the child. This callback limitation is not a managed-worktree
admission condition: that narrower target is disposable, claim-bound, and
validated before any later publication. Removing the primary-target gate
requires a future protocol mechanism that blocks every relevant proposed
action; the existing callback tests are not evidence that such coverage
already exists.
For surfaced requests, the retained duplex implementation derives policy input
from server lifecycle items, never treats best-effort or missing manifests as a
deterministic allow, appends a redacted authenticated orchestration-journal
record before sending accept, and sends a typed GateDenial to the same
thread and expected turn before decline or cancel. The denied item and turn
cannot terminalize until that steer request is acknowledged. Journal failure,
malformed protocol, timeout, cancellation, permission expansion, and missing
manifest all fail closed. Trusted records carry a stable run/review-session
correlation, structured rationale, measured per-decision latency, terminal
item/turn/process evidence, and native review metrics with distinct
action-denial and eligible-run-interruption denominators plus measured p50/p95.
Focused tests run a fake app-server as a real subprocess through the same
interactive runner. The Linux required-containment variant proves both
VerifiedEmpty process-tree evidence and verified strict-offline-workspace
side-effect evidence while exercising journal-before-accept ordering, typed
denial/acknowledgement before decline on the same child, absence of a
post-approval action marker on denial or journal failure, and protocol-loss
evidence retention. It skips only when required containment itself is
unavailable; ownership or protocol failures remain failures. Separate
trusted-best-effort compatibility tests are explicitly nonpublishable and do
not claim verified evidence. These tests validate the bounded duplex
primary-review path; managed-worktree coverage instead exercises native
workspace-write launch and does not claim universal action interception.
For worker assignments, child orchestrators launch the supplied terminal
worker templates through Codex native SubAgent/delegated-worker mechanisms so
the project manager/worker boundary is preserved. If no delegated-worker
mechanism is available, the child stops before mutation and reports the exact
blocked worker task. For child assignments with workers,
the retained supervisor runner requires structured terminal audit evidence before
accepting the child report: the parent launches a read-only REVIEW_AUDITOR
subprocess and requires an accepted AuditorReport with role=auditor,
no_further_delegation=true, read_only=true, and coverage for all assigned
worker ids. A child-side review auditor is advisory unless the parent MACO/O2
acceptance gate collects and accepts it. The accepted parent-launched
AuditorReport is appended to the child audit_reports field.
If a child declares worker assignments but returns zero worker_reports, the
child report is rejected as structurally incomplete. If a child has no worker
assignments but leaves a non-empty child worktree diff, the retained runner
still launches the parent read-only REVIEW_AUDITOR and requires it to cover
the child orchestrator id and changed paths.
The retained supervisor runner does not apply worker changes to the primary worktree
automatically. Omitting --max-concurrent-children selects auto, whose
network-bound entrypoint ceiling is a conservative four children rather than the
host CPU count. Final admission takes the minimum of that entrypoint ceiling (or
the explicit positive flag), the optional plan/CLI maximum, a configured provider
in-flight quota, and host memory/file-descriptor/disk bounds. There is no live
provider probing: provider_inflight_limit and --provider-inflight-limit are
operator-supplied quota data. Host available/per-child inputs can likewise be
specified in a plan's concurrency object or with the corresponding
--host-*-available-* and --host-*-per-child-* flags. Missing host observations
fall back conservatively to one child. Zero inputs are rejected before dispatch.
max_child_assignments separately bounds plan fan-out; it is not the concurrency
limit.
{
"concurrency": {
"max_concurrent_children": 8,
"provider_inflight_limit": 6,
"host_memory_per_child_mib": 1024,
"host_fds_per_child": 128,
"host_disk_per_child_mib": 512,
"host_fallback_children": 1
}
}Every newly finalized supervisor-final.json carries
role_economics_profile.schema_version=6 plus execution telemetry: planned,
started, and completed assignment counts; the resolved configured child bound;
scheduler-observed peak and active-interval mean concurrency; configured and
resolved model/reasoning bindings for every role; resolved effort for every
assignment duty in assignment_effort_bindings; and usage/cost with explicit
observation markers. concurrency.policy_input contains canonical JSON for
evaluation compatibility, while concurrency.policy_input_details retains the
typed entrypoint, plan, CLI, provider-quota, measured/configured host-resource,
and resolved-minimum inputs with scheduler_observed provenance. Missing
catalog, runtime-default model, nested-worker usage, and unpriced cost values
remain explicit unavailable observations. A width-one run with multiple
independent assignment or spec scopes emits a final-report warning. Readers
continue accepting historical reports that omit this block or carry economics
profile schema versions 1 through 5; the generated schema describes the required
version 6 contract for newly finalized reports. Version 4 profiles and the
withdrawn model-tier profile name remain deserializable compatibility input.
A worker assignment may opt into "kind":"megafile_decomposition" only with an
exact canonical "target_path" inside its assigned paths. Ordinary assignments
must omit target_path. Accepted worker reports preserve that typed pair,
bounded bloated_file_flags, and exact decomposition output evidence through
the child report. A successful decomposition worker must list the exact target
in files_changed and return
decomposition_completion={"target_path":"...","replacement_paths":["..."]}
with at least one distinct canonical replacement also present in
files_changed; target-only, ordinary, unrelated, and no-op pseudo-completions
are rejected. The supervisor final report deduplicates flags into
bloated_file_flags and merge-ready output evidence into
decomposition_candidates. The latter name is deliberate: supervisor work
remains isolated, so successful worker/report evidence is not an accepted
decomposition. Only a later successful merge apply backed by the required
reviewed preview, --decomposition-target ..., --decomposition-run-id ...,
and --reviewed-watermark <unchanged-preview.json> using that same finalized
run evidence writes the authoritative accepted_decomposition history record.
In auto mode, every hierarchy-ready assignment from independent roots can run
concurrently up to the measured host-capacity bound, but only when normalized
path sets are disjoint. Equality, ancestor, and descendant relationships use
the same overlap semantics as path claims. Same-lineage scope overlap is
permitted by validation because parent admission gates serialize ancestors and
descendants; cross-subtree overlap remains rejected. The scheduler scans ahead
for later ready, disjoint roots, so a waiting descendant or active overlap does
not impose unnecessary head-of-line blocking. Retries and the parent review
auditor remain inside the assignment's slot. An ordinary assignment failure
suppresses its descendants but does not stop unrelated roots; a fatal scheduler
abort stops new starts and joins every active call before returning.
Before admitting more ready work, the Issue #24 swarm-health cascade circuit breaker evaluates recent coordination outcomes. Repeated coordination failures trip the breaker, journal the transition, stop pending assignment admission, drain active assignments, release their resources, and expose the trip plus recovery guidance in status/final-report evidence. The breaker is the safety backstop that makes a higher automatic default practical; it does not raise the measured capacity bound or allow overlapping claims to run together.
Concurrent outcomes are stored by plan index, keeping final reports, command
records, findings, releases, and deterministic artifacts in plan order. Event
journal appends are synchronized and well formed, although completion events
may interleave. Concurrent invocations use unique bounded scratch roots to
avoid collisions; an effective width of 1 retains the legacy literal scratch
names.
max_child_retries defaults to 0 and may be set up to 2; retries are only
used for child report-shape failures such as missing or invalid report JSON or
the wrong report id/role, and the retry prompt includes corrective feedback.
max_child_processes is accepted only as a legacy JSON alias and normalized out
of reports. The command refuses to start when the primary worktree is dirty; use
--allow-dirty-primary only when the operator has reviewed that state. The
primary worktree dirty-path set is rechecked after each child process and any
newly dirty primary paths fail that child assignment. Tests use
fake subprocesses by default and do not require network access, provider
credentials, or a real Codex login.
Run the fake-first autonomous workflow:
The shipped spine is maco <instruction>, maco supervise run, and
maco inbox run. A bare instruction routes into supervised goal/spec.
supervise run accepts a positional task/plan or decomposes
--from-goal <file> through the same planner as supervise plan, then
executes the validated plan through the live supervisor gates. Pass
--runtime fake for the deterministic in-process Fake runtime. A bare
maco <instruction> routes through --literal-goal, with extra words kept
as goal text. New goal/spec runs without --runtime use provider-neutral,
account-bound normal intake and the loaded routing policy before dispatch;
required account, model, and admission evidence must pass the existing gates.
Explicit --runtime retains operator selection; positional plans and resumed
runs retain plan-runtime sniffing when it is omitted. Omitting
--codex-bin does not select Fake. Stay local with
supervise run --literal-goal ... --runtime fake.
Explicit supervise run must name the reviewed machine-global
configuration and runtime root used by supervise output-staging cleanup;
maco <instruction> resolves the default machine-global binding when those
flags are omitted. inbox run remains the fake-first reaction loop and
still dispatches selected item work through the autopilot library path.
maco autopilot plan and maco autopilot run are retired and fail closed
before side effects with
autopilot plan/run is retired; use literal instruction routing: maco <instruction>.
Remaining maco autopilot status/collect/artifacts inspect leftover
.maco/autopilot/runs/<run-id>/ reports.
This increment does not revive the legacy Autopilot repair/publication loop.
Leftover plan fields for outer validation, reviewer, forge, repair count,
publish mode, and auto_merge remain accepted only as library/inbox
compatibility input and cannot dispatch those effects. Supplying the legacy
--reviewer-command fails closed. The supervisor's own worker/auditor gates
are authoritative. A successful Fake result is isolated and non-publishable,
so Fake-generated follow-ups cannot enter an effectful queue. The live spine
never applies a result to the primary worktree, publishes it, or merges it.
Human-reviewed arbitration and explicit preview/apply remain separate
commands.
Leftover Autopilot plan fields remain library/inbox compatibility input, not
a live autopilot run recipe:
{
"version": 1,
"task": {
"title": "Update README",
"body": "Make the README clearer without touching Rust code."
},
"assigned_paths": ["README.md"],
"semantic_symbols": [],
"semantic_modules": [],
"validation_commands": ["cargo test"],
"max_repair_attempts": 1,
"forge_mode": "fake",
"reviewer": {
"mode": "fake"
},
"publish_mode": "draft_only",
"auto_merge": false
}cargo run -- supervise run --literal-goal "Update the README without touching Rust code." \
--repo . \
--runtime fake \
--machine-global-config /etc/maco/machine-global.json \
--machine-global-runtime-root-id runtime --json
cargo run -- supervise run --from-goal goal.md --repo . \
--run-id readme-goal-demo \
--runtime fake \
--machine-global-config /etc/maco/machine-global.json \
--machine-global-runtime-root-id runtime --json
cargo run -- inbox run --repo . --run-id inbox-demo --json
cargo run -- autopilot status readme-demo --repo . --json
cargo run -- autopilot collect readme-demo --repo . --json
cargo run -- autopilot artifacts latest --repo . --json
cargo run -- review pr 123 --repo . --json
cargo run -- review pr 123 --repo . --reviewer-program tools/reviewer --reviewer-arg strict --jsonPlain task files are accepted too; the first non-empty line becomes the title.
When a plan omits assigned_paths, autopilot uses a conservative task-to-path
proposal helper that looks at repository paths, Rust semantic names, and common
task wording instead of defaulting only to README.md. The helper is only a
starting point: hard sync claims, semantic coordination, live locks, and PR
safety gates remain authoritative, and ambiguous tasks are kept conservative.
Autopilot stores
plan.json, supervisor-plan.json, supervisor-report.json, pr-report.json,
review-report.json, and final-report.json under
.maco/autopilot/runs/<run-id>/. The final report embeds the exact typed
SupervisorFinalReport: GateDenial, EnvironmentFailure (including
runtime_model_catalog_unavailable), role economics/usage attribution, and
autonomy KPIs are composed rather than translated into a second vocabulary.
Autopilot does not recompute KPI rates or denominators; the supervisor aggregate
is the only KPI observation. Reports use repo-relative paths and omit nested
merge-preview paths and full diffs.
The disabled legacy implementation remains source-only design reference for a
deterministic child subprocess, forge, reviewer, repair loop, and publication
receipts. The live spine does not call that loop; autopilot plan/run remain
retired. Forge, PR, review, validation, repair, push, and merge operations in
that loop remain unreachable. The legacy
--reviewer-command shell-string option is retained only for an explicit
fail-closed compatibility error and cannot grant real review authority. The
following external-review rules document that disabled reference surface, not
an active Autopilot dispatch. A JSON reviewer configuration uses
mode: "external_command", a canonical
repo-relative or absolute program, and bounded args. PATH lookup, shell
strings, and shell -c are refused. The independent review report uses a
separate reviewer identity from the child worker, includes
structured findings with blocking, and currently reports
ci_reaction_supported=false. Reviewer configuration serializes as version 1;
an omitted config version remains accepted for compatibility, while unknown
fields are rejected recursively. Fake mode rejects external-program fields.
External-command mode rejects fake-only fields and uses a 300-second timeout
unless an explicit 1-to-86400-second value is provided. Program symlinks are
rejected; a script must use a single absolute shebang interpreter, whose
canonical regular-file identity and content are bound as well. A configured
native shell, language interpreter, or command dispatcher cannot act as the
authoritative reviewer program, including stdin/eval forms such as sh -s,
python -, or node --eval; this prevents the review request JSON itself from
becoming executable program text. A reviewer script with a direct native
shebang remains supported, while dispatcher shebangs are refused.
An external reviewer receives strict version-1 JSON on standard input and must
return one strict UTF-8 JSON object on standard output. The JSON result is
limited to 256 KiB, process capture is limited to 4 MiB per stream, truncated
output is refused, and nested unknown fields or mismatched target, attempt,
repository-relative paths, reviewer identity, or request binding are rejected.
The selected program and any script interpreter are opened without following
links, bounded and hashed, then copied with create-new semantics into an
owner-private runtime directory. Verified authority captures the materialized
program and, for scripts, its materialized native interpreter before the
systemd start gate opens. The bounded request descriptor is authenticated by a
digest fixed in the transient unit's argument vector; the helper revalidates
the bound identity and content, copies each entry image into a sealed memory
file, and executes by descriptor rather than reopening the launch pathname.
The source pathname is not passed to the process runner. This closes the
same-UID pathname-replacement gap for the entry images, but does not pin their
dynamic-library or language-module dependency closure. The authority path also
requires the running maco helper and all of its ancestors to be root-owned and
non-writable, so development and user-local binaries fail closed. Test-only
nonpublishable simulation remains unpinned and cannot create an authority
receipt. The parent derives the reviewer identity from the copied bytes and
bounded argv, and binds each request to the pre-run repository
snapshot, canonical request, sanitized-view manifest digest, effective timeout,
and sandbox-policy version;
the reviewer must echo that binding. Report strings alone do not grant real
publication authority: the Review boundary also returns a non-serializable
in-process receipt bound to the same repository, direct program and argv,
target, attempt, changed paths, diff summary, request binding, and derived
reviewer identity. Autopilot requires that exact receipt together with a
version-1 successful Passed report before Git or GitHub publication. Fake
review, the legacy shell-string input, and a syntactically plausible but
unreceipted report remain non-authoritative. A bounded descriptor prewalk rejects
oversized or excessive ignored/untracked trees before Git status construction.
Verified review separately constructs an owner-private sanitized view outside
the source repository. Its descriptor-stable manifest contains existing tracked
entries plus untracked non-ignored entries, their ordinary permission and
executable bits, and internal relative symlinks only when the lexical target is
a selected regular file or directory. .git, ignored content, and untracked or
ignored .maco runtime data are absent. A tracked .maco entry or a requested
changed path below .maco fails closed because an authoritative reviewer may
not pass content it was not shown. Gitlinks, sparse-missing or unmerged index
entries, case and file/directory collisions, hard links, special mode bits,
special files, escaping or dangling links, and bounded path/depth/count/byte
overflows also fail closed. Files are copied from no-follow source descriptors into
create-new destination descriptors, and the selected source and view manifests
are reverified before and after execution. The reviewer runs with this view as
its working directory; canonical changed paths and the bounded diff summary
remain parent-supplied JSON input, so Git administrative state is unnecessary.
The complete parent snapshot still covers tracked, untracked, and ignored content, modes, link targets, file generations, Git HEAD/ref/index/packed-ref state, and linked-worktree identities. Hard links, special files, external links, and gitlinks fail closed. Concurrent changes to those enumerated worktree entries, bound program/interpreter files, HEAD and its bound ref, packed refs, index, worktree backlink, or bound MACO-state identity invalidate the result; unrelated Git administrative files are not claimed as part of this snapshot. Sensitive output is redacted and converted into a blocking failed review.
The verified external-review runtime enforces both a read-only view and a
restricted root namespace with no network access. A read-only tmpfs replaces
the unit root. The configured path and bind sets re-expose the sanitized view,
the secret-free materialized reviewer program/interpreter directory needed by
the sealing helper, /nix/store, exact root-owned guardian/helper executable
aliases, and the identity-bound unit runtime. The policy also requests
systemd-managed private /proc and /dev views under the existing Protect*,
ProcSubset, and PrivateDevices checks. The original worktree, Git
directory and common directory (including MACO state and authentication keys),
and their parent data roots must have effective InaccessiblePaths properties
and verified systemd inaccessible-placeholder mounts before the start gate is
released. The authentication key is neither read for view construction nor
copied into the child namespace. Private HOME/TMPDIR, the descriptor,
mount report, and start/owner gates live only in the verified unit runtime.
Unexpected entries in the configured BindReadOnlyPaths, ReadOnlyPaths,
BindPaths, ReadWritePaths, and InaccessiblePaths sets, or a missing or
mismatched required mount or mask, fail closed. This does not claim a complete
allow-list inventory of systemd-created API VFS mounts such as /proc, /dev,
or /sys; their exact runtime layout remains part of strict-runtime validation.
The configured Nix-store view does not expose a general /usr or /etc;
non-Nix loader/library layouts therefore remain unsupported rather than
widening the host view. The reviewer can still inspect the explicitly visible
whole /nix/store, its own materialized entry images, and the systemd-created
API VFS surface. Those remain confidentiality boundaries; the source worktree
and ignored files are instead required to stay behind verified inaccessible
masks.
Autopilot refuses launch when the primary worktree is dirty unless
--allow-dirty-primary is supplied, or when active sync claims, semantic
intents, or active/blocked live claim locks overlap its target paths. These
checks run before artifact reservation and again immediately before supervisor
dispatch. Refusal JSON uses the shared GateDenial envelope. The supervisor
then remains responsible for bounded depth, claim admission, repository
cleanliness, journal, breaker, child/auditor acceptance, evidence-only re-audit,
and final primary-integrity checks. Plan files and nested task, path, semantic,
review, and command collections remain bounded and validated before dispatch.
External finding summaries, suggested fixes, next actions, diagnostics, and
finding paths remain available in bounded review artifacts but are never copied
into a later supervisor task. Retry prompts contain only a parent-selected
fixed reason code and validated blocking/severity counts.
Autopilot never auto-merges: auto_merge=true is accepted and reported as
requested, but auto_merge_performed is always false.
| Protection re-enabled or consumed | Satisfaction and retained failure path | Fail-capable evidence |
|---|---|---|
| Repository-cleanliness capability and primary isolation | Issue #11 (42f51aa) capability-binds managed worktree creation. Autopilot checks dirty primary and repository bindings twice; supervise compares its final primary snapshot and fails the run on drift. The E2E independently compares complete HEAD identity/tree, exact index storage/entries, every HEAD- or index-tracked worktree path's content or link target, mode, missing/type state, and raw porcelain-v2 status flags. No result is applied to primary. |
autopilot_rechecks_dirty_primary_immediately_before_supervisor_dispatch, dirty_primary_refusal_emits_public_json, and fake_autopilot_depth_two_e2e_is_gated_durable_and_primary_untouched fail if the pre-dispatch guard, typed dirty denial, or complete before/after snapshot equality regresses. primary_git_snapshot_detects_complete_state_drift independently fails unless otherwise omitted tracked content, mode, index storage/entries, status flags, and HEAD/tree changes are observable. |
| Typed path ownership | Issue #29 (a38d6bc) provides GateDenial. Overlapping durable sync claims, semantic intents, and live locks all become claim_conflict; the command finalizes a refusal without starting supervise. |
active_sync_claim_is_a_typed_preflight_refusal, active_semantic_intent_is_a_typed_preflight_refusal, and active_live_lock_is_a_typed_preflight_refusal independently seed each store and fail if its guard is bypassed. |
| Depth, scheduling, journal, and breaker gates | Issues #9 (1a9642e, 6bc7e44), #10 (9b87d2d through 61d1179), and #24 (d5b46ee) made these live supervise gates. Autopilot accepts only the fixed depth-2, non-recursive assignment spine and calls that public path; other integer depths and non-empty recursive assignments become a typed approval_review/permission_expansion refusal before supervise dispatch, while malformed depth is invalid. Goal decomposition now uses the same validated in-tool planner from both live run entrypoints. Accepted publishable licensed-breakage follow-ups may add one command-level generated batch; evidence for a further batch becomes a typed permission_expansion refusal. |
fake_autopilot_depth_two_e2e_is_gated_durable_and_primary_untouched requires a terminal worker, read-only auditor, review-lens aggregate, and durable supervise report. autopilot_run_refuses_max_depth_three_with_typed_permission_expansion and autopilot_run_refuses_recursive_assignments_with_typed_permission_expansion require a nonzero CLI result, the exact typed denial, a null embedded supervisor result, and no .maco/o2 dispatch artifacts. Existing supervise journal/scheduler/breaker tests remain unchanged. |
| Writable-child containment boundary | Managed-worktree Codex uses native workspace-write under the verified outer boundary and does not require an app-server All callback. The primary-writable target still fails closed when universal callback coverage is absent, and Autopilot does not bypass that refusal. Fake executes in process and never invokes codex_bin or task text. |
Managed-worktree launch tests require native execution and retained child-worktree isolation; the primary-target coverage test retains the containment refusal; fake_runtime_never_executes_codex_bin_or_task_text_and_is_never_publishable fails if Fake launches an executable or becomes publishable. |
| Acceptance lenses, megafile evidence, re-audit, claim lifecycle, and timing | Issues #16 (9a88d44), #19 (098eb6a), #30 (80cce22), structural extractions #45 (bfb59ba) and #49 (8399ad8, merged by 8bda772), #50 (f9b4b33), #51 (76bc21c), and #53 (469e3a6) are consumed through the complete supervisor report rather than reimplemented. Their own failure paths continue to make the supervisor non-successful/non-publishable. |
The depth-2 E2E requires worker, auditor, and review_lens_aggregate output. Existing focused supervise tests for each gate remain load-bearing and unchanged by the Autopilot wrapper. |
| Typed environment failures | Issues #31 (5655419) and #47 (74369ac) provide EnvironmentFailure, including runtime_model_catalog_unavailable. Autopilot embeds the supervisor report unchanged and performs no dispatch/publication after catalog failure. |
runtime_catalog_failure_composes_typed_environment_failure_without_dispatch uses a missing Codex runtime and fails unless the exact typed category is nested in the Autopilot report. |
| Economics and KPI composition | Issues #34 (285c517) and #35 (60ad4f9) provide role economics, honest usage attribution including not_process_observable, and supervisor KPIs. Autopilot passes those fields through without inventing cost observations or recomputing rates. |
public_json_shape_is_stable_and_sanitized requires the nested role-economics profile and supervisor_aggregate KPI observation. Existing supervisor economics/KPI gate tests retain their refusal assertions. |
| Machine-global destructive staging cleanup | Issues #44 (0217cfb), #48 (5b3d8ba), and #54 (4491bf3, merged by a76a4b9) bind both child-orchestrator and parent review-lens auditor staging cleanup through SupervisorRunOptions. CLI omission fails in argument parsing; programmatic omission fails before repository/plan effects; missing/partial or denied binding refuses cleanup and preserves staging. Fake creates no external staging and therefore records no fabricated cleanup. |
autopilot_run_cli_requires_machine_global_binding_before_effect_artifacts, autopilot_missing_retention_binding_fails_before_any_repository_or_runtime_side_effect, and existing supervise_dispatch_refuses_a_missing_staging_cleanup_binding plus child/auditor binding tests fail if any reached destructive launch loses its binding. |
| Human-only integration | Issue #17 (9f92b3e) exposes arbitration only as an opt-in proposal. Generated follow-ups can run only as isolated ordinary supervisor work; Autopilot never calls publication, arbitration, or the merge preview/review/apply workflow, and legacy auto_merge is recorded only. |
auto_merge_request_is_recorded_but_never_performed asserts the false capability fields and exact primary HEAD/index/files; legacy_reviewer_command_refuses_before_autopilot_artifacts and the legacy validation/reviewer plan tests fail if the legacy publication loop becomes reachable. |
maco autopilot plan and maco autopilot run are retired and fail closed
before side effects. Effectful maco inbox run and maco inbox watch
remain live: they dispatch selected item work through the autopilot
library path, so they inherit its machine-global binding requirement
whenever item work launches that path.
Run the fake-first inbox reaction loop:
{
"version": 1,
"repository": {"version": 1},
"permission_mode": "fake",
"selection": {"version": 1, "max_items": 2},
"max_repair_attempts": 1,
"default_validation_commands": [
{"version": 1, "name": "smoke", "command": "cargo test", "timeout_seconds": 60}
],
"default_assigned_paths": ["README.md"],
"privacy": {"version": 1, "allow_private_bodies": false}
}cargo run -- inbox scan --repo . --json
cargo run -- inbox run --repo . --run-id inbox-demo --json
cargo run -- inbox run --repo . --run-id inbox-codex --permission github_local --codex-bin codex --json
cargo run -- inbox run --repo . --run-id inbox-quota \
--max-rolling-tokens 42000 --max-rolling-cost-usd 12.5 --json
cargo run -- inbox intake --pr 123 --repo . --codex-bin codex --json
cargo run -- inbox status inbox-demo --repo . --json
cargo run -- inbox collect inbox-demo --repo . --json
cargo run -- inbox watch --repo . --poll-seconds 60 --once --json
cargo run -- inbox artifacts list --repo . --jsonFor authenticated GitHub review triage, direct inbox scan, run, and
watch accept --review-policy-file /absolute/operator/policy.json. The
operator file must be outside the source repository in an owned,
non-group-writable directory; it must be a regular single-link UTF-8 JSON
file opened without following links. This input is supported on Unix. Its
closed version-1 shape is { "version": 1, "repository": <ForgeRepository>, "policy": <ReviewLoopPolicy> }: repository binds the exact canonical
GitHub locator and provider repository ID; policy names independently
trusted actor IDs, roles, required checks, approval count, and attempt limit.
For every repository or actor stable_id, use MACO's canonical
node:sha256:<lowercase SHA-256 of the raw GitHub node ID UTF-8 bytes> form.
The raw node_id from GitHub is not itself a matching stable_id. Bind actor
handles in lowercase and kinds to the provider's User (human) or Bot
identity; a required check must name its independently approved actor in the
same form. The following sample values are hashes of the illustrative raw IDs
R_APPROVED, U_REVIEWER, and B_CI; replace them with independently
approved real identities before use, rather than copying a PR's participants:
{
"version": 1,
"repository": {
"provider_id": "github",
"canonical_locator": "github.com/example/project",
"provider_repository_id": {"provider_id": "github", "kind": "repository", "stable_id": "node:sha256:1eddabd711a92eac167e58e26a2832c006eceefefd8d560eb442f60712be0ee6"}
},
"policy": {
"trusted_feedback_actors": [
{"identity": {"provider_actor_id": {"provider_id": "github", "kind": "actor", "stable_id": "node:sha256:77a2a0fbff42dabcdd5e048c636e2eb956bc02178ba79863929c5f31ebb46540"}, "canonical_handle": "reviewer", "expected_kind": "human"}, "role": "human_blocking"},
{"identity": {"provider_actor_id": {"provider_id": "github", "kind": "actor", "stable_id": "node:sha256:2ad315ab7dc36665b9b36c1464907bddb43a7e9c5ed28001179de28ea3da9ac6"}, "canonical_handle": "ci-bot", "expected_kind": "bot"}, "role": "bot_advisory"}
],
"required_checks": [
{"name": "ci", "trusted_actors": [
{"provider_actor_id": {"provider_id": "github", "kind": "actor", "stable_id": "node:sha256:2ad315ab7dc36665b9b36c1464907bddb43a7e9c5ed28001179de28ea3da9ac6"}, "canonical_handle": "ci-bot", "expected_kind": "bot"}
]}
],
"minimum_approvals": 1,
"max_attempts": 2
}
}The policy is frozen once per command invocation. A run archives its raw
bytes and canonical binding in private finalized Inbox artifacts, alongside
an initial current-head review state for every successfully observed PR.
Omitting the flag preserves the existing policy_unavailable GitHub report
and Fake behavior. Review readiness never authorizes fix dispatch, comments,
or merge. Authenticated GitHub review threads carry isOutdated separately
from isResolved. A current thread follows the existing comment triage;
an outdated thread or legacy thread without currency evidence blocks readiness.
For a real GitHub PR repair with an explicitly bound policy, each attempted
Autopilot invocation first consumes one repository-authenticated slot under
that policy's max_attempts. The durable key is the GitHub repository ID and
PR number, so changing the PR head or supplying a new policy file does not
reset prior consumption. Failed, refused, and interrupted reservations remain
spent; exhaustion refuses new repair dispatch before model budget reservation.
These slots do not establish that feedback was addressed, grant readiness, or
authorize a comment, publication, or merge. Fake, issue, and no-policy paths
retain their existing behavior.
For a trusted same-repository GitHub PR, repair starts its isolated managed
child at the authenticated PR head even when the primary checkout has a
different HEAD. Missing exact PR commits use the existing bounded, fixed-ref
object transport and a fresh source check. The primary checkout stays at its
own HEAD; repair candidate evidence and any verified child commit cover only
changes after the PR head. A fork or source drift detected by those checks
refuses model dispatch.
This repair path still does not update the original PR branch or grant comment
or merge permission.
maco-inbox.json is optional. Without it, maco inbox scan uses deterministic
fake local data: one safe issue candidate, one PR candidate with requested review
changes and failing CI context, one unsafe item that is skipped, and duplicate
skipping evidence. Public JSON uses the typed schema fields version, repo,
action_policy, github_enabled, success, refused, refusals,
candidate_count, selected_count, items, and next_action; repo is the
public "." placeholder rather than a local absolute path. Item bodies are
bounded summaries with token-like values redacted, private key material refused,
and local absolute paths such as /mnt/..., /home/..., or C:\Users\...
rejected.
Inbox config files are bounded to 256 KiB, must be regular UTF-8 files, and are
opened without following a link. Unknown fields and unsupported schema versions
are rejected at every config level before scanning or acting. Omitted versions
remain compatible with version 1, and legacy validation-command strings remain
accepted. Selection is limited to 100 items, 32 labels, 32 validation commands,
128 assigned paths, 64 privacy terms, and 8 repair attempts; individual labels,
commands, paths, timeouts, body-summary limits, repository selectors, and
codex_bin paths are also bounded and reject control characters or noncanonical
values. CLI overrides pass through the same validation.
Each issue or pull request includes a versioned source_snapshot binding. It
binds the source provider, canonical repository selector, opaque durable local
repository identity, issue/PR kind and positive number, stable source_key,
updatedAt, and—for pull requests—the exact headRefOid and baseRefOid.
The deterministic digest is validated when deserialized and again before an
item is used. Duplicate detection remains stable by repository, kind, and number
while the snapshot digest separately identifies the observed source revision.
Fake fixtures use fixed timestamps and canonical fake OIDs for reproducibility.
maco inbox run and maco inbox watch execute effectfully. Items that need
repair remain on the ordinary Autopilot repair path, whose supervisor cascade
derives the capability-bound repository cleanliness input before creating
managed worktrees. Watch also offers bounded, source-bound open-PR tasks to the
authenticated intake lane; maco inbox intake --pr <number> re-observes the
exact provider-owned PR before admitting that lane. scan, status, collect,
and read-only artifact inspection remain available. The fake-first reaction
flow described below is the executable behavior; the unbound Fake reviewer
still stops as nonpublishable before real publication effects.
maco inbox run accepts optional workspace rolling-quota ceilings
--max-rolling-tokens, --max-rolling-cost-usd, and
--rolling-window-seconds. A quota is bound only when at least one of
--max-rolling-tokens or --max-rolling-cost-usd is set; --rolling-window-seconds
alone is ignored. Values must be finite and positive. When a ceiling is set
and the window is omitted, the window defaults to 86400 seconds (24 hours).
These flags are inbox-run ceilings across Autopilot dispatches in the
workspace rolling ledger; they are not the supervise/autopilot per-run
--max-tokens / --max-cost-usd / --max-duration-seconds flags, which
inbox run rejects. inbox watch and inbox workspace run|watch do not
expose the rolling-quota flags. When a rolling quota refuses further work,
the run records status=refused and the next action asks the operator to
increase or wait for the quota.
Inbox runs write public-safe artifacts under .maco/inbox/runs/<run-id>/,
including scan-report.json, selected-items.json, item-<n>-plan.json,
item-<n>-autopilot-report.json, item-<n>-github-report.json, and
final-report.json. Reports use repository-relative paths and do not include
full diffs, raw secret values, credentials, or local absolute paths.
GitHub inbox intake is explicit opt-in. --permission fake is the default and
does not require network access or credentials. github_read reads live issues
and PRs through gh but only writes plans and reports. github_local reads live
GitHub and runs local repair with fake PR publication and no source comments.
github_pr reads live GitHub, runs repair, and publishes a draft PR through the
GitHub forge without commenting on the source item. github_full also comments
on the source issue or PR after success. github_git reads live GitHub issue/PR
items through gh, runs repair, pushes the branch through real Git, and does
not create a GitHub PR or comment on the source item. Hyphen aliases such as
github-read are accepted. Legacy --github and action_policy: "github" keep
the old full behavior unless permission_mode explicitly overrides them. Fake
PR review and failing CI context are converted into autopilot repair plans with
assigned paths, reasons, and validation expectations. Inbox also preserves the
same path-scoped safety boundary as autopilot: it refuses dirty primary worktree
files, active local locks, active sync claims, active semantic intents, and
active/blocked live claim locks only when they overlap selected target paths,
while ignoring its own .maco/** and .maco-cache/** runtime artifacts.
Refusal JSON includes paths and lock details. Ordinary repair does not merge.
Only the authenticated clean-PR intake lane may merge, and only under
github_full after fresh provider ground truth, approved-actor binding,
producer/auditor separation, passing CI, exact source/head/base/path identity,
clean merge simulation, and merge-receipt verification all pass; every failed
gate reports a blocked lane without a verified merge.
Live GitHub intake uses the same pinned trusted gh network boundary as
publication: private host-specific token/config state, a minimal environment,
bounded capture and timeout, an exact host-qualified --repo, and a fixed
allowlist for issue/PR list arguments. Intake snapshots store the canonical
source host separately and fail closed if the origin host, owner, or repository
changes. GitHub source JSON is schema-strict: every requested field must be
present with its declared type; only author: null and PR
reviewDecision: null are accepted as explicit provider nulls.
Until an external reviewer identity and result are explicitly bound into the
publication evidence, non-dry-run github_git, github_pr, and github_full
runs fail closed; their dry-run plans and read-only intake remain available.
Run the cross-repository inbox workspace supervisor:
{
"version": 1,
"default_permission_mode": "github_read",
"default_max_items_per_repo": 2,
"strict": false,
"repositories": [
{
"version": 1,
"id": "orchestrator",
"path": "../Multi-Agent_Coding_Orchestrator",
"enabled": true,
"permission_mode": "github_local",
"max_items": 1,
"labels": ["bug"],
"include_pull_requests": true,
"include_issues": true
},
{
"version": 1,
"id": "docs",
"path": "../project-docs",
"enabled": false,
"include_pull_requests": true,
"include_issues": true
}
],
"safety": {
"version": 1,
"require_clean_primary": true,
"require_validation_for_publication": true,
"allow_auto_approval": false,
"allow_auto_merge": false
}
}cargo run -- inbox workspace scan --config workspace-inbox.json --json
cargo run -- inbox workspace run --config workspace-inbox.json --run-id workspace-demo --json
cargo run -- inbox workspace run --config workspace-inbox.json --run-id workspace-dry --dry-run --json
cargo run -- inbox workspace watch --config workspace-inbox.json --poll-seconds 60 --once --jsonmaco inbox workspace scan, run, and watch are implemented. scan reads
the workspace config and reports per-repository intake without launching
Autopilot. run writes aggregate artifacts under
.maco/inbox-workspace/runs/<run-id>/ and then executes each enabled
repository through the same inbox run path used by maco inbox run. watch
polls that run path; --once performs a single iteration and returns. --dry-run
plans item work and writes reports without launching Autopilot. Workspace
run/watch do not accept the inbox rolling-quota flags; those apply only to
maco inbox run.
The retained aggregate design reports version, a public-safe config_path,
strict, repo counts, and one entry per repository with id, enabled,
permission_mode, status, success, refused, optional message, and an
embedded scan_report or run_report. Per-repo repair artifacts remain under
each repository's .maco/inbox/runs/<run-id>/ tree. Public reports must not
expose local temp paths, credentials, raw secrets, or private bodies.
Workspace configs use the same 256 KiB bounded, no-follow UTF-8 loading and
strict unknown-field/version rules. They support at most 64 uniquely identified
repositories; repository IDs, paths, labels, per-repository item counts, and
canonical resolved-path collisions are validated before any repository scan.
strict: false keeps scanning or running later repositories when one repository
is disabled, empty, dirty, or refused; the per-repo entry records the failure.
strict: true turns a repository refusal or failure into an aggregate command
failure. Permission modes inherit from default_permission_mode and can be
overridden per repository. github_read only scans and plans through gh,
github_local can run local repair without source comments, github_git can
plan or perform Git branch publication without GitHub PR creation, and
github_pr/github_full are used only when explicitly configured. Workspace
inbox is cross-repository supervision, not approval or merge automation:
automatic approval and automatic merge are unsupported, and reports keep
auto_approval_performed=false and auto_merge_performed=false.
Cleanup examples:
cargo run -- sync status --repo . --json
cargo run -- worktree pending --repo . --json
cargo run -- worktree remove agent-a --repo . --force --delete-branch