PARALLEL_ACCOUNTS_RUNBOOK.md

pipelines/PARALLEL_ACCOUNTS_RUNBOOK.md

The three-account parallel factory — runbook

Josh, 2026-08-06, verbatim charter: "you've got Josh.milks@gmail.com jmilks3790@gmail.com and
Joshua.milks90@gmail.com... we can start the 3 parallels for next week so this current weekly
limit on Joshua.milks90@gmail.com runs every lane for this session then when all 3 reset next
week they will each have their own several pipelines." One 5090 box, three concurrent Claude
Code sessions, one repo pair, the §8.7 queue as the coordination bus.

The shape

(the default config dir). Orchestrates, adjudicates, integrates, pushes. The only session

that talks to Josh by default.

C:\Users\joshu\claude-accounts\claude-hf.cmd. With three dedicated runners the DIRECTOR

ACCOUNT STOPS WAVE-RUNNING ENTIRELY — orchestration is light, so the director survives

the whole week; runners wall and hand off freely.

Sessions do NOT coordinate by talking to each other. The repo is the bus: the SessionStart

hook (project-scoped — fires for ANY account in this cwd) orients every session identically;

each wave-runner claims the TOP UNCLAIMED wave from HANDOFF §8.7, marks it claimed in the

queue (one-line edit, committed immediately — the claim IS the lock), runs the standing loop,

lands in the game + both webpage surfaces, and claims the next.

Launching (already on the box)

Josh.milks (sets CLAUDE_CONFIG_DIR=C:\Users\joshu\.claude-acct-milks).

(CLAUDE_CONFIG_DIR=C:\Users\joshu\.claude-acct-jmilks).

opens. Credentials persist in that dir; every later launch is instant.

Box discipline (all of it already enforced by tooling, listed so nobody relearns)

serialized BY THE QUEUE (one claimant per wave), not by hoping.

(file locks do not care which account holds the terminal). Wait-never-steal.

pull --rebase --autostash -X theirs and retry. The multi-writer ownership discipline in

the handoff §6 binds every session.

burn the director's window. Review on a walled account's claude.ai when possible.

The week plan

HEADLESS RUNNER LOOPS (2026-08-06, supersedes type-"go" in place — Josh: "cant you

just write a python script to do that instead")

The runners are no longer interactive terminals waiting for a keystroke. Each launcher

.cmd now calls C:\Users\joshu\claude-accounts\runner-loop.cmd <acct-dir> <title>, which

loops FOREVER: claude --model opus --dangerously-skip-permissions -p "go" (headless

print-mode; each turn is a fresh session that boots from the SessionStart hook + the

handoff tail, claims a queue wave, lands it, exits — the repo is the memory, so fresh

context per turn is the DESIGNED pattern, not a loss). Turn success -> 60s pause -> next

turn. Nonzero exit (weekly limit, auth, crash) -> 30 min backoff -> retry, which makes

reset-pickup AUTOMATIC: a walled loop costs nothing and self-starts the instant its

window opens. Logs: C:\Users\joshu\claude-accounts\logs\<title>.log (turn timestamps +

full -p output; the limit banner with its reset time lands in the log, which is how the

ledger gets measured numbers). All three loops STARTED 2026-08-06 ~12:25 ET, minimized.

First measured result: josh@humanityrpg.com is ALSO at its weekly limit (resets Aug 11

3am ET) — its "fresh" week was already spent on the earlier waves; the loop idles on

backoff until then. Startup entry unchanged (it opens the same .cmd files, now loops).

THE CALL BUG (found + fixed 2026-08-06 ~15:47): the first loop version invoked claude

(an npm .cmd shim) WITHOUT call, so batch control TRANSFERRED and never returned —

every loop ran exactly ONE turn and silently died. Found by the monitor's own evidence

(no backoff/retry lines after the first turn). Fixed: call claude ...; all three

loops restarted on the fixed script. THE ONE TURN EACH RAN WAS REAL WORK: jmilks's

turn WAS the §8.9 "afternoon sitting" (music survey landed, BUG-0054 A/B, §8.9

authored); milks's turn re-fleshed Ch 6 (pushed, green) + started Ch 7, Ch 8 queued.

CORRECTED PICTURE: jmilks and milks are NOT hard-walled — they had capacity today and

their loops now keep working it; only hf is measured-walled (resets Aug 11 3am ET).

Lesson pinned: a runner "walled/idle" claim is verified from its LOG (turn lines +

banners), never assumed from the reset schedule.

walled session finish its in-flight wave on metered billing (ANTHROPIC_API_KEY outranks

subscription auth) instead of dying mid-flight. Josh pastes the key once; it lands as a

credential pointer per the standing law. Not yet provisioned.

Claim protocol (the one rule that makes three writers safe on one queue)

A wave-runner claims by editing its §8.7 line to [CLAIMED <account-short> <date>],

committing THAT LINE ALONE immediately, and pushing. A push rejection = someone else claimed

first: pull --rebase, take the next wave. Completion flips the line to [DONE <commit>] in

the wave's landing commit. The director audits claims at each sitting.

Resets, tiering, and the monitor ritual (Josh 2026-08-06)

RESET SCHEDULE (weekly): jmilks3790 - Sunday ~10pm ET (FIRST BACK). josh.milks - Tuesday

~3am ET. Joshua.milks90 (director) - Tuesday morning. josh@humanityrpg.com - MEASURED

walled 2026-08-06 12:24 ET, resets Aug 11 3am ET (the "fresh" note above is superseded:

its first week was spent on the launch-day waves). All four therefore walled or working

until Sunday night; the loops handle every re-entry unattended.

THE TIERING (Joshs ruling, the resource ladder end to end): Fable 5 Ultracode = THIS

director session ONLY. Opus 5 = the runner sessions (launchers pin --model opus) AND every

fan-out lane (explicit always). Local LLMs (7B/14B) + deterministic scripts = the mechanical

tier, always preferred where quality allows. The 5090 = generation/captures/renders,

token-free, kept fed by the queue. Lower thinking levels for triage where a lane charters it.

THE MONITOR RITUAL (director, each sitting + at every wave close): read the queue claims in

git (who holds what), glance the three runner terminals states, note each accounts 5-hour

window and weekly standing from its own sessions warnings (runners self-report walls into

their wave notes; a walled runner hands its wave back by un-claiming in the same commit).

THE VERIFICATION LESSON (Josh, verbatim: "take screenshots when you do this stuff to make

sure youve actually done what you say"): any GUI claim the director or a lane makes -

launcher opened, store page reached, dialog clicked - carries a SCREENSHOT read before the

claim is reported. The Tekken miss (deep links landing on Browse, reported as Store) is the

named instance.

The usage ledger (the concrete monitor surface)

No API exposes another accounts subscription quota, so the telemetry is BY CONTRACT: every

runner appends one line to build/ops/usage_ledger.md AT EVERY WAVE CLOSE and at every

usage-warning it sees: `<utc> <account-short> <wave> <5h-window: ok|warned|walled>

<weekly: ok|warned|walled> <note>`. A walled runner un-claims its wave in the same commit.

The director reads the ledger + queue claims each sitting and rebalances assignments around

the recorded resets. Efficiency remains TIERING, never thinness: gates, cold judges, and

the screenshot law run full-strength on every account at every tier - a runner that skips a

judge to save tokens has failed its wave regardless of output.

THE DETACHED-SPAWN AUTH LESSON (2026-08-06 night - hard-won, three wrong theories deep)

A claude spawned DETACHED from inside a running Claude Code session inherits the parent

sessions entire CLAUDE_CODE_* environment (CLAUDECODE=1, CLAUDE_CODE_CHILD_SESSION=1,

the session id, SDK_HAS_HOST_AUTH_REFRESH=1, the desktop entrypoint) and therefore

seeks auth from a HOST BROKER it cannot reach as a detached process - reporting "Not

logged in" while the credentials file sits valid beside it. Synchronous children work

(the broker is reachable); detached ones fail. THE FIX, now baked into runner-loop.cmd

and every seat .cmd: blank the inherited session vars (CLAUDECODE, CLAUDE_CODE_*,

AI_AGENT, BAGGAGE) after setting CLAUDE_CONFIG_DIR, so the spawn behaves as a fresh

top-level CLI reading file credentials. Diagnosis path that worked: instrument the

detached context (where claude + set dump to a log) instead of theorizing - the env

dump named the cause in one read after quoting and stale-token theories both died.

Generated by harness/site/structure_site.py — the URL path is the repo path. review root