# Dispatch — packs, roles, packets, recovery, price

Load when: composing a context pack, dispatching any role, packeting rows, recovering a dead or turn-capped agent, or pricing a run.

## The run folder

`.claude/state/polygraph/{YYYY-MM-DD-slug}/` — machine-local, never tracked, deleted when the run closes:

```
partials/{doc}.psv      one per finder — its whole output, no header
findings.psv            the merge, header first — the working copy
malformed.txt           quarantined lines, kept
packets/{doc}.txt       one per applier: `doc: {path}` then row ids and bounce notes
verify-{group}.psv      id|check|confidence|citations|note
apply-{doc}.psv         id|outcome|note
packs/{doc}.md          the context pack each finder and applier reads
```

Work items pass through files, never through a dispatch call's arguments — a resumed agent may not carry arguments, and one that dies on a missing argument dies before it reads anything.

## The context pack — the agent's whole reading list

One page per target document, written by you before the first dispatch. A brief that sends an agent to the charter, the backlog, the ownership index, or the findings file hands it a 500 KB read to extract 2 KB of fact — and hands the same read to every other agent in the wave. The pack carries the 2 KB:

| Section | Content |
| --- | --- |
| Target | the doc path; for a plan target, the plan path and the Proposed Changes paths that intersect this doc's `owns:` |
| Code | the doc's `owns:` globs, resolved to the files that exist today |
| Precedent | the quotations from guardrails, accepted decisions, and doctrine that **name** a subject this doc covers — the naming words only, with `path:line` |
| Already tracked | backlog and register rows that name a subject this doc covers, as `path:line` |
| Rulings | owner answers that bind this subject, verbatim |
| Read budget | the two clauses below, verbatim |

The two clauses every pack carries:

> Tree state: re-check every citation against today's tree before acting; a claim that fails to reproduce dies as *did not reproduce* — never becomes an edit. READ-ONLY everywhere except your one output file.

> Read budget: the pack is your reading list — read nothing outside it without naming in your return why the pack was insufficient. Grep before you read; never read a file over 20 KB without a line range; read a file once. Compose one shell block per question, not one call per file.

## The roles

| Role | Agent | Receives | Writes | Returns |
| --- | --- | --- | --- | --- |
| Finder | `polygraph-finder` | the pack path, the partial path | `partials/{doc}.psv` — one row per claim, ten fields, no header | ≤ 120 words: the file path, row count, up to three findings, limitations |
| Verifier | `polygraph-verifier` | a queue of `id`, `subject`, `claim` — no evidence, no verdict | `verify-{group}.psv` | ≤ 120 words: the file path and counts per check |
| Applier | `polygraph-applier` | the packet path, the pack path | the packet's docs; `apply-{doc}.psv` | ≤ 120 words: counts per outcome, docs touched, lint result, anything for the register |

Each agent definition carries its role's doctrine and its turn cap; a dispatch names the target and the paths and nothing else. **Findings go in the file, never in the return** — every word returned is re-billed on every later turn of the session.

Where the runtime has no such agent installed, dispatch an independent subagent on the cheapest capable tier with the agent file's body pasted in as its brief, and say so in the report.

## Packets — one doc, one applier

Routing is judgment, so you compose packets by hand; `audit.mjs` asserts the one mechanical invariant: **no document appears in two packets** — appliers run in parallel, and two agents in one file silently lose each other's edits.

**Packet by the doc the fix belongs in, not the doc a row's evidence cites.** A row's citations say where the *evidence* lives; the fix usually belongs elsewhere, and a bounced row's `needs-cross-doc` note says exactly where. A row with no derivable doc goes to the owner — never into a packet "to see what the agent makes of it".

By verdict: QUESTION and `depends_on` rows → the owner, inline. CONTESTED → you, with both sets of evidence. RESIDUE, and any row whose subject is a source file — a stale comment included — → the register. Everything else → the owning doc's packet.

## Verification — budgeted by what it caught

- **The applier re-check is the law.** In the proving run it killed more false positives than every other mechanism combined.
- **Blind re-derivation is discretionary.** Send a row *you* doubt — claim and subject only. As a mandatory stage it refuted nothing: finders' self-doubt is conservative, and the errors live in the confident pile, which is where your own read of the evidence looks. Disagreement makes the row CONTESTED; a verification never overwrites a verdict.

## Fold-back

After each applier returns, its outcomes become row state by your own edit, then `audit.mjs` checks the arithmetic:

- `applied` · `registered` · `exempt-frozen` → `resolved`, the resolution stamped with how.
- `refuted-on-apply` → `resolved`, resolution `did not reproduce`. A legitimate death; its count is the quality signal you report.
- `needs-cross-doc` · `blocked-on-question` · `skipped` → stays open — repacket, or hold for the answer.
- COHERENT rows close when recorded; they carry no work.

## Recovery

**The file on disk is the recovery unit, never the wave.** A dead agent costs its remainder; read what landed and relaunch only that. A finder that returns **partial** at its turn cap is resumed once from its partial — a second partial is accepted as that doc's sweep and named as such in the report. Every dispatch names its output file and a time bound; an agent past its bound with no file is dead — relaunch it, never wait on it, and never let one runaway agent hold the run. Gates — lint, links, ownership — run in your own seat.

## Price

State before dispatching, whenever a run exceeds ten documents or an owner directive names a tier: the per-doc cost at the pinned tier, the wave count under the concurrency ceiling, and the total; for a stronger tier, the multiplier and both totals. The directive and the estimate go in the changelog entry.
