From 0e4619a0c03312b5e1910451eee8f90a806b9b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 10 Sep 2026 11:22:06 +0200 Subject: [PATCH] docs(nav): say why Insights stays closed under a switch, since the old reason lapsed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The entry carried "Non-delegable in v1, server-side and here". That was true at v1.36.0 and is not true now: twenty-seven `/api/insights/*` reads plus `/api/dashboard/summary` and `/api/export/health-record` declare `("manage", "record")`, and the AI-egress objection they were closed for is answered by construction rather than by the flag — the record resolver stamps `setDelegatedGenerationSuppressed`, so a delegate reads what the owner's own account generated and causes no egress. What keeps the door shut is the overview's own reads rather than the tiles': `/api/insights/layout` and `/api/insights/generate` both resolve `requireAuth()` and refuse any switch at any level. Opening the entry without first deciding what those two mean for a delegate — whose saved layout, and whether the briefing reads or regenerates — would hand a whole-record MANAGE delegate a page whose chrome 403s while its tiles answer, which is the failure the presentation inventory exists to prevent. That is a decision about two more routes, not a flag on this one, so the comment now says what is actually load-bearing and the Coach's own reason is stated separately. --- src/components/layout/nav-model.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/components/layout/nav-model.ts b/src/components/layout/nav-model.ts index 300dcec0e..47f9c9fbd 100644 --- a/src/components/layout/nav-model.ts +++ b/src/components/layout/nav-model.ts @@ -224,11 +224,28 @@ export const NAV_DESTINATIONS: ReadonlyArray = [ tourId: "nav-documents", requiresModule: "inboundDocuments", }, - // v1.36.0 — Insights and the Coach carry no `sharedRecord` flag, so they - // drop out under a switch. Both are AI surfaces, and AI egress of a - // person's health data rides the consent THAT person gave for their own - // use; a delegate triggering it would create a consent-shaped act the owner - // never made. Non-delegable in v1, server-side and here (design §4). + // Insights and the Coach carry no `sharedRecord` flag, so they drop out + // under a switch. The reason has changed since v1.36.0 and the old wording + // ("non-delegable, server-side and here") is no longer true of the tiles: + // twenty-seven `/api/insights/*` reads plus `/api/dashboard/summary` and + // `/api/export/health-record` declare `("manage", "record")`, and the + // AI-egress objection they were closed for is answered by construction — + // the record resolver stamps `setDelegatedGenerationSuppressed`, so a + // delegate reads what the owner's own account generated and causes no + // egress. + // + // What keeps the door shut is the OVERVIEW's own reads rather than the + // tiles': `/api/insights/layout` (`insights/layout/route.ts`) and + // `/api/insights/generate` (`insights/generate/route.ts`) both resolve + // `requireAuth()`, which refuses any switch at any level. Opening the entry + // without deciding what those two mean for a delegate — whose saved layout, + // and whether the briefing reads or regenerates — would hand a MANAGE + // delegate a page whose chrome 403s while its tiles answer. That is a + // decision about two more routes, not a flag on this one. + // + // The Coach stays closed on the original argument, unchanged: + // `/api/insights/chat` is genuinely not delegable, and the page is a + // generation surface rather than a read of one. { href: "/insights", tKey: "nav.insights",