Skip to main content

Store provider sizeRemaining where authoritative; keep the canonical size vector current

Refines ADR-0010 and is amended by ADR-0016. Betfair reports unmatched size through sizeRemaining/sr (docs/betfair/wiki/2687465, "the current amount of this bet that is unmatched"). Bifrost proto field 15 is explicitly applicable to exchange markets; it is not match authority for the all-or-nothing 9.x/14.x integration and may be absent on the wire. Future Bifrost 1.x exchange snapshots use the absolute provider bucket.

  • Store both currency mirrors when the canonical observation supplies them: sizeRemaining (provider ccy) and unmatchedStake (user ccy, ratio-derived via the SAME path as lapsedStake/cancelledStake/voidedStake — never a rate, no PT). A nullable provider field means “not reported/not authoritative for this observation,” not zero.
  • Keep the canonical size vector current on every provider update. Betfair and future Bifrost 1.x reconcile provider sizeRemaining. Bifrost 9.x/14.x derive working remainder from the confirmation-gated all-or-nothing lifecycle: full requested size before confirmation, zero after PLACED or a full terminal disposition. Their exchange-only wire bucket is corroborative only.
  • getCanonicalStatus derives working (residual) AND reconciles it against the stored provider remaining when present: |derived − provider| > dust → FINANCIAL_INTEGRITY (a missed stream/poll update or bad data is loud, never a silent wrong status). Null provider remaining (legacy row) → reconcile skipped, derive only. declined/settled short-circuit before the check (their vector isn't on-book).
  • Provider-agnostic core, policy-aware boundary: adapters normalize provider evidence into one canonical vector. The state machine never branches on provider, while the boundary must distinguish all-or-nothing status authority from partial-fill-capable exchange-vector authority.
  • Observability: every order update is logged (structured logger.info) at each ingestion point with the full size vector + status + provider + orderId/betId + source (stream|poll|queue) + ts.

Supersedes ADR-0010's "derive only, don't use the provider's remaining" — we derive and reconcile. Implementation: reconcile + unmatchedStake schema landed; the adapter always-write + logging (hot-money-path, dev-validated) is the remaining step.