Refresh the docs index and reference pages

- docs/README.md: drop the doctor-report.md and audit/ entries (neither
  exists), broaden the ops/ description, list the real subdirectories,
  and stop promising release-by-release migration notes
- migration/v1.3-to-v1.4: note which v1.4 routes have since moved or
  gone; rotation runs via pnpm dlx tsx
- ui-guidelines: six locales with guard tests, settings sections point
  at the registry instead of an eight-item list, /settings redirect is
  a 308
- apple-store-connect-checklist: drop the unsourced 40% rejection-rate
  figure
- codex-protocol-spec: the slug chain rotated on 2026-06-02; default is
  gpt-5.5, the shipped constant is authoritative
This commit is contained in:
Marc-André Bombeck committed 2026-08-27 12:23:37 +02:00
1 parent fa7e1ee739
commit 123fcc4ec3
5 files changed
+52 -38

No files matched your search

+15 -9
View File
@@ -13,9 +13,10 @@ notes, and machine-readable specs that ship alongside the source:
[`api/mcp-capabilities.md`](./api/mcp-capabilities.md) (tools,
resources, prompts, write model) and
[`api/mcp-skills.md`](./api/mcp-skills.md) (building a connector / skill).
- [`ops/`](./ops/) — backup / restore + encryption-key-rotation
playbooks. These are the runbooks an operator reaches for during an
incident.
- [`ops/`](./ops/) — operator runbooks: deploy, backup / restore,
encryption-key rotation, password reset and account recovery, env
checks, TLS pinning, data repair. These are what an operator reaches
for during an incident.
- [`self-hosting/`](./self-hosting/) — horizontal-scaling notes
(`HEALTHLOG_PROCESS_TYPE=web|worker|all`) and the deploy-pipeline
recipe. Routine install steps stay on `docs.healthlog.dev`. Includes
@@ -33,14 +34,19 @@ notes, and machine-readable specs that ship alongside the source:
managed profiles for somebody with no login and the guardians who look
after them, what revocation does and does not undo, and which trust
properties of the instance are unchanged by any of it.
- [`migration/`](./migration/) — release-by-release migration notes.
Read the entry for the version you're upgrading from.
- [`audit/`](./audit/) — per-release audit summaries archived for
forensic traceability.
- [`migration/`](./migration/) — migration notes. Currently only
v1.3 to v1.4; later releases are covered by `CHANGELOG.md` and
<https://docs.healthlog.dev>.
- [`integrations/`](./integrations/) — per-integration reference
(Withings, Fitbit, Google Health, WHOOP, Apple Health, AI providers,
data import).
- [`adr/`](./adr/) — architecture decision records.
- [`security/`](./security/) — threat-model notes.
- [`diagrams/`](./diagrams/) — architecture diagrams rendered through
docs.healthlog.dev.
- [`releases/`](./releases/) — release imagery.
- [`apple-store-connect-checklist.md`](./apple-store-connect-checklist.md)
— the iOS submission gate.
- [`doctor-report.md`](./doctor-report.md) — PDF generator design
notes.
- [`codex-protocol-spec.md`](./codex-protocol-spec.md) — Codex / ChatGPT
OAuth protocol reverse-engineering notes.
- [`ui-guidelines.md`](./ui-guidelines.md) — UI / a11y house style.
+1 -1
View File
@@ -34,7 +34,7 @@ Plus pre-submit final checks.
- [ ] Add the description above to the medical-device-justification field if Apple shows one
- [ ] Cross-reference the in-app `/privacy` page (https://<your-instance>/privacy) §7 MDR-boundary
**Why this matters**: Apple's first-submission rejection rate for health apps is ~40%. The most common reason is unclear medical-device classification. The above wording mirrors the in-app disclaimer + the per-feature gating; consistency between the form and the app is what Apple looks for.
**Why this matters**: health apps get rejected on first submission most commonly for unclear medical-device classification. The above wording mirrors the in-app disclaimer + the per-feature gating; consistency between the form and the app is what Apple looks for.
## Section 2 — Privacy Nutrition Labels
+11 -7
View File
@@ -630,8 +630,9 @@ Confirmed-rejected slugs (despite the source-tree references in the table above)
Confirmed-accepted slugs on a ChatGPT Plus subscription (per `available_in_plans` in `models.json`):
- `gpt-5.3-codex` — coding-optimized, accepted; HealthLog uses this as default
- `gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` / `gpt-5.2` — also expected to work per plan
- `gpt-5.5` — HealthLog's default (first chain entry) as of 2026-06
- `gpt-5.4` / `gpt-5.4-mini` / `gpt-5.2` — accepted per plan
- `gpt-5.3-codex` — was the default (verified 2026-05-09); the backend rotated off the `-codex` line on 2026-06-02 and this slug is now only accepted intermittently, so it sits on a late chain rung
The `codex-rs/tui/src/model_migration.rs` references to `gpt-5-codex` etc. are _migration prompts_ shown to existing users — they are NOT the slugs sent on the wire after migration. The wire slugs come from `models.json`. Always cross-check `models.json` (`gh api repos/openai/codex/contents/codex-rs/models-manager/models.json`) before picking a default.
@@ -641,17 +642,20 @@ The ChatGPT-Codex allow-list is rotated by OpenAI without prior notice (`gpt-5-c
To eliminate that risk class, HealthLog's `CodexClient` walks an ordered chain on every fresh request series.
**Chain** (top = first try; default order is the empirically-safest most-current-first ordering as of 2026-05):
**Chain** (top = first try; default order is the empirically-safest most-current-first ordering as of 2026-06, after the backend rotated off the `-codex` line on 2026-06-02):
```ts
const DEFAULT_SLUG_FALLBACK_CHAIN = [
"gpt-5.3-codex", // current allow-list entry (verified 2026-05-09)
"gpt-5-codex", // historical default (rejected as of 2026-05 but safe to retry — backend may flip)
"gpt-5", // bare slug — rejected on ChatGPT-auth as of 2026-05 but lives on api-key auth
"gpt-4o", // ladder-rung for last-ditch capability
"gpt-5.5", // current default across paid tiers as of 2026-06-02
"gpt-5.4", // documented fallback
"gpt-5.4-mini", // documented lighter-weight fallback
"gpt-5.3-codex", // late rung — still accepted intermittently
"gpt-5.2", // legacy floor
];
```
The shipped constant in `src/lib/ai/codex-client.ts` is authoritative; when the upstream rotates again, that file moves first and this listing follows.
The chain is overridable via the env var `CODEX_MODEL_FALLBACK_CHAIN` (comma-separated). The first env-var-named slug supersedes `CODEX_MODEL`; if both are set, `CODEX_MODEL` is folded into position 0 and de-duplicated.
**Trigger condition** (when to walk to the next slug):
+9 -2
View File
@@ -7,6 +7,12 @@ new env var in §Environment variables below has a safe default. This
guide documents what changes for operators and integrators, in case
you're extending the API or scaling the deployment.
> Historical note: route paths on this page reflect v1.4. Several have
> since moved or gone: `/api/admin/status-overview` is now
> `/api/admin/status`, the Umami probe is
> `/api/admin/monitoring/umami-test`, and the moodLog integration was
> removed entirely.
## TL;DR
```bash
@@ -64,9 +70,10 @@ worker`. Default `all` keeps the single-container behaviour.
- **`ENCRYPTION_KEY`** _(unchanged)_ — still honoured as a fallback
when `ENCRYPTION_KEYS` is empty. No action needed for existing
installs.
- Rotation: `pnpm tsx scripts/rotate-encryption-key.ts <newKeyId>`
- Rotation: `pnpm dlx tsx scripts/rotate-encryption-key.ts <newKeyId>`
re-encrypts every ciphertext under the new key without downtime.
Walk-through in `docs/ops/encryption-key-rotation.md`.
Walk-through in `docs/ops/encryption-key-rotation.md` (the current
playbook; the production image strips `tsx`, hence `pnpm dlx`).
### Off-host backup target _(optional)_
+16 -19
View File
@@ -320,24 +320,18 @@ tile itself, to avoid accidental hide.
### 3.3 Settings — `/settings/[section]`
The 1.4 release splits the legacy 3150-LOC settings monolith into one
route per top-level section:
The 1.4 release split the legacy 3150-LOC settings monolith into one
route per top-level section. The pattern holds: every section is a
route under `/settings/[section]` with its component under
`src/components/settings/`. The section list has grown far past the
original eight (account, integrations, notifications, ai, api,
advanced, about now sit alongside security, access, sources, coach,
environment, export, mcp, and more); the registry in
`src/components/settings/settings-shell.tsx` is authoritative.
Cross-section search lives in the section sidebar header.
- `/settings/account` — profile, password, passkeys, account deletion.
- `/settings/integrations` — Withings, Nightscout, Telegram, ntfy, Web Push.
- `/settings/notifications` — channel matrix + quiet hours + reminders.
- `/settings/dashboard` — tile layout editor, default ranges, threshold
overrides.
- `/settings/ai` — AI provider selection + connection + test.
- `/settings/api` — API tokens for headless ingest + Bearer issuance.
- `/settings/advanced` — exports, imports, danger zone.
- `/settings/about` — version, build, license, links to docs/changelog.
Each section's component lives at `src/components/settings/<section>.tsx`
and stays under 400 LOC. Cross-section search lives in the section
sidebar header.
The legacy `/settings` route 301-redirects to `/settings/account`.
The legacy `/settings` route is a permanent (308) redirect to
`/settings/account`.
### 3.4 Admin — `/admin/[section]`
@@ -505,8 +499,11 @@ is the point.
## 7. Internationalization
All user-facing strings come from `messages/en.json` (default) and
`messages/de.json`. Use `useTranslations()` on the client and
All user-facing strings come from `messages/en.json` (default) plus
the `de`, `es`, `fr`, `it`, and `pl` bundles beside it. Guard tests
(`i18n-call-site-coverage`, `i18n-locale-integrity`) enforce that every
`t()` key resolves in EN and propagates across all six locales. Use
`useTranslations()` on the client and
`getServerTranslator()` (`src/lib/i18n/server-translator.ts`) on the
server. Numbers, dates, currencies, and units always go through
`useFormatters()` — never hand-roll `Intl.NumberFormat(...)` with a