From cf5fd5a55201a9af640881ae23f9238657ff3342 Mon Sep 17 00:00:00 2001 From: marcuspaico Date: Mon, 17 Aug 2026 13:45:56 -0700 Subject: [PATCH] docs: Helios design spec Co-Authored-By: Claude Fable 5 --- .../specs/2026-08-18-helios-design.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-18-helios-design.md diff --git a/docs/superpowers/specs/2026-08-18-helios-design.md b/docs/superpowers/specs/2026-08-18-helios-design.md new file mode 100644 index 0000000..1f7f978 --- /dev/null +++ b/docs/superpowers/specs/2026-08-18-helios-design.md @@ -0,0 +1,148 @@ +# Helios — design spec + +2026-08-18 · status: approved pending Marcus's review + +## What + +Helios is a self-hosted, MIT-licensed web app: a FOSS alternative to Illume +Labs / Superpower. One Docker container per user (or household). The pitch: +**your health data lives on your server, and the AI runs on your key.** + +v1 features: + +- Connect wearables with the user's own credentials: Oura, Whoop, Fitbit + (official APIs), Garmin (unofficial library, clearly labeled). +- Upload lab PDFs → LLM extraction → user reviews/confirms → normalized + biomarkers with units, reference ranges, and flags. +- Log meals by photo or text → LLM macro estimate → editable card. +- Grounded AI chat: tool-calls into the local DB, so only relevant data + slices are sent to the LLM — never a full dump. +- Daily brief generated at a user-chosen hour from the last 24 h + 30-day + trends + flagged labs. +- Dashboards: Today (brief + cards), Sleep, Training, Labs, Nutrition, + Settings. + +Non-goals for v1: multi-user SaaS, mobile app (planned fast-follow for +HealthKit/Health Connect sync), Apple Health ingestion (needs the companion +app), medical advice claims of any kind. + +## Architecture + +API-first monolith. The web UI is a pure client of a typed REST API — that +API is the contract a future mobile app reuses unchanged. + +``` +Web UI (Vite + React SPA) + Today/brief · Chat · Sleep · Train · Labs · Nutrition · Settings + │ typed REST (Zod-validated) +Server (Bun + Hono, one process) + vendor pollers (in-process cron, per-token, with backfill) + lab PDF → LLM extraction → review queue + meal photo/text → LLM macro estimate + chat orchestrator (typed tools over the DB) + daily brief generator (cron) + │ +SQLite (single file, WAL, Drizzle ORM) + uploads dir on one /data volume +LLM: any OpenAI-compatible endpoint — OpenRouter documented default, + Ollama/LM Studio for zero-third-party operation +``` + +Stack rationale: TypeScript end to end (shared types between API, UI, and +LLM tool schemas); SQLite over Postgres because a per-user instance needs +one-file backup and zero ops (Open WebUI ships the same way); SPA over +Next.js because an API-first self-hosted app gains nothing from SSR and the +SPA keeps the mobile-later contract honest. + +`health-api` (marcus/health-api) is **reference only**: its lab +normalization (`normalize.ts`, `units.ts`) and schema shapes inform clean +re-implementations. No code copied with Marcus-specific assumptions, no +personal data, MIT throughout. + +## Data model (Drizzle/SQLite) + +- `settings` — LLM base URL + key, vendor tokens, brief hour. Secret + columns encrypted (see Security). +- `daily_metrics` — per-day, per-source rollups: steps, resting HR, HRV, + active calories, readiness/recovery scores. +- `sleep_sessions` — start/end, stage durations, scores; raw vendor JSON + retained in a `raw` column. +- `workouts` — type, duration, load metrics; raw JSON retained. +- `lab_draws` + `biomarkers` — draw metadata; marker slug, value, + normalized unit, reference range, flag. +- `meals` — timestamp, photo path, macro estimate, LLM confidence, + user-edited flag. +- `chat_threads` + `chat_messages`. +- `briefs` — generated markdown + input snapshot. +- `sync_state` — per-connector cursor/watermark for incremental polls. + +## Connectors + +| Vendor | Path | User setup | +| --- | --- | --- | +| Oura | official API | paste personal access token | +| Whoop | official API | register own free dev app, paste client id/secret (documented 5-min flow) | +| Fitbit | official API | same own-app flow as Whoop | +| Garmin | unofficial `garmin-connect` lib | username/password; labeled "may break without notice" | + +Pollers run on an in-process cron; first connect triggers historical +backfill; `sync_state` makes polls incremental. Every connector normalizes +into the tables above and keeps raw vendor JSON. + +Labs: PDF upload → LLM extraction prompt → **review/confirm screen** — +nothing writes to `biomarkers` until the user approves the parsed values. +Trust in medical numbers requires the human check. + +Nutrition: photo or free-text → LLM estimates items + macros (Open Food +Facts as grounding where possible) → editable card; edits stored, model +estimate retained for calibration. + +## AI layer + +- Provider abstraction: base URL + key + model id; anything + OpenAI-compatible works. OpenRouter is the documented default; Ollama is + the fully-local option. +- Chat tools (typed, Zod-schema'd): `query_sleep`, `query_metrics`, + `query_workouts`, `query_labs`, `query_meals`, `log_meal`. Tools return + bounded slices (date-ranged, capped row counts). +- Daily brief: cron at the user's hour; prompt assembles yesterday's data, + 30-day trends, and out-of-range biomarkers; output stored in `briefs` and + rendered on Today. +- Honest privacy wording everywhere (README + Settings): chat context is + sent to the LLM endpoint the user chose. Only Ollama-class local + endpoints mean zero third parties. + +## Security + +- Auth: single password (argon2id), rate-limited login, httpOnly session + cookie. Passkeys are a later upgrade. +- Secrets at rest: AES-256-GCM column encryption; key generated at first + boot into the /data volume (`secret.key`). +- The SQLite file itself is not app-encrypted in v1 (bun:sqlite lacks + SQLCipher); docs prescribe disk encryption + encrypted backups. Column + crypto covers the credential-theft blast radius. +- No telemetry, no update phone-home. Outbound traffic only: chosen LLM + endpoint + connected vendor APIs. +- CSP on the SPA; uploads served with safe content-type handling. + +## Testing + +- Vitest: unit normalization (units/ranges/marker slugs), connector + transforms against recorded vendor fixtures, tool-schema round-trips. +- API integration tests over an in-memory SQLite. +- CI: Gitea Actions — typecheck + tests on push. + +## Deploy + +- One Dockerfile (bun base), `docker compose up`, single `/data` volume. +- Caddy reverse-proxy recipe in docs. +- Repo: git.rehbock.xyz/marcus/helios (public). GitHub mirror optional + later for discoverability. + +## Milestones + +1. Scaffold: repo, CI, Docker, auth, settings (LLM + encryption plumbing). +2. First connector (Oura) end to end: poll → normalize → Sleep/Today UI. +3. Chat + tools over whatever data exists. +4. Labs pipeline (upload → extract → review → dashboard). +5. Meals + daily brief. +6. Whoop/Fitbit/Garmin connectors; docs site; v0.1 announcement.