Same correct numbers every run, on either machine, with humans only on the genuine judgment calls.
A month-end close that produces the same correct numbers every time it runs, on either machine, with humans only doing the small set of genuine judgment calls. Target is roughly 90% automated and 10% human reasoning, which is fine and expected.
sku cost v2.xlsx (what the skills join to today)? And can COGS come straight from the API connection Will already uses (Sellerboard's per-SKU product cost, or whatever system already holds it) instead of a hand-maintained file? Per "one canonical source, no drift," if an authoritative system already holds COGS, pull from it directly — a parallel xlsx is exactly the file that drifts and caused the COGS-inflation bug. (Anthony: confirm whether you meant Salesforce or Sellerboard — the skills today recon against Sellerboard, which carries per-SKU cost.)
Settlement .txt, orders exports, Paycor xlsx, SKU cost, Sellerboard CSV. These must live in ONE shared, agreed location with a fixed naming convention, so Anthony's machine and Will's machine feed identical files. Determinism is meaningless if the inputs differ. Each skill prints the input filenames and row counts it used.
One new Google Sheet, separate from the main P&L.
Written by ONE assembler skill only. It reads the validated month row from each staging tab and writes the corresponding P&L columns. Because it is the only writer to the master, we harden one write path instead of thirteen.
"Deterministic" is not enough. A wrong script is consistently wrong. Every staging row, when written, is checked against an independent source and aborts if it diverges beyond tolerance:
summary.py; this is the model.Reasoning is permitted ONLY for genuinely ambiguous calls, and only as a flag for human approval, never an auto-write:
This is a loop, not a one-way handoff. Anthony's Claude reviews a skill and sends feedback. Will's Claude reviews it, applies what fits, and pushes back with the context Anthony's side doesn't have (Will's machine holds the real data, file layouts, and history). It repeats until the skill is agreed-solid. Anthony's side is the second opinion to make the skill efficient and correct; Will's side is the source of truth on how it actually runs. Acceptance test per skill: it does its own write, its own read-back assertion, and its own recon gate; Claude does no arithmetic and chooses no cells. For any reasoning step, both sides agree why and define its guardrail first.
Create the new staging sheet; decide the tab grouping; define each tab's column schema (the fields per skill). Migrate each skill to append its row there.
One skill, living and running on Will's computer, that reads the month's validated staging rows and writes the main P&L. It carries the full pre-flight: honor the user-provided gid/column verbatim, print every write target, insert-not-overwrite, run the recon, abort on FAIL.
A dedicated QC skill runs in its own fresh session, with no memory of how the numbers were produced, and checks them cold against source data and the recon gates. It runs FIRST and outputs a green/red report. Only after it passes does Will do his manual QC. The separate session matters: a fresh agent can't rationalize a number it didn't compute, so it catches what the producing session would wave through. That is the exact failure from the May close, where the producing session declared its own output correct.
Write the dependency map — the run order, "what must run before what" (e.g. amz-settlement to cm/wip fills; brand P&L to channel P&L to software-splits to recurring; payroll to channel payroll rows). Build ONE orchestrator that runs the skills in that encoded order in a single session. Order is encoded, never guessed live. Whole-pipeline dry-run (no writes) first, so Will sees all numbers and recon results before the assembler touches the main P&L.
Run the orchestrator on demand. Acceptance test: Anthony runs the full pipeline on his machine, Will runs it on his, same inputs, same day, numbers match to the cent. This proves true determinism. Do NOT schedule until this passes.
Once proven, use a local launchd/cron job on the Mac to fire the orchestrator on the close date. It must be local, not a remote /schedule agent, because the pipeline reads local input files and uses local MCP connections that a remote agent wouldn't see. The Mac just needs to be awake at run time.
Runs the second-opinion side in his Claude — reviews each skill, proposes the recon gates and reasoning guardrails, sends feedback to Will.
Owns the skills and the data. His Claude applies fixes and pushes back with real context; he owns the assembler (on his machine), the staging-tab QC, and the two-machine reproducibility test.
Agree the tab grouping, the dependency map, and the human-judgment checklist before locking. Phase 1 runs as a back-and-forth between the two Claudes.