The spec watched the day flip from provisional to final on a hero that only its own subject was keeping on screen: the arrival marker was the last thing in the calm-degrade guard holding the hero up for the bare fixture account, so removing the arrival chip took the hero with it and left the spec nothing to observe. Putting the arrival back into the guard would bring back a worse problem. An arrival-only digest lands in the compact all-clear composition, which would tell someone with no readings at all that everything is clear - a claim about their health made from nothing, and made only on the days something happened to sync. The guard stays as it is; the fixture was what was wrong. So the spec now seeds its own precondition: one integration needing a reconnect, which is an ordinary Today for anyone whose readings come from a device. It is read fresh on every request rather than through the dashboard snapshot cache, so unlike a seeded score or briefing it cannot lose a race with a cached snapshot, and the rail item admits no module gate and no dismiss path. The row is removed again afterwards. While the spec was open: it now pins the state it starts from. It only ever asserted that the pending-sleep note was absent at the end, which a note that never rendered also satisfies. It asserts the note is up and the day reads provisional first, so the two halves are one assertion with the number flipped. The component side is pinned in unit tests, since the spec needs a built app and a database to run.
src/components/
React components. The UI primitives are shadcn/ui (new-york style, zinc base) over Radix + Tailwind 4 + Lucide; everything above the primitives is feature-grouped by surface. Components are server components unless they need a hook, state, or browser API, in which case they open with "use client". Charts use Recharts 3 — replacing the chart library requires explicit approval.
Primitives and shell
ui/— shadcn/ui primitives (button, dialog, sheet, table, …). Generated by the shadcn CLI; keep edits minimal and on-style.layout/— the app shell: sidebar, topbar, bottom nav.providers.tsx,version-poller.tsx— top-level context providers and the self-healing stale-shell poller.i18n/— translation context + locale switcher.
Feature groups
insights/— insight status, assessment cards, Coach surface, advisor cards (the largest group).medications/— medication cards, the schedule wizard, intake timeline, detail history.settings/— the section components behind each settings page.measurements/,mood/,dashboard/— entry forms, lists, dashboard tiles.charts/— Recharts wrappers.monitoring/— Umami / GlitchTip client bootstrap.gamification/,targets/,comparison/,doctor-report/,clinician/,onboarding/,admin/— the remaining per-surface groups.
Conventions
Kebab-case filenames; React component exports stay PascalCase regardless. (A handful of PascalCase-filename outliers under medications/ + onboarding/ are pre-existing drift, noted in ../../CLAUDE.md.) Every t() call needs a matching key in messages/en.json — guarded by i18n-call-site-coverage.test.ts. Data reads go through TanStack Query with keys from @/lib/query-keys and unwrap (await res.json()).data. Tests live in __tests__/.