Agent Delegation — One Executor, Cheap Specialist Lanes
DRAFT — pending Harsh's verification.
This page documents Harsh's personal delegation setup on the pi-coding-agent framework — a user-level configuration, kept entirely outside any shared work package, that pairs one frontier model running the main loop with cheap specialist subagents for reading and writing. It is the layer behind the agent work described elsewhere on this site (the build-triage skill and code-search tool both run inside this topology); this page is about the topology itself and the agent-architecture judgment it embodies.
1. One frontier executor, four delegation lanes
The whole setup is organized around a single rule: one frontier model runs the main loop and owns every write. Everything else is a specialist the executor can call on, run in an isolated subprocess, and verify itself.
- The executor is the most capable model available (Opus 4.8). It runs every
turn of the main task loop and is the only role that makes decisions and
commits real writes. It is governed by a single
AGENTS.mdfile — consult triggers, delegation rules, and the check contract — that applies to the whole session. - Four delegation lanes sit alongside it, each a separate agent defined by a frontmatter file that forces its model and toolset at spawn time:
| Lane | Model | Access | Role |
|---|---|---|---|
| Advisor | Fable 5 (Sonnet-tier) | read-only | deep reasoning, consulted on demand |
| Advisor-Opus | Opus 4.8 | read-only | sticky fallback when the advisor throttles |
| Scout | Haiku 4.5 | read-only | token-heavy coverage/discovery reads, parallel |
| Coder | Haiku 4.5 | write (edit/write/bash) | mechanical implementation batches, verified |
| loco | Opus 4.8 | full (all tools) | autonomous well-understood writes, one at a time |
The three lanes this page centers on are the advisor (judgment consults),
scouts (parallel read-only recon), and coders (sandboxed
implementation). The fourth, loco, is deliberately distinct: it is not a
cheap delegate. It runs in-process in the same session, on the same frontier
model, mutex'd to one at a time — for autonomous writes that need the full tool
set (including extension tools subprocess workers can't reach). Splitting it
off from the cheap lanes is part of the point: cheap parallelism and
full-tool autonomy are different problems, and they get different mechanisms.
flowchart TD
subgraph session["pi SESSION (user-level)"]
executor["EXECUTOR — frontier\nmain task loop · every turn · all WRITES\ngoverned by AGENTS.md (consult / delegate / check)"]
advisor["ADVISOR\ndeep reason\nREAD-only"]
scout["SCOUT\nREAD-only\ncheap recon"]
coder["CODER\nWRITE\n(edit / write / bash)"]
loco["loco\nin-proc · same session\nmutex ×1"]
advisorOpus["ADVISOR-OPUS\nREAD-only"]
executor -->|advisor| advisor
executor -->|"scout ×N"| scout
executor -->|"coder ×N"| coder
executor -->|loco| loco
advisor -->|sticky fallback| advisorOpus
end
subgraph extensions["EXTENSIONS"]
subagent["subagent\nspawns each agent as an isolated subprocess\nforces model + tools from frontmatter\nper-task cwd · parallel max 8 / 4 concurrent"]
autoconsult["advisor-autoconsult\nwatches edit / write / bash errors\n3 same-key fails in a 6-call window -> consult now"]
end
Every subagent runs in a separate subprocess with an isolated context
window and a forced --model and --tools from its frontmatter — so a
worker can neither drift off its assigned model nor exceed its tool scope. The
scout and coder are read-only and write-confined by policy enforced at spawn,
not by hoping the model complies. The only added tool in the whole setup is
subagent; agent names (advisor, scout, coder) are roles, not tools, so
there is no tool-name collision with the domain tools the framework already
provides. Everything is user-level and additive — nothing is committed to a
shared package, and no teammate is affected.
2. Why the executor/advisor split saves frontier tokens
The cost logic is the reason the topology exists. The executor is the most expensive model in the stack, and its context is the most expensive real estate in the session. Every lane is a way to spend a cheaper model's tokens instead — or to keep the executor's context lean — without giving up the frontier judgment that only the executor provides.
The advisor is consulted on demand, not always-on. The executor pays for a deep-reasoning second opinion only when an observable trigger fires — the same tool errors on the same target twice (stop before a third attempt), an architectural or hard-to-reverse decision is pending, a plan needs a second opinion on tradeoffs, or the root cause is ambiguous and the wrong choice is costly. The advisor returns a fixed-shape brief — Recommendation, Why, Risks, Next Steps — and the executor decides and executes. Routine, low-risk, well-understood work never spawns a subprocess, because a subprocess costs tokens and latency for no value. The split is "think deeper, don't write": the advisor reasons, the executor acts.
Scouts keep the executor's context lean. A cheap read-only worker (Haiku)
does token-heavy mechanical reading in its own isolated context and returns a
distilled, cited index — verbatim quotes with file:line references, plus a
coverage report. The raw material never enters the executor's context, which
avoids the two things that degrade a frontier model: cache-read bloat and
reasoning degradation under volume. The reading leg runs on a model roughly an
order of magnitude cheaper per input token than the executor. The executor
plans, delegates the bulk reading, then synthesizes and spot-reads the flagged
hotspots itself — "plan big, execute small." Scouts fan out in parallel (max 8
tasks, 4 concurrent), partitioned by directory or repo, with one scope per
scout.
Haiku, not Fable, for any fan-out. This is a deliberate constraint, not a preference. Fable 5 is Sonnet-tier but rate-limited — fanning out parallel Fable workers produces a 429 storm. Haiku is the only model in the lineup that is both truly cheap and parallel-safe, so scouts and coders are both Haiku. The win from the cheap lanes is parallelism + context isolation + executed verification, not raw cost arbitrage. The deep-reasoning advisor is never parallelized: it is consulted serially, on demand, with a sticky fallback.
The sticky fallback. Fable 5 has a low rate limit and may throttle (HTTP
429) or stall on backoff. The fallback rule: if the advisor call fails twice, or
a single call exceeds roughly 45 seconds — whichever comes first — switch to
the advisor-opus agent (the same frontier model as the executor, read-only)
for all remaining consultations that session. The switch is sticky: once
tripped, the executor never retries Fable again in that session. This is
orchestration-level — enforced by the executor following the AGENTS.md rule,
not by hard-coded extension logic — which the setup notes flag honestly as
judgment-driven rather than deterministic, with a noted path to a bulletproof
version (forking the subagent extension to auto-respawn on failure/timeout).
3. Enforcement lives in the harness, not the prompt
The two hardest parts of a delegation setup are (a) noticing when you are stuck
and should consult, and (b) not trusting a worker that reports "done" with full
confidence. This setup hardens both — but it hardens them in code, not as
prompt prose. The soft AGENTS.md rules set intent; two enforcement extensions
make the failure cases deterministic.
advisor-autoconsult — the failure-loop nudge. The implicit "consult when stuck" trigger is soft, because the executor has to notice it is stuck, and self-tracking a failure loop is exactly what a model in a failure loop is bad at. One trigger — "stuck in a failure loop" — is hardened by a local extension so it fires deterministically:
- Failure signal:
tool_result.isError === true, counted only for mutating or executing tools (edit,write,bash). Read-only recon (read/grep/find/ls) andsubagentfailures are excluded — recon misses are normal, and nudging on a failed advisor/scout call would loop. - Trip rule: 3 failures sharing the same grouping key
(
${toolName}:${normalizedTarget}) within a rolling window of 6 tool calls. - Action: inject a forceful steer nudge telling the executor to consult the advisor now — delivered after the current tool calls finish, before the next model call. It does not auto-spawn the advisor; that would lose the executor's framing and the sticky-fallback judgment. It tells the executor to consult, and leaves the decision there.
- Sticky-fallback aware: the nudge names roles (
advisor/advisor-opus), never models, and tells the executor to switch toadvisor-opusif the advisor is throttling — so it respects the existing fallback rule. - Anti-nag: a per-key latch that re-arms only on a success for that key, plus a global cooldown of 8 tool calls between any two nudges. All state resets on context compaction.
The result is the deliberate two-tier design: the explicit "ask the advisor"
path and the manual route still work, the soft triggers set intent, and the one
case the executor is genuinely bad at self-tracking is enforced deterministically.
A known limitation is noted honestly: bash non-zero exits do not set isError,
so silent bash failures are not counted directly (they usually surface as a
follow-on error from a missing file or a failed edit).
verified-writes — the check is the contract. The write-side analog: when the
executor delegates write work to a cheap coder worker (or to loco), the
worker's own "done" is not evidence. Parallel, isolated workers report
success with full confidence whether or not the work is correct. So the setup
inverts trust: it defines "done" as an executable check the executor runs
itself, and exit 0 is the only signal it believes.
- The check must execute the artifact — compile it, run its tests, run the script, or grep-assert that the exact required content is present and the old content is gone. A check that cannot fail is not a check.
- The check must print why it failed — a diff, an assertion message, the
offending line — so the retry has context to fix against. A silent
exit 1gives the retry nothing. - Retry once on failure, injecting the check's failure output into the worker's next spec. If it still fails, the executor finishes it or escalates — it does not loop a weak worker.
- Log the verdict. One line per attempt goes to a shared JSONL verdict log
(carrying a
sessionfield, appended atomically so concurrent sessions can't corrupt it), sliced withjqinto per-(model, task type)pass and first-try-pass rates. The weak worker's reliability is measured, not guessed — and a per-session human audit log keeps a glanceable, verbatim record of every failure.
The framing is borrowed from Nate Jones's Ringer: a swarm you don't trust, made useful by an institution that verifies work product. The model is not made better; the harness is. The executor ignores the worker's summary, runs the check itself, and treats the worker as an auditioner whose output is only as good as the check that gates it. The weaker the worker (Haiku), the stronger the check must be — the check plus a single retry is what makes a cheap writer safe.
The throughline of both extensions: guardrails in the harness, not guardrails in the prompt. Prompt-prose pleas ("remember to consult when stuck", "don't trust the worker's report") degrade silently and don't survive a model swap. A deterministic failure-loop nudge and an executed-check-and-retry contract do.
4. Skills as codified procedures
The delegation rules above are the protocol; the skills are the procedures the executor reaches for once it decides to act. A skill is a markdown runbook that encodes the decision tree an experienced operator follows — the same move as the build-triage page's signal→action table: an expert's implicit pattern-match converted into something a model executes deterministically, run after run, across model versions. The model supplies the reasoning glue between steps; the skill is the judgment that survives a model swap.
The verified-writes skill is the coder-swarm playbook, and it reads like a
checklist: partition the batch into 2–8 independent tasks (no two write the
same file; prefer one repo/dir each) → check-first (each task ships an
executable check the executor will run itself) → isolate (a git worktree per
same-repo task, cross-repo tasks use the repo dir) → fan-out (parallel
subagent calls, agent: "coder", per-task cwd) → executor-run checks
(ignore the worker's summary) → retry once with failure output injected →
verdict and audit (log to the JSONL + the per-session markdown audit) →
merge (one PR per repo for cross-repo, or merge branches + a final builder
for same-repo).
The coder worker's own contract is equally fixed and is designed to make the
check easy to write: do exactly the spec, confine all writes to the given
working directory, no mutating git commands, never certify success (the
executor's check is the only verdict), never ask questions (the context is
isolated and non-interactive), and report changed files with file:line
references and verbatim quotes. A fixed worker output shape — Changed, Not
done, Flags — makes "the worker skipped a section" an obvious, checkable
failure, the same way the advisor's Recommendation/Why/Risks/Next Steps and
the scout's Coverage/Findings/Flags do.
Three further skills coexist in the same directory — cross-repo-sweep,
release-system, and document-pi-changes — each a procedure of the same
shape. Their internals are not detailed in the documents this page was distilled
from; they are named here to show that the delegation protocol is one procedure
among several, not the whole setup.
5. What this demonstrates — agent-architecture judgment
The setup is interesting not because it "uses agents" but because of the architecture decisions behind it. Each is a deliberate choice under constraint, and each is the kind of judgment this site exists to make publicly legible.
- Assigning models by cost tier. The frontier model is reserved for the one thing only it can do — judgment plus the writes that carry real consequences — and it runs the main loop. Cheap models take the token-heavy legs (parallel reads, mechanical writes) where volume matters more than depth. The deep-reasoning model is consulted serially, on demand, with a sticky fallback. The model is chosen for the role, not the other way around.
- Scoping worker toolsets as a security boundary. Read-only advisors and
scouts; write-confined coders that can only touch their own working directory
and are forbidden from mutating git state; toolsets forced per frontmatter at
spawn so a worker can't drift off its assigned model or reach for a tool it
wasn't given. Extension tools (the broader domain integrations) stay in the
main loop or
loco— subprocess workers get built-in tools only. The toolset is the blast-radius control. - Brief and report contracts. Every lane returns a fixed shape — the
advisor's Recommendation/Why/Risks/Next Steps, the scout's
Coverage/Findings/Flags with verbatim quotes and
file:linereferences, the coder's Changed/Not done/Flags. Fixed contracts make output skimmable, make "the agent skipped the evidence" an obvious failure, and make the executor's verification cheap. - Guardrails in the harness, not the prompt. The failure-loop nudge is a deterministic extension, not a prompt plea. The check-is-the-contract is an executed verification the executor runs itself, not a request that the worker "be careful." Reliability is measured by a verdict log and a scoreboard, not asserted. The harness is what survives a model swap.
Taken together this is the same thesis the rest of the site argues: the durable value is in the architecture — the encoded judgment — and the model is the reasoning glue, swappable underneath it. The build-triage page codifies an SRE's triage procedure into a skill; this page codifies an agent operator's delegation procedure into a topology, a contract, and a harness. Both are "codify the expert, then let the model execute."
6. Honest gaps
- No production impact numbers are in the source. The verdict log is
designed to measure delegate reliability (pass and first-try-pass rates per
model and task type), but no production aggregate is published in the setup's
own documents. The one exercised run recorded in the source is a zero-risk
scratch swarm (three independent
/tmptasks — a shell script, a Python program, ajqfilter — each checked by executing the artifact and diffing against an executor-owned expected fixture, 3/3 first-try pass). That is a proof-of-mechanics, not production evidence; a headline version of this story would publish the scoreboard once real mechanical work has flowed through it. - The sticky fallback is soft. It is orchestration-level — the executor
following the
AGENTS.mdrule — not hard-coded extension logic, and the source flags this honestly as judgment-driven rather than deterministic, with a noted bulletproofing path (forking the subagent extension to accept a fallback model and auto-respawn on failure/timeout). - Two lanes are named but not detailed here. The
locolane and thecross-repo-sweep,release-system, anddocument-pi-changesskills are named in the source but not fully documented in the material this page was distilled from. A complete architecture story would document them in their own right. - The setup is personal and user-level. Everything lives outside any shared package, so there is no teammate impact — but there is also no production-scale validation in the source. It is a well-instrumented personal rig, not a hardened team platform.
Sources
This page was distilled from the setup's own docs — its architecture overview, the global agent rules, the four agent definitions (advisor, advisor-opus, scout, coder), and the setup notes for the executor/advisor pattern and the verified-writes swarm. No provider account details, configuration values, credentials, or internal hostnames appear; the architecture is described, not copied. Every architectural claim above traces to that material.