# Exception Taxonomy — Assertion-Level Reviewer Framework **Status:** Treasury Desk author synthesis, publication candidate. Not an industry standard. **Scope:** evidence classification for bounded reconciliation assertions; payment status, cause, severity and human disposition remain separate axes. ## 1. Required case envelope Before classification, record at minimum: - `case_id`, `assertion_id`, `as_of`, `scope`, `rule_version`; - what is compared to what; - entity/account/ownership perimeter; - asset/currency/network/contract identity where relevant; - event time vs booking/value date, timezone and cutoff; - amount unit/decimals/sign and gross/net/fee basis; - expected evidence population and source of expectation; - authoritative source for each field; - access/coverage state; - versioned tolerance or comparison rule. Name/amount similarity is not identity. ## 2. Four labels | Label | Proposed assertion-level criterion | Forbidden inference | |---|---|---| | MATCH | Necessary evidence is usable and comparable in scope and satisfies the versioned rule. | Payment success, authorization, safety, legality, full multi-leg settlement, or complete review. | | MISMATCH | Known usable values/states for the same assertion are comparable and disagree under the rule. | Cause, fault, loss, fraud or correct remediation. | | MISSING | A required-now record/field is absent inside a justified, sufficiently complete scoped population. | Economic event did not happen, funds are lost, or retry is appropriate. | | UNKNOWN | Information is insufficient on value, identity, applicability, completeness, comparability or authority for the conclusion. | MATCH, low risk, permission to proceed, or infinite waiting. | ### Governing distinction Known comparable `100` versus `95` is `MISMATCH`, even when `cause_status=unknown`. Unknown cause does not downgrade the known break to UNKNOWN. Visible `100` and `95` in unknown currencies, entities or cutoffs do not prove an economic amount mismatch. The amount assertion is UNKNOWN until comparability is established. A separate assertion about currency-code identity can still be MISMATCH. ## 3. Separate axes These axes must not silently create new values in the four-label enum: - `applicability`: `applicable | not_applicable | not_established`; - `observation_quality`: `present | known_absent | unobservable | stale | conflicted`; - `provider_or_rail_status`: source-native status only; - `cause_status`: `unknown | hypothesis | confirmed` plus evidence pointer; - `disposition`: `open | awaiting_evidence | escalated | corrected | accepted_exception | closed_with_explicit_unresolved_limit`; - `severity/materiality`: policy-specific, separate from evidence class; - `review_state`: draft/reviewed/reopened/superseded as applicable. `not_applicable` is an explicit exclusion from the denominator, not a fifth class and not a green MATCH. ## 4. Decision table | Gate | Observation | Result for the assertion | |---|---|---| | Applicability explicitly false | Stage/field is not due or out of scope | `not_applicable`; excluded from four-label denominator | | Applicability cannot be established | Rule/scope applicability unresolved | UNKNOWN | | Source inaccessible / 403 / timeout | Dependent evidence unavailable | UNKNOWN | | Pagination/filter/late-arrival horizon incomplete | Record not observed but coverage incomplete | UNKNOWN | | Identity not established | Candidate records cannot be safely joined | UNKNOWN | | Currency/entity/unit/cutoff not comparable | Economic values cannot be compared | UNKNOWN | | Required-now record absent + expectation justified + scoped coverage complete | Known scoped absence | MISSING | | Required field NULL and schema defines NULL as missing + complete coverage | Known required absence | MISSING | | NULL semantics unknown / redacted / unreadable | Evidence sufficiency unresolved | UNKNOWN | | Known zero vs known zero under comparable rule | 0 is a value, not absence | MATCH | | Known comparable values satisfy rule/tolerance | — | MATCH | | Known comparable values violate rule/tolerance | Cause may remain unknown | MISMATCH | ## 5. NULL rule A database query and a financial conclusion are different layers. PostgreSQL ordinary comparison with NULL yields unknown/null. `IS NOT DISTINCT FROM` can return true for NULL/NULL. A reconciliation implementation may use those predicates for technical purposes, but a reviewer must first establish the business meaning of NULL for the exact field. Two required missing values do not become evidence-sufficient merely because a null-safe predicate returns true. Do not coerce these into one bucket: missing row, required key missing, explicit null, empty string, known zero, optional/not-applicable, redacted, unreadable, access denied, timeout, incomplete pagination. ## 6. MISSING coverage gate Before MISSING, record evidence that: 1. the source was accessible; 2. correct tenant/account/entity was selected; 3. correct period/cutoff was selected; 4. filters and identifiers were correct; 5. pagination/population coverage was sufficient; 6. relevant late-arrival horizon was checked; 7. an independent rule/source establishes that the record should exist now. A bounded query proves only scoped absence, not “absence everywhere.” ## 7. Event / payment / chain separation - Event receipt is not payment completion. - Duplicate notification is not duplicate economic movement. - Provider status/reason is not reconciliation class. - On-chain inclusion/state is not bank credit or available funds. - Ethereum `latest`, `safe`, `finalized` are different source states; choose the criterion required by the workflow rather than using one universal confirmation count. - A late old event does not automatically supersede newer authoritative evidence. Preserve `event_id`, provider object/payment ID, economic movement ID, source version, `event_time`, `source_updated_at`, `received_at`, `retrieved_at`, comparison cutoff and selected authority where material. ## 8. Gross/net and mapping rule Do not force closure through invented fees or offsets. For a documented one-to-one fee rule: `expected_net = gross - documented_applicable_fees` For one-to-many / many-to-one / batch cases, validate mapping identity and line relationships before totals. A zero aggregate delta can coexist with line-level MISMATCH values. ## 9. Multi-assertion case aggregation Each child assertion retains its own four-label result. A case-level `MIXED` display roll-up is allowed only as a summary word and is **not a fifth assertion label**. The roll-up must expose the child labels present and counts. For in-scope evaluated assertions: `N = MATCH + MISMATCH + MISSING + UNKNOWN` `not_applicable` and not-yet-evaluated/pending assertions are reported separately. If `N=0`, shares are undefined. Do not add multi-label case counts as if they were mutually exclusive. Do not sum different currencies/legs into “exposure” without a defined model. ## 10. Closure and reopen Closure records a human/operational decision. It does not rewrite evidence. A closure record should state: - what exact assertion/task is closed; - closure evidence; - decision authority/role; - unresolved limits; - reopen condition. Risk acceptance can close an administrative task while the underlying assertion remains UNKNOWN. A corrected source record requires a new comparison run. Reorg, reversal, return, corrected mapping, superseding statement or new authoritative evidence can reopen the case. Preserve the prior evidence and classification history. ## 11. Reference classifier status The accompanying Python classifier is educational and deterministic. It operationalizes the table above for synthetic unit checks only. It is not production-ready and contains no live API calls, posting logic, retry logic, transfer logic or accounting instructions.