Configuration & env vars
Every runtime tunable in one place — cycle timing, concurrency, evaluation, delegation, hiring, and budget — with defaults and where to set them.
Last updated
This is the single reference for every runtime knob. Most have a sensible
default, so a bare org needs none of them. Precedence throughout is CLI flag →
environment variable → file (QUORUM.md) → built-in default.
Runtime tunables
| Option | Env | Default | Meaning |
|---|---|---|---|
tickMs |
TICK_MS |
10000 | cycle interval in ms |
concurrency |
TASK_CONCURRENCY |
4 | max tasks run in parallel per cycle |
evaluate |
EVAL=off |
true | run the quality gate at all |
evalThreshold |
EVAL_THRESHOLD |
60 | minimum passing score (0–100) |
maxAttempts |
— | 2 | total executions per task (initial + reworks); 2 = one rework |
maxDelegations |
— | 3 | subtasks one task may hand to reports |
maxDelegationDepth |
— | 2 | delegate → integrate chain depth cap |
maxAgents |
— | 16 | headcount ceiling for self-hiring (auto + explicit) |
maxTasks |
— | 12 | most subtasks the lead may split one goal into |
maxOrgDepth |
— | 2 | deepest goal nesting / management layers (CEO → directors → ICs) |
planReviewConfidence |
— | 60 | reviewer certainty a plan is thin before it’s sent back for one re-plan |
concludeConfidence |
— | 90 | auditor certainty required to confirm MISSION_COMPLETE and stand the org down |
idleMeetingEvery |
— | 30 | idle cycles between the lead’s standing mission reviews (is the mission done?) |
failOpenOnUnparsedEval |
— | false | auto-pass an unparseable verdict (echo/no-judge only) |
The ones with a flag or env var are also settable there; the rest are runtime constructor options.
Budget
Set as budget in QUORUM.md, by env var, or with --budget (which
maps to totalUsd). An omitted field means no cap.
| Field | Env | Behavior when hit |
|---|---|---|
totalUsd |
BUDGET_TOTAL_USD |
org halts for good (lifetime) |
dailyUsd |
BUDGET_DAILY_USD |
skip cycles until the day rolls over |
monthlyUsd |
BUDGET_MONTHLY_USD |
skip cycles until the month rolls over |
perCycleUsd |
BUDGET_PER_CYCLE_USD |
warn + halt new dispatch mid-cycle |
warnAt |
BUDGET_WARN_AT |
fraction of a cap (default 0.8) that files one deduped budget.warn per period |
Agents take a budget key of their own (dailyUsd / monthlyUsd / totalUsd
/ warnAt) — a capped agent is benched, not the org; see
Cost & budget.
See Cost & budget for the full behavior.
Server
| Option | Env | Flag | Default |
|---|---|---|---|
| port | PORT |
--port |
3000 (walks up if taken; an explicit port is fixed) |
| host | HOST |
--host |
127.0.0.1 |
| enabled | — | --headless disables |
on |
| webhook secret | QUORUM_TRIGGER_SECRET |
— | unset (webhooks off) |
| control secret | QUORUM_DASHBOARD_SECRET |
— | unset on loopback; generated + printed once when binding beyond it |
The steering endpoints (chat, request approval) honor the control secret;
binding beyond loopback requires one — set QUORUM_DASHBOARD_SECRET or quorum
generates it at boot. Read-only endpoints stay open on whatever the bind
reaches, so front anything more than a LAN with a real proxy or tunnel — see
Dashboard. Inbound
webhook triggers are fail-closed either way:
POST /api/trigger/<name> does nothing unless QUORUM_TRIGGER_SECRET is set,
and every call must present that secret.
Brain / provider
Set per agent (or as defaults.provider). Full detail in
The brain.
| Field | Default | Meaning |
|---|---|---|
type |
claude |
claude, codex, opencode, cline, copilot, cursor, grok, qwen, amp, pi, goose, hermes, kimi, droid, antigravity, llm, openai, fake |
model |
provider default | model id |
effort |
— | low | medium | high | xhigh | max (claude) |
maxBudgetUsd |
— | per-session spend ceiling (claude) |
bin |
$CLAUDE_BIN / $CODEX_BIN / binary name |
path to the binary |
timeoutMs |
600000 | per-call timeout (10 min) |
retries |
3 | retry count on pre-effect failure |
args |
— | extra raw CLI args per call |
launch |
— | launcher prefix, e.g. ollama launch claude (claude) |
oss |
false | run against a local open-source model (codex) |
localProvider |
— | ollama | lmstudio — target of oss (codex) |
sandbox |
derived | read-only | workspace-write | danger-full-access (codex) |
mcp |
— | org-owned MCP config path(s); null disables (claude) |
strictMcp |
true | isolate from the operator’s own MCP servers (claude) |
settingSources |
— | --setting-sources value (claude) |
browser |
false | give the brain the org-owned browser as MCP tools (claude) |
bare |
false | no session persistence — every turn starts fresh (claude) |
baseUrl |
https://api.openai.com/v1 |
any OpenAI-compatible server, e.g. LM Studio (openai) |
apiKeyEnv |
OPENAI_API_KEY |
env var read at call time; unset = no auth header (openai) |
fallbacks |
— | failover chain: entries inherit this config and override what they set |
pricing |
— | override the cost-per-token table |
Capabilities
allow / ask / deny, resolved per-agent → org default → base. Base defaults:
allow for everything except crm and charge (both ask). See
Tools & permissions.
Example: a tuned run
TASK_CONCURRENCY=6 \
EVAL_THRESHOLD=70 \
BUDGET_DAILY_USD=5 \
BUDGET_MONTHLY_USD=100 \
quorum --tick 15000 --budget 200
# ...or persist it in QUORUM.md
- budget: { "totalUsd": 200, "dailyUsd": 5, "monthlyUsd": 100 }
- defaults: { "provider": { "type": "claude", "model": "claude-opus-5", "effort": "medium" } }
Analytics
Anonymous, opt-out usage stats — full detail on Analytics & privacy.
| Env | Effect |
|---|---|
DO_NOT_TRACK=1 |
turn analytics off (the cross-tool standard) |
QUORUM_ANALYTICS_DISABLED=1 |
turn analytics off |
QUORUM_POSTHOG_HOST |
override the ingest host (defaults to EU; e.g. https://us.i.posthog.com) |
QUORUM_POSTHOG_KEY |
override the project key |
The choice is machine-global, not per-org: quorum analytics disable (or
enable, or status) records it once for every org you run. Analytics is off by
default in CI.
A note on .env
quorum auto-loads a .env file from the org home when one is present, so the
tokens your MCP servers reference (a Cloudflare key, a bot Gmail account, …) can
live in one file instead of QUORUM.md. Point at a different file with
--env-file <path>. Variables already set in your shell take precedence over the
file. The fake brain needs none of these variables.