Skip to content

[C] Orion Audit Request — Post Injection Behavior Regression

To: Orion CC: Katja (Captain), Atlas From: Vesper Date: 2026-04-17

Atlas has reviewed and signed off on this audit scope. See [C] Atlas Alignment — Post-Injection Regression Diagnosis.md for his full read. Summary of his call:

"This does not look like a market problem. It looks like a post-injection state interpretation problem, with anchor displacement as a secondary amplifier."

Do not start a live session to validate. Audit is code-only. Return findings before any implementation.


Context

Katja stopped Session 35 and called for an audit. Pre-injection (S30–S32), the engine was filling normally on both sides. Post-injection (S33–S35):

  • S33: immediate halt (XRP exposure limit — fixed, config updated)
  • S34: buy_inventory_guard_blocked: true every tick, zero fills (XRP-heavy — guard behavior plausible)
  • S35: buy_inventory_guard_blocked: true every tick, zero fills — but inventory was RLUSD-heavy (XRP = 47.4%, drift = -2.6%)

S35 is the diagnostic signal. If the guard is correctly checking XRP weight, RLUSD-heavy should not trigger buy block.

The capital injection introduced one structural change: xrp_capital_overlay: 35.21 XRP is now applied at every rebuild via FLAG-030. Pre-injection, overlay was 0. This is the primary suspect.


Config Changes Made Tonight (in order)

Current config_live_stage1.yaml state for affected keys:

order_size:
  base_size_rlusd: 15.0          # was 10.0 — Atlas-approved scale validation

risk:
  max_xrp_exposure: 150.0        # was 100.0 — raised after S33 halt (76.92 XRP × 1.497 = 115.20 > 100)
  max_rlusd_exposure: 120.0      # was 100.0 — raised for headroom

strategy:
  max_inventory_usd: 20.0        # was 10.0 — raised after S34 showed guard blocking every tick

Atlas's read: config changes were directionally correct and are not the root bug. They exposed a deeper state-consistency issue.


Priority 1 — Inventory Guard Balance Source (PRIMARY, BLOCKING)

The question Atlas wants answered:

For each component below, identify whether it uses xrp_balance / rlusd_balance (post-overlay total) or fills-only reconstructed balances / pre-overlay state.

A. Buy inventory guard decision path

What balances and denominator does buy_inventory_guard_blocked use?
Exact fields — not "roughly."

B. Skew computation path

Is skew using total portfolio composition or fills-only composition?

C. Max inventory USD check

Does max_inventory_usd operate on total inventory or only trade-derived inventory?

Why this matters: Before injection, xrp_fills_only == xrp_balance (overlay = 0). After injection, they diverge by 35.21 XRP. If the guard checks xrp_fills_only, it sees ~41.71 XRP vs ~85 RLUSD fills-only — a portfolio that appears XRP-underweight on fills basis. But the actual balance is 76.92 XRP vs ~85 RLUSD — approximately neutral/XRP-heavy on total basis. A guard using fills-only state would have inverted or incorrect directional reads post-injection.

Atlas's matrix — Orion fills in the right two columns:

Component Expected source Actual source Bug?
buy guard total (xrp_balance) ? ?
skew total (xrp_balance) ? ?
max_inventory_usd check total ? ?
quote generation active when not guarded ? ?
dashboard display live source ? ?

Priority 2 — Order Displacement Trace

Observed (S35): - Our spread: ~24 bps vs market ~6.8 bps - CLOB-AMM divergence: 20–23 bps - anchor_max_divergence_bps: 10.0 — engine follows CLOB up to 10 bps above AMM

Atlas's interpretation: Anchor lag of ~10–13 bps explains the displacement. This is an anchor-following artifact, not a quote engine bug.

Effective quote placement vs CLOB was displaced by capped anchor lag — not a config regression.

Trace request: Confirm that the only displacement factor is anchor cap. Specifically: are bid_offset_bps / ask_offset_bps / skew applied relative to the capped anchor (correct), or is there any additional displacement source?

Note from Atlas: Do NOT loosen anchor_max_divergence_bps yet. Fix state-consistency first, then reevaluate anchor behavior with clean attribution.


Priority 3 — Quote Presence vs Guard State

Observed: BUY at dist_to_bid = 0, near≤5bps 7 times during S35. Zero fills.

Two possibilities (Atlas): - Case 1: Quote existed, normal execution, no fill due to queue position / size-ahead / brief touch - Case 2: Quote/intent was not actually live — guard or quote-state inconsistency

Trace: Was BUY intent actually being emitted and maintained during those 7 at-touch events?

If yes → microstructure (queue), not suppression. If no → guard / quote-state inconsistency.


Priority 4 — Config Safety Review

Atlas's read: changes are reasonable. Sanity check only.

  1. max_xrp_exposure: 100 → 150 — any other risk checks also needing update for new portfolio size?
  2. max_rlusd_exposure: 100 → 120 — current RLUSD ~85, giving ~35 headroom. Sufficient?
  3. max_inventory_usd: 10 → 20 — any interaction with inventory_scale_factor, max_skew_bps, or other inventory parameters?

Priority 5 — FLAG Bundle (queue for this pass)

FLAG-033: Add PRAGMA quick_check to run_paper_session.py startup, after pre-run backup, before engine instantiation. If check fails: print location of most recent clean backup, prompt operator, exit 1. ~10 LOC. Design complete.

FLAG-034: Session summary logs Ending inventory XRP: 41.71 (fills-only). Should show total balance (76.92). Find the log line and change to use xrp_balance (total). Low effort, cosmetic.

FLAG-028 remainder: idx_fills_session_id index in state_manager.py.

These are non-blocking for the current diagnosis but bundle with this pass.


What We Need Back

From Priority 1: The filled-in matrix above. Exact variable names. Yes/no on bug.

From Priority 2: Confirmation that displacement = anchor cap only, or identification of additional factor.

From Priority 3: Was BUY intent live during the at-touch events?

If the guard is using fills-only state: propose the fix, show the affected lines, and get Atlas alignment before implementing. Do not self-approve a behavior change on live capital logic.

— Vesper