SUPERSEDED — DO NOT ACTION. This tasking was based on an incorrect diagnosis (DEGRADED cancel path missing FLAG-047 detection). Diagnosis was corrected after code review. The actual root cause is a truth-check timing race. Vesper has delivered the correct fix. See
[C] Atlas-Orion Briefing — S54 Root Cause, FLAG-052 Fix, FLAG-051 Summary.mdfor the full corrected analysis. Orion is on hold for FLAG-052. branch: fix/degraded-cancel-race priority: HIGH — S55 blocked
FLAG-052 — DEGRADED Entry Cancel Path Missing Cancel-Fill Race Detection¶
What happened¶
S54 halted via inventory_truth_halt at ~02:04 UTC. The sequence:
- Engine entered DEGRADED
- Fired "Degraded entry cancel" on active buy order (sequence ~103476262)
- That order had already been filled on-chain before the cancel arrived
- XRPL returned
tecNO_TARGET - Engine recorded order as
CANCELLED_BY_ENGINE RECONCILER_SKIP_ENGINE_CANCELsuppressed fill recognition on subsequent ticks- Truth check saw:
delta_xrp = −13.646, delta_rlusd = +19.5→inventory_truth_halt
Actual fill: ~13.65 XRP bought, ~19.5 RLUSD paid (~1.429 RLUSD/XRP). Capital was flat. The halt was spurious — caused by the engine not recognizing its own fill.
Root cause¶
FLAG-047 added tecNO_TARGET → CANCEL_RACE_UNKNOWN → account_tx on-chain lookup on the atomic replace cancel path only.
The DEGRADED entry cancel path — wherever _cancel_all_orders() (or equivalent) is called when the engine enters DEGRADED state — was NOT covered by FLAG-047's fix.
Same race condition. Different call site.
Required fix¶
Extend FLAG-047's cancel-fill race detection to the DEGRADED entry cancel path.
When a DEGRADED entry cancel returns tecNO_TARGET:
- Demote order to CANCEL_RACE_UNKNOWN (same as atomic replace path)
- Query on-chain via get_account_tx_for_offer (existing gateway method from FLAG-047)
- Three-way resolution:
- FILL → record atomically via mark_filled_after_race; do NOT mark CANCELLED_BY_ENGINE
- CANCEL → terminal (landed, order gone)
- INCONCLUSIVE → fail-closed; flag for manual review (do not suppress reconciler)
Do NOT mark an order CANCELLED_BY_ENGINE until on-chain resolution confirms the cancel landed.
Where to look¶
The atomic replace path fix (FLAG-047) is in:
- Cancel response handling in the XRPL gateway (look for tecNO_TARGET handling added in fix/cancel-fill-race)
- mark_filled_after_race atomic method in reconciler
- get_account_tx_for_offer gateway method
Find the DEGRADED entry cancel call site — likely in state manager or main loop, wherever cancel_all_orders / cancel_for_degraded is invoked on DEGRADED entry. Apply the same tecNO_TARGET handling there.
Tests required¶
Minimum:
1. DEGRADED entry cancel returns tecNO_TARGET → FILL resolution → fill recorded, no CANCELLED_BY_ENGINE, no truth halt
2. DEGRADED entry cancel returns tecNO_TARGET → CANCEL resolution → order terminal, no phantom fill
3. DEGRADED entry cancel returns tecNO_TARGET → INCONCLUSIVE → fail-closed, not suppressed
4. DEGRADED entry cancel returns success (normal path) → unaffected
Existing FLAG-047 tests should continue to pass.
Delivery¶
Branch: fix/degraded-cancel-race
Apply instructions: standard git am patch bundle to C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\08 Patches\
Apply path: C:\Users\Katja\Documents\NEO GitHub\neo-2026\
Branching rules (standing):
- Do NOT pre-create the branch during investigation
- Use Get-ChildItem ... -Filter "*.patch" | Sort-Object Name | ForEach-Object { git am $_.FullName } form (no glob in PowerShell)
- Include git branch -D fix/degraded-cancel-race before git checkout -b fix/degraded-cancel-race in apply instructions
— Vesper