Skip to content

Orion Delivery — Branch #2: fix/summarize-paper-run-capital-overlay

To: Katja CC: Vesper, Atlas From: Orion Date: 2026-04-18


One-line

Baseline-filter the summarize-layer capital overlay so the shutdown summary stops double-counting pre-baseline deposits. Two commits, 5 new tests, behavior-preserving refactor in the pre-commit, 0 new test failures introduced.

Commits

Base: local-katja-main @ e38103b (Branch #1 merge) Branch: fix/summarize-paper-run-capital-overlay

  1. 1ed20f7chore(halt-reason): use HALT_REASON_* constants in run_paper_session Vesper's Branch #1 code-review nit, folded in as a pure pre-commit refactor. Replaces 7 inline halt-reason string literals in run_paper_session.py with imports from neo_engine.main_loop. No behavior change. test_halt_reason_lifecycle.py still 4/4 green.

  2. fe7087efix(summarize-paper-run): baseline-filter the capital-events overlay The S39 root-cause fix. _get_inventory_balance now delegates to a new read-only helper _get_capital_delta_post_baseline(conn, asset) which mirrors StateManager.get_capital_delta_total (FLAG-030 contract — only capital_events with created_at >= MIN(inventory_ledger.created_at) contribute). Adds tests/test_summarize_paper_run_overlay_baseline.py with 5 tests and corrects one expectation in tests/test_flag_034_display_overlay.py that was validating the bug.

Structure rationale

Two commits, not one. The pre-commit is a pure refactor — zero risk — so isolating it keeps commit #2's diff to exactly the behavior change Vesper and Atlas need to review. If for any reason the fix has to be reverted, the constants refactor can stay. If the constants refactor ever needs to be reverted, the fix can stay.

Test results

Focused suite (files touching summarize_paper_run, run_paper_session, or HALT_REASON_*):

tests/test_anchor_error_stat.py                      PASS
tests/test_flag_033_startup_integrity.py             PASS
tests/test_flag_034_display_overlay.py               PASS  (5/5, incl. corrected fallback expectation)
tests/test_halt_reason_lifecycle.py                  PASS  (4/4)
tests/test_inventory_manager.py                      PASS
tests/test_summarize_paper_run_overlay_baseline.py   PASS  (5/5 NEW)
tests/test_write_synthetic_initial_basis.py          PASS

68 passed, 0 new failures.

Pre-existing failures on local-katja-main (not this branch): - tests/test_summarize_paper_run.py::test_summary_uses_existing_persisted_state — expects a total_paper_orders_created key that doesn't exist in load_paper_run_summary output (schema drift). - tests/test_run_paper_session.py — 4 tests fail with OrderSizeConfig.__init__() missing max_size_pct_of_portfolio (upstream config schema drift).

I verified both sets fail identically on local-katja-main with my branch stashed. Flagging so Vesper/Atlas see them but they're out of scope for Branch #2. Candidates for a future cleanup branch (or the test-suite reconciliation FLAG-016).

The fix in one picture

S39 live-DB reconstruction (Katja's Apr 18 query confirmed):

                     pre-baseline            post-baseline
XRP:     deposit 39.27 (2026-04-13)    deposit 35.21 (2026-04-17)
RLUSD:   deposit 85.00 (2026-04-13)    (none)

Baseline ledger (first fill):          XRP new_balance = 38.08
                                       RLUSD new_balance = 91.03

Engine (baseline-filtered):       Summarize (old, unfiltered):
  XRP   = 38.08 + 35.21  = 73.29    XRP   = 38.08 + 74.48 = 112.56
  RLUSD = 91.03 +   0    = 91.03    RLUSD = 91.03 + 85.00 = 176.03
  total @ mid 1.48       ≈ $199     total @ mid 1.48      ≈ $337
  matches wallet ✓                    phantom $140 — the bug

The new test_s39_fact_pattern_matches_wallet reconstructs exactly this fixture and asserts $190 < total < $210.

Run it on your box

From the VS Code terminal at the repo root, in order:

# 1. Copy the patches from the workspace into the repo's patch dir
Copy-Item "C:\Claude Homebase Neo\02 Projects\NEO Trading Engine\patches-summarize-overlay\*.patch" "patches-summarize-overlay\" -Force -Recurse

# 2. Make sure you're on local-katja-main and up to date locally
git checkout local-katja-main
git status  # should be clean

# 3. Cut the branch and apply
git checkout -b fix/summarize-paper-run-capital-overlay
git am patches-summarize-overlay\0001-chore-halt-reason-use-HALT_REASON_-constants-in-run_.patch
git am patches-summarize-overlay\0002-fix-summarize-paper-run-baseline-filter-the-capital-.patch

# 4. Verify
python -m pytest tests/test_summarize_paper_run_overlay_baseline.py tests/test_flag_034_display_overlay.py tests/test_halt_reason_lifecycle.py -v

# 5. Merge when Vesper approves
git checkout local-katja-main
git merge --no-ff fix/summarize-paper-run-capital-overlay -m "Merge branch 'fix/summarize-paper-run-capital-overlay' into local-katja-main"

If step 4 doesn't show 14 passed, stop and ping me before merging.

Review surface

Commit #1 (5 KB patch): one-file diff, all edits are identifier swaps. Nothing to review beyond confirming the 7 literals map to the 7 constants I claim they do.

Commit #2 (27 KB patch — most of it the new test file): - summarize_paper_run.py: ~35 lines net, one new helper + one rewritten body - tests/test_flag_034_display_overlay.py: 1 test's expected value flipped 14.5 → 12.5 + docstring expanded - tests/test_summarize_paper_run_overlay_baseline.py: new file, 5 tests

The helper _get_capital_delta_post_baseline is SQL-identical to StateManager.get_capital_delta_total but operates on a raw sqlite3.Connection — no StateManager instantiation, no migrations, no side effects (keeping summarize read-only by contract). I documented the lock-step requirement in the docstring. If anyone ever changes the engine contract, it'll need to change here too — noted in the commit message so it's grep-able.

Open question for Atlas

None. The fix aligns summarize with the engine; there's nothing new to rule on.

Open question for Vesper

None pending. Branch #1 nit folded in as commit #1; ready for your review on commit #2.

What's next

On merge of Branch #2, the audit branch plan says:

  • Branch #3: chore/archive-cleanup
  • Branch #4: fix/flag-029-async-pin-and-orphon
  • Branch #5: audit/config-wiring-pass (incl. clob_switch_threshold_bps promotion)
  • S40 before Phase 7.3

I'll wait for your go-ahead before cutting Branch #3.

— Orion

Attachments

  • patches-summarize-overlay/0001-chore-halt-reason-use-HALT_REASON_-constants-in-run_.patch
  • patches-summarize-overlay/0002-fix-summarize-paper-run-baseline-filter-the-capital-.patch