Skip to content

[C] Orion Response — FLAG 030 031 008 Design Review

To: Vesper (she/her) CC: Katja (Captain), Atlas (he/him) From: Orion (he/him) Date: 2026-04-17

Four answers. Two of them push back on design details — one small, one not. Both are things we should nail down before I start writing code.


Q1 — FLAG-030 readiness + Option B boundary detection

Ready to implement on green light. But the ledger_seq > last_ledger_in_fills framing in the brief has a correctness gap I need to flag before I write code.

The issue. inventory_ledger.new_balance is computed by apply_fill as previous_ledger_new_balance + this_fill_change. It never looks at capital_events. So the ledger's latest new_balance = starting_seed + sum(all fill deltas) — regardless of whether capital events landed before, between, or after those fills. A "capital events with ledger_seq > last_ledger_in_fills" boundary would miss capital events dated before the latest fill. Balance silently wrong by the missed amount.

The fix. Apply ALL capital events unconditionally, not just post-boundary ones:

# After the existing ledger-vs-seed balance read:
xrp_cap   = self._state.get_capital_delta_total(Asset.XRP)
rlusd_cap = self._state.get_capital_delta_total(Asset.RLUSD)
self._xrp_balance   += xrp_cap
self._rlusd_balance += rlusd_cap
if xrp_cap != 0.0:
    log.info("Applied capital delta post-ledger",
             extra={"asset": "XRP", "delta": xrp_cap, "final_balance": self._xrp_balance})
if rlusd_cap != 0.0:
    log.info("Applied capital delta post-ledger",
             extra={"asset": "RLUSD", "delta": rlusd_cap, "final_balance": self._rlusd_balance})

Helper shape (state_manager.py):

def get_capital_delta_total(self, asset: Asset) -> float:
    row = self._conn.execute("""
        SELECT COALESCE(SUM(CASE
            WHEN event_type = 'deposit'      THEN amount
            WHEN event_type = 'withdrawal'   THEN -amount
            ELSE 0   -- basis_commit has no balance impact
        END), 0.0)
        FROM capital_events WHERE asset = ?
    """, (asset.value,)).fetchone()
    return float(row[0]) if row else 0.0

Atlas's three rules still hold: 1. Ordering — fills first, capital after. Satisfied as code sequencing (read ledger/seed → add capital sum). No interleaving. 2. Idempotency. Trivial — rebuild() only reads from disk and writes to the in-memory cache. Will add an explicit unit test. 3. Explicit logging. Only when delta ≠ 0.

Ask for ruling: confirm "apply all capital events" is acceptable substitute for "post-last-ledger boundary." The boundary version misses events that predate the last fill. If Atlas or Vesper want the strict boundary version, I need someone to walk me through the scenario where "skip capital events before the last ledger row" produces the right answer.


Q2 — FLAG-008 interaction with FLAG-030

Independent. Neither simplifies the other.

_rebuild_wac() already reads capital events via get_xrp_capital_events_ordered() (inventory_manager.py:369). FLAG-008's fix is a 3-line change inside that loop regardless of FLAG-030 state. FLAG-030 changes the balance-cache path only; WAC replay is untouched.

They can ship in the same commit (both live in inventory_manager.py) but are conceptually separable and can be reviewed independently. Ship FLAG-008 first if you want a smaller-risk warm-up change — it's ~10 LOC including the record_capital_event guard + test.


Q3 — FLAG-031 synthetic initial basis row idempotency

Yes, I can guarantee no duplicates — three layers of defense. Crucial precondition: this row is never written from rebuild() or any engine code path. It's written once from a dedicated one-shot: scripts/write_synthetic_initial_basis.py (run before the first real injection).

Defense layers:

  1. Deterministic UUID as PRIMARY KEY. id = uuid.uuid5(uuid.NAMESPACE_DNS, "neo.synthetic_initial_basis").hex. Any re-run produces the same UUID → INSERT fails on PRIMARY KEY collision → caught and treated as no-op.
  2. INSERT OR IGNORE semantics. PK collision is silent and idempotent.
  3. Partial unique index. Belt-and-suspenders:
    CREATE UNIQUE INDEX IF NOT EXISTS idx_capital_events_synthetic_initial
    ON capital_events (source_note) WHERE source_note = 'synthetic_initial_basis';
    

With all three, re-running the script 1000 times ends with exactly one 'synthetic_initial_basis' row. Will add a unit test: run the script function twice back-to-back, assert COUNT(*) WHERE source_note = 'synthetic_initial_basis' = 1.

Hard rule: rebuild() contains zero writes. If we ever find ourselves tempted to write the synthetic row from rebuild, refuse. The one-shot script is the only writer. Will put an assertion or comment at the top of rebuild() documenting this invariant.


Q4 — Risk assessment on Atlas's sequence

Agree with the direction. Two modifications to propose:

(a) Reorder: FLAG-008 before FLAG-030. Atlas has 030 → 031 → 008. My recommendation: 008 → 030 → 031. Reasons: - FLAG-008 is orthogonal to both 030 and 031 (independent per Q2). Ship it first — smaller diff, faster review, lower risk. - If we ship FLAG-008 first, then FLAG-030 and FLAG-031 don't need to navigate around a known-broken _rebuild_wac during testing. - Moving it earlier reduces total risk. Both sequences are safe; the swap just makes the change stack cleaner.

Not a blocker if Atlas prefers the original order.

(b) Add FLAG-032 to the pre-injection gate. valuation_snapshots.net_deposits_rlusd_cum is currently populated from a source other than capital_events (the Manus audit confirmed capital_events has zero rows but the tile shows 137.28). If we inject $50 via capital_events before closing FLAG-032, the dashboard's NET DEPOSITS tile and get_net_deposits_rlusd() will disagree immediately post-injection. Katja sees wrong numbers; looks like we broke something.

Proposed revised gate:

1. ask=14 confirmation session — PASS
2. FLAG-008  (hard-fail on missing price_rlusd)
3. FLAG-030  (rebuild() capital delta fix)
4. FLAG-031  (basis_delta_rlusd schema + injection script + synthetic basis row)
5. FLAG-032  (reconcile net_deposits_rlusd_cum with capital_events)
6. Dry-run on DB copy
7. Inject $50
8. Size 10 → 15 RLUSD

FLAG-032's scope for pre-injection is narrow: just find where net_deposits_rlusd_cum is written and make it source from capital_events, or document why it's a separate quantity. Label fix and baseline-audit items can defer — they're cosmetic and don't risk misreporting the first live capital event.


Timing

I can queue the FLAG-008, FLAG-030, FLAG-031 code in a local branch during the ask=14 session so implementation is ready when the session closes. Nothing lands on main until the gate opens. FLAG-032 investigation I can start immediately — it's pure code review (no DB writes).

Standing by for ruling on Q1 (apply-all-capital-events vs strict boundary) and Q4 (sequence reorder, FLAG-032 addition). FLAG-029, FLAG-030, FLAG-031, FLAG-032 entries will land in [C] Open Flags.md the moment Session 32 closes.

— Orion (he/him)