CLI Reference
This page is the command surface from the spec, section 10, annotated against the capability matrix, section 11. It documents the whole contract - and it is exact about what runs in the binary today versus what the contract specifies for commands not yet built.
Status legend
Section titled “Status legend”- Shipped - in
cmd/loopexecwith tests. Runs today. - In progress - on a feature branch. Not in a release build.
- Planned - specified in the contract. Not yet built.
The source of truth for this column is SPEC section 11. When a capability moves status, the spec changes first; this page and the binary tests both reference it.
What runs today
Section titled “What runs today”The full engine ships - eighteen commands:
loopexec init # scaffold workspace metadataloopexec run # real bounded check_fixpoint looploopexec status # show loop statusloopexec check # validate invariants (state hygiene)loopexec step # execute a single steploopexec probe-check / doctor / explain-haltloopexec replay / attest / reexecuteloopexec escalate / watch / ackloopexec build-context / isolateloopexec run --json # emit exactly one JSON object to stdoutThe iterating run is Shipped, and computed halts now emit across the 13 (integrity), 14 (oracle-untrusted), 15 (check-inadequate, via the doctor --mutate-cmd adequacy canary), 16 (resumable-judgment), 17 (no-convergence), 18 (budget, via inspect-cost), 19 (liveness/drift), and 30 (workspace/isolation) classes, alongside the original 0/10/12/20/40/50. Every class 13-19 now emits; the only reasons still reserved are class 11’s task_list-mode reasons (no_actionable_tasks / human_required), which belong to the task_list loop topology. A few individual reasons inside active classes, and in-loop budget enforcement during run, stay Planned. See Exit codes below.
Command matrix
Section titled “Command matrix”| Command | Purpose | Status | Exit semantics |
|---|---|---|---|
init | scaffold .loopexec/ workspace metadata (versioned loop.yml scaffold Planned) | Shipped | 0 / workspace_invalid |
run | the real iterating loop (section 4); computed halt | Shipped | per halt map |
run --once | single iteration for debugging; absorbs step | Shipped | per halt map |
probe-check | determinism as a confidence bound; agent-free | Shipped (core) | 0 / class 14 |
build-context | bounded relevant slice; budget ceiling; workdir-confined | Shipped | 0 / context_budget_unsatisfiable (19) |
isolate | two-zone orchestration: detached-clone sandbox + per-run minted/revoked key + rendered/launched zones | Shipped | 0 / isolation_unsatisfiable (30) / execution_failure (40) |
doctor | precondition gate: determinism + isolation preflight + adequacy mutation canary (hermeticity O3 and coverage-delta tier still Planned) | Shipped (determinism + isolation preflight + adequacy canary) | 0 / class 13 |
check | SMALL / state-hygiene validation (not the oracle) | Shipped | 0 / invariant_failed |
ratchet | no-regression ratchet over the failing set (ships inside run via --failures-cmd); standalone inspect/advance command Planned | Shipped (in run) | 0 / class 17 |
replay | VERIFY a recorded receipt (agent-free, budget-free) | Shipped | 0 / class 13 |
reexecute | live re-run; statistical match; --confirm | Shipped | 0 |
report | render a recorded receipt (digest + timeline); re-runs nothing | Shipped | 0 |
status | live status / tail | Shipped | 0 |
inspect-cost | cost ledger -> run-total cap + sigma anomaly | Shipped | 0 / class 18 |
explain-halt | human rationale; “raise the limit” vs “never retry” | Shipped | 0 |
escalate | structured packet (file/stdout); marks the run paged | Shipped | 0 (paged) |
watch | heartbeat staleness detection (kill-PID actuator Planned) | Shipped | 0 / heartbeat_stale (19) |
attest | HMAC-sign + verify a receipt | Shipped | 0 / class 13 |
ack | clear comprehension debt + paged escalation; records --reviewer | Shipped | 0 |
Global flags
Section titled “Global flags”--json- Shipped. Emit exactly one JSON object to stdout. Human logs and errors go to stderr. See JSON contract.
Commands
Section titled “Commands”init - Shipped
Section titled “init - Shipped”Scaffold the workspace. Today init creates the .loopexec/ metadata directory; durable, resumable run state (.loopexec/state.json, section 8) is written by run and is Shipped. The contract additionally extends init to scaffold a versioned loop.yml; that fuller scaffold is Planned.
- Flags:
--json. - Exit:
0on success;workspace_invalid(30) if the workspace cannot be written.
loopexec initloopexec init --jsonrun - Shipped
Section titled “run - Shipped”The real iterating loop, section 4: execute the work step (--exec), run the external check (--check) once, evaluate guards before any green branch (guards dominate success), apply the anti-regression ratchet, append a receipt, then continue or halt on a computed condition. With no --check it refuses to start (workspace_invalid): no check, no loop.
- Flags:
--check(required oracle),--exec,--max-iterations,--run-id,--workdir,--budget-usd; optional--failures-cmd(ratchet),--integrity-cmd(metric-integrity gate), the receipt-pinning flags, and--comprehension-every.--budget-usdis recorded today; live metering is Planned. --halt-reasonsurvives as a hidden test fixture only. The contract forbids a flag-forced halt: every halt reason is derived from observed state.- Exit: per the halt-reason map.
runemits0/10/12/40plus the computed13(integrity),17(no-convergence), and19(liveness) reasons it owns.runitself does not emit class15(check-inadequate) or class18(budget): those come fromdoctor --mutate-cmdandinspect-costrespectively, and in-loop budget enforcement duringrunstays Planned. No class is globally reserved except class11’s task_list-mode reasons.
loopexec run --run-id local --max-iterations 20 --jsonrun --once - Shipped
Section titled “run --once - Shipped”A single iteration, for debugging. It runs one iteration of the real loop (--exec then --check) and halts on the computed outcome: success_condition_met if the check passes, else max_iterations_reached. It overrides --max-iterations, and absorbs the legacy step stub.
- Exit: per the halt-reason map -
10if the one iteration converges,12if not,40if the work step fails.
loopexec run --once --check "go test ./..." --exec "make fix"loopexec step # legacy stub; prefer run --onceprobe-check - Shipped (core)
Section titled “probe-check - Shipped (core)”Determinism as a confidence bound, not a pass/fail of N runs. probe-check reports an achieved confidence bound on the check’s flake rate; the run count is derived from a target max_flake_rate, not a magic constant. Probing is adversarial where configured - test order, seed, clock, concurrency, load - and reports which dimension broke. Agent-free.
- Exit:
0, or class14(oracle-untrusted):check_flaky,check_has_side_effects,check_not_hermetic,hermeticity_violation.
See Determinism for the sequential in-loop monitor that maintains this bound across the run.
build-context - Shipped
Section titled “build-context - Shipped”Emits a narrow, budgeted context slice: machine state + the open failure + relevant source files (from the failure stack trace, the last git diff via --diff-base, and untracked files). The token budget is a true ceiling, measured with a code-calibrated estimator. It is never fatal on no relevant files; it emits context_budget_unsatisfiable only when the mandatory state+failure slice cannot fit. File resolution is workdir-confined and symlink-safe - untrusted failure text cannot read files outside the workdir; reads are size-bounded and untrusted content is fence-escaped. The import_closure / dep_graph relevance tiers are Planned.
- Exit:
0/context_budget_unsatisfiable(class19).
doctor - Shipped (determinism + adequacy canary)
Section titled “doctor - Shipped (determinism + adequacy canary)”The precondition gate. The contract requires doctor to refuse to start a loop when the check is not deterministic (O2) or not hermetic (O3), is inadequate - coverage delta plus a mutation canary that MUST turn the check red (O4) - or when two-zone isolation is unsatisfiable: a cloud or local-host model paired with network: none, a ~/.claude bind-mount, an exec_zone with network, or a missing egress allowlist (section 7). Fail-closed.
--mutate-cmd now ships the core of the O4 adequacy gate: it runs an operator-provided mutation in an isolated copy of the workdir and verifies the --check turns RED. If the check stays green with a planted bug, that is check_inadequate (15); a --mutate-cmd that cannot apply is execution_failure (40). The coverage-delta tier of adequacy and the hermeticity (O3) gate remain Planned.
- Exit:
0, class15(check_inadequate) via--mutate-cmd, or40(execution_failure) when the mutation cannot apply. The specified surface also covers class13(credential_scope_invalid) |14(oracle-untrusted) |30(isolation_unsatisfiable).
check - Shipped
Section titled “check - Shipped”SMALL / state-hygiene validation only. This is the small check --strict analog: it validates structural state hygiene. It is explicitly not the application oracle - it cannot decide application correctness, and the contract forbids treating it as a check_fixpoint stop condition.
- Flags:
--fail-invariant(fixture, forces failure),--json. - Exit:
0/invariant_failed(20).
loopexec check --jsonratchet - Shipped (in run)
Section titled “ratchet - Shipped (in run)”The no-regression ratchet over the failing-test set is the anti-random-walk Lyapunov function (section 3.2). It ships inside run: pass --failures-cmd and each iteration’s failing set is tracked against a best-so-far; the loop halts same_test_regressed (a resolved failure returned), oscillation_detected (the set exactly repeated an earlier iteration), or no_progress_detected (no new best within --no-progress-k iterations). A standalone ratchet inspect/advance command and git revert-to-best are Planned.
- Exit:
0standalone;class 17(no-convergence) when the ratchet halts a run.
replay - Shipped
Section titled “replay - Shipped”VERIFY a recorded receipt. replay re-runs the deterministic check against the recorded end-state and confirms the fingerprint matches the receipt. Agent-free, budget-free, deterministic. It answers “does this receipt’s verdict still hold?”
A live-LLM trajectory is not reproducible; only the verdict is. This is why the contract says replayable verdicts, never “replayable runs.”
- Exit (specified):
0/ class13(integrity), e.g.objective_unverified.
reexecute - Shipped
Section titled “reexecute - Shipped”RE-RUN the live agent loop. Non-deterministic - the LLM samples - so it reports a statistical match, never byte identity. Budget-burning and --confirm-gated.
- Exit (specified):
0.
report / status - both Shipped
Section titled “report / status - both Shipped”report renders a recorded receipt as a digest: the run’s outcome (phase, halt reason, exit class), its pins (check, fingerprint, model, sampling, cost, context-manifest size), whether it is attested, and the per-iteration timeline parsed from the JSONL log. It re-runs nothing and exits 0 even for a failed run - it reports, it does not re-decide. --run-id addresses any recorded run (default: the latest). status is the live tail and ships today.
statusflags:--run-id,--iteration,--halt-reason,--json.- Exit:
0.
loopexec status --run-id local --iteration 1 --jsoninspect-cost - Shipped
Section titled “inspect-cost - Shipped”Analyze a per-iteration cost ledger against a run-total hard cap and a sigma anomaly bound. loopexec does not meter live token cost (the model call lives in --exec); it owns the math over costs you supply, and decides the class-18 halt. The cap and the anomaly detector are distinct: a run can be under budget yet flag a spike.
- Inputs:
--ledger <file>(one USD per line) and/or--cost <usd>(repeatable). --budget-usdis the run-total cap; over it haltsbudget_exceeded.--sigma N(default 3) flags any iteration above the rolling mean + N standard deviations of the iterations before it ->cost_anomaly. A flat ledger has no variance and raises nothing; an empty ledger or a negative cost isinvariant_failed.- Exit:
0within cap and no spike;18forbudget_exceeded/cost_anomaly;20on bad input. - Planned: auto-parsing provider usage and in-loop enforcement during
run.
explain-halt - Shipped
Section titled “explain-halt - Shipped”The honest realization of “explain why.” It reads .loopexec/state.json and distinguishes max_iterations_reached reached while the failing-test set was still strictly decreasing (“raise the limit, retry”) from a stalled, regressed, oscillating, or infeasible halt (“do not retry - it burns budget forever”). That distinction is the one piece of information the 3am operator actually needs.
- Exit:
0.
escalate / watch - Shipped
Section titled “escalate / watch - Shipped”escalate emits a structured human-handoff packet (--channel file|stdout; github/slack Planned) and marks the run paged, cleared by ack. watch is the external supervisor that polls the heartbeat’s age and emits heartbeat_stale (19) when it goes stale - a heartbeat nobody reads is just a file. The SIGKILL-the-wedged-PID actuator is Planned.
- Exit (specified):
escalation_pending(16) /heartbeat_stale(19).
attest (Shipped) / ack (Shipped)
Section titled “attest (Shipped) / ack (Shipped)”attest signs a receipt so provenance is checkable. ack records a signed comprehension ack that clears comprehension_debt_exceeded - a forcing/visibility gate, not proof of comprehension.
- Exit (specified):
0.
loopexec ack --through <sha> --reviewer <id> # PlannedJSON contract
Section titled “JSON contract”Every command in --json mode emits exactly one JSON object to stdout. Human logs and errors go to stderr. The object includes at least {tool, version, status, errors[]} and, where applicable, {run_id, iteration, halt_reason}. The schema is additive: new fields MAY be added; existing field meanings MUST NOT change within a major spec version.
| Field | Type | Notes |
|---|---|---|
tool | string | always "loopexec" |
version | string | binary version |
status | string | e.g. ok, initialized, halted, error |
run_id | string | present where applicable |
iteration | integer | present where applicable |
halt_reason | string | the computed halt reason, when halted |
errors | array of strings | always present (may be empty) |
Current example object, emitted by the Shipped binary:
{ "tool": "loopexec", "version": "0.2.0", "status": "ok", "run_id": "local", "iteration": 1, "errors": []}The halt_reason string is the stable integration contract. Integrations SHOULD branch on it. The exit code is a coarse class for CI that does not parse JSON.
Exit codes
Section titled “Exit codes”The base codes 0/10/12/20/30/40/50 are wired in the binary today, and classes 13, 14, 15, 16, 17, 18, and 19 now emit their core reasons - from the iterating run, the determinism / ratchet / receipt / ops / context / isolation commands, (class 18) inspect-cost, and (class 15) the doctor --mutate-cmd adequacy canary. Every class 13-19 now emits; only class 11’s task-list reasons remain reserved. The full canonical map:
| Exit | Class | halt_reason strings | Wired today |
|---|---|---|---|
0 | nominal | (loop ran, no halt) | Yes |
10 | converged | success_condition_met | Yes |
11 | terminal-blocked | no_actionable_tasks, human_required | Reserved (task-list mode) |
12 | iteration-cap | max_iterations_reached | Yes |
13 | integrity | blocked_path_modified, reward_hacking_detected, metric_integrity_violation, credential_scope_invalid, objective_unverified | Partial (metric_integrity_violation, credential_scope_invalid, objective_unverified) |
14 | oracle-untrusted | check_flaky, check_has_side_effects, check_not_hermetic, hermeticity_violation | Partial (check_flaky) |
15 | check-inadequate | check_inadequate | Yes (via doctor --mutate-cmd) |
16 | resumable-judgment | escalation_pending, reviewer_rejected | Partial (escalation_pending) |
17 | no-convergence | no_progress_detected, same_failure_repeated, oscillation_detected, same_test_regressed, unsatisfiable_constraints, infeasible_suspected | Partial (no_progress_detected, oscillation_detected, same_test_regressed) |
18 | budget | budget_exceeded, cost_anomaly | Yes (via inspect-cost) |
19 | liveness/drift | heartbeat_stale, model_drift_detected, comprehension_debt_exceeded, context_budget_unsatisfiable | Partial (heartbeat_stale, comprehension_debt_exceeded, context_budget_unsatisfiable) |
20 | invariant | invariant_failed | Yes |
30 | workspace | workspace_invalid, isolation_unsatisfiable | Yes (workspace_invalid, isolation_unsatisfiable) |
40 | execution | execution_failure | Yes |
50 | internal | internal_error | Yes |
See also
Section titled “See also”- Halt reasons - every
halt_reason, its detector, and its owner. - Determinism - the
probe-checkconfidence bound and the in-loop monitor. - Loop engineering - the discipline this surface enforces.
- Getting Started - install and run the Shipped surface.