# Stage 19 matching and correction completion — 2026-09-09

Owner instruction: continue typed FX matching, then grouped matching, remaining gateway/balance/
internal/reference strategies, correction authoring and nature/account reporting, and release preparation.
Base commit: `9d19cf755e44312e2aad5de8d4876e9402116a64` (previous work committed and pushed).

## Implemented behavior

- BNKMAT exposes evidence class, priority, numeric/calendar windows and ambiguity margin through
  the existing catalogue form. FX requires an explicit Percent/Absolute/Both policy, percentage
  and/or amount plus currency, rate-period basis and rounding precision. Both means both limits
  apply. No owner policy is backfilled from the legacy free-text allowance.
- FX converts through period-specific EXCRAT rates to EUR. EUR is the explicit unit anchor;
  missing, duplicate, nonpositive or overflowing rates refuse a claim. Single and multi-document
  shapes compare amounts only after conversion. Multi-document FX requires one source currency
  and one rate period, converts the aggregate once, and applies one allowance to that aggregate.
  The accepted aggregate difference is recorded once; no fee or offset document is invented.
- Group matching supports N movements to one document, one movement to N documents, the declared
  calendar-month variant and the longer chronological window. It searches the full eligible pool
  up to 16 candidates; a larger pool is held rather than truncated. Same-account, same-direction
  grouping avoids debit/credit netting. Equal-tier overlapping groups remain ambiguous and block
  weaker overlapping claims. Arrival order does not award a document.
- Gateway payout, counterparty balance and payment/receivable control-reference evaluators consume
  explicit **Matching Source Declarations**. These are attributable human transcriptions of an
  independent source, with source SHA256, reference, period, currency, exact movement/document
  membership and printed amounts. They are never produced from derived PAYCTR/RCVCTR rows.
  Gateway requires a declared fee and numeric BNKMAT tolerance: gross minus fees must equal net.
  Balance requires declared opening and closing balances and checks the ledger equation. It creates
  an association without allocating cash to invoices, declaring them paid or closing the residual.
  Reference matches retain Reference evidence class. Missing evidence/policy stays a review finding.
- Internal transfers require opposite same-currency movements in distinct owned accounts of the
  same company, within the declared window/tolerance, and printed identification of the other
  account. Coincident amounts alone are insufficient. Accept sets both counterpart links atomically;
  no fiscal document is required or created.
- Every machine match proposal records sorted membership and a hash of policy, document, movement,
  rate and applicable source facts. Human apply rechecks the facts with locks; stale proposals refuse.
  Decided review snapshots cannot be rewritten. Complete group rejection stores a permanent
  membership constraint. A company replay cannot supersede another company's proposals. Select
  a company in the top bar and use **Refresh matches** in Match & Review after changing a rule,
  exchange rate or source declaration; complete groups use a blank decision-input field.
- Fiscal correction lines can be added, inserted and removed (200 maximum), with contiguous line
  numbers and contract-derived blank facts. Statements keep their 150-row limit. Missing header,
  statement, service-period and sub-issuer objects can be authored; newly added objects open for
  editing. Original extraction evidence remains immutable and invalid arithmetic cannot save.
- Quality reporting compares declared ENTITM nature with live SNC accounts using the source Stage 17
  policy: Stock allows 3/61, Asset 4, Consumable 61/62, Service excludes 3/4. Missing accounts are
  counted separately. Findings never infer or rewrite item nature from an account.

## Schema and validation

Added Argus migrations:

- `20260909142842_TypedFxMatchPolicy`
- `20260909143029_MatchingProposalSnapshot`
- `20260909145041_MatchingSourceEvidence`
- `20260909151520_PreserveFxDifferencePrecision` (18,2 to 22,6; preserves integer capacity)
- `20260909152000_ScopeMatchingSnapshotGuard` (legacy reviews without native snapshots retain their sync behavior)

The source declaration table has forced owner RLS and composite owner/company/account and
owner/entity references. Main and Preview were aligned with `local/migrate.ps1 -Target All`,
including the six preceding persistence migrations previously present only on Preview.
No sync history, credentials, legacy paths or owner policy values were removed or replaced.

Development validation artifacts are in `local/artifacts/tests/matching-completion`:

- Full Argus: 410 passed; subsequent focused matching/catalogue/nature run: 62 passed.
- Full Platform: 561 passed; full API: 56 passed.
- Full Browser: 164 passed with Playwright enabled, including PT/EN desktop/mobile flows.
- Correction contract: 6 passed. UI detector returned no findings. Browser testing exposed and
  verified the fix for newly added optional objects initially remaining collapsed.

- Full TenantIsolation: 58 passed, including Main/Preview migrations, tables, RLS and role-grant parity.
- Final correction browser rerun: 2 passed; internal account-identity boundary regression: 1 passed.
- An unfiltered solution run passed API 56, isolation 58, Platform 561 and Argus 411, but its
  Browser run had one 5-second timeout waiting for Apollo channel configuration-save feedback
  (163 passed). The subsequent complete Browser rerun passed all 164. Both results are retained;
  this record does not relabel the first combined run as green. No timeout or assertion was relaxed.
- Internal-transfer apply integration passed: both legs protected and linked without a fiscal link.
- Final precision/snapshot checks: 24 passed, including an exact six-decimal FX register round trip
  and preservation of legacy review semantics. Final full isolation/parity rerun: 58 passed.
  The precision migration rebuilds the dependent view transactionally; its Main owner, security
  options and complete ACL were compared before/after and remained identical.

Packaging outcomes are recorded in the release preparation artifact.
These are synthetic development checks, not the independent persistence acceptance result.

## Remaining release gates and precise limits

The owner approved an [existing-corpus regression gate](persistence-regression-decision-260909.md)
because no additional documents are available. The original independent acceptance protocol has
not been fulfilled and must not be claimed. Freeze source/key hashes, expected outcomes, operator
actions and software/configuration for the reused-corpus checks; retain initial failures.

Production activation awaits that gate. NP Group native activation additionally requires its own
C6 cutover ruling: its recorded 52 sync runs remain protected. Deploying binaries or migrating the
schema does not waive C6. No production binary activation is claimed by this record.

These evaluators do not add bank-generated fiscal-document writers, document-to-document credit-note
settlement, cross-currency internal transfers, arbitrary mixed-period FX baskets or inferred gateway
fees. Balance associations do not implement invoice-level cash allocation. Those shapes are outside
this requested strategy batch and must not be presented as full parity with every legacy pipeline.
