| Decision | Choice | Why |
|---|---|---|
| Runtime | Python 3.12 (engines + local server) | Data science stack (numpy/pandas/scikit-learn/LightGBM) in one language; no Rust/Node toolchain on the target PC. |
| Desktop shell | Local web app (FastAPI on 127.0.0.1:8765, opened in the default browser by start.bat) |
Zero native build chain, instant start, same UI reusable by the SaaS. Tauri 2 can wrap the same ui/ later without code changes (documented in DEVELOPER_GUIDE). |
| Store | SQLite (WAL, versioned migrations) | Local-first, single file, backups = file copy. Append-only observation tables allow point-in-time reconstruction. SaaS path: PostgreSQL + TimescaleDB (same schema, user_id already present). |
| UI | Vanilla JS SPA + hand-written SVG charts, no CDN | Works offline, no build step, fast. |
| Secrets | Windows Credential Manager via keyring |
No secret ever on disk or in Git. |
| AI | Optional Claude API (tool-use over engine functions); deterministic rule engine when no key | Core features never require a subscription or network LLM. |
auction_oracle/)connectors/ independent source adapters → ConnectorResult (raw → normalized records + health)
ingest.py orchestrates connectors, writes scans/observations/candles/items/recipes, logs source_health
db.py connection + migrations (schema_migrations table)
engines/
series.py per item/market time series assembly (OBSERVED only)
quality.py Data Quality Score (age, sources, coverage, frequency, samples, gaps)
market.py scanner, flip + vendor arbitrage detection, anomalies, depth simulation
forecast.py multi-model forecasting with walk-forward model selection vs naive
scarcity.py Scarcity Score 0–100 with explained components
graph.py economy graph: event → category → recipe → reagent → item
demand.py dependency-driven demand pressure
crafting.py recipe cost/profit, sell-raw vs smelt vs craft comparison, progression planner
farming.py real farming-session gold/hour vs AH buy
strategy.py capital-aware portfolio optimizer with risk caps
backtest.py walk-forward strategy backtests vs passive
portfolio.py ledger, holdings (FIFO), realized/latent P&L, goals; paper trading
alerts.py rule evaluation + dedup
index.py Forever Economy Index (proprietary health index)
learning.py prediction/recommendation outcome resolution + metrics
briefing.py 8 analyst agents → consolidated, arbitrated daily briefing
ai/strategist.py conversational assistant (Claude tool-use or rule-based)
api.py REST API + static UI
cli.py collect | serve | diagnose | backup | restore | evaluate | import
OBSERVED (measured), ESTIMATED (computed / reference value), PREDICTED (model output, always with created_at, horizon, interval, confidence), UNKNOWN (never replaced by a fake number — fields are null).
sources, source_health, markets, items, scans, observations, listings, daily_candles, recipes, recipe_reagents, vendor_items, predictions, model_registry, recommendations, transactions, goals, profiles, farm_sessions, alert_rules, alerts, events, settings.
Personal tables carry user_id ('local' in desktop mode) — the SaaS isolation key.
Observations are append-only keyed by (scan_id, item_key); a market state at date T = last scan per item with observed_at ≤ T.
class Connector:
id: str; name: str; commercial_ok: bool
def health(self) -> list[HealthCheck] # real HTTP calls, never faked
def collect(self, db) -> CollectReport # idempotent (scan uniqueness)
Implemented: ahfyi, everloot, blizzard, foreverdb, wowgg, addon (SavedVariables), file_import (CSV/JSON), manual. OCR: interface reserved, not shipped (see RESEARCH_REPORT §3.8).
For each horizon h ∈ {6,12,24,48,72,168,336,720} h: candidate models = naive, EMA, robust drift (Theil–Sen), seasonal-naive (24 h), LightGBM global (lag/return/qty features). Walk-forward evaluation on chronologically ordered origins (no future data in features). The model with lowest MAE on log-price is selected only if it beats naive; otherwise naive is served. Intervals = empirical walk-forward residual quantiles (fallback: volatility × √h). INSUFFICIENT_DATA when span < 2h or < 8 observations.
All money in copper. Every analytic payload has status and, where relevant, generated_at, confidence, explanation, sources.
GET /api/diagnostics sources, engines, db stats
POST /api/collect run all enabled connectors now
GET /api/markets markets + last scan + DQS
GET /api/overview?market= dashboard bundle
GET /api/scanner?market=&q=&cls=&min_price=&max_price=&min_conf=&sort=&limit=
GET /api/item/{key}?market= item detail, series, stats, forecasts, scarcity, recipes
GET /api/opportunities?market=&capital=
GET /api/depth/{key}?market=&qty=&side=
GET /api/forecasts?market=&horizon=
GET /api/models model registry + evaluation metrics
GET /api/scarcity?market=
GET /api/demand?market=
GET /api/trends?market=
GET /api/crafting?market=&profession=&sort=
GET /api/crafting/compare/{item}?market= raw vs transform vs craft
GET /api/crafting/plan?profession=&from=&to=&market=
GET/POST /api/farming farm sessions + gold/hour
GET/POST/DELETE /api/events release calendar
GET /api/events/{id}/impact?market=
GET/POST/DELETE /api/transactions ledger (is_paper flag for paper trading)
GET /api/portfolio?paper=0|1&market=
GET/POST/DELETE /api/goals
POST /api/simulate/scenario POST /api/backtest
GET /api/briefing?market=
POST /api/ask {question} → answer + evidence
GET/POST/DELETE /api/alert-rules ; GET /api/alerts ; POST /api/alerts/{id}/read
GET/POST /api/settings ; GET/POST /api/profiles ; POST /api/secrets/{name}
GET /api/index?market= Forever Economy Index
GET /api/learning prediction + recommendation track record