# Exact-tree financial classification release review

Use for an independent final review of a bounded working tree that changes financial classification, import readiness, request-local caches, or Preview → Confirm behavior.

## Review sequence

1. **Freeze scope:** record status, base/HEAD, changed and untracked files, and `git diff --check`. Review the exact working tree and do not edit during an independent verdict unless asked.
2. **Trace priority:** prove transfer/card/refund semantics and explicit user decisions outrank learned/public fallback; conflicting confirmed history must remain `decision_needed` and outrank stable public merchant families.
3. **Prove cache parity under valid adversarial schema states:** compare complete cached and uncached results. Include duplicate active category names when names are not schema-unique, duplicate normalized merchants, tied aliases/rules, inactive categories, conflicting history, and all source types. Preserve SQL `ORDER BY`/`LIMIT` tie-breaking exactly. Any changed category, origin, conflict state, or evidence is P1 in a financial classifier.
4. **Attack merchant token boundaries:** test intended punctuation/glued variants plus unrelated words containing each token. Never apply punctuation-stripped substring matching to an entire taxonomy: `hospital` can match `hospitality`, `parking` can match `sparkingshop`, and `fitness` can match `unfitness`. Prefer an explicit compact-variant allowlist or boundary-aware patterns.
5. **Test readiness boundaries:** exercise maximum minus one, maximum, and maximum plus one; search backend constants, API types, UI fixtures, and tests for stale limits.
6. **Verify Preview → Confirm binding:** Confirm uses the exact applied request and both fingerprints; dirty drafts disable it; a failed apply preserves the last valid applied preview without marking drafts applied; the server reconstructs and checks baseline under the write lock.
7. **Trace approval-token reachability, not only validation:** for any server-secret-bound owner approval, enumerate token minting, authenticated API exposure, frontend action, applied-request persistence, reconstruction, and Confirm consumption. A positive unit test that imports a private token helper bypasses the product boundary and cannot prove the owner can perform the action. Require one synthetic API/UI → Preview → Confirm test, and verify the token is exact cluster/subset-bound, omitted from logs/audits, invalid after exclusions or baseline/input changes, and cannot authorize a broader mutation set.
8. **Keep timings outside identity:** add telemetry only after deterministic preview-core fingerprinting. Compare stable response fields independently from telemetry shape/non-negative checks.
9. **Use synthetic counterexamples:** disposable in-memory databases only—never productive financial data. Green happy-path tests do not replace adversarial probes.
10. **Re-freeze after verification commands:** final status must include newly generated or concurrently introduced untracked files (for example lockfiles). If candidate membership changed during review, do not silently approve the earlier snapshot; report the scope drift or restart against the newly frozen tree without deleting an artifact whose ownership is uncertain.
11. **Verdict format:** begin with APPROVE/BLOCK, give P0/P1/P2 counts, then exact findings with file/line, reproduction, impact, and correction. Separate passed gates and focused test evidence.
12. **Separate release gates from quality indicators:** when the product contract deliberately makes a 90/10 concept gate authoritative while retaining stricter 95%/3%/count/cluster metrics, trace each denominator and predicate independently. Prove neutral transfers, card settlements, receipts, pending rows, and exact duplicates do not dilute the ordinary-movement denominator; boundary-test 9/10 and 8/10; verify the strict indicator remains visible but is absent from Confirm authorization. A renamed old gate still present in `readiness_checks` is not separation.
13. **Treat owner-attested neutrality as a separate authenticated override contract:** trace the operator-only token minting route, independent secret/header check, exact cluster and included-row binding, fixed evidence/version, exclusion handling, fingerprint participation, Confirm reconstruction, neutral persistence, and aggregate audit count. The ordinary preview endpoint must reject forged tokens, and the normal frontend/API decision path must neither call the minting route nor manufacture approval fields. Keep ordinary row-level transfer actions restricted to decisive server-derived evidence plus fee/charge disqualifiers; an ordinary expense must not become neutral through a normal click or unsigned request. Do not require the privileged override itself to masquerade as ordinary transfer evidence—the separation and owner attestation are the contract.
14. **Audit expected writes as executable postconditions:** derive candidate, transaction, transfer-pair, file, and durable receipt-link counts from the same reconstructed write set used by Confirm. Verify linked receipts resolve to exactly one durable money target, duplicate/pending rows are excluded as designed, neutral single legs write once, paired legs write twice, and any count divergence rolls back the whole transaction. Audit payloads may record aggregate decision counts and versions, but must omit approval tokens, raw rows, and reusable identifiers.
15. **Scan only added candidate lines for privacy residues:** inspect every added source/test/doc line, not surrounding legacy context. Flag emails, IBAN/account-like identifiers, private paths, secret literals, long identifiers, personal names, and CSV-shaped date/amount records. Synthetic fixtures are acceptable only when unmistakably synthetic (`SYN-*`, generic counterparties) and must not encode reconstructed real records. Pair this with the repository safety scanner and a final untracked-file re-freeze.
16. **Attack snapshot cursors through every live rendering dependency:** obtain page one and its cursor, mutate one relation at a time in a disposable database, and require the old cursor to return 409. Cover open candidates, categorized confirmed candidate history, confirmed transactions, categories, merchants, aliases, review rules, recurring-payment lookups, source mappings, budget accounts, and canonical accounts whenever they can affect membership, ordering, rendered state/category/explanation, source facets, or confirmability. Also require a post-read data-version recheck so an in-request mutation cannot return a mixed snapshot.
17. **Prove server-scoped default queue state and clean restarts:** compare the server membership predicate with the state assigned by the live classifier/renderer; they must use compatible truth sources. Global counts/facets remain global while `filtered_total` is filter-scoped. On append 409, page one must be fetched without the stale cursor and must replace—not append to—the old page. Obsolete filter and append responses must not win races.
18. **Trace category type and confirmability end to end:** the backend emits transaction direction and current `can_confirm`; the UI offers only compatible active categories and disables category selection, row selection, and confirmation for non-confirmable items. Then bypass the UI and prove preview/confirm rejects wrong category type, special cases requiring dedicated actions, missing CHF conversion, stale rows, and incompatible/deactivated mappings. Confirm must re-resolve all of these under fingerprint/baseline binding.
19. **Audit monetary provider → API type → visible formatter contracts:** a green backend semantic test is insufficient if the frontend still consumes an old field. Probe a non-zero neutral-transfer volume and verify the visible KPI uses the volume field rather than a deliberately zero financial-effect field. Use realistically signed imported expense fixtures: if storage already carries `-42.00`, a type-derived prefix must not produce `− CHF -42.00`. Missing-FX rows must show original amount/currency with exactly one correct sign. Keep transfer effect, transfer volume, and transfer availability as separate concepts.
20. **Assess cursor correctness costs and opacity:** identify repeated full-table digests, correlated refund checks, and duplicate badge/page requests; validate them against realistic relation sizes or disclosed production timings. Base64 is encoding, not secrecy—check whether cursor payloads expose internal identifiers and whether the contract requires tamper resistance.

## Minimal matrix

| Area | Positive | Adversarial |
|---|---|---|
| Compact merchant | known glued/punctuation brand | unrelated containing word |
| Category cache | one canonical active name | duplicate active names allowed by schema |
| History | one consistent category | two confirmed categories for a public-family merchant |
| Readiness | exact allowed maximum | maximum plus one |
| Draft binding | apply then confirm | edit after apply; failed apply; stale response |
| Telemetry | non-negative fields | repeated deterministic fingerprint remains identical |
| Review cursor | unchanged classifier/mapping families | mutate each live family; old cursor returns 409 |
| Queue restart | append stable next page | append 409 replaces old items with fresh page one |
| Confirmability | compatible active category and mapping | wrong type, special case, missing CHF, stale/deactivated mapping |
| Finance presentation | non-zero transfer volume and signed import | old API field consumed; double-negative or invented CHF |
