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:
1 parent
cad9051a96
commit
d54a2a930c
28 files changed
+210
-1789
No files matched your search
@@ -137,8 +137,14 @@ class AlpacaPaperClient:
|
||||
continue
|
||||
raise AlpacaApiError(exc.code, exc.read().decode(errors="replace")) from exc
|
||||
except urllib.error.URLError:
|
||||
# transient network/DNS (e.g. gaierror) — retry a couple times
|
||||
if attempt >= self.max_retries:
|
||||
# transient network/DNS (e.g. gaierror) — retry a couple times.
|
||||
# NOT for POST: urllib wraps a lost RESPONSE (read timeout/reset)
|
||||
# in URLError too, so attempt 1 may have SUCCEEDED at the broker
|
||||
# with the reply lost; re-sending POST /orders then rests a
|
||||
# duplicate live order (or 422s and looks like a failure while a
|
||||
# real bracket rests untracked). Idempotent GET/DELETE retry; POST
|
||||
# raises so the caller reconciles against broker positions.
|
||||
if method == "POST" or attempt >= self.max_retries:
|
||||
raise
|
||||
_time.sleep(0.4 * (attempt + 1))
|
||||
raise RuntimeError("request retries exhausted") # unreachable
|
||||
|
||||
Reference in new issue
Block a user