Finance · Month-End Close

Month-End Close: Re-Architecture Plan

Same correct numbers every run, on either machine, with humans only on the genuine judgment calls.

For: Anthony + Will Status: Plan, pre-build Target: ~90% automated / ~10% human reasoning
01

The Goal

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.

02

The Core Idea

One sentence: Separate the working data (per-skill, append one row per month) from the boss-facing P&L (written by a single assembler), and gate every number with a fail-closed check against an independent source.
03

Architecture: Three Layers

Layer 1 · Inputs

Raw files

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.

Layer 2 · Working Sheet (NEW)

The staging layer

One new Google Sheet, separate from the boss P&L.

  • One tab per skill (or a few skills grouped by shared source data, e.g. one Amazon Settlement tab, one Payroll tab, one P&L Channel Inputs tab).
  • Each month appends one new row per tab. Flat table: columns are the fields that skill produces.
  • No blocks, no inserts, no stacking, no per-month column discovery. Appending a row is the lowest-risk write there is.
  • This is where Will and the auto-QC review numbers before anything reaches the boss doc.
Layer 3 · Master P&L

The existing boss doc

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.

04

Why This Kills the Current Bug Classes

Wrong column / wrong row / insert-shift math
Gone. Staging is append-a-row; the assembler writes fixed master cells.
One skill overwriting another's data
Structurally impossible. Each skill owns its own tab.
Cross-month wipes (the April-wipe)
Gone. Months are separate rows, never overwritten.
Silent wrong numbers (the summary.py bug)
Caught by the recon gate below.
05

Non-Negotiable: The Fail-Closed Recon Gate

"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:

Checks are code, not a Claude eyeball. A QC dashboard can display green/red, but the checks themselves are deterministic assertions. Claude re-reading its own work and saying "looks right" is exactly what failed in the May close.
06

Where Reasoning Is Allowed — the ~10%

Reasoning is permitted ONLY for genuinely ambiguous calls, and only as a flag for human approval, never an auto-write:

Guardrail for each: Claude proposes and explains, Will approves, the approved value is then written deterministically. Plus a sanity-range check on any reasoned value. We list every reasoning step explicitly during the audit so the human-judgment set is a known checklist, not a surprise.
07

The Work, in Phases

Phase 1

Audit + determinize every skill (Anthony leads, in his Claude)

Anthony QCs each month-end skill, produces the fix, hands it to Will to apply in his Claude. 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 step that needs reasoning, Anthony and Will agree why and define its guardrail before it is allowed.

Phase 2

Build the working spreadsheet

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.

Phase 3

Build the assembler

One skill that reads the month's validated staging rows and writes the master 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.

Phase 4

Auto-QC

A deterministic check suite over the staging tabs and master that outputs a green/red report for Will. Will also eyeballs the staging rows.

Phase 5

Dependency map + orchestrator

Write the DAG (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 boss doc.

Phase 6

Run manually, prove it

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.

Phase 7

Schedule

Once proven, cron the orchestrator to fire on the close date. Both machines (or one) run the same encoded pipeline and get identical output.

08

Division of Labor

Anthony

Audits/QCs each skill in his Claude, defines the recon gates and reasoning guardrails, hands fixes to Will.

Will

Applies fixes in his Claude, owns the staging-tab QC, confirms the two-machine reproducibility test.

Both

Agree the tab grouping, the DAG, and the human-judgment checklist before locking.

Order to execute: Phase 1 (audit/determinize) and Phase 2 (staging sheet) first — they remove most of the pain. Phases 3-5 wire it together. Don't touch Phase 7 (scheduling) until Phase 6 (two-machine match) passes.