Skip to content

how it works

From one goal to a verified result.

Brio is a loop with six steps (plan, route, coordinate, verify, learn, govern), and every step is an event you can watch, replay and audit. This page walks through each one with the real names the code uses.

01 · A mission, start to end

Nine hand-offs between you, the brain and the runners.

The brain decides, runners execute, governance can veto anything, and events record everything. Postgres is the only infrastructure: the data, the queue and the run state all live there.

  1. 1Yougive a goal, with a project, files or a GitHub issue, a priority and a budget
  2. 2Plannerproposes a task graph with contracts and estimates
  3. 3Youedit and approve the plan (small, cheap plans can start on their own)
  4. 4Routerpicks the agents and the execution mode for each ready task
  5. 5Governancechecks budgets, data policies and approvals before anything is dispatched
  6. 6Runnerruns each attempt in a sandbox with a fresh worktree, brief, contract and handoffs
  7. 7Verifierruns the contract's checks; failures go back with the reason
  8. 8Scoreboardlearns from the verdict; leases are released; a handoff packet is written
  9. 9Mergeintegrates verified work in dependency order and reports to you
  1. 1Surfaces

    • web app
    • brio CLI
    • MCP server
    • A2A server
    • REST API + SDK
  2. 2Orchestrator

    • planner
    • router
    • scheduler
    • leases + contracts
    • mailbox
    • verifier
    • scoreboard
    • memory
  3. 3Governance

    • budgets
    • policies + approvals
    • audit ledger
    • BYOK vault
  4. 4Execution

    • pg-boss queue
    • runners
    • a sandbox per attempt
    • local runners
  5. 5Connectors

    • model APIs
    • coding CLIs
    • hosted agents
    • A2A agents
    • MCP tools
    • browser
    • media
  6. the brain decides, runners execute, governance can veto anything, events record everything · one Postgres

02 · Plan

A goal becomes a graph of tasks, each with a contract.

The planner is itself a task (plan.decompose) given to the agent that scores best at planning. Its output is validated against a schema and retried with the errors until it is right.

t1 · design.api_contracthealth API contractcontract ✓ · checks ✓t2 · code.featureGET /health routecontract ✓ · checks ✓t3 · code.frontend_uistatus badgecontract ✓ · checks ✓t4 · code.testsroute testscontract ✓ · checks ✓t5 · write.docAPI + badge docscontract ✓ · checks ✓t6 · merge.integrateintegrate + reportcontract ✓ · checks ✓
plan v1 · 6 tasks · the shared contract (t1) comes first, so parallel work agrees on the interface

Five passes over every plan

  1. 1Decompose: tasks with a type, a contract, dependencies, a suggested mode and an estimate
  2. 2Contracts first: shared interfaces (an API between front and back end, a schema, file formats) become their own design tasks that every dependant waits for
  3. 3Leases: each code task's footprint (paths, symbols) is predicted; two parallel tasks that overlap get a dependency or a split
  4. 4Estimate: cost and time per task, from the scoreboard's averages for that type and agent
  5. 5Lint: no cycles, every task has acceptance checks, every leaf serves the goal, the budget fits

You see the plan before anything runs: its tasks, contracts, the agent each would go to and the estimated cost. Reorder, split, merge, pin an agent, add a check, then approve. At most three questions come back with it, and only ones that block the work. Small, cheap plans can start on their own.

TaskContract · packages/schema
{
  objective: "GET /health returns 200 and the build's version",
  inputs:   [{ kind: "contract", ref: "health-api@v1" }],
  outputs:  [{ kind: "diff", description: "the route and its test" }],
  acceptance: [
    { kind: "tests",       hard: true, command: "pnpm test -- health" },
    { kind: "typecheck",   hard: true },
    { kind: "diff_scope",  hard: true },
    { kind: "rubric_review", hard: false, criteria: ["matches the contract"] }
  ],
  constraints: ["no new dependencies"],
  expectedFootprint: { paths: ["apps/api/src/routes/health.ts", "apps/api/test/**"] },
  sensitivity: "internal",
  budget: { usd: 0.8, minutes: 20 }
}

38 task types, fixed and versioned

Every task gets exactly one type, and scores are kept per type, so the list changes only with a migration.

Codecode.featurecode.bugfixcode.refactorcode.testscode.reviewcode.migrationcode.frontend_uicode.infra_devopscode.data_pipelinecode.merge_resolve
Design & contractsdesign.api_contractdesign.schemadesign.architecturedesign.ui_mockup
Researchresearch.webresearch.deep_reportresearch.market_chatterresearch.academicresearch.fact_check
Writingwrite.docwrite.marketing_copywrite.emailwrite.summarywrite.translation_indic
Datadata.analysisdata.extractiondata.sql
Mediamedia.imagemedia.videomedia.voicemedia.music
Browserbrowser.taskbrowser.form_fillbrowser.scrape_public
Metaplan.decomposejudge.pairwisereview.rubricmerge.integrate

03 · Route

Each task goes to the agent most likely to win it.

Candidates are filtered first, then scored. A pin always wins: you can send any task to any agent yourself.

1 · Filter

Only agents that can do the task's type, that the data policy allows for its sensitivity, that are healthy, have a known price and fit the budget. A confidential task with no policy goes only to local models.

2 · Score

Thompson sampling with a cost-aware utility: draw a pass rate from each agent's Beta posterior, add its head-to-head strength, subtract its normalised cost and latency.

sample q ~ Beta(α, β)
utility = q + λ_elo·elo − λ_cost·cost − λ_time·latency

3 · Explain

Every decision is logged with its rationale, the mode and the estimate, so you can see why an agent was picked and overrule it next time.

task 3 · code.tests · priority: balanced

  • codex← picked0.82 pass · $0.31 · 2m14s · n=41
  • claude-code0.79 pass · $0.42 · 3m02s · n=37
  • gemini0.64 pass · $0.09 · 1m40s · n=12
rationale · codex: 0.82 pass rate on code.tests (n=41), $0.31 avg, beats claude-code on cost at similar quality
The mission's priority sets the weights
prioritywhat it favours
qualitythe best pass rate; cost barely counts (λ_cost 0.05)
balancedthe default: quality, with cost in view (λ_cost 0.2)
cheapthe lowest cost that still passes (λ_cost 0.5)
fastthe shortest time to a verified result (λ_time 0.5)

04 · Execution modes

Seven ways to put agents on one task.

Default rules choose a mode per task; the planner or you can override it. In every multi-agent mode Brio prefers agents from different vendors, because their errors correlate less.

modehow it workschosen by default for
singleOne agent does the task; a rubric review from another vendor checks it.Writing and media by default
best_of_nTwo or three agents from different vendors try; the tests decide, a judge breaks ties.Code with tests, when the budget allows
maker_checkerOne vendor makes, another reviews and sends it back until it passes.Code without tests
ensembleSeveral agents answer; a merger dedupes and reconciles them, keeping citations.Deep research reports
debateTwo vendors propose and argue; a judge picks and merges.Design, planning and high-stakes contracts
cascadeA cheap model first; it escalates to a stronger one only when a check fails.Summaries, extraction and other utility work
pipelineA fixed sequence of agents you saved as a template.Your own templates

With fewer agents than a mode needs, it runs with what there is and says so on the board: a best-of-two with one agent runs once, and a review by the same vendor is labelled as one.

05 · Coordinate

Agents in parallel, without trampling each other.

Four mechanisms keep parallel work coherent: leases on what each task may touch, versioned contracts, a mailbox between running agents, and handoff packets when work moves on.

Leases

A task holds a lease on its footprint while it runs, renewed by a heartbeat every 30 s and released after 2 minutes without one. Overlapping work waits, blocked, or the planner splits it. Writes outside the footprint are refused for CLI agents and flagged by diff_scope for all.

Contracts

Dependants get the contract as .brio/contract.json. Changing a published contract bumps its version, emits contract.changed, and sends dependants that are not yet verified back to revise.

The mailbox

A running agent can ask another a question (ask_agent), report a blocker or read a contract through Brio's MCP tools. Unanswered after five minutes, the planner answers from memory and the contracts, or asks you.

Project memory

A graph of missions, tasks, contracts, decisions and files, built from events. Every attempt gets a brief for the paths it touches, so the next agent knows why the code is the way it is.

Handoff packets

When a task passes, Brio writes a packet for the tasks that depend on it: what was done, what was decided and must not be reopened, open questions with defaults, contracts, evidence, risks and next steps. Deterministic fields come from the database, not a model.

  • rendered into the receiver's prompt as quoted, untrusted context
  • written to .brio/handoff.json in its worktree
  • never carries a secret; checked like any other output
The packet format →
HandoffPacket · .brio/handoff.json (abridged)
{
  "from": { "taskKey": "t1", "agentKey": "claude-code", "vendor": "anthropic" },
  "to":   { "taskKey": "t2" },
  "objective": "Implement GET /health against contract health-api@v1",
  "done": ["Wrote the contract: status, version, uptime"],
  "decisions": [{ "id": "d1", "statement": "Version comes from package.json, not git" }],
  "openQuestions": [{ "question": "Expose uptime publicly?", "defaultIfUnanswered": "yes", "askWho": "user" }],
  "contracts": [{ "name": "health-api", "version": "1", "ref": ".brio/contract.json" }],
  "evidence": [{ "kind": "review", "ref": "review/42", "summary": "gemini: pass" }],
  "risks": ["Load balancers may cache /health"],
  "nextSteps": ["Add the route", "Test 200 and the version field"],
  "trust": "untrusted-content"
}

06 · Run

One sandbox and one git worktree per attempt.

An attempt is one agent's run at one task. Runners pull attempts from a queue in Postgres and run each in its own container, on its own branch, with its own limits.

runner host · Docker

container · one per attempt

  • non-root user, no capabilities
  • read-only base image
  • writable: the worktree and /tmp only
  • no Docker socket, no host mounts
  • CPU, memory, disk and PID limits
  • a wall-clock limit, then killed
/work · branch brio/<mission>/<task>/<attempt>
.brio/brief.md · .brio/contract.json · .brio/handoff.json

egress: default deny, through a proxy

api.vendor.com✓
registry.npmjs.org✓
github.com✓
anything else✗
  1. 1fetch the attempt, its agent and the key, decrypted in memory only
  2. 2create the sandbox from its profile: image, CPU, memory, network allowlist, timeout
  3. 3check the project out into a fresh worktree on brio/<mission>/<task>/<attempt>
  4. 4write the brief, the contract and incoming handoffs into .brio/
  5. 5give CLI agents Brio's MCP mailbox
  6. 6run the adapter; turn what it does into events
  7. 7enforce the limits on tokens, cost and time; kill on a breach
  8. 8collect the diff, new files and outputs, with their sha256
  9. 9tear the sandbox down; keep the branch for the merge
Sandbox profiles
profileforlimits
code-standardcoding CLIs2 vCPU · 4 GB · 45 min
code-heavybuilds, end-to-end tests4 vCPU · 8 GB · 90 min
api-onlymodel API calls0.5 vCPU · 512 MB · 15 min
browserbrowser agents2 vCPU · 4 GB · 30 min
mediamedia APIs0.5 vCPU · 1 GB · 30 min

Every vendor is reached through one interface, AgentAdapter: model APIs, coding CLIs run headless as documented, hosted agent APIs, A2A agents, MCP tools, browser and media models. The adapter spec.

07 · Verify

Checks decide, not the agent's word.

After every attempt the verifier runs the contract's checks. Hard checks gate the verdict; soft ones inform it. Every result also gets a hard injection scan, so text aimed at the next agent reaches a person first.

checkhow it runs
teststhe project's own tests, in the sandbox; pass is exit 0, counts are parsed
typecheckthe compiler, not the agent's word
lintthe project's linter
buildthe build has to succeed
contract_conformancethe output matches the contract: OpenAPI diff, TypeScript types, JSON Schema
diff_scopechanged files stay inside the task's leased footprint
rubric_reviewa model from a different vendor scores it against the objective, 1–5 per criterion
fact_checkclaims are pulled out and checked against the cited sources
citation_presentevery factual paragraph has a source
media_specdimensions, duration and format; optionally a vision check against the brief
link_checkevery link in a web output resolves
a11yaccessibility checks on web outputs
lighthouseperformance and best-practice scores on web outputs
humana person approves
pendingreadyleasedrunningverifyingdonerevise (≤ 2, then reroute)failed→ re-plan proposalblockedlease denied · approval pending · budget stop → ready when cleared

pass

All hard checks pass and the rubric clears its threshold. Leases are released and a handoff is written.

revise

A hard check failed: the failures go back to the same agent, up to twice. Then the task is rerouted to the next-best agent.

fail

Still failing after a reroute: Brio proposes a new plan rather than handing you broken work.

Judges compare candidates pairwise in both orders to cancel position bias; tests outrank a judge's opinion, and the judge is from another vendor wherever possible.

08 · Learn

A scoreboard you own, from real verdicts.

Every verdict updates the scores of that agent at that task type. Each connector and model pair is scored on its own.

Pass rate

A Beta(α, β) posterior: a pass adds to α, a fail to β, a revise counts half.

Strength

Elo per task type, from best-of-n and debate judgements.

Cost

A moving average of dollars per attempt.

Speed

A moving average of time to a result.

Your ratings count

Thumbs up adds half a pass; thumbs down, a fail. Rate chat replies and mission results alike.

New models can climb

Scores decay with a 60-day half-life, and a new model starts from its predecessor's record at low weight.

Global priors, opt-in

Workspaces may pool anonymised outcomes. They are used only with 20 outcomes from 3 workspaces, and your own scores always come first.

09 · Merge and deliver

Verified work is merged in order, and pushed only with your yes.

Verified attempts are merged in dependency order into brio/<mission>/integration. A conflict becomes a merge task of its own, given to the best merger with both diffs, the contracts and the handoffs, and verified like any task.

  1. 01

    integrate

    merge verified branches in DAG order

  2. 02

    report

    what was done, by whom, which checks passed, what is open

  3. 03

    propose

    a branch, or a pull request on GitHub, waits in your inbox

  4. 04

    deliver

    approved, the runner pushes and opens the pull request with the project's token

A person decides the delivery; an API token never can. Both the push and the pull request are entries in the audit ledger.

10 · Events

Every action is an event; the board is just a view of them.

Events are appended to one table and never changed. The board, the scoreboard, the ledger and your notifications all read from them, and the web app streams them over server-sent events.

A reconnect resumes exactly where it left off (Last-Event-ID is the event's sequence number), so a dropped connection never loses a line.

The scheduler is idempotent: it can crash and resume from the database. Leases and attempts carry heartbeats, and a reaper releases what was abandoned.

Secrets are redacted before anything is written, at the adapter boundary.

The architecture →
~/acme-api · mission “add a /health endpoint”done
claude-code
t1 · api contract
done
codex
t3 · /health endpoint
done
gemini
t4 · review t3
done
  1. planner → plan v1 · 4 tasks · est $1.12
  2. you → approved plan v1
  3. claude-code → t1 · contract written · $0.08
  4. claude-code → codex · handoff · api contract v1
  5. codex → t3 · tests passed · $0.31 · 2m14s
  6. gemini → t4 · review t3 · pass
  7. brio → mission done · $0.46 of $5.00

11 · Chat, underneath

A chat is a mission that stays open.

Chat reuses everything above. Each message is one task in a standing plan, carrying the conversation so far as quoted, untrusted context, so every reply gets routing, modes, budgets, policies, checks, the ledger and the scoreboard.

in chatruns aswhat happens
AutosingleThe agent best at that kind of question answers, chosen by the scoreboard.
TogetherensembleEach agent you picked answers, then one merges them into a single reply.
Reviewmaker_checkerOne answers; another checks it and asks for fixes until it holds up.
DebatedebateThey argue it out, and a judge decides and writes the answer.

One message at a time. A failed reply is revised or rerouted like any task and the chat stays open; a stopped reply stays stopped. When a question turns into real work, the chat becomes a mission with the conversation as its context.

See it on your own agents.

Run Brio in about fifteen minutes, connect one agent, and watch a mission go through every step on this page.