From a3e2fc6528f303fd5b1967644614ea012016220e Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 13 Jul 2026 10:42:07 +0200 Subject: [PATCH] dita_v2(test): preserve indeterminate post-ack state --- .../dita_v2/test_bingx_post_ack_invariants.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/prod/clean_arch/dita_v2/test_bingx_post_ack_invariants.py b/prod/clean_arch/dita_v2/test_bingx_post_ack_invariants.py index 8801867..8d60107 100644 --- a/prod/clean_arch/dita_v2/test_bingx_post_ack_invariants.py +++ b/prod/clean_arch/dita_v2/test_bingx_post_ack_invariants.py @@ -29,6 +29,7 @@ from prod.clean_arch.dita_v2.contracts import ( TradeStage, ) from prod.clean_arch.dita_v2.rust_backend import ExecutionKernel +from prod.clean_arch.dita_v2.venue import VenuePostAckError def _intent(*, trade_id: str = "post-ack-1") -> KernelIntent: @@ -186,6 +187,58 @@ def test_async_kernel_does_not_roll_back_acknowledged_fill(monkeypatch): _assert_fill_trace(outcome.emitted_events) +@pytest.mark.parametrize("submit_method", ["sync", "async"]) +def test_adapter_types_post_ack_event_conversion_failure(monkeypatch, submit_method): + backend = _SyncBackend() if submit_method == "sync" else _AsyncBackend() + venue = _venue(backend) + monkeypatch.setattr(venue, "_publish_telemetry", lambda **_fields: None) + monkeypatch.setattr( + venue, + "_events_from_submit", + lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("bad receipt")), + ) + + with pytest.raises(VenuePostAckError, match="post-ack failure") as captured: + if submit_method == "sync": + venue.submit(_intent(trade_id="sync-typed-post-ack")) + else: + asyncio.run(venue.submit_async(_intent(trade_id="async-typed-post-ack"))) + + assert backend.submit_count == 1 + assert captured.value.receipt.order_id == "venue-order-1" + assert isinstance(captured.value.__cause__, ValueError) + + +@pytest.mark.parametrize("submit_method", ["sync", "async"]) +def test_kernel_never_rolls_back_indeterminate_post_ack_outcome(monkeypatch, submit_method): + backend = _SyncBackend() if submit_method == "sync" else _AsyncBackend() + venue = _venue(backend) + monkeypatch.setattr(venue, "_publish_telemetry", lambda **_fields: None) + monkeypatch.setattr( + venue, + "_events_from_submit", + lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("bad receipt")), + ) + intent = _intent(trade_id=f"{submit_method}-kernel-indeterminate") + + with ExecutionKernel(max_slots=1, venue=venue) as kernel: + if submit_method == "sync": + outcome = kernel.process_intent(intent) + else: + outcome = asyncio.run(kernel.process_intent_async(intent)) + slot = kernel._get_slot(0) + + assert outcome.accepted is True + assert outcome.emitted_events == [] + assert slot.fsm_state is TradeStage.ENTRY_WORKING + assert slot.trade_id == intent.trade_id + assert slot.size == pytest.approx(0.0) + assert all( + event.kind is not KernelEventKind.ORDER_REJECT + for event in outcome.emitted_events + ) + + def test_every_publish_telemetry_call_site_binds_to_live_signature(): """Catch call/signature skew before any order path can execute it.""" source_path = Path(inspect.getsourcefile(BingxVenueAdapter) or "")