How it works
- Intake. A mention delivers into the chief’s single live session (spawning it if none exists). The chief reacts to the message, subscribes to the thread, splits the request into tasks that each land as one focused PR, raises ambiguities as crisp questions with a recommended answer, and posts a roster.
- Dispatch. For each clear task the chief calls
auto.sessions.spawn— agentstaff-engineer, an idempotency key of thread + task slug, and a message that is the brief: slug, statement, acceptance criteria, constraints, the chief’s session id, and the reporting protocol. - Execution. Each staff engineer works in its own sandbox: branch, test-drive the change, open a PR with a Review Map, then bind the PR to its session with
auto.bindand end its turn. Check failures, review comments, and merge conflicts on that PR wake the same session. - Shepherding. Staff engineers report milestones (
started,pr-opened,fixing-ci,blocked,ready) into the chief’s session withauto.sessions.message. A 15-minute heartbeat has the chief sweep the fleet: nudge stalled sessions, respawn dead ones, answer questions it can resolve itself, escalate the rest. - The packet. When every task’s PR is green, reviewed, and reported ready — verified through introspection, not taken on faith — the chief posts one packet in the originating thread: per task, the PR link, what changed, what verification ran, and residual risks. Merging stays with humans.
The configuration
Three files: a shared runtime fragment, the orchestrator, and the worker..auto/fragments/environments/agent-runtime.yaml
.auto/agents/chief-of-staff.yaml
.auto/agents/staff-engineer.yaml
github-acme and a Slack connection named slack.
Walkthrough
Division of labor is enforced by capabilities, not prompts
Both agents mountacme/widgets, but the chief’s mount is all-read (contents: read, pullRequests: read) with a depth: 1 shallow clone, and the chief has no github tool at all — it cannot write code, whatever a prompt injection or a confused turn might want. The staff engineer’s mount can push (contents: write, pullRequests: write) and its brokered GitHub tool names exactly five operations: read PRs, open them, update them, comment, search. Neither agent can merge — merge_pull_request would require both naming it and a mount merge: write capability, and this fleet grants neither. commitAuthor on the staff engineer’s mount sets the author on every commit the fleet pushes.
The chief is one durable slot with automatic replacement
Four fields turn the chief from “an agent” into “a service”:concurrency: 1caps the chief at one live session and makes baredelivertriggers resolve to that slot member. All four triggers deliver: mentions and subscribed replies useonUnmatched: spawn(a human message must never drop — it starts a fresh chief if none is live), while reactions and the heartbeat useonUnmatched: drop(cron and emojis never resurrect a finished chief).replace: autoenrolls the slot in the platform’s pool reconciler. If the live chief’s session fails, or its agent definition changes underneath it, the reconciler replaces it: a definition change first delivers a five-minute wind-down warning so the session can checkpoint and archive itself cleanly, then a replacement spawns on the latest spec. Failure replacements are crash-loop guarded (at most three per 30 minutes).onReplaceis the replacement’s start message — the rebuild recipe. This chief’s recipe is a checklist against durable external state: session lists, open PRs, Slack threads. It works because the chief keeps no private state worth losing.managesgrants the chief authority to stop sessions of the named agent types viaauto.sessions.stop— how it reaps dead staff engineers before respawning their task. A session can always stop itself (withrespawn: trueto cycle onto the latest spec deliberately); listingchief-of-staffadditionally lets a replacement chief stop a lingering predecessor session.
Dispatch and reporting are tool calls between sessions
The fleet’s nervous system is threeauto.* tools (see auto tools):
auto.sessions.spawncreates one staff-engineer session per task. TheidempotencyKey(thread id + task slug) makes dispatch replay-safe: re-running intake after a crash returns the existing session (created: false) instead of double-spawning an implementation.auto.sessions.messagecarries traffic both ways — milestone reports up to the chief’s session id, steering and answers down to a worker — by injecting a message into the target session’s transcript.auto.sessions.listplus the read-only introspection tools (auto.sessions.summary,auto.sessions.conversation,auto.sessions.triggers) let the chief verify “ready” claims against reality before assembling the packet.
started / pr-opened / fixing-ci / blocked / ready, each prefixed with the task slug) is pure prompt convention — but it is the convention that makes a fleet legible from one roster.
Staff engineers wait by ending their turn
After opening its PR, a staff engineer callsauto.bind (target type github.pull_request) and stops. From then on its four bind-routed triggers deliver everything that matters about its PR into its session: individual check failures, the aggregate roll-up success, conversation updates, and the synthetic github.pull_request.merge_conflict event from auto’s mergeability tracking. Check-completion deliveries defer until the session is idle, so a burst of CI results never interrupts a fix in progress. The check triggers use the same aggregate/individual split and headIsCurrent staleness guard explained in the handoff example.
Composes with the code-review example
The staff engineer’s definition of done includes reading the pr-review comment for the latest commit — that reviewer is the code review example. Deploy both for the full loop: the fleet writes, the reviewer gates, the chief only reports ready when both agree. Without a reviewer agent, drop the pr-review clauses from the staff-engineer prompt and the aggregate-CI trigger message.Install from the consolidated agent package
The retained Chief of Staff and Staff Engineer roles are published in@auto/agents — one thin file per agent:
.auto/agents/chief-of-staff.yaml
.auto/agents/staff-engineer.yaml
optional: true, so applies succeed with no Slack connection), and it may merge a ready PR when the requester explicitly says so — read the template before assuming the exact behavior above. Override any field locally; drop inherited entries with remove:. See managed templates.
Adapt it
- Replace
acme/widgets,github-acme,slack, and the staff engineer’scommitAuthor(your GitHub App’s bot login and noreply email). - Set the aggregate check name (
All checks) to your repository’s real roll-up check, or remove that filter to react to every check. - Tune the heartbeat to batch volume — 15 minutes suits an active repository.
- Point both prompts at your real contribution docs and test commands.
- Add spend caps before large batches:
maxPerSessionUsdon the staff engineer bounds a runaway task;dailyUsdon either agent bounds the fleet.