Pi Extension
The Brainfile extension for Pi is the primary way to run multi-agent orchestration against a Brainfile board.
Source code: protocol/example/integrations/pi/brainfile-extension/
Features
PM and Worker Roles
Every Pi session runs as either a PM (project manager) or a Worker:
| Role | Listener default | Responsibility |
|---|---|---|
| PM | Off | Creates contracts, delegates work, validates deliveries |
| Worker | On | Picks up assigned contracts, implements, delivers |
Set the role with /listen role <pm|worker|auto>. In auto mode the extension checks for an existing open PM run on startup — if one exists, the session demotes itself to worker to avoid conflicts. The same check runs on model switch.
Event-Sourced Coordination
All orchestration state is recorded as an append-only event log at .brainfile/state/pi-events.jsonl. Each PM run gets a unique runId, and events are scoped to that run.
| Category | Events |
|---|---|
| Run lifecycle | run.started, run.blocked, run.closed |
| Contracts | contract.delegated, contract.picked_up, contract.delivered, contract.validated |
| Tasks | task.stale, task.completed |
| Workers | worker.online, worker.heartbeat, worker.offline |
worker.offline is best-effort — it fires on shutdown, listener disable, or role switch, but a crashed session won't emit it. The heartbeat TTL handles that case.
Run Lifecycle
- PM enables listener →
run.startedis emitted. - PM creates contracts and assigns workers →
contract.delegatedfor each. - Workers claim and complete contracts →
contract.picked_up,contract.delivered,contract.validated. - The PM tracks all delegated tasks by
runId. - The run ends with
run.closed, which includes:result—success,blocked, etc.counts— how many tasks were delegated, completed, failedopenTasks— any unresolved tasks (required when result is notsuccess)
PM Notifications
During multi-agent runs the PM chat stays quiet. The PM is only interrupted for:
- Deliveries ready — all open tasks in the run have been delivered and are awaiting validation
- Blocked — a worker hit an external dependency (
run.blocked) - Run complete — all delegated work is validated and finished (
run.closed)
Routine progress is visible via /listen status.
Stale Task Detection
If an in_progress contract shows no activity for too long, the extension flags it as stale:
task.staleis emitted for each affected task.run.blockedis emitted with the reason and counts.- If the run cannot continue,
run.closedis emitted with remainingopenTasks.
The default timeout is 1 hour. Override per workspace in .pi/settings.json:
{
"brainfileExtension": {
"staleTimeoutSeconds": 1800
}
}Worker Presence and Identity
Workers are auto-assigned numbered identities based on their model family — claude-1, codex-2, gemini-1, etc. Slot assignment uses filesystem lease locks under .brainfile/state/worker-claims/ so that multiple workers starting at the same time never collide on the same identity.
Presence is tracked via periodic heartbeats:
| Event | When |
|---|---|
worker.online | First heartbeat after listener starts |
worker.heartbeat | Every 20 seconds while active |
worker.offline | Listener stops, role changes, or session exits |
A worker is considered unavailable if no heartbeat arrives within the 45-second TTL. From the PM session, /listen status shows the current run ID, online workers, and stale timeout.
Assignee matching: Numbered identities match exactly — codex-1 only picks up tasks assigned to codex-1. Bare family names like codex act as wildcards for backward compatibility.
Delivery Verification
/bf contract deliver checks that all declared deliverable files exist before accepting. It also records evidence in contract metrics: git HEAD, file sizes, and validation output.
Commands
Listener
| Command | Description |
|---|---|
/listen | Toggle listener on/off |
/listen on | Start the background listener |
/listen off | Stop the listener |
/listen status | Show run state, active workers, stale timeout |
/listen now | Run one poll cycle immediately |
/listen role <pm|worker|auto> | Set session role |
/listen assignee <name> | Override worker identity |
/listen auto | Reset to auto-assigned identity |
/listen mode <start|wait> | Start working immediately or wait for assignment |
Role aliases: main, planner, orchestrator → pm; agent → worker.
Board
| Command | Description |
|---|---|
/bf pick | Interactively select an active task |
/bf <task-id> | Set active task directly (shortcut) |
/bf status | Show current task and contract state |
/bf board | Print the board summary |
/bf clear | Clear the active task |
/bf move <id> <column> | Move a task to a column |
/bf contract pickup <id> | Claim a specific contract |
/bf contract deliver <id> | Mark a contract as delivered |
/bf contract validate <id> | Validate deliverables and run checks |
/bf plan | Toggle plan mode (mutations disabled) |
Top-Level
| Command | Description |
|---|---|
/plan | Toggle plan mode (mutations disabled) |
Setup
- Copy the extension into your workspace:
cp -r protocol/example/integrations/pi/brainfile-extension/ .pi/extensions/brainfile-extension/- Install dependencies:
cd .pi/extensions/brainfile-extension && npm install- In Pi, run
/reloadto activate.
Typical Workflow
- PM session —
/listen role pm→/listen on - Worker sessions —
/listen role worker→/listen on - PM creates tasks with contracts and assigns them to workers
- Workers automatically pick up
readycontracts matching their identity - Workers implement deliverables and run
/bf contract deliver - PM receives a notification when work is blocked or the run is complete, then validates
Backward Compatibility
Existing /listen, /bf, and brainfile_* tool workflows continue to work unchanged.
See Also
- Orchestration Guide — General orchestration patterns
- AI Agent Integration — MCP, hooks, and manual setup
- MCP Server — Tool-based integration for other agents