Acceptance Lab: Run a Fund End-to-End
The Acceptance Lab (apps/acceptance-lab) turns a declarative
FundScenario — a fund described as data: calendar, terms, investors — into
a deterministic multi-period close on an in-memory Postgres (pglite), and
emits Carta-shaped statements (P&L, balance sheet, per-LP PCAP) that tie
out against an independent set of §1a reconciliation identities.
It exists to be a data-model forcing function — because the cheapest place to discover that the schema cannot express a real LPA is a synthetic run, not a live customer close. You author a real fund’s terms, run it, and either it ties out or it surfaces a gap. Where an option isn’t built yet, the Lab fails closed (errors) rather than guessing.
Running a scenario
Author the scenario
A FundScenario is JSON validated by @opsdna/fund-scenario: fiscal calendar,
terms (fee schedule, waterfall, expenses), investors and their commitments,
and optional side letters/investments. The full option reference is
apps/acceptance-lab/README.md.
Validate
bun apps/acceptance-lab/src/cli.ts validate path/to/scenario.jsonExits 1 on a decode failure or any error-severity issue. Fast, no DB.
Explain (optional, no DB)
bun apps/acceptance-lab/src/cli.ts explain path/to/scenario.json --quarters 2Emits JSON: the normalized scenario, the event timeline + hash, per-period fee summaries, the per-LP allocation split, and coverage gaps. Deterministic — useful for eyeballing computed numbers before a full run.
Run the close
bun apps/acceptance-lab/src/cli.ts run path/to/scenario.json --out ./out --quarters 2Stands up pglite, runs the multi-period close, and writes a RunManifest
directory. Exits 1 if a period fails to freeze or any §1a reconciliation
identity fails. Add --no-artifacts to skip PDF/xlsx rendering, --explain
to also print the explain JSON. Under accrual_cadence: "annual",
--quarters counts fiscal years.
Review and diff
bun apps/acceptance-lab/src/cli.ts review ./out
bun apps/acceptance-lab/src/cli.ts diff a.json b.json --timeline
bun apps/acceptance-lab/src/cli.ts diff-ir old-ir.json new-ir.json --format textreview prints the one-page review packet (scenario summary, period-by-period
activity, the §1a checklist, top deltas vs a prior run with --prior-ir).
diff is a semantic scenario diff — two scenarios that serialize
differently but decode to the same value produce an empty diff
(fundScenarioContentHash is the oracle). diff-ir compares statements IR at
per-period → statement → LP → line-code grain in integer minor units. Both
diffs exit 1 when a difference exists, so CI can gate on them.
The package script form is bun run --cwd apps/acceptance-lab cli <mode> …,
and the test suite runs with bun run --cwd apps/acceptance-lab test.
What a run exercises
The Lab drives the whole stack documented in this section: it lowers the
scenario’s terms through the policy IR layer,
runs the runtime evaluators that emit
canonical application records, posts
through the ledger kernel, projects PCAP,
and builds statements. The per-domain close modules live in
apps/acceptance-lab/src/ — e.g.
european-carry-persisted-quarter-close.ts,
distribution-persisted-quarter-close.ts,
fair-value-adjustment-persisted-quarter-close.ts,
fund-statements-builder.ts, and live-pcap-bridge.ts. The Lab’s gates also
reconcile the persisted *_application_details rows row-for-row against the
runtime records — which is how they earned their keep in the ADR-0019 §5
drop-wave proof.
Pitfalls.
- The Lab runs on pglite, which silently accepts things real Postgres
rejects (EXECUTE grants, RLS FORCE, catalog invariants). A green Lab run is
not a green
postgres integrationlane — schema changes need the real-Postgres tests too (see Persistence). - Fields a milestone hasn’t built yet (
waterfall,expense,investments,side_lettersat AL0) are accepted by the schema but not exercised; the Lab fails closed rather than guessing. Don’t interpret an error as a bug before checking the current scope note inapps/acceptance-lab/README.md. - The IR diff (
diff-ir) is the “safer golden review” artifact — prefer it over byte-diffing rendered PDFs/xlsx when reviewing golden changes.
The Lab’s composed-close identity model is recorded in
docs/adrs/0008-acceptance-lab-partner-capital-gl-and-composed-close-identity.md.