Roles and models

SkillAI & models

The role catalogue and the descending-model rule for a multi-session fleet - which roles exist at each tier, what each owns, which model tier each runs on, and when a role should be its own session versus a subagent. Use when standing up a fleet, deciding who owns an activity, choosing a model for a spawned agent, writing a role brief, adding a second lane to one repository, or building the RACI for a run. Enforces that every spawned agent names its model - the orchestrator reasons, mid-tier executes, cheap models verify mechanically - and that a role which must heartbeat cannot be a subagent.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Roles and models skill

What this skill tells your AI

The instructions your AI receives, as published by thelobbi/claude in plugins/delivery-orchestrator/skills/fleet-roles/SKILL.md and read by ahel’s review.

The descending-model rule

The orchestrator reasons, mid-tier executes, cheap models verify mechanically. Every spawned agent names its model.

Not naming a model is the failure mode, not choosing the wrong one. An unnamed dispatch inherits whatever the caller happens to be running, so a fleet that never names models drifts to a single tier and pays either in quality or in cost, silently.

TierModel classWork
orchestratorhighest reasoningoutcomes, escalations, replacement, the run's own judgement
judgementhighranking, review verdicts, release readiness, proposals
mechanicalmidmerges, conflicts, routing, coverage sweeps
lanemid (high for the hardest repos)implementation in one repository
workermidone bounded edit, dispatched and discarded
verifiercheapre-run a stated command, check one fact, confirm a count

Configure the actual model per tier in fleet.config.jsonmodels. model: accepts a tier alias, a full model id, or inherit.

Right-size every dispatch, and never fork. A verifier that needs to reason is the wrong verifier; a lane that spends its own turns on bounded edits is not delegating.

Session or subagent?

This decides more than the model does.

A role that must heartbeat, be woken by a message, or survive between turns must be its own session. Subagents cannot do any of those, and a foreground subagent call blocks the caller's turn entirely — it cannot heartbeat and cannot read messages until the call returns. One lane went 60+ minutes silent that way, and the monitor read it as hung.

RoleNormally runs as
orchestrator, all management roles, all repo lanesits own session
worker, verifiera subagent, spawned in the background, unnamed

The agent files this plugin ships under agents/ serve both uses: dispatch the worker and verifier directly, and use a management or lane agent file as the brief you paste into the session that takes that role. Each such file says so in its own body.

If you must block on a foreground call, heartbeat first: waiting | <task> | foreground worker, expect silence.

Tier 0 — orchestrator

Owns outcomes, promotion decisions, escalations to the human, lane replacement, and the run directory. Receives digests from the router, not a stream, and messages nobody directly except the router.

Tier 1 — management

Run only the roles your fleet's size justifies. A three-lane fleet needs a planner and a merge gate; the rest is overhead.

RoleOwnsTierEnable when
plannerthe ranked backlog, assignments, the numbered amendment logjudgementalways
reviewerAPPROVE/BLOCK verdicts on lane PRs, scoped to a head SHAjudgementalways
gitopsthe merge gate, branch↔PR coverage, runner loadmechanicalalways
conflictsbase re-absorption, conflict resolution, merge forecastsmechanicalmore than ~4 lanes
dispatchfan-out, acks, registry upkeep, digests to tier 0mechanicalmore than ~5 sessions
releaseper-product release board: blocker, proof, exact next actionjudgementanything ships
brainstormevidence-backed proposals, planner-gated into issuesjudgementthere is slack

Two roles are worth adding early rather than when it hurts:

  • dispatch, because without it every session messages tier 0 and tier 0 becomes the bottleneck it was created to avoid. It was added mid-run in the source fleet and immediately became the required relay.
  • release, because "what blocks the next release, and the exact next action" is nobody's job by default, and the human ends up doing it.

Scale reviewers before anything else. Reviewer attention is the scarce resource — not reviewer assignment. Two concurrent reviewers splitting the repository set, with in-flight items staying with whoever already holds them, is the shape that worked. Mechanical changes go to a peer lane instead; see the protocol's review routing.

Tier 2 — repo lanes

One session per repository, exclusive scope, from lanes[]. A lane:

  • reads its repository's own instructions before the first edit,
  • works in a per-task worktree,
  • pushes and opens the PR in one action,
  • announces the PR to the reviewer with the exact commands run and the CI state at the announced head,
  • removes its worktree only after the merge gate confirms,
  • loops until the planner says the queue is empty, then writes its report and goes to standby.

Second lane on one repository: allowed when the queue justifies it, split by file space, named and confirmed by the planner before the second lane's first edit. Task claiming locks claims, not files.

A structurally starving lane goes to standby; it is never repurposed across repositories mid-task. Repurposing a finished session to another role is fine and should be recorded explicitly — a census that counts registry rows will otherwise count one session twice.

Tier 3 — workers and verifiers

Unnamed subagents, spawned in the background, discarded after one task.

  • worker — one bounded edit with a stated acceptance test.
  • verifier — re-runs one stated command and reports the literal result.

A worker's "done" is ASSERTED. It becomes DELIVERED when a verifier re-runs the stated command, or a link (PR, SHA, check state) confirms it.

Where the velocity comes from

Discipline that costs turns slows a fleet down. The source run spent a real fraction of its day on bookkeeping and on waiting for work that was already finished. Each item below removes a measured loss, and each is a default in fleet.config.json or a command in scripts/fleet.mjs — not a rule to remember.

Loss in the source runMechanism that removes it
566 + 68 + ~120 minutes of lanes idle on work that was already donefleet blockers <lane> every heartbeat while waiting; exit 1 = move
one reviewer, eight PRs queued, hung at hour 12; second reviewer added at hour 15review.parallelReviewerstwo from the start above four lanes, splitting the repo set
management reviewers spent on docs, templates and link fixesreview.peerRoutableGlobs — a PR whose files all match goes to a peer lane that has run the same gate
5 of 15 approvals stale against a moved head, none flaggedfleet verdicts <repo> at the start of every reviewer cycle
merge gate: 5–6 hand commands per merge, one of them skipped oncefleet checks in the same message as the merge; exit 0 is the only state you merge from
a merge invalidated an unrelated PR's green and nobody could knowfleet unblocks as part of the merge — both audiences
every session hand-writing registry rows, heartbeats, digestsfleet register, fleet hb, fleet digest
an evening on a CI cap counting runsfleet queue-depth counts jobs
4 of ~40 assigned items already fixed before a worktree was cutverify the symptom before the worktree — rule 9, unchanged; it is a judgement, not a command
many PRs to the same base merged one at a time, each re-absorbingbatch-integration drain: one integration branch absorbs the queue, re-absorbs the base once, merges once with a merge commit — squash orphans the heads

Two of these deserve a sentence more than the table gives them.

Two reviewers from the start. Reviewer attention is the fleet's scarce resource, not reviewer assignment. Split the repository set between two concurrent reviewers, with in-flight items staying with whoever already holds them. Adding the second reviewer late, under a queue, is how the source run did it; adding it first costs one session and removes the bottleneck the whole management tier existed to avoid.

Peer review for mechanical changes. Docs, templates, issue forms, link fixes — anything whose correctness a gate already decided — goes to a lane that has run that gate, not to a management reviewer. The peer is bound by every rule the reviewer is bound by: verdict as a PR comment, scoped to the head SHA, naming the falsifier and the set. Never route a lane to its own branch. This distributes the scarce resource without lowering the bar, and review.peerRoutableGlobs is what makes it a routing rule rather than a judgement call each time.

The RACI

Write one per run. The activities that need an explicit owner, because they are the ones that go unowned:

ActivityRA
Backlog ranking and assignmentplannerorchestrator
Implementation in one repothat lanethat lane
Second lane's file splitthat laneplanner confirms before first edit
Verification of a worker's claimverifierthe lane
Review verdictreviewer or peer lanethe reviewer
Merge into the integration branchgitopsorchestrator
Conflict resolution / re-absorbconflictsgitops
Branch↔PR coverage, worktree hygienegitops + lanesgitops
Heartbeat monitoring and replacementorchestratororchestrator
Release readiness per productreleaseorchestrator
Promotions, releases, production, spend, trust chainthe humanthe human
Escalation routingorchestratororchestrator

The last two rows are the ones fleets get wrong. Everything in founderClass reaches the human as a ready-to-merge PR with proofs, never as a question that parks the work.

Signals

GitHub stars
21
Forks
2
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
fleet-roles
Source
github.com/thelobbi/claude