Review sweep: money-path fixes + security + delete 805MB dead weight

Consolidated 4-tool review (2 correctness agents + Codex + over-eng audit).

Money-path (regression-tested):
- _flatten_all: moved the fresh-broker close from close_session INTO the
  shared function + added a broker-held guard on entry cancellation, so
  the daily-loss CIRCUIT BREAKER (which called _flatten_all raw) no
  longer strips a just-filled bracket's legs or leaves a sync-gap fill
  naked. One guard, all callers.
- restart state rebuild: _fresh_entries cap, _requested_symbols dedup,
  and losing benches now rebuild from today's events on boot — a
  mid-session restart no longer resets the cap to 0 or re-fires a
  resting order into a duplicate (the 2026-07-06 incident).
- POST /orders no longer retries a lost-response URLError (was
  re-sending duplicate live orders); GET/DELETE still retry.
- expire_stale_entries now @_locked (raced the trigger thread).
- _session_open: ET conversion instead of a hardcoded 13:30-13:33Z
  window that only matched EDT — the fast path armed nothing all winter.

Security:
- admin panel fail-CLOSED on empty ADMIN_TOKEN (was fail-open on a panel
  fronting the docker socket); header-only token, constant-time compare.
- admin API responses redact secret override VALUES (live keys would
  have echoed after a paper->live switch).
- dashboard: removed wildcard CORS (cross-origin drive-by could drive
  trade actions); optional DASHBOARD_TOKEN gate on POST.

Deletions (~805MB + dead code shipped in the prod image): momentum-
rebuilt.zip, archive venv/htmlcov, and schwab/ core/ telemetry/ models/
runtime/providers/ storage/replay.py controlroom/ + three dead
evaluation stubs + package.json — all verified zero-importer.

+4 regression tests. 99 money-path/trigger/exit tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
momentum devandClaude Opus 4.8 committed 2026-07-11 13:00:10 -04:00
1 parent cad9051a96
commit d54a2a930c
28 files changed
+210 -1789

No files matched your search

@@ -231,3 +231,31 @@ def test_reconcile_seeds_from_persisted_snapshot_after_restart(store):
rows = _closed(store)
assert len(rows) == 1 and rows[0]["symbol"] == "REST"
assert rows[0]["realized_pnl"] == 5.0 # (2.5 - 2.0) * 10
def test_post_not_retried_on_urlerror(monkeypatch):
"""Lost-response URLError on POST /orders must NOT re-send (duplicate live
order, 2026-07-06). GET/DELETE still retry."""
import urllib.error
import urllib.request
from alpaca_paper.client import AlpacaPaperClient
from alpaca_paper.settings import AlpacaPaperSettings
cli = AlpacaPaperClient.__new__(AlpacaPaperClient)
cli.timeout = 1
cli.max_retries = 2
cli._headers = lambda: {}
calls = {"n": 0}
def boom(req, timeout=None):
calls["n"] += 1
raise urllib.error.URLError("connection reset")
monkeypatch.setattr(urllib.request, "urlopen", boom)
import pytest
with pytest.raises(urllib.error.URLError):
cli._request("POST", "https://x/v2/orders", body={"symbol": "AAA"})
assert calls["n"] == 1, "POST must not retry a lost-response URLError"
calls["n"] = 0
with pytest.raises(urllib.error.URLError):
cli._request("GET", "https://x/v2/account")
assert calls["n"] > 1, "idempotent GET should still retry"
View File
Whitespace-only changes.
+56
View File
@@ -875,3 +875,59 @@ def test_session_gate_bars_after_hours_entries():
assert svc._outside_session(datetime(2026, 7, 9, 9, 30, tzinfo=ET)) is None # the open
svc.settings = ExecutionSettings(session_only=False)
assert svc._outside_session(datetime(2026, 7, 9, 20, 9, tzinfo=ET)) is None # opt-out works
def test_flatten_all_closes_broker_position_missed_by_snapshot(store):
"""Naked-through-breaker fix: a position that filled in the sync gap isn't in
the event-store held set, so _flatten_all's step-2 skips it. Step 3 (moved out
of close_session so the daily-loss breaker gets it too) closes it from fresh
broker positions."""
from alpaca_paper.execution import AlpacaPaperExecutor
class _Cli:
def __init__(self):
self.closed = []
self.pos = [{"symbol": "GAP", "qty": "100"}] # filled, snapshot missed it
def get_positions(self, fresh=False):
return list(self.pos)
def close_position(self, symbol, qty=None, percentage=None):
self.closed.append(symbol)
self.pos = [p for p in self.pos if p["symbol"] != symbol]
return {"id": "c"}
def get_orders(self, **kw):
return []
def cancel_order(self, oid):
pass
cli = _Cli()
svc = TradingExecutionService(
store, executor=AlpacaPaperExecutor(store, client=cli),
settings=ExecutionSettings(auto_approve=True), session_id="t")
result = svc._flatten_all("daily_loss_circuit_breaker")
assert "GAP" in cli.closed, "breaker flatten must close broker positions the snapshot missed"
assert "GAP" in result["closed_positions"]
def test_daily_state_rebuilds_from_events_on_restart(store):
"""Mid-session restart must not reset the entry cap to 0 or forget resting
orders (re-fire => duplicate order, 2026-07-06). A new service instance
rebuilds fresh-fill count, requested symbols, and losing benches from today."""
from storage.event_schema import OrderSubmittedEvent, OrderFilledEvent, PositionClosedEvent
now = datetime.now()
store.emit(OrderSubmittedEvent(timestamp=now, mode=EventMode.PAPER, correlation_id="t",
message="sub", order_id="o1", symbol="AAA", side="buy", quantity=10, price=5.0,
broker_order_id="b1"))
store.emit(OrderFilledEvent(timestamp=now, mode=EventMode.PAPER, correlation_id="t",
message="fill", order_id="o1", symbol="AAA", fill_price=5.0, fill_quantity=10,
broker_order_id="b1"))
store.emit(PositionClosedEvent(timestamp=now, mode=EventMode.PAPER, correlation_id="t",
message="closed", position_id="p1", symbol="AAA", side="buy", quantity=10,
entry_price=5.0, exit_price=4.5, realized_pnl=-5.0, exit_reason="stop"))
svc = make_service(store) # boot AFTER the events land
assert svc._fresh_entries["n"] == 1, "cap count must survive restart"
assert "AAA" in svc._requested_symbols, "resting-order dedup must survive restart"
assert "AAA" in svc._exited_today, "losing bench must survive restart"