Skip to content

CLI Commands

no-mistakes

Attach to the active pipeline run for the current branch when one exists. If none exists, bare no-mistakes can start the setup wizard to create a branch, commit changes, push through the gate, wait for the daemon to register the new run, and then attach. If the push succeeds but no run is registered, that wizard path now exits with an explicit error instead of silently falling through. By default this wizard path is interactive and only runs in a TTY session. In non-interactive contexts, bare no-mistakes falls back to showing the last 5 runs inline unless you pass -y or --yes to run the wizard and accept defaults automatically. When a TTY is available, -y keeps the wizard visible, shows a brief waiting for run… state after push, and auto-advances the default path; without a TTY it falls back to the headless path.

Terminal window
no-mistakes
no-mistakes --skip test,lint
FlagTypeDefaultDescription
-y, --yesboolfalseRun setup wizard and accept defaults automatically
--skipstring(none)Comma-separated pipeline steps to skip for a new run

Unlike no-mistakes attach, bare no-mistakes only auto-attaches to an active run on the current branch. --skip only applies when bare no-mistakes starts a new pipeline run through the wizard; it does not skip a step on an already-active run. The only valid --skip step names are intent, rebase, review, test, document, lint, push, pr, and ci. Repository gate names are refused.

no-mistakes init

Initialize or refresh the gate for the current repository.

init requires an origin remote to identify the upstream repository: later pipeline steps push validated branches to the configured target and open pull requests against that upstream. If origin is missing, add it with git remote add origin <url>, replacing <url> with the upstream repository’s URL, then re-run init.

Terminal window
no-mistakes init
no-mistakes init --fork-url git@github.com:you/my-repo.git
no-mistakes init --worktree-root ~/work/my-repo-runs
FlagTypeDefaultDescription
--fork-urlstring(none)GitHub fork remote URL to push branches to while opening PRs against origin
--worktree-rootstring(none)Directory to create this repository’s run worktrees in; prints the worktree_roots entry to add

Creates or refreshes a local bare repo, installs the managed pre-receive admission and post-receive notification hooks, best-effort isolates the gate repo’s hook path from shared git config changes when Git supports config --worktree, adds or repairs the no-mistakes git remote, detects the default branch, records or updates the repo in SQLite, installs the /no-mistakes agent skill at user level into ~/.claude/skills/no-mistakes/SKILL.md and ~/.agents/skills/no-mistakes/SKILL.md, and ensures the daemon is running, installing the managed service when available and falling back to a detached daemon otherwise. init writes no skill files into the repo; the user-level copies serve Claude Code (~/.claude/skills) and agents that use the vendor-neutral ~/.agents/skills convention (Codex, OpenCode, Rovo Dev, and Pi) across all repos. Grok Build is a pipeline runner and does not consume this installed skill. If the home .claude links to .agents, .claude/skills links to .agents/skills, or the reverse, init follows that layout and still makes the skill readable from both logical paths. If the repo still contains a vendored skill copy written by an older no-mistakes version, init leaves it untouched and prints a notice that it is no longer needed and can be removed. The gate advertises Git push-option support, so you can skip steps for one push with git push -o no-mistakes.skip=test,lint no-mistakes <branch>.

For GitHub fork contributions, keep origin pointed at the parent repository and pass --fork-url with your fork remote URL. The Push step, rebase branch-sync, and CI repair publication use the fork, including when ci.revalidate_repairs sends a repair back through Push, while GitHub PR and CI commands stay scoped to the parent repository and create PRs with --head <fork-owner>:<branch>. Fork routing currently requires both origin and --fork-url to be GitHub remotes with owner/repo paths.

--worktree-root is for directory-scoped toolchain configuration (mise, direnv), which resolves by path ancestry and so never reaches a run worktree under NM_HOME. The flag resolves the directory, then prints the worktree_roots entry to add to ~/.no-mistakes/config.yaml; the global config is hand-maintained, so init never rewrites it for you. When the file already has a worktree_roots: block, init prints just the entry line to add under it - a second worktree_roots: key would make the config unparseable and stop the daemon. Runs are created at <dir>/<run id> once the entry is in place; no-mistakes only ever touches the directories its own run records name, and everything else in that directory is left alone. init rejects the directories the daemon would refuse to start on, so the entry it prints is always one you can paste: a directory inside NM_HOME, inside the repository being initialized or any other gated checkout, already used by another checkout (it names that checkout), or that exists as a non-directory.

Two refusals apply to every init, with or without the flag. It refuses to register a checkout that contains a directory an existing worktree_roots entry points at, naming that entry, because registering it is what would make the placement unusable and stop the daemon; place the checkout elsewhere or repoint the entry first. It also refuses to register anything while ~/.no-mistakes/config.yaml does not load, naming the fault, because the daemon refuses to start on that same config.

Re-running init on an already-initialized repo succeeds and reports Gate already initialized (refreshed). It refreshes managed gate wiring, origin/default-branch metadata, hook-path isolation, and the installed agent skill, overwriting any stale SKILL.md content from an older binary. When a fork URL is already recorded, re-running init without --fork-url preserves it. Passing --fork-url again replaces the stored fork URL after validation. If you rename or move an initialized working directory and the old path no longer exists, re-running init from the new path reattaches the existing gate, preserves the repo ID and run history, and updates the stored working path. If you copy an initialized working directory while the original still exists, the copy is treated as a separate repo and gets a fresh gate. Fresh init rolls back gate setup when a required gate or daemon step fails; refresh does not eject a pre-existing gate if daemon startup fails. Skill installation is best-effort: if the skill write fails, init reports it and leaves the working gate in place.

no-mistakes ci-workflow

Generate .github/workflows/ci.yml from the repository’s .no-mistakes.yaml commands, so GitHub Actions registers real checks that the gate’s CI step can monitor.

Terminal window
no-mistakes ci-workflow
no-mistakes ci-workflow --force
FlagTypeDefaultDescription
-f, --forceboolfalseOverwrite existing workflow file

Run it from anywhere inside a repository with a .no-mistakes.yaml; the config is read from and the workflow written at the git toplevel, and commands.test must be configured or the command errors. The generated workflow runs the configured test command (and lint command when commands.lint is set; with an empty commands.lint it emits a test-only workflow, since lint runs as the combined document+lint agent pass) on push to the repository’s default branch, resolved from the origin remote and falling back to main, and on all pull requests. Commands are inserted verbatim into YAML block scalars, with multi-line commands indented to stay inside the scalar. The template is Go-focused (it uses actions/setup-go with go-version-file: go.mod); non-Go repos can adapt the generated file. An existing .github/workflows/ci.yml is never overwritten without --force, overwrites are atomic, and the command refuses to write through a symlinked .github, workflows, or ci.yml. Commit and push the generated file to enable the checks.

no-mistakes axi

Agent eXperience Interface for non-interactive agents. Most agent workflows use the installed /no-mistakes skill, which drives this command surface underneath. It prints TOON to stdout, prints progress to stderr, and uses structured stdout errors with exit code 1 for operational failures and 2 for bad usage. At the TOON output boundary, unsupported C0 control bytes are rendered as visible \xNN escapes while tabs, carriage returns, newlines, printable Unicode, and the underlying durable logs remain unchanged. If TOON encoding still fails, AXI prints a structured error instead of returning successful empty stdout. The calling agent drives AXI approval gates but does not replace the configured pipeline agent that performs validation.

Terminal window
no-mistakes axi

With no subcommand, shows the executable path, description, repo, current branch, daemon state, recent runs, and next-step help, including a pointer to no-mistakes axi run --help and the installed /no-mistakes skill for full driving guidance. When the current branch has an active run, that run appears as active_run with any approval gate and help for axi respond when it is parked or axi status when it is still running. If an active run object is parked at a decision gate, it includes awaiting_agent: parked <duration> immediately after status. That field is observability only; the gate: object still tells the agent which response to send. If a step is actively running or fixing, the run object can also include an active_steps table with step-scoped active_for, current-round round_active_for, last_activity, native agent_pid when one is currently running, and the current execution or fix round. When only another branch has an active run, that run appears as other_branch_active_run; the help tells agents to leave it alone and start validation for the current branch. AXI help and outputs always repeat the preserve-prior-gate-progress contract: after a gate round has already produced fix commits, additional fixes belong on the same branch. When a relevant branch_sync object is present, they also include version-matched synchronization guidance to follow before a post-pipeline local commit or fresh run. Agents must not abort-and-restart, reset, replace the branch, or improvise Git recovery in a way that drops prior gate-fix commits. A fresh run re-validates the current branch state, so already-resolved findings do not re-surface.

no-mistakes axi run

Start or reattach to validation for the current branch, blocking until the first approval gate, CI-ready decision point, or final outcome. An active run on another branch does not block starting validation for the current branch.

Terminal window
no-mistakes axi run --intent "the user's goal"
no-mistakes axi run --intent "the user's goal" --skip test,lint
no-mistakes axi run --intent "the user's goal" --yes
no-mistakes axi run --intent "the user's goal" --base-branch epic/foo
FlagTypeDefaultDescription
--intentstring(none)What the user set out to accomplish; required to start a new run
-y, --yesboolfalseAuto-resolve eligible gates until a decision point or outcome
--skipstring(none)Comma-separated pipeline steps to skip
--base-branchstring(none)Integration branch for this run only; overrides pr.base_branch
--waitduration8mMaximum time for active-run lookup and run driving before the caller must reattach
--launch-noncestring(none)Non-secret correlation identifier for a durable pre-drive receipt; requires --validation-generation
--validation-generationstring(none)Caller-selected validation generation bound to --launch-nonce; requires that flag

--intent is not a description of the diff. It is the user’s goal or request, and no-mistakes uses it verbatim instead of transcript inference. Err on the side of completeness: include the goal, important decisions and tradeoffs, constraints or approaches ruled in or out, and explicit requests that might otherwise look surprising in the diff. When starting a new run, axi run refuses the default branch and uncommitted working trees with actionable errors instead of auto-branching or auto-committing. Ordinary reattachment to an in-flight run does not require --intent; strict launch receipts require the original intent bytes on every retry. --base-branch is persisted on the run so rebase, PR, and CI honor it after resume. Reattaching with a --base-branch that differs from the active run’s stored target is refused rather than silently discarded; omit the flag to reattach, or abort the active run first. Ordinary reattachment accepts either the run’s immutable submitted head or its current pipeline head, so pipeline-created fix commits do not detach an unchanged submitting worktree. When neither identity matches, axi run keeps the fresh-run path but refuses a gate push while branch_sync says the pipeline still owns the branch. That refusal returns the complete structured state and its continue_active_run or recover_custody next action instead of a raw Git non-fast-forward. Reattaching to an in-flight run can proceed while the daemon is already running even if the global config file has become invalid, but starting a fresh run still requires valid global config. Starting a fresh run also requires a runnable effective pipeline agent. If the configured native agent or ACP runner is unavailable, the run fails before any pipeline step starts instead of reporting command-only validation as a passed gate. With --yes, axi run treats both action: auto-fix and action: ask-user findings as standing consent for the pipeline to fix them by selecting every finding, then accepts the resulting fix review. Gates with no findings or only action: no-op findings are approved as-is, and each step is fixed at most once so unresolved findings do not loop forever. The protected_paths refusal rules are an exception to this automatic handling. Without --yes, an agent driving axi run should stop when a gate contains action: ask-user findings and relay each finding’s ID, file, and full description to the user before responding. Review gates include a note field reminding agents that auto_fix.review defaults to 0, so blocking and ask-user review findings park for a decision unless configuration explicitly opts back into review auto-fix. Long-running axi run calls are working, not stalled; if one returns a gate:, read that output and answer it with axi respond. --wait defaults to 8m so an agent harness with a 10-minute tool cap gets a structured error instead of an unbounded hang. It bounds the active-run lookup, event-subscription acknowledgement, and subsequent run driving. Elapsed wait is not a pipeline failure and does not mean the daemon is dead: run no-mistakes axi status and reattach with axi run. A live daemon that is slow to answer a pre-drive get_active_run or get_run state read is retried after a health probe rather than reported as an I/O failure or mistaken for an absent run. Backgrounding a call is fine for an agent harness, but the run never advances past a gate on its own. When the CI step is still monitoring an open PR and checks are green - or the trusted default-branch config declares no_ci: true with no registered checks - axi run exits successfully with outcome: checks-passed instead of waiting for a human merge. A generic empty check list without that declaration is not ready. Treat that as the agent stopping point: ask the user to review and merge the PR from the help line. If that PR later falls behind the default branch or hits a merge conflict, do not run axi run, rerun, or a manual rebase while the CI monitor is still running. The monitor auto-rebases onto the base, resolves actual conflicts, revalidates from Review because rebasing cannot prove continuity with the reviewed head, and re-pushes the branch through Push; a PR that is merely behind but clean needs no command. After that monitor ends, see no-mistakes rerun for the restart conditions. Successful outcomes (checks-passed, passed, passed-with-override, and passed-with-skips) also carry help instructions telling the agent to summarize the run. passed-with-override is a completed run whose CI approval gate was approved by a human while a live check was still failing; it stays a success but reads distinctly from a genuinely green passed, and its help names the failure the operator approved past. passed-with-skips is a completed run where PR publication or CI verification automatically skipped because its provider was unavailable, or CI had no PR URL. It retains exit code 0: missing verification is not a failing code verdict. run.automatic_skips names each affected step and cause, and run.head_sha gives the full recorded head in both drive output and axi status. Report that missing evidence; this outcome does not establish CI readiness or a merge. Explicit per-run skips retain their existing behavior. If the run also has a CI approval override, passed-with-override takes precedence and the automatic skip causes remain visible. Legacy rows without a recorded skip cause keep their prior classification; their logs remain inspectable. When the pipeline applied fixes, they include a fixes table and a help instruction to acknowledge the misses and list those fixes for the user’s review.

Strict launch receipts

Supply --launch-nonce and --validation-generation together to bind a launch to an exact request instead of reattaching by branch and head alone. Both identifiers must be 1–128 ASCII characters from A-Z, a-z, 0-9, ., _, ~, and -; they are non-secret correlation values and must not contain credentials. This mode requires the same exact --intent bytes on retries.

Terminal window
no-mistakes axi run --intent "the user's goal" \
--launch-nonce request-42 --validation-generation validation-3 \
--base-branch epic/foo

After durable creation or claim, AXI writes a TOON launch_receipt object to stdout before driving the run. The receipt remains available to a caller that captures stdout even if driving later stops at a gate or fails. It contains run_id, disposition (created or reused), launch_nonce, validation_generation, branch, head_sha, submitted_head_sha, and intent_digest. Both head fields contain the full, immutable submitted commit SHA; intent_digest is the lowercase SHA-256 digest of the exact persisted intent bytes, including whitespace. Raw intent is not included in receipts, and generic run/status output does not expose the nonce binding or intent digest.

The nonce is scoped to the repository and branch. The first successful receipt claim returns created; subsequent matching claims return reused for that same run, including after the gate or pipeline head advances. A conflicting submitted head, validation generation, or intent is refused. A different nonce creates a distinct run rather than reattaching to a same-head run; both post-receive creation and the up-to-date-push fallback follow this contract. The up-to-date-push fallback preserves the latest same-head run’s PR URL unless its recorded PR state is closed or merged, including when an explicit --base-branch retargets that PR. An explicit --base-branch is persisted on creation and must match the stored per-run base on replay; omitting it on replay preserves the stored base. A conflicting claim does not consume the first created disposition. Without the two proof flags, ordinary reattachment is unchanged, and historical runs without a nonce are not adopted into a proof binding.

no-mistakes axi respond

Answer the current approval gate and continue until the next gate, CI-ready decision point, or final outcome.

Terminal window
no-mistakes axi respond --action approve
no-mistakes axi respond --action fix --findings F1,F2 --instructions "optional guidance"
no-mistakes axi respond --action fix --add-finding '{"description":"...","action":"auto-fix"}'
no-mistakes axi respond --action skip
FlagTypeDefaultDescription
--actionstring(none)approve, fix, or skip; required
--stepstringawaiting stepStep to respond to
--findingsstring(none)Comma-separated finding IDs for --action fix
--instructionsstring(none)Guidance applied to selected findings
--add-findingstring(none)JSON finding object to add and fix
-y, --yesboolfalseAuto-resolve subsequent eligible gates until a decision point or outcome
--waitduration8mMaximum time for pre-drive reads and post-response driving before the caller must reattach

After the explicit response, --yes uses the same auto-resolution behavior and exceptions as axi run --yes. Each axi respond blocks until the next gate, CI-ready decision point, or final outcome, subject to the same default --wait 8m boundary as axi run. That boundary also covers its initial active-run and run-state reads plus event-subscription acknowledgement, so a caller can interrupt establishment as well as the later event wait. If it returns another gate:, answer that gate; do not idle-wait for the run to move forward by itself. When the daemon is already running, axi respond can continue an active run even if the global config file has become invalid, because it is not starting a fresh run. The same successful-output reporting instructions apply to axi respond results.

no-mistakes axi status

When --run is omitted, show this branch’s run: its active run, else its most recent one. Resolution is scoped to the current branch and never falls back to another branch’s run, because one clone commonly has several worktrees on different branches. On a successful status response, when the current branch has no run of its own - including a detached HEAD, which owns no branch and so reports current_branch: unknown - the output carries no run object at all. It reports current_branch, runs_on_current_branch: 0 where a branch is known, and the recent-runs listing, so an unrelated run can never be read as this worktree’s. If the implicit current-branch lookup itself fails, status returns that error instead of presenting the failure as a detached or no-run result. Detached-HEAD help offers deliberate --run <id> inspection or checking out a branch; it does not offer axi run, which requires a branch. With --run <id>, inspect exactly that run regardless of branch; when its branch differs from a known current branch, it is rendered under other_branch_run: instead of run:, alongside a top-level current_branch, so a parser keyed on run: never picks up a run proven to be on another branch. An explicit --run <id> rendered under run: while the current branch is unknown (detached HEAD or a branch-lookup failure) encodes no branch relationship.

Terminal window
no-mistakes axi status
no-mistakes axi status --run <id>
FlagTypeDefaultDescription
--runstringcurrent-branch runInspect a specific run ID

When the resolved run is parked at an awaiting_approval or fix_review gate, its top-level run: or other_branch_run: object includes awaiting_agent: parked <duration> immediately after status. The field disappears after that run’s gate is answered, on cancel, and on terminal outcomes; use it to distinguish a run waiting for the driving agent from one actively running, fixing, or watching CI. Status offers branch-scoped axi respond commands only for the current branch’s implicitly resolved run. An explicitly selected gate stays inspection-only even when its branch matches, because a newer active run on that branch could receive the bare response command instead; the gate remains visible and its log commands retain --run <id>. When a repository has no configured lint command and Document performs the combined Document/Lint housekeeping invocation, the run object includes shared_work evidence naming its document+lint housekeeping scope and the duration attributed to Document; Lint’s own duration remains the cached-result handoff time. When the resolved run has a running or fixing step, the run object includes active_steps. Each row reports the whole step’s elapsed time as active_for, the displayed execution or fix round’s elapsed time as round_active_for, the latest meaningful log or native-agent lifecycle activity, the native agent PID if one is currently running, and the current round such as round 1, auto-fix 1/3, or fix 2. round_active_for resets when a fix round starts; older active runs created before this timing was recorded show it as empty. If no activity arrives for longer than step_quiet_warning, last_activity is prefixed with quiet; this is only a liveness signal and does not cancel the step. For older active runs with no recorded activity timestamp, AXI falls back to the step log file modification time. Gate summaries and finding descriptions are bounded in this default status view; truncated values disclose their original length, and the gate help points to no-mistakes axi logs --step <step> --full for an implicitly resolved run or no-mistakes axi logs --run <id> --step <step> --full for an explicitly selected run. Relevant current-branch states also include a cached branch_sync object with full SHAs, the run’s status, the persisted pipeline push binding, target kind and ref, relation, safety result, PR lifecycle, and a structured next action. Cached home and status rendering performs no network read and labels the remote observation pipeline_push; only explicit sync check or apply reports live freshness.

no-mistakes axi sync

Freshly check or apply the guarded synchronization offered by a branch_sync.next_action.

Terminal window
no-mistakes axi sync --check
no-mistakes axi sync
no-mistakes axi sync --recover
no-mistakes axi sync --recover --keep-local
no-mistakes axi sync --bind-archive-ref refs/heads/archive/<name>
FlagTypeDefaultDescription
--checkboolfalseVerify the live target and exact plan without changing HEAD
--recoverboolfalseReturn custody of a branch stranded by a terminal run with unpublished pipeline commits (a no-op when cancellation already released the branch)
--keep-localboolfalseWith --recover: keep the current local head; never touches the worktree
--bind-archive-refstring(none)Bind one existing refs/heads/archive/* commit as exact evidence for a keep-local recovery; never creates or moves a Git ref

The default command is an explicit non-interactive apply request and never prompts. All modes return the complete branch_sync object as TOON. Exit code 0 means an eligible check, applied synchronization or recovery, already-synchronized, custody-returned, or user-owned no-op, or expected merged-and-removed no-op; blocked operational states return 1. The ordinary worktree mutation is either a strict fast-forward of the invoking clean checked-out branch to the freshly verified pipeline-owned pushed SHA, or an equivalent-diverged advance. When a clean local branch and the pipeline-pushed head are diverged but the local unique work is content-equivalent to work already represented in the live pipeline head, sync reports safety: safe_equivalent_advance, anchors the pre-sync head under refs/no-mistakes/sync-anchor/<run>, and moves to the pipeline head with reset semantics. Genuine divergence still reports safety: blocked_diverged and changes nothing during ordinary synchronization. Under --recover, the possible worktree mutation is a strict fast-forward to the preserved pipeline head, or an adoption of a preserved head proven to carry every local change, both after relation-specific preservation checks. The bound-archive exception described below never changes the worktree at all. When the local gate branch is exactly at a newer same-branch pushed binding and Git proves that an older terminal run’s unpublished preserved head is its ancestor, branch synchronization selects the newer binding; missing gate evidence, non-ancestor heads, or different or ambiguous target provenance remain blocked. Fork configurations verify the configured fork URL and exact feature ref rather than assuming origin. Dirty, in-progress, ahead, genuinely diverged, detached, wrong-branch, offline, changed-target, rewritten, deleted, legacy, or retired states fail closed without destructive recovery. Run axi sync only when structured output offers next_action.code: sync; process any blocked state instead of substituting reset, stash, merge, rebase, force, or branch replacement.

Custody recovery

A run that goes terminal (cancelled, failed, or completed without a push stage) after moving the pipeline head leaves the branch pipeline_owned. Status offers next_action.code: recover_custody only when recovery can establish the same eligibility it will enforce: an equal or ahead local head proves the source locally and can create the local anchor when the gate is unavailable, but any existing gate recovery ref must still match the recorded head; importing a missing preserved head requires an exact run-specific gate anchor (or legacy commit evidence that can be anchored), a clean worktree, and either local ancestry or the content-preservation proof described below. The archive-backed keep-local exception has its own stricter proof below. An eligible state reports safety: blocked_pipeline_owned_recoverable, the run’s terminal pipeline.status, and the exact submitted_head/current_head/relation ownership facts. A run whose terminalization verifies that the managed worktree head never changed from the submitted head releases the branch instead: the terminal outcome, including cancellation, ends ownership; status reports state: user_owned with the same exact ownership facts and no next_action; the branch and head are immediately usable for any separately authorized delivery; and nothing blocks a direct push or PR. Without positive evidence that the submitted head stayed unchanged, custody is not guessed away. Conflicting evidence, import cases with a dirty worktree, and genuinely divergent history retain manual-reconciliation guidance instead of being labeled as a missing preserved head. When a verified recorded head is absent from both the invoking worktree and an accessible local gate, with compatible recovery refs, status reports safety: blocked_recover_preserved_head_missing with next_action.code: recover_custody and no-mistakes axi sync --recover --keep-local: that flag is the operator’s explicit choice to keep the current local head and discard the missing preserved commits. An unavailable gate remains blocked because absence cannot be established there. The archive-backed keep-local exception has its own stricter proof below. While a run is still active, it reports state: pipeline_owned, the exact submitted/current heads and their relation, and next_action.code: continue_active_run with no-mistakes axi status, even when its head has not moved yet. --recover verifies the run is terminal, anchors the preserved head under refs/no-mistakes/recover/<run> in the invoking repository, and stamps custody returned so a fresh run can start. For equal or ahead worktrees where the preserved head is already locally reachable, recovery writes that anchor locally without requiring gate access. If the gate is available, an existing symbolic, non-commit, or mismatched recovery ref is conflicting evidence and recovery refuses without overwriting it. For behind or diverged worktrees, recovery verifies the preserved head at the run-specific recovery ref in the local gate and fetches it into the anchor before moving or refusing. Legacy recorded heads that remain available as unreferenced gate objects are anchored before recovery continues. A clean behind worktree fast-forwards. A diverged worktree is adopted only when the preserved head provably carries every local change, proven by an executable three-way merge whose result is exactly the preserved head’s tree. This covers a pipeline rebase onto a newer base without requiring the gate branch to advance to the preserved head. Terminalization pins a verified unpublished pipeline head under a run-specific recovery ref, so recovery does not require the gate branch itself to have advanced. If the verified recorded head is absent from both the worktree and an accessible gate and the recovery refs are compatible, status still offers recover_custody, but the command is --recover --keep-local rather than taking that head. Plain --recover without --keep-local still refuses. That adoption anchors the pre-recovery local head under refs/no-mistakes/recover-local/<run>, then moves the branch with Git operations that refuse on their own rather than after a preceding check: an atomic compare-and-swap on the branch ref, and a working-tree update that aborts instead of overwriting a modified or untracked file. The proof is deliberately narrow and never uses patch identity, which discards hunk locations and whitespace and so cannot tell a genuine replay from a same-shaped edit elsewhere. Anything it cannot decide - unlanded local commits, or a rebase whose fix rounds also rewrote your own lines - still refuses with the anchor named, because only escalation can tell a deliberate pipeline fix apart from a dropped change. A dirty worktree refuses with explicit choices. When you explicitly keep a behind or diverged local head instead of taking the preserved head, --keep-local returns custody at the current head without touching the worktree and atomically points the gate branch at it. --keep-local is also the recovery when an accessible gate confirms that the verified recorded head is missing and the recovery refs are compatible: the operator is keeping the current local head and discarding those unpublished commits, so that missing object does not block the path. One --keep-local call releases the full stranded stack: genuinely missing heads are explicitly discarded, while still-available heads are anchored under their run-specific recovery refs first. Unverified or conflicting evidence on any run blocks the release before any custody stamp. If the gate branch moved independently, recovery first preserves that head under refs/no-mistakes/recover-gate/<run>; a conflicting pre-existing anchor makes recovery refuse, and a concurrent gate push wins the compare-and-swap and also makes recovery refuse.

A narrower archive-backed path handles a divergent later validation head that must be preserved but must not become the working result. First create the archive ref through a trusted preservation workflow, then explicitly bind that already-existing ref with --bind-archive-ref. Binding writes only an append-only recovery-archive record; it never creates, moves, fetches, or deletes a Git ref. The record snapshots the repository ID, lookup and evidence run IDs, branch, exact required working head, exact preserved later head, archive ref, and creation time.

Status uses the same recoverySourceAvailable classification as recovery and accepts this path only when exactly one record matches the selected terminal run, the clean checked-out branch remains at an exact submitted, reviewed, or successfully pushed required head, the later recorded head genuinely diverges, the raw archive ref is a non-symbolic commit at that exact later head, and the gate’s run-specific recovery ref independently still pins it. The gate branch itself must be at either the required head or the preserved head. It revalidates the repository, run, branch, both full SHAs, archive ref, gate branch, and every existing recovery anchor before each action. Missing, moved, replaced, symbolic, malformed, cross-repository, wrong-run, wrong-branch, stale, hash-mismatched, or multiple records fail closed with next_action.code: inspect_and_reconcile_manually; similarly named branches, reflogs, loose objects, remote-tracking refs, and tags are never scanned or inferred as proof.

A verified archive plan reports its evidence in branch_sync.recovery, keeps next_action.code: recover_custody, and sets the command to exactly no-mistakes axi sync --recover --keep-local. That action leaves the worktree and local branch at recovery.required_head, leaves the divergent archive at recovery.preserved_head, and never merges, replays, fast-forwards, resets to, or otherwise selects the archived history. Running plain --recover against this plan refuses without adding an anchor or moving a ref.

For the alternative validation path and its refusal conditions, see no-mistakes rerun; it is not offered for the archive-backed keep-local plan. A recovered never-pushed run reports state: custody_returned; a recovered pushed run reports its ordinary classification against the last push binding, typically local_ahead. On a user_owned branch, --recover is an idempotent no-op success: nothing pipeline-created exists to recover, and no file, ref, or database row changes.

no-mistakes axi logs

Show the log output of one pipeline step.

Terminal window
no-mistakes axi logs --step review
no-mistakes axi logs --step review --full
no-mistakes axi logs --step review --run <id>
no-mistakes axi logs --step gate.test.mutation-budget
FlagTypeDefaultDescription
--stepstring(none)Step name; required
--runstringcurrent-branch runRun ID to inspect
--fullboolfalseShow the entire log instead of the tail

When --run is omitted, the run is resolved the same way as axi status: this branch’s run, never another branch’s. With --run <id>, logs are read from exactly that run regardless of branch. An unknown explicit run ID exits nonzero with error: run "<id>" not found instead of reporting that the current branch has no run. Without --full, long logs show the last 40 lines and a help hint for the full log; when --run <id> selected the log, that hint retains the same run ID. Step logs include native subprocess agent lifecycle lines such as codex started pid=4242, codex exited pid=4242 status=success, and transient retry messages when the selected agent supports lifecycle events. They also include fix-loop markers such as auto-fix round 1/3 starting after round 1 and user-fix round starting after round 2. --step accepts the nine core step names and valid repository gate names such as gate.test.mutation-budget. Use the exact gate name shown by axi status.

no-mistakes axi abort

Cancel the active run for the current branch. Active runs on other branches are left alone.

Terminal window
no-mistakes axi abort

If there is no active run, this succeeds as a no-op.

Pass --run <id> to cancel a specific run by its id instead of resolving the current branch:

Terminal window
no-mistakes axi abort --run <id>

--run does not need a repo, branch, or worktree, so it works from anywhere. Use it to reap an orphaned CI monitor whose worktree was torn down before the PR merged - the run id is shown in axi run output and in the axi home view. A --run id that is not currently active is resolved against the exact run’s durable record rather than trusted blindly: a known already-terminal run returns an idempotent success carrying its terminal run_status with no fabricated new cancellation, a positively proven unknown id keeps the documented successful no-op with no fabricated state, and a run that is recorded as still nonterminal or cannot be read returns the nonzero terminal-unconfirmed contract. When the daemon is not running, nothing can be cancelled and abort never starts one: the durable record alone decides the same three outcomes, and a recorded nonterminal run reports that cancellation could not be requested. When the daemon is already running, axi abort can cancel an active run even if the global config file has become invalid, because it is not starting a fresh run. Both abort surfaces report a completed cancellation only after the exact run positively confirms a terminal state within the bounded wait; success then includes the terminal run_status, and branch-scoped abort renders the refreshed branch_sync object and its exact next action, if any. When terminal quiescence cannot be confirmed - the bounded wait expires, the wait is cancelled, or a status read fails - abort exits nonzero, states explicitly that cancellation was requested but terminal quiescence is unconfirmed, includes the last structured run state when one is available, and never claims aborted: true or presents user-owned or recoverable ownership guidance as authoritative; re-run the abort or watch axi status --run <id> until a terminal status is confirmed. Pipeline-created commits remain preserved in the gate and a recoverable cancellation points directly to no-mistakes axi sync --recover; when the submitted head never moved, cancellation instead reports state: user_owned with no sync action. While a run is active, do not use axi abort or no-mistakes rerun to go fix a finding yourself. That cancels the pipeline’s in-flight work and forces a full re-validation; use axi respond --action fix at the gate so the pipeline applies and re-checks the fix.

no-mistakes eject

Remove the gate from the current repository.

Terminal window
no-mistakes eject

Removes the no-mistakes remote, deletes the bare repo directory, cleans up worktrees, and deletes the database record (cascades to runs and steps). It does not remove any legacy repo-local agent skill files left by older versions; current init installs the skill at user level instead.

no-mistakes attach

Attach to the active pipeline run.

Terminal window
no-mistakes attach [--run <id>]
FlagTypeDefaultDescription
--runstring(none)Attach to a specific run ID instead of the active run

Opens the TUI for the active run anywhere in the current repo. If --run is specified, attaches to that specific run regardless of branch. Unlike bare no-mistakes, this does not stay branch-scoped before falling back.

no-mistakes rerun

Rerun the pipeline for the current branch.

Terminal window
no-mistakes rerun
no-mistakes rerun --intent "the revised user goal"

Starts a new pipeline run from the current gate branch, except when the latest terminal run has a verified unpublished head whose custody has not been returned: rerun then uses that preserved terminal head even if the gate branch is stale. The command refuses instead of falling back to the gate branch when the run-specific recovery ref is conflicting, invalid, or the recorded head is unavailable. Use no-mistakes axi status and reconcile custody first in that case. When invoked from a clean worktree, rerun also refuses if that worktree’s HEAD differs from the selected gate or preserved head, before starting or superseding any run. The error names both full commit SHAs; inspect no-mistakes axi status and follow its custody guidance, then use no-mistakes axi run to submit local commits. The refusal leaves both branches unchanged; rerun never replaces its selected head with the caller’s head. The same check applies to axi run’s rerun fallback after an up-to-date push. Dirty worktrees and callers without clean-head evidence, including TUI reruns, retain the existing selection behavior. If the selected prior run has explicit intent, rerun inherits it exactly by default; otherwise it performs fresh intent inference. --intent supplies a new canonical explicit intent in either case. Inherited intent keeps distinct rerun provenance; an override is recorded as newly supplied explicit intent, while fresh inference records the transcript source. If another run is active on that branch, rerun cancels it before starting over. Treat rerun as a between-runs action after a failed or cancelled outcome; use axi run for separate local fixes, and do not use rerun to bypass a gate.

FlagTypeDefaultDescription
--intentstring(none)Explicit intent overriding inherited intent or fresh inference

no-mistakes sync

Freshly verify and, with confirmation, safely move the invoking branch to an exact pipeline-owned push binding.

Terminal window
no-mistakes sync
no-mistakes sync --check
no-mistakes sync --yes
no-mistakes sync --recover
no-mistakes sync --recover --keep-local
no-mistakes sync --bind-archive-ref refs/heads/archive/<name>
FlagTypeDefaultDescription
--checkboolfalseVerify and print the fresh plan without changing HEAD
-y, --yesboolfalseApply an eligible guarded synchronization without an interactive prompt
--recoverboolfalseReturn custody of a branch stranded by a terminal run with unpublished pipeline commits (a no-op when cancellation already released the branch)
--keep-localboolfalseWith --recover: keep the current local head; never touches the worktree
--bind-archive-refstring(none)Bind one existing refs/heads/archive/* commit as exact keep-local recovery evidence without changing Git refs

Without --yes, apply prints the exact full-SHA plan and requires TTY confirmation; --recover prompts the same way before returning custody. Archive binding is itself explicit, does not prompt, and cannot be combined with synchronization, recovery, or --yes. A non-TTY apply or recovery refuses with a direct --yes hint. The command uses the same service and safety contract as no-mistakes axi sync, including the guarded equivalent advance and custody recovery documented there; it never stashes, rebases, creates a merge commit, switches branches, deletes a branch, or updates an external remote.

no-mistakes status

Show repo, daemon, active run, and relevant cached local-branch synchronization status.

Terminal window
no-mistakes status

Displays:

  • Repo path, upstream URL, and fork URL when configured
  • Gate path
  • Daemon status (running/stopped, PID)
  • Active run details: ID, branch, status, head SHA, start time

no-mistakes runs

List recorded pipeline runs for the current repo.

Terminal window
no-mistakes runs [--limit <n>]
FlagTypeDefaultDescription
--limitint10Maximum number of runs to display

Shows runs newest-first with branch, status (styled), short SHA, timestamp, and PR URL if set.

no-mistakes eval

Inspect the locally collected review-case corpus before spending tokens, replay an explicit agent and model with isolated no-mistakes state and a throwaway worktree, and report finding-level scores, token cost, wall time, and the recall-versus-cost frontier. Eligible cases are collected automatically as runs finish; eval capture <run-id> collects one on demand; eval miss ingest <run-id> --finding '<json>' labels a confirmed post-PR miss (review passed green, later caught) as false-negative gold.

See Evaluation toolkit for the local-only boundary, collection and retention, command flags, label policy, and reporting semantics.

no-mistakes stats

Show historical usage stats across all repos.

Terminal window
no-mistakes stats

Displays total changes, rescued changes, rescue rate, reported and fixed mistakes, fixes by pipeline step, and the top repos by rescue activity.

Use --agents for local, per-purpose agent performance aggregates: duration and the subprocess-vs-model time split, session mode, errors, the token totals (input, output, cache-read, cache-creation, fresh input, reasoning), and the model round-trip and tool-category activity histogram, with a METRICS coverage count that tells a real zero apart from missing instrumentation. Use --run <id> to inspect the individual agent invocations for one run - including each invocation’s per-round token deltas next to the raw counters (cumulative across a resumed session for codex; per-invocation for pi), tool-category breakdown, workload size, finding count, and fallback reason - plus the total time parked at approval gates; it implies --agents. The combined Document/Lint invocation is labeled housekeeping (document+lint) and attributed to document+lint, making its shared duration and tokens explicit without adding a second agent call. Nullable fields an adapter did not report render as - (unknown), which is distinct from a recorded 0; the legacy raw input, output, and cache-read counters remain numeric.

Terminal window
no-mistakes stats --agents
no-mistakes stats --run <id>

This detailed performance evidence stays local in state.sqlite; it is not sent to telemetry. The field definitions and their local/remote split are owned by the environment reference.

no-mistakes doctor

Check system health and dependencies.

Terminal window
no-mistakes doctor

Checks:

  • git binary
  • gh CLI (optional, needed for GitHub PR and CI steps)
  • az CLI (optional, needed for Azure DevOps PR and CI steps)
  • Data directory (~/.no-mistakes/)
  • SQLite database
  • Daemon status
  • Agent runners: native binaries claude, codex, grok, acli, opencode, pi, copilot, and agy (Antigravity), plus the optional ACP bridge acpx
  • ACP alias default binaries: cursor-agent plus acpx for cursor
  • Effective global agent configuration, reported as gate validation; an unavailable configured runner is a failed check because the gate cannot validate without it
  • Every configured forge_profiles entry, reported as forge <host>: the profile resolves and validates, its provider CLI is installed, and that CLI is authenticated for the profile’s host

Uses indicators: (available), (not found, optional), (problem detected).

The standalone runner rows inspect default binary names; the cursor row reports whichever of cursor-agent and acpx are missing. The Global Config Reference owns ACP gate-validation availability and probing semantics. Each validation run performs the authoritative agent resolution again after applying any trusted repository-level override.

doctor checks gh and az availability. Provider Integration owns the separate setup checks for GitLab, Forgejo, Bitbucket Cloud, Gitea, and the Azure DevOps extension and PAT.

tea stays docs-only like glab, forgejo-axi, and Bitbucket’s env vars, rather than an active doctor check like gh/az: Gitea is almost always self-hosted, so a bare “tea not found” row would be a near-universal, low-value warning for the vast majority of users who have no Gitea instance at all.

no-mistakes update

Update the installed binary and reset the daemon.

Terminal window
no-mistakes update
no-mistakes update --beta
no-mistakes update -y
no-mistakes update --force

Downloads the latest release, verifies the SHA-256 checksum, atomically replaces the running binary, and resets the daemon when it is running or stale daemon artifacts exist so the new executable is picked up, preferring the managed service path and falling back to a detached daemon if service startup is unavailable or fails. By default this installs the latest stable release. Pass --beta to include prereleases and install the latest beta when one is newer than the current stable release. Version discovery reads a channels.json manifest from the GitHub release-asset CDN (releases/download/channels/channels.json) so it does not consume the unauthenticated REST API rate limit. If the manifest is unavailable or invalid, the update fails without falling back to the REST API. If the daemon is running from a different executable path, update still prompts before replacing it; pass -y/--yes to answer that prompt non-interactively. If the daemon executable path cannot be determined, the update aborts before replacement. If the daemon does not come back cleanly after a successful replacement, the command reports that failure. On macOS, removes the quarantine extended attribute. Daemon & Worktrees owns the active-run guard, the scope of --force and --yes, and recursive validation-step containment.

Because update installs the latest official release binary, the replacement binary includes the default self-hosted telemetry host and website ID. Disable telemetry with NO_MISTAKES_TELEMETRY=0, or override the host and website ID with NO_MISTAKES_UMAMI_HOST and NO_MISTAKES_UMAMI_WEBSITE_ID.

Background update checks run automatically on each CLI invocation (except update itself and version queries --version / -v, which stay side-effect-free). If a newer version is available, a notification is printed to stderr. Suppressed for dev builds or when NO_MISTAKES_NO_UPDATE_CHECK=1 is set.

no-mistakes daemon start

Start the daemon, installing or refreshing the managed service when possible.

Terminal window
no-mistakes daemon start

Prefers the managed service path and falls back to a detached daemon if service install or startup is unavailable or fails. If the daemon is already running, the command refreshes a stale macOS launchd or Linux systemd service definition and restarts through the managed service; if the definition is unchanged, it reports that the daemon is already running. Daemon & Worktrees owns the startup readiness, timeout, fallback cleanup, and singleton lifecycle details.

no-mistakes daemon stop

Stop the running daemon process.

Terminal window
no-mistakes daemon stop
no-mistakes daemon stop --force

Daemon & Worktrees owns the active-run guard, the scope of --force, and recursive validation-step containment.

This does not remove the managed service. A later no-mistakes, no-mistakes daemon start, init, attach, rerun, or update can start the daemon again through the same service manager when available, or as a detached daemon otherwise.

no-mistakes daemon restart

Restart the daemon.

Terminal window
no-mistakes daemon restart
no-mistakes daemon restart --force

Stops the current daemon and starts it again. This works whether the daemon is currently running or not. Daemon & Worktrees owns the active-run guard, the scope of --force, and recursive validation-step containment.

no-mistakes daemon status

Check whether the daemon is running.

Terminal window
no-mistakes daemon status

Shows the PID if the daemon is running.