Defining an organization

QUORUM.md format

Define an entire organization — name, budget, mission, and every agent — in a single Markdown file. The complete reference.

A QUORUM.md in the org root is the org definition — its name, budget, mission, and every agent, all in one file. Nothing else is scaffolded, and edits take effect on the next boot. (The mission, as always, only seeds the board on the first boot.)

The whole thing

# Acme Labs

A two-person studio shipping weekend projects.

- budget: 25
- defaults: { "provider": { "type": "claude", "model": "claude-opus-4-8" } }

## Mission

Launch the landing page and collect 100 signups.

## Agents

### CEO

You are the CEO. Set direction, break the mission into tasks, delegate.

### Engineer

- reports to: CEO
- capabilities: { "cms": "allow" }

You are the engineer. Build what's asked and verify it works.

One rule throughout

A key: value line (optionally - bulleted) whose key is recognized for its scope is metadata; every other line is prose. Values are single-line and parse as JSON when possible, exactly like agent-file frontmatter. Keys match loosely — reports to, reports-to, and reportsTo are the same key.

That means:

  • The # title is the org name; prose under it is the description.
  • ## Mission is the mission — everything in that section, headings and all, verbatim.
  • Each ### under ## Agents is one agent: the heading is its role (and id), the prose is its system prompt.
  • Each ### under ## Triggers is one event trigger — a schedule, an inbound webhook, or a process watcher. See Triggers & scheduling.
  • Unrecognized ## sections are ignored, so the file can hold notes for humans too.

Org keys

Placed as key: value lines under the # title.

keymeaning
nameorg name (default: the # title)
descriptionone-liner (default: the prose under the title)
budgetspend caps in USD — a bare number means { "totalUsd": n }; the full object takes totalUsd (lifetime — the org halts for good), dailyUsd, monthlyUsd, perCycleUsd; omitted fields mean no cap
defaultsorg-wide agent defaults: { "provider": {...}, "capabilities": {...} }
providershorthand for defaults.provider

Agent keys

Placed as key: value lines under a ### agent heading.

keymeaning
idbus address and directory name (default: slug of the heading); what other agents’ reports to must reference. Repeat a heading and the id is auto-numbered (engineer, engineer-2)
rolethe agent’s label / job title (default: the heading)
goalthe agent’s own standing goal, injected alongside the org mission
reports tothe manager’s id; omit it to make the agent a root (the org lead)
providerthis agent’s brain — overrides defaults.provider
capabilitiesper-agent allow / ask / deny overrides

The reporting tree’s root (an agent with no reports to) is the lead — it coordinates, plans, and reviews. There is normally exactly one.

The provider object

Used as provider: on an org default or a single agent. See The brain for the full story.

fieldmeaning
typethe brain: "claude", "codex", an agent-CLI family member ("opencode" / "cline" / "copilot" / "hermes" / "kimi" / "droid" / "gemini"), the lightweight "llm" text brain, or "fake" (deterministic, offline)
modelmodel id, e.g. claude-opus-4-8, gpt-5-codex, gpt-oss:20b
effortreasoning effort: low | medium | high | xhigh | max (claude)
maxBudgetUsdhard per-session spend ceiling enforced by the binary (claude)
binpath to the binary (default $CLAUDE_BIN / $CODEX_BIN / the binary name on PATH)
timeoutMsper-call timeout (default 10 minutes)
retriesretry count on failure (default 3)
argsextra raw CLI args appended to every call
mcppath(s) to MCP server config JSON the org owns; null disables
strictMcpisolate from the operator’s own MCP servers (default true)
settingSources--setting-sources value (e.g. "project,local") limiting which settings the binary loads
pricingoverride the cost-per-token table used by the cost ledger

Capabilities

Each capability is "allow", "ask" (routes an approval request to you), or "deny". Set org-wide via defaults.capabilities, per agent via capabilities. Built-in defaults are allow for everything except crm (ask). Full details in Tools & permissions.

- defaults: { "capabilities": { "crm": "allow", "hire": "ask" } }

A fuller example

This example uses nearly every option — custom ids, per-agent brains, standing goals, and capability overrides.

# Meffecta Studio

A four-person product studio that ships small SaaS products end to end.

- budget: { "totalUsd": 50, "dailyUsd": 10, "monthlyUsd": 40, "perCycleUsd": 2 }
- defaults: { "provider": { "type": "claude", "model": "claude-opus-4-8", "effort": "medium" }, "capabilities": { "crm": "allow", "hire": "ask" } }

## Mission

Launch a paid landing page for the scheduling product and collect the first
100 signups. Validate pricing with at least ten real customer conversations.

## Agents

### CEO

You are the CEO. Set direction, break the mission into tasks, and delegate to your
leads. No `reports to` makes you the root — the lead.

### CTO

- id: ren
- goal: Keep the product shippable at all times.
- reports to: CEO
- provider: { "type": "claude", "model": "claude-opus-4-8", "effort": "high" }
- capabilities: { "hire": "allow" }

You are the CTO. Own technical strategy and direct the engineer.

### Engineer

- reports to: ren
- provider: { "type": "claude", "model": "claude-sonnet-4-6", "effort": "medium", "maxBudgetUsd": 2 }
- capabilities: { "hire": "deny", "delegate": "deny" }

You are the engineer. Note the `reports to: ren` — it points at the CTO's custom
`id`, not the heading.

### Dry-Run Analyst

- reports to: CEO
- provider: { "type": "fake" }

You run on the no-API `fake` brain — deterministic echoes, no key needed. Give
one agent (or `defaults.provider`) this type to dry-run a QUORUM.md for free.

Drafting one from a brief

Don’t want to write it by hand? Describe the org in plain words and let Claude draft the file — one call, validated against the real parser, which you review before spending anything more:

quorum init --prompt "a newsletter studio: an editor leading a writer and a researcher"

Booting the drafted file never calls the LLM again. See the CLI reference.