The key backup sections become "Save the recovery kit": which keys the kit lists and why, the fingerprint of the token key, and the readiness card with its Backup health notification.
Fix two dead anchors (the MCP trust model, the README quick start) and the
statements that no longer match the app: a guardian can connect a managed
profile's services, the environment module is on by default and reaches the
air-quality host too, its readable location columns were dropped in 0409,
settings sections carry their current names, the Withings card lives on
/settings/integrations, the TrueNAS start period matches the image, the
deploy check names HEALTHLOG_PROD_URL, and the docs index describes what
self-hosting/ and integrations/ hold.
Every configured key id now has a canary in encryption_key_canaries,
checked at boot. A key that cannot open its canary, or existing data
written before the canary existed, puts the process in a refusal state:
every API route answers 503 encryption.key_mismatch, /api/health reports
reason encryption_key_mismatch, the pages render one explanation, and
neither the queue producer nor the worker starts. The process stays up
so the reason is visible instead of hiding in a crash loop.
The admin Encryption page gains a "Back up your encryption key" step:
key id and fingerprint (never the key), where the key lives per
platform, a check of a pasted copy that is compared and discarded, and
a confirmation bound to the active key id and fingerprint. The overview
gets a tile and admins get a dashboard banner while it is due.
HEALTHLOG_PLATFORM picks the platform the step opens on. Adds the
TrueNAS self-hosting page and key backup sections in the docs.
- geolite2: quote the real commented compose mount (./geolite2 to
/opt/geolite2, the GEOLITE2_DIR default, so no env var is needed for
the default path)
- getting-started: healthcheck probes /api/health, not /api/version;
the environment module reaches archive-api and geocoding-api
.open-meteo.com, relevant for egress allowlists
- mcp: the module is opt-in and off by default, but no longer the only
such module
- reverse-proxy: the Coach stream is SSE over plain HTTP, not
WebSockets; note that TRUST_PROXY_HOPS is not on the bundled compose
whitelist and must be added by hand
- scaling: /api/health healthcheck; worker liveness is in-memory and
invisible across a web/worker split; pool sizing now goes through
getConnectionBudget with DB_CONNECTION_LIMIT as the compose knob and
a 2-connection pg-boss share
- sso: the native SSO handoff shipped, OIDC_ONLY works with app builds
that carry it
- unraid: geo databases are baked in only when the build had a licence
key, or mounted; replaceable either way
Surface the load-bearing first-run vars in docker-compose.yml and the README
quick-start: secret generation, the SESSION_COOKIE_SECURE=false LAN note, the
single persistent volume, and a /api/version verify step. Add an Unraid
Community Applications template plus a NAS walkthrough covering the external
Postgres setup, and a Portainer app template referencing the compose stack.