# Architecture ## System context ```mermaid flowchart LR U[Authenticated browser] -->|same-origin HTTPS| H[Hermes dashboard / FastAPI :7860] T[Telegram webhook] --> H H --> R[Futures dashboard router] R --> C[Deterministic trade cycle] R --> S[Dashboard state] C --> D[Dual datasource client] D --> DS4[Datasource 4\nAuthoritative] D --> B[Binance public\nFallback] D --> DS2[Datasource 2\nComplementary] C --> K[Risk / sizing] C --> E[Paper execution] C -. advisory only .-> A[External AI] ``` ## Container and filesystem architecture ```mermaid flowchart TD I[Docker image] --> O1[/opt/hermesface_overlay\nimmutable current-image overlay] I --> O2[/opt/data/hermes_overlay\npersisted/restored copy] I --> S[/opt/data/scripts] B[scripts/entrypoint.sh] --> Y[scripts/sync_hf.py] Y -->|prefer| O1 Y -->|fallback only| O2 Y -->|copy modules| H[/opt/hermes] Y --> M[overlay manifest] Y --> P[patch existing dashboard router] P --> W[Hermes dashboard :7860] ``` The immutable `/opt/hermesface_overlay` is preferred so a restored dataset containing an older overlay cannot downgrade the current image. ## Layer responsibilities ### HTTP and UI layer `futures_dashboard_api.py` owns request validation, authentication dependency, response shaping, runtime diagnostics, and browser-facing error semantics. It does not implement signal scoring or sizing. ### Datasource layer `dual_datasource_client.py` owns: - HTTP acquisition; - KuCoin-compatible time range construction; - nested payload discovery; - field normalization; - source priority; - field provenance; - source health metadata; - `noTradeGuard`, missing-field, stale-field, merge, and readiness results. ### Decision layer `trade_cycle.py` owns deterministic score calculation, decision thresholds, SL/TP construction, risk module orchestration, plan expiry, and optional execution handoff. ### Risk layer `risk.py` owns risk profile lookup, leverage caps, volatility haircut, quantity calculation, margin/notional gates, daily-loss and position-count gates. ### Execution layer `futures_execution.py` owns Paper mode, account/position state, exchange adapter boundaries, slippage estimation, and protective order behavior. The dashboard route never directly constructs an exchange order. ### State layer `state.py` stores only a bounded view of the latest context/plan for the dashboard. It removes raw exchange payloads and does not authorize any decision. ## Trust boundaries | Boundary | Trusted for decisions? | Notes | |---|---|---| | Browser controls and localStorage | No | Convenience only; server revalidates everything. | | Datasource 4 | Yes, for verification/safety | Still subject to parsing, freshness, and completeness checks. | | Binance public | No, as authority | Field fallback only; cannot clear DS4 guard. | | Datasource 2 | No, as authority | Complementary context only. | | External AI | No | Advisory explanation only. | | Telegram input | No | Authorized, rate-limited, analysis-only commands. | | Server-side latest plan | Partially | Must still pass freshness and execution revalidation. | ## Router installation `sync_hf.py` modifies the existing Hermes dashboard code to include: ```python from tools.futures_dashboard_api import router as _futures_dashboard_router app.include_router(_futures_dashboard_router) from tools.telegram_bot import router as _telegram_router app.include_router(_telegram_router) ``` The patch is idempotent and must not create a new FastAPI app. ## Persistence Hermes data under `/opt/data` may be synchronized to a private Hugging Face Dataset. The repository overlay is also copied into the image, but the immutable image overlay is the source used for installation. Runtime state such as Telegram owner data and symbol cache lives under `/opt/data` and must not be committed. ## Failure behavior - DS4 unreachable: merge may use fallback data for display, but Futures verification/readiness remains blocked. - Binance HTTP 451: source status is restricted/unavailable; no bypass is attempted. - DS2 unavailable: complementary context is degraded; it does not independently block a plan unless it was the only attempted fill for a still-missing field. - Market endpoint exception: HTTP 503 with structured `API_UNAVAILABLE` payload. - Analysis exception: HTTP 503, state becomes `ANALYSIS_FAILED`, previous plan is cleared from current state. - Template read failure: minimal fallback page is served and trading remains blocked.