my pi harness customizations, including a structured, multi-model system of iterative work

Files
README.md

pi-rig #

My Pi setup: the subagents I delegate to, the review pipeline I run changes through, and the ledger that decides which reviewers are worth keeping.

Layout #

  • AGENTS.md — workflow and routing rules; start here.
  • agents/ — reviewer, advisor, rebaser, scout, and summarizer cards.
  • skills/ — the review tiers and branch reviews.
  • extensions/ — Gemini reviewer tool, subagent runner, review ledger, catalog filter.
  • scripts/ — ledger tooling, the roster generator, a few probes. Node runs the .ts directly.
  • scripts/snapshot.zsh — on-demand V8 heap snapshot wrapper and trigger (SIGUSR2) for profiling extensions with zero overhead.
  • docs/ — reviewer head-to-heads and spend.
  • peak-guard.zsh — launcher hook that reroutes DeepSeek runs to Luna during peak pricing (PI_PEAK_GUARD=off disables it).

The loop #

The main session keeps the edits; read-only work goes to subagents, usually the free ones.

  1. Build the change.
  2. Once it compiles and the obvious checks pass, review the diff before showing it.
  3. Two or three reviewers read the same diff in parallel; I check every claim against the code before repeating it.
  4. Fix the real findings, then verify with a pass one tier down.
  5. If that pass still finds real issues, a third round is allowed. Two rounds is the norm.
  6. Docs-only and throwaway changes skip review.

Per-commit reviews stop once the user says the branch is ready to be considered for merging; from then on it gets one branch-review-* pass instead — see below.

Review tiers #

tier what it's for
review-min a trivial change, or an extra round when the last one still found things
review-low a small, low-risk change; the usual verification pass
review-medium an ordinary finished change — the default
review-high rare; genuinely tricky, or riskier than average
review-xhigh rarer; three reviewers instead of two
review-max very rare — the expensive panel

Two reviewers a tier, three for review-xhigh, from different labs. Each skill names its own roster and effort level; the rosters are generated from one file, so the tables in the skills, AGENTS.md, and the shared procedure can't drift.

  • review-min's second reviewer is OpenRouter's free router (openrouter/free), which picks a free model per request: cheap breadth, but no stable identity, and occasionally a 429 or a thin reply — a run like that is recorded as a missing arm, not a clean pass.

  • No model reviews its own work: when the change's author or session model is on the panel, that arm is swapped out (a peak-guard reroute to Luna counts).

  • Every finding is Confirmed, Plausible, or Rejected before it's reported. Silence isn't proof: one arm once came back clean on a change two others found a real bug in.

Not in any tier: the advisor agents (haiku, luna, nemotron, sol) for ad-hoc questions. Nothing they say is recorded.

Branch reviews #

Once the user says the branch is ready to be considered for merging, commit-level reviews stop and the branch gets one branch-review-* pass instead. It runs against the merge base rather than the latest commit: it reads the whole git diff <merge-base>...HEAD, audits every commit message, and judges whether the branch is one PR or several. If the branch has fallen behind its upstream, rebase it first (upstream-rebase) so the review sees the final code.

track first pass verify fixes
headed to your own main branch branch-review-low branch-review-min
upstream-bound branch-review branch-review-min
large or genuinely risky branch-review-high branch-review-low

branch-review-min is also fine for a small or draft branch. Every finding is validated against the repository and history before it's reported, exactly as for a per-commit pass, and the same reviewer-independence rule applies — a branch usually has mixed authors, so run the tier's panel as specified rather than adjusting it for the active model.

The ledger #

Every reviewer run is appended to a JSONL ledger under ~/repos/review-ledger (outside this repo). A run records who it was (arm, model, effort), what it cost (dollars for metered arms, plus wall-clock and tokens), and whether it delivered — a run cut short, answered nothing, or replied with narration is flagged, never counted as a clean arm that found nothing. Each panel also gets a hand-written assessment: a score, and a tally of how many of its findings were real. Capture is automatic.

scripts/review-stats.ts rolls it up. Across the current ledger (337 panels, 599 invocations, 411 assessments), the per-variant table is:

variant avg score runs cells mean median min max
sol-medium 8.33 3 3 $0.2511 $0.2446 $0.1420 $0.3666
haiku-medium 8.06 19 16 $0.0124 $0.0093 $0.0039 $0.0430
haiku-high 7.67 10 6 $0.0223 $0.0168 $0.0072 $0.0467
luna 7.63 4 8 $0.0068 $0.0057 $0.0006 $0.0151
haiku-low 7.16 78 69 $0.0050 $0.0043 $0.0004 $0.0177
luna-medium 7.00 58 66 $0.0081 $0.0075 $0.0025 $0.0216
openrouter-free 7.00 12 8 $0.0000 $0.0000 $0.0000 $0.0000
gemini-medium 6.89 97 124 sub sub sub sub
luna-xhigh 6.70 5 10 $0.0151 $0.0149 $0.0138 $0.0162
gemini-low 6.52 69 65 sub sub sub sub
gemini-high 6.51 53 98 sub sub sub sub
luna-low 6.31 31 29 $0.0026 $0.0024 $0.0016 $0.0052
luna-high 6.30 54 74 $0.0147 $0.0128 $0.0028 $0.0336
gemini 5.97 19 38 sub sub sub sub
luna-max 5.88 4 8 $0.0525 $0.0481 $0.0353 $0.0783
ling-high 5.82 58 51 $0.0040 $0.0030 $0.0000 $0.0143
free-nemotron3super-120b-high 5.47 22 17 $0.0000 $0.0000 $0.0000 $0.0000

What the columns mean:

  • avg score — the mean assessment score (out of 10) this variant earned, over cells judged cells.
  • runs — how many invocations it took.
  • mean / median / min / max — its per-run cost, in dollars. sub means subscription-billed (the Gemini tool) rather than metered, so the exact per-run cost is not recorded and cannot be known.
  • Ordering — by avg score (highest first); variants with no score are excluded.

Two things worth keeping in mind. Read the median over the mean, since a few cache-heavy runs pull the mean up. And compare arms within a tier, never across tiers — a follow-up round is a cheaper, smaller job than a first pass.

review-stats.ts also flags runs that produced no usable report, since their cost is retry overhead rather than the arm's price for a review. --write emits the full report under the ledger, and --panel <review-id> shows one panel's arms and its assessment state. Rosters are picked from this table: an arm that scores low for a high price doesn't keep its slot.

Profiling memory #

scripts/snapshot.zsh profiles extension and session memory using Node's built-in V8 heap snapshots via SIGUSR2. It requires zero code changes and has zero runtime overhead until triggered. Snapshots are saved into snapshots/ (gitignored).

Workflow #

  1. Launch Pi with profiling enabled (Terminal 1):
    ./scripts/snapshot.zsh
    
  2. Take a baseline snapshot (Terminal 2):
    ./scripts/snapshot.zsh snap
    
  3. Execute the workload in Pi (e.g. run a subagent task, review pass, or chain).
  4. Take an after-action snapshot (Terminal 2):
    ./scripts/snapshot.zsh snap
    
  5. Inspect in Chrome DevTools:
    • Open Chrome or Brave and navigate to chrome://inspect.
    • Go to the Memory tab and click Load.
    • Load both snapshots from snapshots/.
    • Select the second snapshot and switch the view perspective from Summary to Comparison to inspect exact retained byte deltas.

Helper commands:

  • ./scripts/snapshot.zsh list — list saved snapshots and total disk footprint.
  • ./scripts/snapshot.zsh clean — remove all captured snapshot files.

Maintenance #

  • Rosters are generated: edit scripts/review-matrix.ts, then --write, then --check. Don't hand-edit the marked tables; the drift check will fail.
  • Ling is off every roster while its provider is rate-limited (LING_AVAILABLE).
  • auth.json, sessions, logs, and the model store are gitignored.