---
name: terry
description: Invoke when orchestrating a FLEET of parallel long-running agent tasks via a priority-queue manager over git worktrees — agent queue + task list + dispatched agents + a self-pacing heartbeat loop; covers dispatch, worktree isolation, the manager-only merge protocol, and the resource/orphan/determinism anti-patterns that make fleets fail.
---

# Terry — agent-fleet orchestration

Terry is a long-running **manager loop** that drives a fleet of independent
worker agents. Each worker does ONE well-scoped, long-running task in its OWN
git worktree + branch. They coordinate through a single JSON priority-queue
state file, and **Terry is the only one that merges** worker branches into an
integration branch — distributed-VCS style.

It is the generalization of four primitives wired into one durable loop:

- **agent queue** — a JSON state file (`agent_queue.json`)
- **task list** — native `TaskCreate` / `TaskList`
- **dispatched agents** — the native Agent tool (`run_in_background`)
- **heartbeat** — `ScheduleWakeup` (or a `/loop`) that self-paces the manager

## When to use

Use Terry when you have **N independent long-running tasks** that each take
many minutes-to-hours, benefit from running concurrently, and are merged as
they finish. Typical shapes:

- parallel exploration of competing hypotheses (one worker per hypothesis)
- a fleet of per-target migrations (one worker per target)
- multiple validation / iteration runs against a shared codebase
- anything where **dispatch → it runs a while → it reports → merge → dispatch
  the next blocker** repeats.

## When NOT to use

- A single quick task — just do it.
- Work that must be strictly sequential because each step needs the previous
  step's result — no parallelism to exploit, so no fleet.
- More heavy concurrent runs than the machine can hold (see the resource-wall
  lesson in `references/lessons-and-antipatterns.md`).

## The heartbeat loop (5 steps)

Terry wakes on a completion notification or a fallback timer and runs:

1. **OBSERVE** — read completion notifications; poll live state of in-flight
   workers (HTTP status endpoint or log tail, preferring structured polling).
   Recognize and IGNORE stale completion echoes from already-handled agents.
2. **INTEGRATE** — for each genuinely-completed worker, merge its branch into
   the integration branch, resolve conflicts deterministically, and run the
   test/verify suite **in the main checkout** (never the worktree). Commit only
   if green.
3. **DEQUEUE + DISPATCH** — pick the next-priority blocker from the queue;
   dispatch exactly ONE worker in a fresh worktree+branch off the **current**
   integration HEAD, with a unique resource handle (port/dir).
4. **RECORD** — update the JSON state file (completed → `done_this_session`
   ledger; add the new `in_flight` entry; bump `integration_head`); commit it.
5. **RE-ARM** — schedule the next heartbeat with a LONG fallback delay.
   Completions wake Terry sooner; the timer is only a safety net.

Full detail (polling cadence, stale-echo detection, what to do when a slot is
blocked vs. idle): **`references/heartbeat-loop.md`**.

## Mental model: distributed VCS

Treat the fleet like a team using a shared repo:

- **Workers are contributors.** Each works on its own branch in its own
  worktree, commits CODE ONLY to that branch, and never touches the integration
  branch or another worktree.
- **Terry is the maintainer.** It is the only actor that merges, and it always
  verifies in the canonical checkout before accepting a merge.
- **The integration branch is "main."** It is the single merge point; nothing
  edits it directly except Terry's merges and the state-file commits.
- **The queue is the backlog.** Priority-ordered blockers waiting for a free
  slot.

Isolation and merge rules (worktree setup, symlinking deps, never `git clean`,
conflict resolution): **`references/worktree-merge-protocol.md`**.

## Worked example: one tick

State before the tick — one worker in flight, two queued:

```jsonc
// agent_queue.json (excerpt)
"integration_head": "a1b2c3d",
"in_flight": [
  { "id": "mtmoon-grind", "agent": "agent-7", "wt": "../wt-mtmoon",
    "branch": "terry/mtmoon-grind", "port": "8801", "run": "vanilla-squirtle",
    "title": "grind to Lv24 before Mt Moon exit; resume cp_pre_mtmoon; next: survive 1F trainers" }
],
"queue": [
  { "prio": 1, "id": "misty-viability", "title": "Lv24 Bite vs Misty Starmie — confirm OHKO route" },
  { "prio": 2, "id": "surge-route",     "title": "Vermilion gym trash-can puzzle nav" }
]
```

The tick:

1. **OBSERVE** — completion notification fires for `mtmoon-grind`. Poll
   `http://127.0.0.1:8801/state` to confirm it is genuinely done (not a stale
   echo): party_lv reads 24, branch `mtmoon-grind` has commits.
2. **INTEGRATE** — `git merge mtmoon-grind` into the integration branch; run
   `uv run pytest tests/` in the main checkout → 168 pass → commit.
3. **DEQUEUE + DISPATCH** — pop `prio:1 misty-viability`; `git worktree add -f
   -b misty-viability ../wt-misty <new-integration-HEAD>`; symlink `deps`; copy
   the needed `cp_*.state`; dispatch one worker on `--http-port 8802` with the
   dispatch-prompt contract (`templates/dispatch-prompt.md`).
4. **RECORD** — move `mtmoon-grind` to `done_this_session`; add the new
   `misty-viability` `in_flight` entry; bump `integration_head`; commit the
   state file.
5. **RE-ARM** — `ScheduleWakeup` with a long fallback; yield until the next
   completion or timer.

## Quick start

1. **Init the queue file** from the template:

   ```bash
   mkdir -p tools
   cp skills/terry/templates/agent_queue.json tools/agent_queue.json
   # edit integration_head, seed `queue` with your prioritized blockers
   git add tools/agent_queue.json && git commit -m "terry: init queue"
   ```

2. **Dispatch the first worker** — create its isolated worktree off the current
   integration HEAD, then dispatch one Agent (`run_in_background`) using the
   dispatch-prompt contract:

   ```bash
   HEAD_SHA=$(git rev-parse --short HEAD)
   git worktree add -f -b worker-1 ../wt-worker-1 "$HEAD_SHA"
   ln -sfn "$PWD/deps" ../wt-worker-1/deps          # symlink heavy untracked deps
   cp tas_saves/cp_seed.state ../wt-worker-1/tas_saves/cp_seed_worker1.state   # UNIQUE untracked name
   ```

   Fill `templates/dispatch-prompt.md` (scope, worktree path, branch, unique
   `--http-port`, determinism bar, report-back contract) and pass it to the
   Agent tool.

3. **Arm the heartbeat** — schedule the manager loop with a long fallback delay
   (`ScheduleWakeup` or `/loop`). Completions wake Terry sooner; the timer just
   guarantees forward progress if nothing reports in.

## References

- `references/heartbeat-loop.md` — the 5-step loop in depth: polling, stale-echo
  detection, blocked-vs-idle slots, re-arming.
- `references/worktree-merge-protocol.md` — worktree isolation, symlinks,
  manager-only merges, conflict resolution, verify-in-main.
- `references/lessons-and-antipatterns.md` — orphaned runs, resource wall,
  handle/port collisions, stale-base regression, tooling false-negatives,
  verify-before-claim, parallel-hypotheses-when-stuck.

## Templates

- `templates/agent_queue.json` — the priority-queue state file shape.
- `templates/dispatch-prompt.md` — the worker dispatch-prompt contract.
