docs(ios-handoff): E-Closeout — cross-link patch across sibling files

Sibling docs (00..20 except README) referenced 16 file names that don't
exist in the final pack — names like 10-coach-pipeline.md, 12-ai-coach.md,
15-withings-bridge.md, 17-personal-records.md, 18-onboarding.md,
19-deploy-runtime.md, 02-architecture.md, 03-system-overview.md,
10-architecture.md, 12-ai-providers.md, 13-medical-content.md,
09-ui-state.md. Every one mapped to a real file in the final pack;
patched all cross-links in:

- 00-philosophy.md            (STOP HERE table)
- 01-repo-tour.md             (deploy link + STOP HERE table)
- 02-server-architecture.md   (6 Detail-in references + STOP HERE table)
- 03-api-contracts.md         (STOP HERE table)
- 04-data-model.md            (prerequisites + What is NOT in this file)
- 05-auth-flows.md            (What is NOT in this file)
- 06-ios-responsibilities.md  (prerequisites)
- 07-server-responsibilities.md (prerequisites)
- 08-locked-contracts.md      (What is NOT in this file)
- 11-web-ui-tour.md           (prerequisites)
- 12-design-system.md         (prerequisites)
- 13-state-management.md      (prerequisites)
- 14-coach-mental-model.md    (prerequisites)
- 17-error-handling.md        (What is NOT in this file)
- 18-pattern-cookbook.md      (prerequisites)
- 19-i18n-system.md           (prerequisites)
- 20-glossary.md              (multiple Coach + provider references)

Every cross-link in the doc-pack now resolves to an existing file or to
a section heading inside an existing file.
This commit is contained in:
Marc-André Bombeck committed 2026-05-14 23:44:17 +02:00
1 parent b4a98ef38e
commit 759028ad8f
17 files changed
+35 -35

No files matched your search

+2 -2
View File
@@ -181,7 +181,7 @@ AI / insights / chart work runs through a research agent first. The agent benchm
| --- | --- |
| "Just call one endpoint" | `03-api-contracts.md` |
| "Understand the data shape" | `04-data-model.md` |
| "Wire the Coach drawer" | `10-coach-pipeline.md` |
| "Build a chart" | `06-ui-conventions.md` |
| "Wire the Coach drawer" | `14-coach-mental-model.md` |
| "Build a chart" | `12-design-system.md` |
Otherwise: continue to `01-repo-tour.md`.
+2 -2
View File
@@ -258,7 +258,7 @@ The runtime is **Coolify** on a self-hosted server. The deploy config lives:
For iOS purposes: the public URL is the production HealthLog instance; the API base URL is configurable in the app's Settings (the iOS app supports self-hosted operators, not just Marc's instance).
Detail in `19-deploy-runtime.md`.
Detail in `02-server-architecture.md` § Coolify deploy + § Stack at a glance.
## Planning artifacts — `.planning/`
@@ -278,6 +278,6 @@ When investigating a feature: search `.planning/` first — a report explains "w
| "What does endpoint X return?" | `03-api-contracts.md` |
| "What does the DB look like?" | `04-data-model.md` |
| "How do I run the dev server?" | `CONTRIBUTING.md` (root) |
| "What's the deploy story?" | `19-deploy-runtime.md` |
| "What's the deploy story?" | `02-server-architecture.md` § Coolify |
Otherwise: continue to `02-server-architecture.md`.
@@ -242,7 +242,7 @@ The `provenance` SSE frame carries the enriched envelope:
`keyValues` is the parsed `---KEYVALUES---` block — load-bearing numbers the Coach drew on. iOS surfaces these in the collapsible "What is this based on?" disclosure under the assistant bubble.
Detail in `10-coach-pipeline.md`.
Detail in `14-coach-mental-model.md`.
## Insights module
@@ -273,7 +273,7 @@ Each per-status writer:
The per-status cards (`/api/insights/cards`) compose the cached blobs into the iOS-friendly `InsightCard` DTO with `severity ∈ { alert, caution, info, good }`.
Detail in `11-insights-pipeline.md`.
Detail in `15-insights-architecture.md`.
## Health Score
@@ -290,7 +290,7 @@ Total 0–100. Each component carries an `asOf` timestamp and a canonical source
Computation: `src/lib/analytics/health-score.ts` → `computeHealthScore(input)`. The input is built in `src/app/api/analytics/route.ts` (see lines ~698-720 for the canonical builder) by pulling the same last-30-day metric set the dashboard tiles consume — single source of truth for the displayed numbers vs the score.
Detail in `16-health-score.md`.
Detail in `16-health-score-logic.md`.
## Source priority — two-axis resolver (Since v1.4.25)
@@ -424,7 +424,7 @@ Webhook subscription channels (Since v1.4.25):
OAuth scope upgrade banner: when `WithingsConnection.scope` is null (legacy v1.4.24 connection) or doesn't include `user.activity`, the Settings → Integrations card surfaces a reconnect banner. iOS surfaces the same banner; on tap, opens the Withings OAuth URL in `SFSafariViewController`.
Detail in `15-withings-bridge.md`.
Detail in `02-server-architecture.md` § Withings integration above + `08-locked-contracts.md` § 8 (webhook path-segment secret).
## Apple Health bridge
@@ -457,7 +457,7 @@ State machine guards:
- Already-completed user → 409
- Concurrent advance (read-then-write race) → 409 via `updateMany` with conditional WHERE
Detail in `18-onboarding.md`.
Detail in `02-server-architecture.md` § Onboarding wizard above + `.planning/research/w14b-onboarding-rebuild.md` for the design rationale.
## Personal Records (Since v1.4.25)
@@ -471,7 +471,7 @@ Detail in `18-onboarding.md`.
| Push opt-in | Per-user toggle (default off) |
| Trend tile badge | Renders when record landed in last 30 days; WCAG-AA contrast |
Detail in `17-personal-records.md`.
Detail in `07-server-responsibilities.md` § Domain 4 (PR detection) + `.planning/research/w16c-pr-detection.md` for the design rationale.
## Per-user timezone (Since v1.4.25)
@@ -504,8 +504,8 @@ iOS reads `user.timezone` from `/api/auth/me` and uses it as the canonical displ
| If your task is… | …skip the rest and read… |
| --- | --- |
| "How do I call endpoint X?" | `03-api-contracts.md` |
| "How does the Coach really work?" | `10-coach-pipeline.md` |
| "How do I wire the AI providers?" | `12-ai-providers.md` |
| "How does Withings sync?" | `15-withings-bridge.md` |
| "How does the Coach really work?" | `14-coach-mental-model.md` |
| "How do I wire the AI providers?" | `14-coach-mental-model.md` § Provider routing |
| "How does Withings sync?" | `02-server-architecture.md` § Withings integration |
Otherwise: continue to `03-api-contracts.md`.
@@ -1053,5 +1053,5 @@ Reports the deployed semver + git sha.
| --- | --- |
| "How do I refresh tokens?" | `05-auth-flows.md` |
| "What's in the DB tables I touch?" | `04-data-model.md` |
| "Why does the Coach refuse this prompt?" | `13-medical-content.md` |
| "How does PR detection actually work?" | `17-personal-records.md` |
| "Why does the Coach refuse this prompt?" | `08-locked-contracts.md` § 1 (GROUND RULES) + `14-coach-mental-model.md` § Refusal |
| "How does PR detection actually work?" | `07-server-responsibilities.md` § Domain 4 |
+2 -2
View File
@@ -2,7 +2,7 @@
file: 04-data-model.md
purpose: Prisma schema reference for the v1.5 iOS client — enums, models, migrations 0051-0060, relations.
when_to_read: Before generating any DTO; before touching any ingest path; whenever an API field shape is unclear.
prerequisites: 02-architecture.md (skim), 03-tech-stack.md (Prisma section).
prerequisites: 02-server-architecture.md (skim), 02-server-architecture.md § Database (Prisma section).
estimated_tokens: 6800
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -585,5 +585,5 @@ the full batch contract.
- **Auth + token flows** → `05-auth-flows.md`
- **Error envelopes, idempotency** → `17-error-handling.md`
- **Locked contracts (GROUND RULES, batch shapes, refusal probes)** → `08-locked-contracts.md`
- **AI Coach prompt + snapshot construction** → `12-ai-coach.md` (Agent D)
- **AI Coach prompt + snapshot construction** → `14-coach-mental-model.md`
- **OpenAPI 3.1 spec on disk** → `docs/api/openapi.yaml` (regenerated via `pnpm openapi:generate`)
+1 -1
View File
@@ -370,7 +370,7 @@ req.setValue(idempotencyKey.uuidString, forHTTPHeaderField: "Idempotency-Key")
- **Error envelopes, rate-limit response shape** → `17-error-handling.md`
- **Cookie names + their UX purpose** → web docs (web devs, not iOS)
- **Codex / ChatGPT OAuth** → `12-ai-coach.md` (Agent D) — iOS does not participate
- **Codex / ChatGPT OAuth** → `14-coach-mental-model.md` § Provider routing — iOS does not participate
**Cookies the iOS app may observe but never sets**:
@@ -2,7 +2,7 @@
file: 06-ios-responsibilities.md
purpose: Exhaustive list of what the native iOS app owns — everything the server cannot or will not do for the client.
when_to_read: First, before any iOS implementation. Defines the boundary so iOS Claude doesn't accidentally reinvent server features (see 07-server-responsibilities.md for the inverse).
prerequisites: 03-system-overview.md, 04-data-model.md, 05-auth-flows.md
prerequisites: 02-server-architecture.md, 04-data-model.md, 05-auth-flows.md
estimated_tokens: ~4500
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -2,7 +2,7 @@
file: 07-server-responsibilities.md
purpose: Exhaustive list of what the server already handles — so iOS doesn't reinvent any of it.
when_to_read: Right after 06-ios-responsibilities.md, before any iOS feature design. The inverse of that doc.
prerequisites: 03-system-overview.md, 04-data-model.md
prerequisites: 02-server-architecture.md, 04-data-model.md
estimated_tokens: ~4500
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -469,6 +469,6 @@ BEFORE shipping.
## 12. What is NOT in this file
- **API envelope details (`{ data, error, meta }`)** → `17-error-handling.md`
- **Coach snapshot construction** → `12-ai-coach.md` (Agent D)
- **Coach snapshot construction** → `14-coach-mental-model.md`
- **Glossary terms (MDR, MDCG, OneCompartment PK, etc.)** → `20-glossary.md`
- **Schema columns** → `04-data-model.md`
+1 -1
View File
@@ -2,7 +2,7 @@
file: 11-web-ui-tour.md
purpose: Page-by-page walkthrough of the HealthLog web UI so the iOS native build can mirror layout, data dependencies, and user actions screen-for-screen (or make conscious deviations where the iOS HIG demands it).
when_to_read: Before building any iOS screen. Re-read the matching section every time you port a new surface.
prerequisites: 10-architecture.md, 12-design-system.md, 13-state-management.md
prerequisites: 02-server-architecture.md, 12-design-system.md, 13-state-management.md
estimated_tokens: 7900
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -2,7 +2,7 @@
file: 12-design-system.md
purpose: Visual language reference — tokens, components, mobile-first rules, accessibility floors — so the iOS native build mirrors the web look without re-deriving it.
when_to_read: Before laying out any iOS screen, picking colours, or sizing touch targets. Re-read when porting a specific web surface (dashboard tile, chart band, range bar) to UIKit/SwiftUI.
prerequisites: 10-architecture.md (stack), 11-web-ui-tour.md (per-page composition)
prerequisites: 02-server-architecture.md (stack), 11-web-ui-tour.md (per-page composition)
estimated_tokens: 5200
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -2,7 +2,7 @@
file: 13-state-management.md
purpose: TanStack Query conventions on the web side plus the iOS data-layer mirror so the native app reuses the same cache contracts without poisoning state.
when_to_read: Before wiring any iOS network call, designing an iOS data store, or porting a mutation. Re-read when a screen looks "stale" or a cache invalidation isn't propagating.
prerequisites: 10-architecture.md, 12-design-system.md
prerequisites: 02-server-architecture.md, 12-design-system.md
estimated_tokens: 4400
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -2,7 +2,7 @@
file: 14-coach-mental-model.md
purpose: Mental model of the HealthLog Coach AI for the iOS-native client.
when_to_read: Before designing a Coach UI in Swift — to confirm the server owns prompts, refusals, safety contracts, and the streaming contract.
prerequisites: 03-system-overview.md, 04-data-model.md, 08-locked-contracts.md
prerequisites: 02-server-architecture.md, 04-data-model.md, 08-locked-contracts.md
estimated_tokens: ~5200
version_anchor: v1.4.25 / sha 49f71c92
---
@@ -335,5 +335,5 @@ function send(req):
## 10. What is NOT in this file
- **Auth flows + token lifetimes** → `05-auth-flows.md`
- **Coach refusal copy and parsing** → `08-locked-contracts.md` §1, `12-ai-coach.md`
- **Coach refusal copy and parsing** → `08-locked-contracts.md` §1, `14-coach-mental-model.md` § Refusal
- **Glossary (Wide Event, GlitchTip, pg-boss, DLQ)** → `20-glossary.md`
@@ -2,7 +2,7 @@
file: 18-pattern-cookbook.md
purpose: Recipe book for the 8 cross-cutting "how do I add X without breaking Y" tasks that recur across every release. Each recipe is a step-by-step + drift-defence checklist so iOS-Claude can extend the contract surface safely.
when_to_read: Before adding a route, migration, chart, Coach probe, locale key, CHANGELOG entry, shared helper, or any change that risks tripping the OpenAPI hard-flip gate.
prerequisites: 10-architecture.md, 12-design-system.md, 13-state-management.md, 19-i18n-system.md
prerequisites: 02-server-architecture.md, 12-design-system.md, 13-state-management.md, 19-i18n-system.md
estimated_tokens: 6800
version_anchor: v1.4.25 / sha 49f71c92
---
+1 -1
View File
@@ -2,7 +2,7 @@
file: 19-i18n-system.md
purpose: How the 6-locale translator works, key naming conventions, maintainership policy, and the runtime parity probe — so iOS can mirror the same locale shape and contribute keys without breaking the gate.
when_to_read: Before adding any user-facing string to web or iOS, before adding a new key, when porting a screen that needs localisation.
prerequisites: 10-architecture.md
prerequisites: 02-server-architecture.md, 00-philosophy.md (Rule 4 — six locales)
estimated_tokens: 3100
version_anchor: v1.4.25 / sha 49f71c92
---
+7 -7
View File
@@ -51,7 +51,7 @@ releases, docs site, or user-facing copy. UI surfaces it as
**Briefing** — Daily summary the user reads first thing. Distinct
from **Insight** (long-form chart-anchored analysis) and **Coach**
(conversational Q&A). All three live behind the Insights surface but
serve different needs. See `12-ai-coach.md` (Agent D).
serve different needs. See `14-coach-mental-model.md`.
---
@@ -61,7 +61,7 @@ serve different needs. See `12-ai-coach.md` (Agent D).
drawer (`/coach` route + drawer surface). Reads a snapshot of the
user's data, replies in warm conservative prose. Refuses GLP-1 dose
prescriptions (GROUND RULE 9) and drug-level estimates (GROUND RULE
15). See `08-locked-contracts.md` §1, `12-ai-coach.md`.
15). See `08-locked-contracts.md` §1, `14-coach-mental-model.md`.
**Coach-Snapshot** — The structured JSON the Coach reads as its
single source of evidence. Built fresh per turn by
@@ -78,7 +78,7 @@ prompt change. See `08-locked-contracts.md` §9.2.
**Codex** — ChatGPT OAuth provider (Marc's ChatGPT subscription).
Stored on `User.codexAccessTokenEncrypted` etc. Web-only path; iOS
does not participate. See `12-ai-coach.md` (Agent D).
does not participate. See `14-coach-mental-model.md`.
**Coolify** — Self-host deployment platform HealthLog runs on. Multi-
arch Docker image builds at GHCR. iOS team interacts with Coolify only
@@ -314,7 +314,7 @@ See `04-data-model.md` §4.2, Migration 0053.
| --- | --- | --- |
| GROUND RULES 1-15 | `08-locked-contracts.md` §1 | `src/lib/ai/prompts/safety-contracts.ts` |
| Refusal-probe matrix | `08-locked-contracts.md` §7 | `src/lib/ai/prompts/safety-contracts.*.yaml` |
| Coach-Snapshot | `12-ai-coach.md` (Agent D) | `src/lib/ai/coach/snapshot.ts` |
| Coach-Snapshot | `14-coach-mental-model.md` | `src/lib/ai/coach/snapshot.ts` |
| Measurement model | `04-data-model.md` §4.1 | `prisma/schema.prisma:363` |
| Source-priority two-axis | `08-locked-contracts.md` §4 | `src/lib/validations/source-priority.ts` |
| Bearer + refresh flow | `05-auth-flows.md` §3 | `src/lib/auth/refresh-token.ts` |
@@ -329,6 +329,6 @@ See `04-data-model.md` §4.2, Migration 0053.
## What is NOT in this file
- **Architecture overview** → `02-architecture.md` (Agent A)
- **UI primitives, design tokens** → `09-ui-state.md` (Agent C)
- **AI provider chain, model selection** → `12-ai-coach.md` (Agent D)
- **Architecture overview** → `02-server-architecture.md`
- **UI primitives, design tokens** → `12-design-system.md` + `11-web-ui-tour.md`
- **AI provider chain, model selection** → `14-coach-mental-model.md` § Provider routing