Arthur Loop

How the loop works

Five stations, in order: the advisor plans, the queue records, the executor builds, the review gate holds, and a human decides. Two rules make it trustworthy: save before acting, and never lose state.

The cycle

  1. Advisor plans. The advisor (an agent CLI, a browser ChatGPT session, or you in manual mode) produces a plan. The response is saved to the artifact store first — nothing acts on unsaved text.
  2. Queue records. Work becomes a job in an append-only ledger with an idempotency key. Re-queueing the same work is refused, so a crash never doubles a job.
  3. Executor works. The executor receives one packet at a time and implements it.
  4. Review gate. Results wait at a required gate. Only the final fenced control block of an advisor response is parsed, against a fixed vocabulary; anything ambiguous is quarantined as control_block_valid: false — which means "get a human", never "use your judgment".
  5. Human decides. A blocking question lands in human-decisions/open.md and pauses that project only. Everything else keeps moving.

Tick: the loop's heartbeat

arthur tick costs no tokens and answers one question — what should happen next?

VerdictMeansNext move
POLL_DUEA job is due and nothing blocks itClaim it and work it
WAITNothing due yetStop; come back at next_due_at
HUMAN_INPUT_REQUIREDA project has an open decisionSurface it; that project is paused
BLOCKED_BY_BROWSER_LOCKAnother session holds a fresh advisor leaseWait, do not break it
BLOCKED_BY_QUOTAQuota at or below your reserveCheckpoint; start nothing new

With --exit-verdict, each verdict maps to a distinct exit code (0, 10, 11, 12, 13) so a shell chain can gate on it. Codes start at 10 so a blocked loop is never mistaken for a broken command.

The resource governor

The governor watches two things. Quota: how much of your subscription the agents have left, read from a provider you choose (CodexBar, a command, or a file), classified GREEN/YELLOW/RED, with a reserve line (default 5%) below which the loop checkpoints instead of starting new work. The machine: host memory and CPU pressure, sampled best-effort and shown beside quota in the console topbar. Per-task usage attribution (arthur usage task) tells you what each packet actually cost.

The files under it all

PathWhatRule
queue/jobs.jsonlJob snapshots, last write winsOnly arthur queue writes here
queue/events.jsonlThe audit trailAppend-only, never rewritten
projects/<ID>/artifacts/Saved advisor responses + indexWritten before anything acts on them
human-decisions/open.mdBlocking questionsStatus: OPEN pauses that project only
runtime/Tick state, session registryDerived; safe to lose
config/arthur-loop.jsonAdapters, quota, projectsHand-edited, validated on load

Never hand-edit the ledgers. The full invariants live in the repo's AGENTS.md.