Teams
Teams group multiple sub-agents under a single team identity with a shared task queue, inter-member message bus, and per-team event log. A coordinator session spawns a lead plus zero or more teammate members, decomposes the goal into tasks, and watches the team progress through completion or shutdown.
Maturity: Opt-in coordination surface. Teams is for multi-agent goals where you want named members, shared tasks, and cross-member messaging — it is not required for normal single-agent or sub-agent workflows.
When to use it
Section titled “When to use it”- You have a goal that decomposes naturally into parallel tasks owned by different members.
- You want a durable team identity and event log so you can inspect or resume coordination later.
- You need cross-member messaging and broadcast — not just sequential spawn-and-collect.
If you only need a single sub-agent, use the regular sub-agent / A2A surfaces and leave teams disabled.
Enable / disable
Section titled “Enable / disable”In your config (e.g. bmo.toml or ~/.config/bmo/bmo.toml):
[options.teams]enabled = trueFor a multi-host setup, point at a remote teams server (another BMO
instance running the /v1/teams/* route group):
[options.teams]enabled = trueserver_url = "https://teams.example.com"Teams is opt-in; leaving the section absent (or enabled = false) is the
default and keeps all team-aware tools and routes off.
Operator surfaces
Section titled “Operator surfaces”Every operator surface reads from the same shared snapshot
(app.BuildTeamsStatusSnapshot) so CLI / TUI / HTTP / agent see the same
posture at the same instant.
CLI
bmo team list # active teams (one row per team)bmo team status <team-id> # detailed per-team inspectorbmo team cleanup --all # remove stale / orphaned team statebmo config show-teams # merged config + recent events tailTUI
/teams— full posture report (config, team count, recent events)./team <id>— per-team inspector dialog (members, tasks, messages).- Sidebar chip —
idle,<n> active,<n> blocked, orwarn: <action>when the recent ring tail surfaces a failure or degraded arm. Click-equivalent routes to the/teamsreport.
HTTP
The same routes work for both local and remote teams servers (same auth
middleware as /v1/teams/*):
GET /v1/teams # list teamsPOST /v1/teams # create a teamGET /v1/teams/{id} # one teamDELETE /v1/teams/{id} # cleanupGET /v1/teams/{id}/events # per-team event log (existing)GET /v1/teams/posture # merged posture snapshot (this feature)Agent tool
list_recent_team_events(limit=16)Returns the last n metadata-only events from the in-process ring as JSON — same shape the slash command and HTTP posture endpoint serve.
Telemetry
Section titled “Telemetry”Teams emits two slog channels via teamsEmitter:
teams.fired— once per lifecycle invocation (paired with one or moreteams.actionrecords viainvocation_id).teams.action— one record per bounded action (team_created,member_joined,task_completed,remote_degraded, …).
The full enum and copy-paste jq recipes live in the
Tracing recipes for Teams
maintainer page.
Field discipline. Identifiers are stored as 8-char FNV32 hex prefixes (
team_id_hash,session_id_hash) — never raw goal text, member names, message bodies, or auth tokens. The remote URL is stored host-only (no scheme, no path) on every operator surface.
Containment behaviour
Section titled “Containment behaviour”Sticky remote_degraded. When the configured remote server returns
≥3 consecutive failures on any operation, the snapshot’s remote_degraded
flag flips sticky. The first transition into degraded emits exactly one
remote_degraded arm; the next successful operation emits exactly one
remote_recovered arm and clears the flag. Subsequent failures while
already degraded do not re-emit. This is the same containment
contract used by the workspace strategy persistence-degraded surface.
Orphan cleanup. bmo team cleanup --all walks the local team state
directory, removes teams whose lead session no longer exists, and emits a
single cleanup_completed arm with removed=N / scope=all (or
scope=single for the single-team path). A run with zero stale teams
still emits one cleanup_completed arm with removed=0 so the audit
trail captures every cleanup attempt.
Scope and non-goals
Section titled “Scope and non-goals”Teams is a coordination surface — not a workflow engine. The following are explicitly out of scope:
- No retries on remote failures. The 3-failure threshold flips the sticky degraded flag; it does not silently retry the failing operation.
- No mid-flight chaos containment. A remote partition during an
in-flight operation surfaces as
remote_failedand (eventually)remote_degraded; the operation itself is not auto-recovered. - No goal text or message body in telemetry. Operators inspect
payloads through the per-team
events.jsonllog; the boundedteams.actionchannel carries metadata only. - No global team registry. Teams remain per-data-dir / per-server; cross-server team aggregation is not provided.
See the maintainer topic
docs/topics/orchestration/teams.md
for the architecture and the per-team event log shape.