Scaling up — secondmates, dispatch & quota
Route tasks to the right harness/model/effort with natural-language dispatch rules, rank by subscription quota with quota-axi, and add persistent secondmates locally or on other machines.
A single first mate with a handful of crewmates takes you a long way. This page covers the three things that push further: choosing the right worker per task, spending quota wisely, and persistent second mates on other machines.
Dispatch profiles#
By default a crewmate runs on config/crew-harness, or on the first mate's own harness if that file is absent. config/crew-dispatch.json replaces that with natural-language rules the first mate matches with judgment. There is no regex.
The shipped example, docs/examples/crew-dispatch.json, verbatim:
{
"rules": [
{
"when": "The task depends on fresh news, current events, live public facts, or recent market and product changes.",
"use": { "harness": "grok" },
"why": "Grok is the preferred dispatch when current web-connected context is central to the work."
},
{
"when": "The task is a trivial mechanical edit such as a rote rename, formatting sweep, targeted typo fix, or simple file gathering.",
"use": { "harness": "claude", "model": "haiku", "effort": "low" },
"why": "Use the cheapest fast profile when the task is narrow and low ambiguity."
},
{
"when": "The task is a big or ambiguous multi-file feature, a risky refactor, or work that requires holding many moving parts in mind.",
"use": [
{ "harness": "claude", "model": "claude-sonnet-5", "effort": "high" },
{ "harness": "codex", "model": "gpt-5.5", "effort": "high" }
],
"why": "Use a strong coding profile for big, ambiguous work; resolve the alternatives through quota-array-dispatch."
}
],
"default": [
{ "harness": "codex", "model": "gpt-5.5", "effort": "medium" },
{ "harness": "pi", "model": "anthropic/claude-sonnet-5", "effort": "medium", "provider": "claude" }
]
}
Each rule has a when (plain English), a use (one profile or an array of alternatives) and an optional why. Profiles take harness, model, effort, provider and floor. The optional approval: "captain" and min_confidence are enforced only by the typed resolver. The full schema is in docs/configuration.md, "Crew dispatch profiles".
Rules to know:
- Once the file exists, every spawn must resolve an explicit harness. There is no silent fallback. A malformed file shows as
CREW_DISPATCH:at session start. - A
usearray means "any of these". The choice among them goes to quota-array dispatch (next section). - The file is inherited by secondmate homes.
fm-spawn.sh --harness/--model/--effortand your explicit instruction ("do this one on codex") override it.
Why route at dispatch, not per request#
Kun argues this against per-request model routers:
the complexity of a task only reveals itself when you start working on it... routing should work at the boundary between agents and subagents, not per each LLM request. — @kunchenguid, 2026-07-23
The first mate plans with you, writes the brief, and then picks the worker. At that point it knows much more about the task than any router looking at one request.
Typed resolution (Jev)#
With TYPESAFE_API_KEY in .env, bin/fm-dispatch-resolve.sh sends the brief, your rules and your quota data to a small classifier model (Jev) instead of spending an LLM turn on the choice. Kun reported same-quality choices on 25 evaluated tasks at −71% cost and −90% wall time for the dispatch step (2026-09-17). It reports a confidence, which min_confidence can gate. A clear result from the resolver "never replaces firstmate's judgment, quota-array-dispatch, the captain-approval gate, or fm-spawn.sh validation."
Quota-aware choice: quota-axi#
When a rule resolves to several candidates, the quota-array-dispatch skill decides. It reads quota-axi's TOON output once, then applies three hard gates in order:
- Eligibility. The model exists in that harness's catalog, quota matched at the vendor's granularity, and credentials are checked by
bin/fm-vendor-auth-probe.sh. - Reasoning-class fit. It is never silently downgraded to save quota.
- Runway feasibility. A candidate whose window will run out before the task's horizon fails, even if its spend priority is best.
Survivors are ranked by quota-axi's spendPriority. Genuine ties go to you; they are not broken by array order. That keeps the VISION rule: "Quota, model, and effort choices stay inspectable and captain-owned."
npx -y quota-axi --provider claude,codex,cursor,grok
# quota[n]{provider,scope,effectivePercentRemaining,spendPriority,runway,confidence,limitedBy,resetsAt}: ...
Secondmates#
A secondmate is a whole persistent firstmate home with a charter. It is not a single worker. It has its own FM_HOME, backlog, projects, session lock, and crewmates.
Use one when:
- a domain has enough steady work to deserve its own standing context (a mobile app, infra, docs),
- work should run on another machine (a Mac mini for iOS builds, a Linux box for heavy tests),
- or you want supervision to survive your laptop lid closing.
Kun runs "1 firstmate and 7 second mates" (2026-08-24). His iOS secondmate runs on a headless Mac mini "so it never competes for interactive resources" (2026-08-05).
Creating one#
Say what you want ("set up a secondmate for the iOS apps on my mac mini"). The first mate loads secondmate-provisioning and runs, roughly:
bin/fm-brief.sh <id> --secondmate <project>... # charter scaffold
bin/fm-home-seed.sh <id> - <project>... # local home
# or, whole home on another host:
bin/fm-remote-home-seed.sh <id> <ssh-alias> <remote-root> <remote-home> <project>[=<origin-url>]...
bin/fm-spawn.sh <id> --secondmate # launch / recover
A charter brief has # Charter, # Routing scope, # Project clones, # Operating model, # The captain and the parent channel, # Escalation to main firstmate, and more. The routing table lives in data/secondmates.md.
How it behaves#
- Persistent and idle by default. "An empty queue never authorizes a survey, audit, or self-directed improvement sweep." An empty queue is healthy and never triggers teardown.
- Routing is by scope, never by which clones it holds.
- It never talks to you. Its decisions and PR-ready events go up the parent channel to the first mate.
- Queued work moves with
bin/fm-backlog-handoff.sh <id> <item>.... Only## Queueditems move, viatasks-axi mv. - Config inheritance. Some
config/files are inherited (backend, crew-dispatch, claude-permission-mode, brief-include is not). Each file's row in the on-demandoperational-home-layoutskill says which.data/captain-shared.mdpropagates read-only. - Liveness. A dead secondmate is auto-relaunched (
FM_SECONDMATE_LIVENESS_*). Remote routes are never silently replaced with a local one. - Retirement.
bin/fm-teardown.sh <id>refuses while child work, an unfinished outbox or an unresolved routed reply exists.
Remote secondmates#
- They always run on Herdr in a shared
fm-remotesession. Herdr's server lives in the host's GUI login session, so the agent survives SSH drops. - Required on the host:
git,jq,herdr,tasks-axi,treehouse, and at least one harness. - Remote jobs never use a login shell. PATH is discovered in a fixed order:
<remote-root>/bin,~/.local/bin, nvm/asdf/mise, Nix, Homebrew, then system. bin/fm-remote-doctor.sh(check/--fix) owns "is this host ready?". It fixes automatable gaps and tags the resthuman:: console login, FileVault, tool installs, the worker's own/login.
firstmate has native support for remote machines. it's called "remote second mates". you can talk to your firstmate to set it up. — @kunchenguid, 2026-09-10
Worker accounts and permissions#
| File | Effect |
|---|---|
config/claude-permission-mode |
bypass (default → --dangerously-skip-permissions) or auto (→ --permission-mode auto) for every Claude worker |
config/claude-account, config/pi-account |
Pin workers to a specific login. A launch is refused if the pinned account isn't signed in. The first mate reports the needed login and never edits the pin. |
config/launch-env-allowlist |
Restricts which ambient env vars reach workers. The docs say plainly it is "not a sandbox". |
config/secondmate-harness |
<harness> [<model>] [<effort>] for launching secondmates (primary only) |