Two sentences about the Health Score stopped being true the moment someone could choose which pillars count toward it. The one people read said the score averaged "every pillar that has enough recent data". For an account that took a pillar out, that describes ground the number does not cover, and it reads as a reassurance rather than a description. It now says the average is over the pillars that count, that a pillar without recent data is still left out rather than zeroed, and that which pillars count is the reader's own choice, so the combined number is not itself a clinical standard. All six locales. The one nobody reads named the WHO HEARTS technical package flat, as though a standards body had signed off on whatever selection the account holds. HEARTS names the risk factors the pillars are drawn from; it prescribes no average over them. The entry now says what it is cited for. While checking where that citation surfaces it turned out it surfaces nowhere: ProvenanceExplainer takes the prop and renders only the method caption, which v1.22 did on purpose when the info popover went away. That is written down in the file now, because the map's own header implies otherwise and the next person would trust it. The registry entry for HEALTH_SCORE lists all eight pillars with a minimum of three, which reads like the recipe and like a threshold. It is neither. The published coverage and confidence are built in computeComposite over the resolved composition, so a person counting four pillars is not measured against a denominator of eight, and the real floor is the breadth rule, which counts distinct domains rather than inputs. Both facts are now stated at the entry instead of being inferable only by following the call chain. Tests: the published denominator is never the eight-pillar catalogue; a pillar somebody took out of their score is never listed back as missing coverage; a pillar they kept and have no data for still is; the registry list stays equal to the score catalogue; the choice sentence is present in all six locales.
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__/.