Tasks: YU05-post-trade-compliance
Deliveredβ
Settlement + reconciliation (ADR-022)β
- T-01 Fix
TradeOrder.fromEvent()to useOrderSnapshot.tradeIdFor(e.tradeSeq)(order-matcher, legacy/tradesNATS path; the live writer,ProjectorHandler, already did this correctly). - T-02
TradeBlotter+TradeBlotterHandler: new bounded, replay-rebuilt in-memory trade record on the output ring (order-matcher). - T-03
ReconController:GET /recon/trades/blotter(order-matcher). - T-04
TradeService: idempotent booking keyed on the now-deterministic id (trade-processor, legacy path; the live path was already idempotent viaINSERT IGNORE). - T-05
settlementdatecolumn added to the real runtime MariaDB schema (k8s init ConfigMap override, not the legacydatabase/initialSchema.sql); the fix applied where it matters,ProjectorHandler.toTrade()(order-matcher, the live writer); no longer setsSettledimmediately, setsProcessing+ a real T+N settlement date;SettlementServiceT+N sweep +POST /trades/{id}/settlement/force(trade-processor). - T-06
ReconciliationService: scheduled sweep against the order-matcher blotter, MATCHED/MISSING_IN_PROJECTION/FIELD_MISMATCH classification,GET /recon/status. - T-07 Corrected two existing integration tests (
LmaxHotPathParityTest) that asserted instant-Settled; updated toProcessing, confirming the fix landed on the live path. - T-08 Tests:
TradeBlotterTest,TradeServiceIdempotencyTest,SettlementServiceTest,ReconciliationServiceTest,ProjectorHandlerTest(tests the actual live writer). - T-09 Spec pack (spec, requirements, ADRs 022β025, architecture, runtime-topology, data-model, contract-delta, plan, research, this file); pipeline hooks; catalog + runtime-harness wiring.
Full-history orphan detection (FR-PTC10)β
- T-10
LmaxEngine.reindexFullHistory(): on-demand shadow-engine full journal replay into an unboundedTradeBlotter, reusingverifyJournalReplay()'s construction pattern.POST /recon/full-history/reindex+GET /recon/full-history/trades(order-matcher). - T-11
ReconciliationService.runOrphanSweep(): triggers the reindex, diffs every local trade id against it, flagsORPHAN_IN_PROJECTION.POST /recon/orphan-sweep+GET /recon/orphan-sweep/last(trade-processor).
Regulatory reporting (ADR-023)β
- T-20
AuditRecord+AuditLogHandler: captures every reportable output kind (accept/reject/partial-fill/fill/cancel/trade-booked) during a shadow replay, filtered byOutputEvent.inputSeqrange.LmaxEngine.generateRegulatoryReport(fromSeq, toSeq)+GET /regulatory/report(order-matcher). - T-21 Tests:
AuditLogHandlerTest(kind coverage, range filtering, unbounded-toSeq).
TCA (ADR-024)β
- T-30
PriceHistoryStore+PriceTickHandler: bounded per-ticker price history fed by price-publisher's existingpricing.*NATS feed (trade-processor, no BLP involvement). - T-31
TcaService: arrival price + TWAP benchmark + signed slippage-bps.GET /tca/report/{tradeId}(trade-processor). - T-32 Tests:
PriceHistoryStoreTest(TWAP math, bounded eviction),TcaServiceTest(slippage sign convention for buy/sell, null-benchmark honesty).
Real auth/entitlements (ADR-025)β
- T-40
JwtAuthenticator/JwtPrincipal/JwtTokenMinter(order-matcher and trade-processor, each its own copy): real HS256 signature verification via JDKjavax.crypto+ Jackson, no new dependency, no live OIDC provider. - T-41 Retrofitted every YU05 endpoint from token+operator headers to JWT:
ReconControllerandRegulatoryReportController(order-matcher,admin-only),SettlementController,TcaController, and orphan-sweep endpoints (trade-processor, account-entitlement oradmin).ReconciliationServicemints its own long-lived service-account JWT for machine-to-machine calls into order-matcher. - T-41a
POST /auth/dev-token(trade-processor): local dev/test token minting, gated by its own master secret. - T-41b Tests:
JwtAuthenticatorTest(both modules); valid round-trip, wrong-secret/tampered/ expired/malformed rejection,adminoverride, entitlement checks.
Observabilityβ
- T-50 Wired
traderx_recon_matched_total,traderx_recon_missing_in_projection_total,traderx_recon_field_mismatch_total,traderx_recon_cursor,traderx_recon_orphan_total,traderx_settlement_swept_totalinto Micrometer (trade-processor). - T-51
traderx-post-trade-compliance.jsonGrafana dashboard (recon cursor/classifications, settlement rate, TCA/regulatory-report request rate), added to the aggregated dashboards ConfigMap.
Entitlement resolution into the admission path (FR-PTC42)β
- T-42
EntitlementGateon every command entry point:OrderMatcherService.createOrder/createOrderBatch/bookMarketTraderesolve the caller's JWT principal (reusing YU05'sJwtAuthenticator) and reject a caller not entitled to the order's account (401 if the token is missing/invalid, 403 if valid-but-unentitled; admin claim passes any account).OrderController/MarketTradeControllerthread theAuthorizationheader through. Gated byrisk.entitlement.enforced(default false), so the existing token-less UI is unaffected until enforcement is enabled. Closes FR-IMRG02/FR-IMRG30 for real. Tests:EntitlementGateTest(7 cases: disabled, missing/invalid/wrong-secret token β 401, entitled β pass, unentitled β 403, admin β pass). Full order-matcher suite green (85 tests; the only failure is the pre-existing environmental 72-byte NGC-01 allocation flake inAllocationGateTest, on code this change does not touch).
Still openβ
- VWAP (FR-PTC32); needs a real per-tick-volume data source;
PriceHistoryStore's contract doesn't change to add it later. - Full container smoke: order fill β blotter β recon sweep β settlement sweep, end to end against a real MariaDB in an isolated staging namespace (same discipline as YU03).
- Isolated staging Cloud Build trigger + Cloud Deploy pipeline for YU05 (same pattern as YU03/YU04); requires explicit user go-ahead before touching any live CI/CD resource.