The autonomous cycle
The heart of Quorum — the loop that turns a pool of Claude sessions into a team that absorbs, plans, executes, reviews, and accounts.
Last updated
The runtime runs one cycle every tickMs (default 10s). A cycle is a pure
function over the persisted board: it absorbs directives, plans, executes,
reviews, and accounts. Because all coordination state is files, a mid-cycle crash
simply resumes on the next tick.
The five steps
Each cycle runs the same five steps, then loops.
1. Absorb directives → goals
Operator messages queued from the dashboard become goals on the shared tracker, oldest first (FIFO), so a burst of directives is never silently reordered.
2. Select the goal to plan
The runtime picks one goal to plan this cycle: the oldest new directive, else the least-recently-advanced open goal. This is fair rotation (below), and it bounds meeting cost to one goal per cycle. One thing jumps the queue: a fired appointment — a time-bound commitment is attended the cycle it fires, not worked into the rotation.
3. Plan (if never planned)
For a goal that’s never been planned, the planner and their direct reports
meet — a real multi-round debate where each speaker argues and the chair polls
for consensus (a line-anchored RESOLVED: yes/no). It’s the planner’s own team in
the room, not the whole company — like a real org, a lead plans with the people
who report to them, which keeps the debate focused and its cost bounded. The
synthesized decision is threaded into decomposition, which breaks the goal
into a task DAG, so the debate shapes the plan rather than being
discarded.
Decomposition is scope-first, not speed-first. The lead is prompted to judge
how large the goal genuinely is and to cover it end-to-end — research, execution,
review, and follow-through — splitting a large or open-ended goal into distinct
workstreams (each handed to the best-suited member, or a new specialist to
hire), using as many subtasks as the work
honestly needs up to maxTasks. The explicit instruction is not to collapse a
big goal into a handful of shallow tasks.
Planning is also grounded in what the org actually operates. The planner
sees the org’s live-services registry, and a goal whose precondition doesn’t
exist yet — a funnel review before anything is live, a metrics pull with
nothing deployed — is deferred, not fanned out into busywork: the goal is
closed with the missing precondition on record (audited as plan.defer), and
a recurring trigger that seeded it simply re-checks on its next firing.
Deferral is for missing preconditions only — work that is itself actionable
(building, researching, drafting) is always planned.
A plan-coverage gate backs that up. Before any task hits the board, an
independent reviewer — never the lead who drew it up, the same “no one grades
their own work” rule as evaluation — judges, skeptically,
whether the plan actually covers the goal or is thin, rushed, or missing whole
workstreams. When the reviewer is confidently unsatisfied (plan.review.rejected
is audited), the goal is sent back for one re-plan with the critique threaded
in, so the second attempt is fuller than the first. A solo org (no independent
reviewer) skips the gate rather than let the lead rubber-stamp itself.
A branch that’s too big for one task becomes a workstream — a child goal a
director owns and decomposes further on a later cycle, bounded by maxOrgDepth.
So planning is recursive: the same meet → decompose → review path runs one level
down, owned by the director instead of the lead. See
Workstreams.
4. Execute
The runtime builds a batch from every non-done task across all goals and runs it in dependency order with bounded concurrency, using an intra-cycle drain loop so that delegation and hiring resolve within the same cycle. Budget or a stop halts new dispatch mid-cycle. Full detail in Task DAG.
5. Account
Each open goal’s progress is recomputed bottom-up. A goal is done only when
it has content (tasks and/or child workstreams) and all of it is done — its
own tasks and every child workstream. Processing deepest-first means a finished
workstream rolls up to its parent within the same cycle. A synthesis (decision
doc) is written once, on the transition to done. Then the loop turns again.
Standing down
Mission accomplished — the org can end its own life. A goal-driven org would
otherwise run forever, idling once its work is done. So the lead (and only the
lead) can end the org’s life when its mission is truly achieved by declaring
MISSION_COMPLETE: <evidence>. It can do this in a task’s output, but the usual
moment is the idle review: once every goal is complete and there’s no open
work, the runtime asks the lead — skeptically — whether the mission is actually
achieved. Crucially, the lead (and the auditor below) are shown the actual
deliverables the org produced — the files on disk, with their contents — not
just a tally of finished goals. Without that, a conscientious lead asked for
“verifiable” completion it can’t inspect would refuse, and a finished org would
idle forever; grounding the review in the real work is what lets a done org
recognise it’s done. Because concluding is irreversible, the claim must still
clear a deliberately high bar before it’s honored:
- Only the lead may claim it, and only with the
concludecapability (setconclude: denyto disable the whole mechanism). - The board must be objectively clear — no unfinished tasks and no undecomposed goals. A claim made while work remains is logged and ignored.
- An independent auditor must confirm it. A different agent (never the claimant — the same “no one grades their own work” rule as evaluation) re-checks the mission against the completed work and must return a yes at ≥ 90% confidence. A solo lead self-audits under the same strict, skeptical prompt.
Only when all three pass does the org stand down: the lead writes a final
report (what was achieved, key deliverables, caveats — saved as a decision
document and printed), the event is audited as mission.complete, and the
runtime stops and exits cleanly. Anything short of that and the org keeps
working. The fake test brain never emits the confirmation, so this can’t fire by
accident.
Fair scheduling — no starvation
A naive runtime works the first unfinished goal every cycle, so a goal that never converges head-of-line-blocks the whole backlog. Quorum avoids that two ways:
- Selection rotates. Each open goal carries a
lastAdvancedCyclecursor; the runtime picks the smallest (never-advanced sorts first), tie-broken by creation time, and stamps the chosen goal. Every open goal is therefore planned within N cycles. - Execution is decoupled from selection. The task batch is the global set of ready tasks across all goals — not just the selected one. So reworked, delegated, and follow-up tasks on any goal run as soon as their dependencies are met. A stuck goal can’t starve the rest.
Only planning is one goal per cycle; execution spans everything ready.
Communication is load-bearing
The message bus isn’t write-only. Each task turn folds a bounded “messages for you” block into the agent’s prompt — prioritizing directives, meeting decisions, and operator responses. The backlog is bounded (the oldest messages drop), so a long run never grows its prompts without limit. Meeting decisions drive planning; operator answers to an agent’s request are delivered to its memory and inbox, and re-open the originating task so the next cycle retries it with the granted thing in hand.
Session continuity
A task and its retries are one conversation, not a series of restarts. Each settled attempt stores the brain’s resumable session id on the task; the next attempt at the same task — a rework carrying reviewer feedback, a retry after an execution error, or a re-open after an operator answer — resumes that session and sends only what changed: the feedback or answer, new inbox messages, and the agent’s current credential grants. The full brief, upstream context, and standing instructions are already inside the conversation, so they aren’t re-sent — or re-billed.
The checkpoint is keyed to the brain that minted it (assignee + model/effort +
persona), so changing any of those — or reassigning the task — starts fresh
rather than resuming a conversation a different brain built up. A turn that
dies before reporting a session keeps the last good checkpoint. Brains without
resumable sessions (the fake test brain, text-only brains, bare mode) simply
run every attempt fresh. An agent’s MEMORY.md remains its memory across
tasks; sessions are its memory within one.
Cost safety & cancellation
Budget is a live control input, re-checked before each task and between drain passes:
- A hard daily/monthly cap, an exceeded
perCycleUsd, or an abort stops new dispatch; in-flight work drains. - Each task run passes the remaining per-cycle budget as the binary’s
--max-budget-usd, so one agentic run can’t blow the cycle cap. - Every cycle can be aborted instantly, killing in-flight
claudechildren — an operator stop or runaway spend halts real work immediately, not at the next tick.
See Cost & budget for the caps themselves.
Failure isolation
One flaky agent must never discard the batch — and one broken brain must never
spin forever. A thrown task is caught, audited, and requeued, bounded by
maxAttempts; at the bound (or on the first auth failure — retrying a
rejected credential can’t succeed) it parks blocked and files a request
saying exactly what failed, and answering the request re-queues the task.
Failed calls cost $0, so this bound — not the budget — is the brake on a
broken-credential org. Provider weather is treated apart: a vendor overload
or rate-limit, an upstream 5xx or a dropped connection isn’t the task’s fault, so
it’s deferred and retried without spending that maxAttempts rework budget —
a passing overload no longer blocks a task or escalates to a human. It’s bounded
by its own higher stall ceiling, so a genuinely persistent outage still
escalates rather than respinning free forever. Siblings still finish; accounting
still runs. A
departed assignee (fired, or a roster shrink) never throws the batch
either — the task is reassigned to the delegating manager, then the lead,
then any live agent, or parked blocked.
Design principles
The runtime is built on six ideas:
- Board as source of truth. All state is persisted files; the runtime is a pure function over them, so a crash resumes cleanly.
- Decouple selection from execution. One goal is planned per cycle, but every ready task across all goals executes — so no goal starves.
- Isolate failure. One flaky agent can’t abort the batch.
- Ground review in independence. No agent grades its own work; an unparseable verdict fails closed rather than rubber-stamping.
- Make cost a live control input. Budget is re-checked mid-cycle and a stop actually kills in-flight children.
- Grow the org from the work. When a task needs a skill the team lacks, the
coordinator hires a specialist; when a branch is too big for one task, it grows
a management layer — planned up front or escalated when discovered — bounded by
maxOrgDepth.
All the knobs mentioned here are collected in Configuration.