bro

Fleet & supervision

Read the fleet, supervise agents, drive orphaned PRs, and expose a local web facade.

Fleet commands separate the read plane from the write plane. bro fleet and bro review watch report what needs attention; bro fleet agents and bro review drive take the deliberate actions.

Fleet and agents

CommandWhat it does
bro fleetOne-shot rows for molecules, steps, agents, worktrees, and PRs
bro fleet --jsonMachine-readable rows plus degraded-backend details
bro fleet --live [--every N]TTY dashboard; --every changes the repaint cadence
bro fleet agents status [<id|step>] [--json] [--connector <name>]Read the agent plane or one agent
bro fleet agents up [<step>] [--connector <name>]Bring up a supervisor or spawn/respawn a step
bro fleet agents down [<id|step>] [--connector <name>]Bring down a supervisor or stop one agent
bro fleet agents prune [--connector <name>] [--older-than Nd] [--json]Reap terminal registry entries (exited, stopped, crashed); blocked stays β€” a wall-parked worker is still a worker

The agents facade resolves native detached processes, tmux, and Gas City backends. A lost or exited worker can be respawned with bro fleet agents up <step>; the same agentId is preserved, and the recorded worktree and stored prompt are reused when they still exist β€” otherwise it falls back to the conventional <repo>--<step> worktree and the bead's own text. --worktree, --prompt-file, and --beads-dir are available on up when an override is needed.

Spawns can ride a named provider instead of a backend's baked-in command: --provider, --model, --profile (a fleet.profiles.<name> preset), and --auto-approve on up. Resolution order is flag β†’ profile β†’ agents.<backend>.provider config. Provider provenance (BRO_AGENT_PROVIDER / BRO_AGENT_MODEL) is recorded in the registry entry and shown by bro fleet and bro fleet agents status.

Session kinds can carry host-wide admission quotas β€” agents.<kind>.maxSessions caps live sessions of that kind across every repo on the host (the devin plane is the known instance), and agents.<kind>.maxWorkers caps only the spawned subset so the user's interactive sessions never consume worker budget; admission claims a slot file under a shared lock, and once the child lands its own session mark takes over β€” leftover slot files are reaped on a ~120 s TTL rather than released by down.

--live is a TTY dashboard and cannot be combined with --json. For a non-interactive ticker, use bro review watch --every N.

Watch and notify

CommandWhat it does
bro review watch [--once]One read-only heartbeat with attention, molecules, gates, and fleet rows
bro review watch --notifyDrop the initial snapshot and transitions into the mailbox
bro review watch --jsonEmit {ts, attention, mols, gates, fleet}
bro review watch --every N --for SRepeat the heartbeat on a cadence β€” the session pulse: holds bro/pulse.lock (one per repo, a duplicate stands by) and refuses under BRO_AGENT_ID; --for is required so the window's exit exists as the session's wake event
bro review watch install [--every N] [--print]Arm the session pulse β€” writes bro/pulse.json (the want-marker session-start rearms from), strips any legacy systemd/cron entry; cadence --every N or watch.intervalSec (default 60)
bro review watch uninstallDisarm the marker + strip any legacy timer/cron entry; a live pulse exits on its own
bro comms notify <text>Write one mailbox event for live sessions β€” addressed drops, kinds, and the bus are in Events

Each tick also rewrites <git-common>/bro/heartbeat.json β€” the durable last-known-state file (mailbox drops expire after ~1h; this file does not), surfaced as the watch: row in bro fleet status and a session-start context line.

Watch never claims steps, mutates beads, or respawns workers. Its attention list is the decision surface; a lost β€” respawn? row is not permission to spawn blindly, especially when a backend is degraded. The notify connector drains unseen drops during the next post-tool probe, so a watcher can reach the parent session without a wait loop.

Detach the watcher, don't block on it: bro review watch --every N --for S --notify in a background shell keeps a bounded heartbeat running while the agent works β€” --for caps the watcher window; it does not tie the watcher to session exit (an unbounded --every is for an external supervisor that owns its lifecycle), and the --notify drops surface in the parent session mid-turn, on its next tool call (the mailbox is pull-based: a drop lands when the session next acts, it never wakes a sleeping one). The session-pulse model is the durable form: bro review watch install arms bro/pulse.json, and a session start with no live pulse (lock holder dead) gets the rearm nudge β€” the orchestrator session then runs bro review watch --every N --for S --notify in a background shell; the window's end is the wake event, followed by one bro review drive pass, a digest, and the next window. OS timers are retired β€” the session owns the cadence, and spawned workers (BRO_AGENT_ID) never arm it.

Drive

bro review drive is the write-side counterpart to watch. It walks open PRs on fleet branches and uses the act gate to decide what happens:

Gate stateOwnerAction
open_threads > 0occupiedSkip; the live owner keeps its work
open_threads > 0orphanedSpawn or respawn a fixer on the PR worktree
greenoccupiedReport; the owner's merge step lands it
greenorphanedMerge through bro review act merge, retire clean work, close the fixer
bro review drive [--once] [--every [N]] [--no-merge] [--connector <name>] [--json]

--once is the default pass. --every is for a detached supervisor; --no-merge supervises without merging. --json emits one verdict per PR. The config section is drive.intervalSec (default 300) and drive.merge (auto, the default, or never).

The durable form is bro review drive install [--every N] [--print]: it arms <git-common>/bro/drive.json β€” the want-marker β€” and brings the supervisor up (bro fleet daemon owns the process). Orchestrator-session checkpoints then rearm a dead supervisor on every lifecycle event β€” spawned workers (BRO_AGENT_ID) never arm one β€” so the merge path is always-on infrastructure, not an opt-in. bro review drive uninstall disarms the marker and stops the supervisor; bro fleet daemon down under an install is only a transient stop β€” the next checkpoint brings it back. For a one-off detached supervisor without the install, bro fleet daemon up spawns the same loop by hand.

Local service

bro fleet serve [--port N] hosts the fleet facade on loopback for thin clients β€” see status + serve.

Convoy fan-out

Several molecules are parallel work. Spawn workers detached, pin the agent ID, PID, log, and claimed step, and monitor with point checks such as bro fleet agents status or bro fleet. Never serialize the work in one session and never wait in a blocking loop. Completion is detected from the agent state and exit record, or from the claimed step closing; a process disappearing is not proof that it finished.

On this page