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
+16
-5
@@ -16,6 +16,7 @@ Run: python admin_api.py (ADMIN_HOST/ADMIN_PORT, default 0.0.0.0:8767)
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hmac
|
||||
import http.client
|
||||
import json
|
||||
import os
|
||||
@@ -70,6 +71,14 @@ SEED_PROFILES = {
|
||||
}
|
||||
|
||||
|
||||
def _safe_overrides() -> dict:
|
||||
"""Overrides for API responses with secret VALUES redacted — a /api/mode live
|
||||
switch writes ALPACA_LIVE_* into overrides.env; without this they'd echo back
|
||||
in every /api/status and /api/config response."""
|
||||
return {k: ("***" if any(m in k for m in SECRET_MARKERS) else v)
|
||||
for k, v in env_overrides.read_overrides().items()}
|
||||
|
||||
|
||||
def _editable(key: str) -> bool:
|
||||
if key in EDITABLE_EXACT:
|
||||
return True
|
||||
@@ -194,10 +203,12 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self.wfile.write(raw)
|
||||
|
||||
def _authed(self) -> bool:
|
||||
# FAIL CLOSED: no token configured => deny (this panel fronts the docker
|
||||
# socket + the paper/live switch; an unset env var must not open it to the
|
||||
# LAN). Header only — a ?token= query would leak into proxy/access logs.
|
||||
if not ADMIN_TOKEN:
|
||||
return True # explicit opt-out: no token configured
|
||||
return (self.headers.get("X-Admin-Token") == ADMIN_TOKEN
|
||||
or f"token={ADMIN_TOKEN}" in (self.path.split("?", 1) + [""])[1])
|
||||
return False
|
||||
return hmac.compare_digest(self.headers.get("X-Admin-Token", ""), ADMIN_TOKEN)
|
||||
|
||||
def do_GET(self): # noqa: N802
|
||||
path = self.path.split("?")[0]
|
||||
@@ -208,7 +219,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
return self._send(401, {"error": "bad or missing X-Admin-Token"})
|
||||
if path == "/api/status":
|
||||
return self._send(200, {"containers": list_containers(), "checks": checks(),
|
||||
"overrides": env_overrides.read_overrides()})
|
||||
"overrides": _safe_overrides()})
|
||||
if path == "/api/config":
|
||||
eff = {k: v for k, v in sorted(os.environ.items()) if _editable(k)}
|
||||
secrets = {k: bool(os.environ.get(k)) for k in
|
||||
@@ -216,7 +227,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
"ALPACA_LIVE_SECRET_KEY", "TELEGRAM_BOT_TOKEN", "YOUTUBE_API_KEY",
|
||||
"FMP_API_KEY")}
|
||||
return self._send(200, {"effective": eff, "secrets_present": secrets,
|
||||
"overrides": env_overrides.read_overrides()})
|
||||
"overrides": _safe_overrides()})
|
||||
if path == "/api/profiles":
|
||||
return self._send(200, profiles())
|
||||
return self._send(404, {"error": "unknown route"})
|
||||
|
||||
Reference in new issue
Block a user