diff --git a/.planning/v15-ios-handoff/00-philosophy.md b/.planning/v15-ios-handoff/00-philosophy.md index 12beef93e..7c1d3bd26 100644 --- a/.planning/v15-ios-handoff/00-philosophy.md +++ b/.planning/v15-ios-handoff/00-philosophy.md @@ -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`. diff --git a/.planning/v15-ios-handoff/01-repo-tour.md b/.planning/v15-ios-handoff/01-repo-tour.md index 33b51c969..049168f56 100644 --- a/.planning/v15-ios-handoff/01-repo-tour.md +++ b/.planning/v15-ios-handoff/01-repo-tour.md @@ -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`. diff --git a/.planning/v15-ios-handoff/02-server-architecture.md b/.planning/v15-ios-handoff/02-server-architecture.md index a28c5244e..0cd16f57a 100644 --- a/.planning/v15-ios-handoff/02-server-architecture.md +++ b/.planning/v15-ios-handoff/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`. diff --git a/.planning/v15-ios-handoff/03-api-contracts.md b/.planning/v15-ios-handoff/03-api-contracts.md index e9ffca7b7..4cfc731fa 100644 --- a/.planning/v15-ios-handoff/03-api-contracts.md +++ b/.planning/v15-ios-handoff/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 | diff --git a/.planning/v15-ios-handoff/04-data-model.md b/.planning/v15-ios-handoff/04-data-model.md index 92503692b..1e585978c 100644 --- a/.planning/v15-ios-handoff/04-data-model.md +++ b/.planning/v15-ios-handoff/04-data-model.md @@ -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`) diff --git a/.planning/v15-ios-handoff/05-auth-flows.md b/.planning/v15-ios-handoff/05-auth-flows.md index 0e6fbf42e..eaee0a686 100644 --- a/.planning/v15-ios-handoff/05-auth-flows.md +++ b/.planning/v15-ios-handoff/05-auth-flows.md @@ -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**: diff --git a/.planning/v15-ios-handoff/06-ios-responsibilities.md b/.planning/v15-ios-handoff/06-ios-responsibilities.md index f7b1fe59c..e2e2b3511 100644 --- a/.planning/v15-ios-handoff/06-ios-responsibilities.md +++ b/.planning/v15-ios-handoff/06-ios-responsibilities.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/07-server-responsibilities.md b/.planning/v15-ios-handoff/07-server-responsibilities.md index 7a8918551..d05b5ac8c 100644 --- a/.planning/v15-ios-handoff/07-server-responsibilities.md +++ b/.planning/v15-ios-handoff/07-server-responsibilities.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/08-locked-contracts.md b/.planning/v15-ios-handoff/08-locked-contracts.md index f6ed8a57b..b2e1863b0 100644 --- a/.planning/v15-ios-handoff/08-locked-contracts.md +++ b/.planning/v15-ios-handoff/08-locked-contracts.md @@ -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` diff --git a/.planning/v15-ios-handoff/11-web-ui-tour.md b/.planning/v15-ios-handoff/11-web-ui-tour.md index c18df2b6c..3b40e2c33 100644 --- a/.planning/v15-ios-handoff/11-web-ui-tour.md +++ b/.planning/v15-ios-handoff/11-web-ui-tour.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/12-design-system.md b/.planning/v15-ios-handoff/12-design-system.md index 3c4968800..ec72e797c 100644 --- a/.planning/v15-ios-handoff/12-design-system.md +++ b/.planning/v15-ios-handoff/12-design-system.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/13-state-management.md b/.planning/v15-ios-handoff/13-state-management.md index 2dd69facc..8040dd7ec 100644 --- a/.planning/v15-ios-handoff/13-state-management.md +++ b/.planning/v15-ios-handoff/13-state-management.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/14-coach-mental-model.md b/.planning/v15-ios-handoff/14-coach-mental-model.md index 1e8c8c619..d3b91b989 100644 --- a/.planning/v15-ios-handoff/14-coach-mental-model.md +++ b/.planning/v15-ios-handoff/14-coach-mental-model.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/17-error-handling.md b/.planning/v15-ios-handoff/17-error-handling.md index 09568b0eb..05aea074d 100644 --- a/.planning/v15-ios-handoff/17-error-handling.md +++ b/.planning/v15-ios-handoff/17-error-handling.md @@ -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` diff --git a/.planning/v15-ios-handoff/18-pattern-cookbook.md b/.planning/v15-ios-handoff/18-pattern-cookbook.md index f6d7f140b..316d7f880 100644 --- a/.planning/v15-ios-handoff/18-pattern-cookbook.md +++ b/.planning/v15-ios-handoff/18-pattern-cookbook.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 --- diff --git a/.planning/v15-ios-handoff/19-i18n-system.md b/.planning/v15-ios-handoff/19-i18n-system.md index 0848ba5d4..eae2e5ce6 100644 --- a/.planning/v15-ios-handoff/19-i18n-system.md +++ b/.planning/v15-ios-handoff/19-i18n-system.md @@ -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 --- diff --git a/.planning/v15-ios-handoff/20-glossary.md b/.planning/v15-ios-handoff/20-glossary.md index 4d05922f3..503e5d215 100644 --- a/.planning/v15-ios-handoff/20-glossary.md +++ b/.planning/v15-ios-handoff/20-glossary.md @@ -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