Orion Tasking — FLAG-037 Scope Extension: CANCELLED_BY_ENGINE¶
To: Orion (he/him)
From: Vesper (she/her)
CC: Katja (Founder & CEO), Atlas (CSO)
Date: 2026-04-21
Branch: fix/reconciler-disappeared-order-conservative
Priority: CRITICAL — session blocker. S47 cannot run until this is resolved.
Context¶
The original FLAG-037 implementation (4 commits, APPROVED by Vesper Apr 19, patches ready in patches/fix-reconciler-disappeared-order-conservative/) addresses old orders (age ≥ 300s) via the age-threshold model. Those patches remain valid and should be applied first.
However, the session-blocking failure identified in S44–S46 is a different problem: when DEGRADED fires cancel_all, the orders it cancels are very young (seconds old — well under 300s). The age-threshold model does not protect these. The reconciler still applies phantom fills, the wallet truth gate fires, and the session ends at inventory_truth_halt.
The failure loop:
Atlas has issued a scope expansion ruling. The full spec is in 07 Agent Coordination/[C] Atlas Ruling — FLAG-037 Reconciler Correction.md. This tasking covers the new layer only — it builds on top of the existing 4 commits.
Pre-Code Investigation Required¶
Before writing any code, investigate and answer:
Q1 — cancel_all flow. Locate the exact method(s) in the codebase where cancel_all is called during the DEGRADED flow. What order objects are available at that point? What fields do they have (order_id, status, etc.)? What DB write methods are available to update order status?
Q2 — Orders table schema. Inspect the orders table schema (via StateManager or models.py). Does a status field already exist? What are the current valid status values? Does cancelled_at exist? Confirm whether Atlas's preferred implementation (status = CANCELLED_BY_ENGINE, cancelled_at timestamp) requires a schema migration or can reuse existing fields.
Q3 — Reconciler read path. In _handle_disappeared_active_order(), what does the order object look like at that call site? Is it a dataclass, dict, or DB row? Can you read order.status from it directly, or does it need a DB lookup? Confirm the pattern for the CANCELLED_BY_ENGINE guard check.
Q4 — Write-before-reconcile ordering. Confirm that cancel_all completes its DB writes before the reconciler can next run. Is there any async gap between order cancellation and reconciler execution that could create a race condition? Identify the call sequence in main_loop.py.
Q5 — Schema migration safety. If new columns are required on the orders table, confirm that StateManager.initialize_database() handles the migration safely (no crash on existing DB, existing rows get sensible defaults).
Report findings before writing any code. Do not create the branch until ready to commit.
Implementation Spec (Atlas-locked 2026-04-21)¶
Layer 1: Mark cancelled orders in cancel_all¶
In the DEGRADED cancel_all flow, for each active order being cancelled:
# Before the reconciler can next run:
order.status = "CANCELLED_BY_ENGINE"
order.cancelled_at = <utc_now_iso_string>
# optional: order.cancel_reason = "DEGRADED_CANCEL"
# Persist to DB
This must be written to the DB before the reconciler's next pass. Atlas constraint: ordering matters — no race conditions.
Preferred storage: orders table status update (not a new table, not in-memory). Must survive restart (restart continuity is required by test 3 below).
Layer 2: Reconciler guard in _handle_disappeared_active_order()¶
Add as the first check — before the cancel-race short-circuit, before the age-threshold gate:
if order.status == "CANCELLED_BY_ENGINE":
# Skip phantom fill logic entirely
# Log: RECONCILER_SKIP_ENGINE_CANCEL
# Finalize as cancelled (no inventory change, no delta)
return
Final evaluation order (canonical per Atlas):
1. CANCELLED_BY_ENGINE check → never phantom fill
2. cancel_tx_hash check (existing cancel-race short-circuit)
3. Age-threshold gate (existing FLAG-037 age logic)
Inventory rule for CANCELLED_BY_ENGINE orders: no phantom fill, no synthetic inventory movement, no delta applied. These are state transitions, not economic events.
Log token: RECONCILER_SKIP_ENGINE_CANCEL
Required Tests (5 — Mandatory, from Atlas)¶
These 5 tests are in addition to the existing 10 tests from the age-threshold implementation. Do not ship without all 15.
- DEGRADED cancel test — cancel_all fires, reconciler runs on those order IDs, no phantom fills applied, inventory unchanged, RECONCILER_SKIP_ENGINE_CANCEL logged
- Ambiguous disappearance test — order NOT in CANCELLED_BY_ENGINE, no cancel_tx_hash; age < threshold → phantom fill; age ≥ threshold → held_pending_review (confirms age-threshold still works for genuinely ambiguous orders)
- Restart continuity test — cancel_all fires, simulate restart (new engine instance / fresh reconciler), reconciler still skips phantom fill for those order IDs (DB persistence required)
- Mixed case test — some orders marked CANCELLED_BY_ENGINE, some ambiguous disappeared; only ambiguous ones go through phantom fill / held logic; CANCELLED_BY_ENGINE ones are skipped cleanly
- Truth gate preservation test — after cancel_all + reconciler pass with CANCELLED_BY_ENGINE orders, confirm wallet truth delta is zero (no artificial divergence introduced)
Commit Plan¶
Build on top of the existing 4 commits (C1–C4). Add:
- C5 —
fix(models,state_manager): CANCELLED_BY_ENGINE status + cancelled_at field on orders table (FLAG-037) - C6 —
fix(reconciler,execution_engine): CANCELLED_BY_ENGINE guard in cancel_all + reconciler skip path (FLAG-037) - C7 —
test(reconciler): CANCELLED_BY_ENGINE layer — 5 tests (FLAG-037)
Full branch on delivery: C1 through C7, 15+ tests, full regression green.
Constraints¶
- CANCELLED_BY_ENGINE check must precede all other reconciler logic for disappeared orders — not just before age-threshold, but before the cancel-race check. Atlas constraint.
- Inventory must not change for CANCELLED_BY_ENGINE orders under any code path.
- DB write in cancel_all must complete before reconciler runs — no race conditions.
- Schema changes must be backward-compatible (existing DBs, existing rows).
- No pre-creating the branch. Apply C1–C4 first, then add C5–C7 as additional commits on the same branch.
- PowerShell apply pattern required (no
*.patchglob — useGet-ChildItem | Sort-Object | ForEach-Objectform). - Defensive branch delete required in apply instructions.
Apply Instructions (for Katja — to run after Vesper review)¶
cd C:\Users\Katja\Documents\NEO GitHub\neo-2026
git checkout main
git pull
git branch -D fix/reconciler-disappeared-order-conservative 2>$null
git checkout -b fix/reconciler-disappeared-order-conservative
# Apply C1-C4 (existing age-threshold work)
Get-ChildItem "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\08 Patches\fix-reconciler-disappeared-order-conservative" -Filter "*.patch" | Sort-Object Name | ForEach-Object { git am $_.FullName }
# Apply C5-C7 (new CANCELLED_BY_ENGINE layer — Orion to deliver separately)
Get-ChildItem "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\08 Patches\fix-reconciler-disappeared-order-conservative-ext" -Filter "*.patch" | Sort-Object Name | ForEach-Object { git am $_.FullName }
python -m pytest tests/test_reconciler_conservative.py tests/test_reconciler_cancelled_by_engine.py tests/test_ledger_reconciler.py tests/test_config.py -q
Expected: 15+ passed, 10 pre-existing errors from test_reconciler_anomaly_log.py only.
Deliverable¶
Standard format: branch name, all commit hashes and messages (C1–C7), test count and pass rate, pre-code investigation answers (Q1–Q5), any deviations from spec flagged explicitly. Vesper reviews before merge.
File pre-code findings as TO_VESPER_pre_code_findings_FLAG037_ext.md in NEO Desk/handoffs/.
File delivery as TO_VESPER_patch_delivery_FLAG037_ext.md in NEO Desk/handoffs/.
— Vesper, COO, BlueFly AI Enterprises