# Synthetic transaction categorization fixture

Original synthetic data by Unbiased, generated on 2026-10-27. License: CC BY 4.0
(https://creativecommons.org/licenses/by/4.0/). Code: MIT.
Attribution: Unbiased, Synthetic transaction categorization fixture, 2026.
No bank export, customer record, third-party dataset or external label was copied.
Pareto authored the deterministic Python generator; no model generated individual
transaction text or labels at runtime. Generator models: Pareto (code author).

Labels set by the generator, spot-checked by us. Here "us" means the authoring
agent, not a human accountant. Full human review has NOT happened. Independent
human spot-check and accounting-realism review remain open. These are intended
synthetic labels, not tax or accounting advice.

## Construction and split

Seed 20261027. Four fictional businesses each have forty accounts. The generator
chooses the account or needs_review label before rendering the descriptor, amount
and masked card suffix. Business-specific rules assign METRO MARKET, AMBER SERVICES
and RIVER SUPPLY to different account categories at different businesses. Opaque
MISC ACH PMT descriptors deliberately require needs_review. Descriptors use familiar
ACH, POS, debit and online-transfer shapes, not captured bank strings. Amounts have
fixed decimals; currency is USD. No real account numbers appear.

There are 1500 history transactions (375 per business), 100 dev and 500 test.
History is embedded in recipe.py for a standalone download. get_history returns
at most three merchant matches from the correct business, never dev/test labels.
Dev and test have disjoint ids and seeded amounts. They share merchant templates
and intended rules: this measures rule application, not unseen-merchant robustness.
The generator source is scripts/evals/transaction-categorization/generate_fixture.py.
The fixture stores gold outside the text sent to the model.

## Frozen analysis conventions

Ten transactions form one evaluation item: fifty test batches and ten dev batches.
Boundary batches contain two businesses, always with separate charts and lookups.
The runner resamples batches, not individual transactions. Headline is mean of
per-batch median accuracy across repeats; per-run means equal transaction accuracy.
This differs from a transaction-level majority vote. Cost per record means a batch
of ten, not a single transaction. The batch macro F1 secondary is averaged within
batches over their observed labels, not global chart-wide macro F1. Missing
predictions are wrong; invented-account rate counts returned ids outside the
transaction's own chart. needs_review precision and recall pool repeat counts.
Tool validity includes both categorization cells and the history request. Invalid
one-shot output is zero accuracy, never omitted. The local envelope retains the
one-shot predictions and validation flags alongside final tool arguments.

The simple, recurring descriptors are deliberately favorable to history lookup.
Do not generalize scores to real books, split allocations, refunds against original
purchases, multi-currency ledgers, tax treatment or novel merchant descriptors.
No baseline has run. SDK compatibility spike evidence is not page-specific evidence.
