Skip to content

Vesper Ruling — FLAG-037 Q1–Q5 + D1–D4

To: Orion (he/him) From: Vesper (she/her) CC: Katja (Captain), Atlas (he/him) Date: 2026-04-19 Re: Pre-code rulings for fix/reconciler-disappeared-order-conservative — green light given


Q1 — Phantom fill decision point: CONFIRMED

Insertion point confirmed: after the cancel-race guard (line 681–692), before _record_disappeared_order_anomaly (line 704) and _apply_full_fill (line 718). The age gate must fire before any side-effecting call. Your analysis is correct.


Q2 — Order age calculation: CONFIRMED

_age_seconds_since(created_at_iso) at line 391 is the correct helper. No duplicate implementation. Use it. order.created_at is always populated on insert — None only on corrupted rows. None handling is ruled in D2.


Q3 — reconciler_anomaly_log write path: CONFIRMED

action_taken is free-text. "held_pending_review" requires no schema change. Log split ruling in D3.


Q4 — _enter_degraded_mode availability: PATTERN A APPROVED

Pattern A — additive held_pending_review: int field on ReconciliationResult, main loop checks and calls _enter_degraded_mode — is the correct design. Reasons:

  • Preserves the existing return-value contract between reconciler and main loop. No coupling of reconciler to NEOEngine internals.
  • Existing engine_signal=DEGRADED warn-only cases (cancel races, ambiguous) are correctly left as warn-only. The held_pending_review > 0 discriminator cleanly separates the new mandatory-DEGRADED case from legacy soft-signal cases.
  • Existing test harness that constructs LedgerReconciler(execution_engine, state_manager) is unaffected.

Pattern B rejected for the reasons Orion stated.

Main loop wire-in: check recon_result.held_pending_review > 0 after the existing engine_signal handling, call _enter_degraded_mode("reconciler_held_pending_review"). _enter_degraded_mode is idempotent — safe to call even if a guard has already triggered DEGRADED this tick.


Q5 — Config access in reconciler: APPROVED

ReconcilerConservativeConfig in config.py with StrategyConfig field. Default-construct on None in LedgerReconciler.__init__ — existing tests requiring only (execution_engine, state_manager) are unaffected. Main loop passes conservative_config=config.strategy.reconciler_conservative. Wire pattern matches anchor/drift guard precedent. Approved.


D1 — held_pending_review: int on ReconciliationResult: APPROVED

Additive only, no DB touch, no breaking change. Approved.


D2 — age_seconds is None → fail-closed: APPROVED

Treat None as held_pending_review. Atlas invariant: if the engine cannot prove alignment with reality, it does not act. A corrupted created_at means age is unknowable — that is not a safe condition for auto-fill. Fail-closed is correct.

Log at WARNING for the None case: [RECONCILER_ANOMALY] disappeared order — age unknown (parse failure on created_at) — held_pending_review, NOT applying fill. Operator needs to know why it held.


D3 — WARNING log split: APPROVED

Two distinct WARNING messages routed by action_taken. The held_pending_review message must be unmistakably different from the phantom fill message — operators watching logs need to see the difference immediately. Use:

  • Phantom fill: [RECONCILER_ANOMALY] disappeared active order — phantom fill applied | order_id=<id> age=<age>s ...
  • Held: [RECONCILER_ANOMALY] disappeared active order — HELD PENDING REVIEW, NOT applying fill | order_id=<id> age=<age>s ≥ threshold=<threshold>s

D4 — Branch base: OFF MAIN

Stack off main. The drift guard branch (feat/directional-drift-guard) is already merged — main at bef819e IS the drift guard + anchor guard + all prior branches. There is no longer a pending branch to stack on top of. Branch off main, not off feat/directional-drift-guard.


Test plan: APPROVED AS-IS

10 tests covering all required cases. The plan is complete — no missing cases. Proceed with ~10 as scoped.


Green light

All five questions and four deviations resolved. No blockers. Build as planned.

Branch off main. Deliver in standard format. Vesper reviews before merge.

— Vesper