Snapshot · the plan as approved, 2026-07-07, before any code

Drover: The Initial Plan

Implement everything in Stanford/Northeastern's Shepherd — a runtime that makes a live agent run reversible — using Toolpath as the execution trace format.

This page is preserved as-committed so the plan can be judged against what got built. Two details drawn here were later revised by evidence from real runs (the observation transport and the sealing trigger); the as-built page tells that story. Everything else survived contact with reality.

Stop 1 of 8 · why this project exists

The problem Shepherd solves, and why Toolpath is the right substrate

When an agent runs long enough, its trajectory becomes the cheap part and its state becomes the expensive part: the edited files, the installed packages, the running processes, and the provider-side KV cache. When the agent goes wrong at step 10, everything through step 8 was already paid for — and a message log cannot give it back. Restarting re-pays every call; a human rescue does not scale; letting the agent flail burns context.

Shepherd (arXiv:2605.10913) answers by recording execution as a Git-like trace of typed events where every action is a commit, the agent and its environment fork together copy-on-write, and any past state is one checkout away. Reverting is ~5× faster than docker commit, and because the message prefix up to the fork is byte-identical, replay reuses ~95% of the provider's prompt cache. On CooperBench, a supervising meta-agent lifted pair-coding pass rates from 28.8% to 54.7%.

The bet of this plan: Toolpath already is that trace format — a DAG of typed steps with first-class dead ends, actors, and intent, plus projectors that can rebuild any harness's native session files. Shepherd built a private trace and a runtime; we have the open trace and need only the runtime. Building it earns something Shepherd cannot do: forks that cross harnesses, and traces that outlive the run on Pathbase.

Stop 2 of 8 · what "everything" means, precisely

The parity target

Shepherd is four primitives and four demonstrated applications. The primitives: Task (agents as typed values a meta-agent holds and rewrites), Effect (every action a typed event, with intent and outcome separated so interception happens between them, and reversibility tiers for what cannot be undone), Scope (the agent and its environment forked atomically), and Trace (a persistent commit graph where revert is checkout and replay is byte-identical).

The applications, with the paper's numbers as our bars: a runtime supervisor (CooperBench 28.8% → 54.7%), counterfactual replay optimization (beats GEPA and MetaHarness on 4 of 5 datasets at 27–58% less wall-clock), Tree-GRPO (+5.2 points over flat GRPO on Terminal-Bench 2.0), and trajectory compression (68–82% of passing baselines rerun shorter with one hindsight hint). The paper's Lean-mechanized effect calculus is descoped as research garnish.

One reading of the paper's appendix shaped this whole plan: Shepherd's own headline experiment drove an external harness (opencode) over HTTP, with the agent loop on the host and only the sandbox forking. That is structurally identical to how arena already runs claude, codex, and gemini — so parity was never going to require exotic process checkpointing, just live observation, per-step snapshots, and session-truncation-plus-resume.

Stop 3 of 8 · the load-bearing claim: almost everything already exists

Shepherd primitive → Toolpath construct

Shepherd primitive
Toolpath-native implementation (planned)
Taskagents as typed values a meta-agent can hold, call, and rewrite
drover.Run a Python object wrapping a harness process, with .trace, .inject(), .handoff(), .discard(), .scope.fork(at=step)
Effectevery action a typed event; intent and outcome separate; reversibility tiers
Step (tool.invoke) EFFECT-LEVEL LIVE DERIVE — NEW one step per action, streamed as the session grows; hook-captured intents precede outcomes; a denied intent becomes a dead-end step, which the format already treats as first-class
Scopeagent + environment forked atomically, copy-on-write
drover scopes/ NEW Docker sandbox whose /work and $HOME sit inside the snapshot domain; pluggable backends — git-shadow first (portable, unprivileged), OverlayFS second (paper-grade latency, full rootfs)
Tracepersistent commit graph; revert = checkout; byte-identical replay
Path (.path.jsonl) live-appended during the run; forking is already representable — base.uri = "toolpath:parent/step" was in the RFC before this project existed; projectors rebuild the native session prefix byte-for-byte, which is the prompt-cache mechanism
Held proposalsworker output returns for review before touching the target
diff.patch + select / discard arena already holds the final workdir and diff per run; drover adds the accept and reject verbs

The audit that preceded this table found the format needed zero schema changes: the JSONL streaming spec, the fork-shaped base URI, live session watchers, and cross-harness projectors all existed — unexercised — in the toolpath workspace.

Stop 4 of 8 · the shape we committed to — including the one arrow reality later redrew

Planned topology

Two layers, split by where each language already lives. Rust owns the format and trace plumbing inside the toolpath workspace; Python owns orchestration in a new repo, with arena as a path dependency for sandbox images, tasks, and auth. The host process is the meta-agent's seat; the sandbox is the worker's world; four arrows connect them.

Figure 1 · Runtime topology, as planned
Host — drover runtime (Python, new repo) arena as a path dependency meta/ — supervisor loop tick ≈ 5 s over live traces one LLM call per tick, <3K tokens {none | inject | handoff   | discard} prompt seeded from paper App. E trace/ — live path client subscribes to path watch .path.jsonl (append-only) queries: dead ends, ancestors, actor / artifact filters observation adds 0 worker tokens control/ — harness drivers claude: stream-json stdin, hooks codex / gemini: observe + handoff / discard (v1) session surgery via projectors scopes/ — snapshots git-shadow — v1, runs on macOS overlayfs — v2, 72 ms class checkpoint on every step event ref recorded in step.meta.extra held proposals every run ends as diff.patch + final workdir; nothing lands until select Sandbox — per worker Docker container, arena pattern harness CLI claude -p · codex exec · gemini $HOME session store native JSONL — inside snapshot domain /work task repo verifier: pytest via verify.sh PreToolUse hook (claude) posts each tool intent before it runs inject stream-json stdin tail session JSONL * via bind-mounted $HOME checkpoint / restore intent → allow / deny Toolpath workspace (Rust) — the format layer toolpath toolpath-convo -claude · -codex · -gemini toolpath-live path watch · path fork → Pathbase (share) amber = to be built: one streaming-derivation crate and two CLI verbs; everything else already existed

* The amber arrow is the one the build redrew: the plan assumed a host-side tail of the bind-mounted session file. Real runs replaced it with the watcher running inside the sandbox, streaming events over the docker exec stdout pipe — see the as-built page for why.

Stop 5 of 8 · what using it was supposed to feel like — both screens were mocks when drawn

The target experience

Mock A · runtime supervision of parallel workers
drover supervise — 2 workers, 1 meta-agent
$ drover supervise --task pair-webhooks-ratelimit \
    --workers claude:haiku,claude:haiku --meta claude:sonnet

[00:05] worker-a   4 steps   reading tests/                    errors 0
[02:35] worker-b  31 steps   editing src/webhooks.py           errors 2
[02:35] meta       inject → worker-b
                   guidance: "src/webhooks.py belongs to another agent.
                             Implement rate limiting only in src/ratelimit.py."
[04:10] worker-a  22 steps   attempted: rm -rf /work/tests     intent DENIED
[04:10] trace      dead-end step recorded · decision: {status: denied}
[06:48] worker-a   verifier PASS   worker-b   verifier PASS
[06:48] proposals  2 held diffs — review with drover select
Mock B · trajectory compression of a real failed run
drover compress — fork, hint, rerun
$ drover compress --run 20260707T032005-gemini-default-impl-slugify-r2-a09e8423

reading trace     38 steps · verifier FAIL · 1 abandoned file
meta-agent        fork_step=2
hint              "Implement slugify inside textutil.py, the module the
                  tests import. Do not create a new file."
forking scope     snapshot @ s2 → fresh sandbox
resuming          prefix served from prompt cache
rerun             12 steps · verifier PASS
result            COMPRESSED 38 → 12 · original attempt preserved as a dead end

The run ID in mock B was real — a Gemini failure from that morning's arena matrix, which implemented a correct-looking slugify in the wrong file and thrashed for 38 steps. The plan's first demo milestone was to make this mock come true.

Stop 6 of 8 · the four meta-agents, ordered by build order rather than the paper's

The four applications

Build 1 · size S · needs only fork + resume

Trajectory compression

A meta-agent reads a completed trace, picks a fork step, writes one hint; the rerun must pass the verifier in strictly fewer steps. Chosen first because it exercises the whole fork/replay spine with zero live-supervision complexity, against a corpus that already exists.

Paper: 68–82% of passing baselines compress; mean length roughly halves.

Build 2 · size M · needs the control lane + tick loop

Runtime supervisor

One meta-agent watches N parallel workers' live traces on a ~5-second tick and issues inject, handoff, or discard — the paper's Appendix E protocol, prompt included, adapted to arena pair tasks and then a CooperBench subset.

Paper: pair pass rate 28.8% → 54.7%, closing 91% of the coordination gap.

Build 3 · size M · needs the replay loop

Counterfactual replay optimization

A proposer edits agent workflows and validates each edit by forking the parent trace at the first affected step and replaying only the suffix, with fix and guard sets gating candidates — harness self-repair grounded in exact replay.

Paper: beats GEPA and MetaHarness on 4 of 5 datasets, 27–58% less wall-clock.

Build 4 · size L · machinery + a funded training run

Tree-GRPO

During RL rollouts a meta-agent picks fork points; K sibling branches per point yield per-step advantages flat GRPO cannot see. Extends arena's existing world-model export, then a funded Flat-vs-Tree run on Prime Intellect.

Paper: +5.2 points over flat GRPO on Terminal-Bench 2.0 (Qwen3.5-35B-A3B).

Stop 7 of 8 · the order of operations and the milestone that proves the thesis

Phases as committed

PhaseSizeDepends onProof it works
1 · live traceMLive-derived document identical to the post-hoc import of the same run.
2 · scopesL1Post-revert workdir byte-identical; forked resume shows cache reads.
3 · controlM1A destructive tool intent is denied, recorded as a dead-end step; run continues.
4 · meta SDKM2, 3Supervisor A/B uplift on arena pair tasks.
5 · compressionS2 onlyAt least one real corpus run compressed: fewer steps, verifier passes.
6 · CROM2, 5Optimized workflow beats the baseline prompt on held-out tasks.
7 · Tree-GRPOL2, budgetTree beats flat GRPO on a held-out slice at matched compute.
8 · benchmarksMrollingA results table directly comparable to the paper's Tables 3, 8, 10.
First demo milestone — phases 2 + 5

Fork a real failed arena run at a meta-agent-chosen step, resume it with one hint, and watch it pass the verifier in fewer steps — the whole episode one Toolpath graph whose dead end is the original attempt. That artifact is the pitch; everything after it is scale.

Stop 8 of 8 · the five calls flagged for pushback, and the three decisions already made

The bets, as they stood

  1. Python runtime over an all-Rust build.

    Orchestration follows Shepherd into Python because arena, the meta-agent's LLM calls, and prime-rl already live there; Rust keeps the format and trace plumbing.

  2. git-shadow snapshots before OverlayFS.

    Portable, unprivileged snapshots first; the paper-grade backend later for system-mutating tasks and the latency table. Prime Intellect's gVisor blocks OverlayFS anyway.

  3. Codex and Gemini get no mid-run inject in v1.

    Observe-plus-handoff/discard until their streaming input paths are wired — the paper itself supervised exactly one harness.

  4. Denied intents become dead-end steps.

    Interception becomes a format-level fact rather than runtime-only state — elegant, and a semantic commitment the RFC carries forever.

  5. The maximal scope is real spend.

    A funded GRPO run plus full CooperBench replication is research-project territory; subsets gate everything, but the aim-point shapes the calendar.

Location — decided at approval
New standalone repo ~/code/empathic/drover; format work in the toolpath workspace; arena minimally touched.
RL depth — decided at approval
The full Tree-GRPO leg: machinery and a funded Flat-vs-Tree training run on Prime Intellect.
Benchmarks — decided at approval
Replicate the paper's benchmarks (CooperBench, Terminal-Bench 2.0 subsets) on top of arena-native validation.

Explicitly out of scope from day one: the Lean proof envelope, Windows, the pi harness, an opencode driver, and automatic compensation for irreversible effects — v1 records what cannot be undone, and catching it before it fires is the supervisor's job.