Skip to content

[C] Orion Message — Post Injection Cleanup Landed

Branch

fix/post-injection-cleanup off feat/flag-031-basis-model in /tmp/neo_git_work.

Four commits, each self-contained with unit tests. Bundled on one branch per your "bundle if clean" guidance; all four changes are read-path or diagnostic and do not overlap.

Commits

SHA Subject Files
32c5b0a flag-034: display balance uses TOTAL (fills + capital overlay) summarize_paper_run.py, tests/test_flag_034_display_overlay.py
9faba8a retire max_inventory_usd: dead config removed 14 files (code + configs + tests)
d4c88ca flag-033: startup DB integrity check (PRAGMA quick_check) run_paper_session.py, tests/test_flag_033_startup_integrity.py
4ff5241 flag-028: add idx_fills_session_id index neo_engine/state_manager.py, tests/test_flag_028_fills_session_index.py

RLUSD exposure trace (Task 3)

Enforcement location: neo_engine/risk_engine.py:96

if inventory.rlusd_balance > self._config.risk.max_rlusd_exposure:
    ...
    return RiskStatus.HALT

Mirrored halt-reason diagnosis in main_loop.py:789.

Check variable: inventory.rlusd_balance — this is the TOTAL post-overlay balance via InventoryManager.get_snapshot(), same source all other guards use.

Mechanism: Hard HALT, strict > comparison. Not a quote-generation gate, not a sizing attenuator. Any tick where post-fill RLUSD > cap trips the risk engine and stops the main loop for the session.

Headroom analysis at current live state: - Current RLUSD balance: ~97.6 - max_rlusd_exposure: 120.0 - Headroom: ~22.39 RLUSD

At base_size_rlusd = 15: - One SELL fill at base size: 97.6 → ~112.6. OK, still ~7.4 RLUSD under the cap. - Two SELL fills same session: 97.6 → ~127.6. Breaches cap → HALT. - One SELL fill with size-skew multiplier (up to ~1.30× base from inventory drift = ~19.5 RLUSD): 97.6 → ~117.1. OK but within 3 RLUSD of cap.

Verdict: max_rlusd_exposure = 120 is NOT currently gating fills (no quotes blocked, no sizes reduced). But it IS a tripwire — two SELL fills in the same session will HALT the engine mid-run. Not the root cause of S33–S35 zero fills (zero fills means zero pressure on this gate), but the headroom is tight enough that once BUY/SELL activity resumes at size=15 we will see a RLUSD-exposure HALT within the first couple of SELL fills on a high-drift trajectory.

Recommendation: Raise max_rlusd_exposure to 140 or 150 before the next session. Gives comfortable room for 2–3 SELL fills before tripping. Not bundled with this branch — requires Atlas ruling since it's a live risk parameter change.

Test coverage for FLAG-034

Five unit tests, all passing:

Test Covers
test_no_capital_events_returns_fills_only overlay = 0 → returns fills_only unchanged
test_deposit_adds_to_fills_only overlay = +35.21 XRP → fills_only + overlay
test_withdrawal_subtracts_from_fills_only overlay = -25.0 RLUSD → fills_only - overlay
test_basis_commit_does_not_move_asset_balance basis_commit excluded by CASE WHEN → balance unchanged
test_fallback_used_when_no_ledger_rows engine_state seeded balance + overlay

Exceeds the minimum three you specified. Added the basis_commit and fallback cases because the live DB has both a synthetic basis_commit event and the engine_state seeded balances, and I wanted to prove the fix handles them correctly.

FLAG-033 notes

  • _startup_integrity_check runs BEFORE _create_pre_run_backup — corrupt files do not get quietly backed up.
  • Handles both failure modes: PRAGMA quick_check returning non-ok, AND DatabaseError raised when the file is too broken for the pragma to execute (which is what happened on /sessions/peaceful-admiring-allen/mnt/neo-2026/neo_live_stage1.db this afternoon — 311-page truncation).
  • Read-only open via sqlite:///file:…?mode=ro URI so the check cannot itself damage the DB.
  • Five unit tests covering no-op paths (:memory:, missing path, empty file), healthy pass, and truncated file failure.

FLAG-028 notes

Single index: idx_fills_session_id ON fills (session_id). Placed in the migration block alongside the other post-schema column additions, gated by CREATE INDEX IF NOT EXISTS so it's idempotent across existing DBs. Two unit tests: index exists, index covers the session_id column.

max_inventory_usd retirement notes

Touched 14 files: - neo_engine/strategy_engine.py — removed from the init log dict at line 116 - neo_engine/main_loop.py — removed buy_inventory_guard_blocked from _log_no_intents_reason diagnostic (the only remaining consumer) - neo_engine/config.py — removed StrategyConfig.max_inventory_usd field and the loader kwarg - config/config.yaml, config/config_live_stage1.yaml, config/config_live_session1.yaml, config/config.example.yaml — removed from all four - tests/test_task5.py — removed from _make_config helper default, from one call site, and from StrategyConfig(...) constructor - tests/test_phase3d.py, tests/test_phase4a.py, tests/test_main_loop.py — removed all kwargs and mock assignments - neo_simulator/simulation_runner.py — removed kwarg - neo_engine/main_loop_Old.py, neo_engine/strategy_engine_old.py — archive-file references scrubbed for grep hygiene

Smoke tests pass: all four configs load cleanly, StrategyConfig no longer has the field, test_flag_034_display_overlay still passes.

One thing NOT done — workspace config

The git repo at /tmp/neo_git_work is the source of truth. The workspace copy at /sessions/peaceful-admiring-allen/mnt/neo-2026/config/config_live_stage1.yaml is a separate working copy on Katja's machine and has unmerged edits (the base_size_rlusd: 15.0 Atlas change is staged but not yet committed there). I did NOT touch it to avoid stomping her edits.

Katja action: when merging fix/post-injection-cleanup into main locally, delete the max_inventory_usd line from the workspace config_live_stage1.yaml (line 78) before running the next session, OR resolve the merge by keeping the git version.

What stays unchanged (per your instructions)

  • anchor_max_divergence_bps: 10.0 — held.
  • base_size_rlusd: 15.0 — held.
  • No other strategy parameters touched.

Merge ordering (my suggestion)

Given the current stack: 1. fix/flag-008 → merge to main 2. fix/flag-030 → rebase onto main, merge 3. feat/flag-031-basis-model → rebase, merge 4. fix/post-injection-cleanup → rebase, merge

Only step 4 is this branch. Steps 1–3 are pre-existing and blocked on Katja.

— Orion