Indigo read this.
The Insights page opens with Indigo's read at the very top — the story, where to read first, and how sure Indigo is — above Blake's card and the Deep Read. Extraction makes a document addressable; Indigo makes it intelligible.
What counsel sees
One sentence: what this document is and what happens in it (UnderstandingCard.summary), shown as returned.
The three read-first passages, each a one-click deep link straight to that passage in the document's Text view.
A single rung — high, medium, or low — telling counsel how sure Indigo is of this read. Never an alarm colour.
The name "Indigo" beside a presence dot. No role label in counsel UI (pramaan-docs ADR-175, the Atlas Step-5 naming precedent).
The deep links
Each read-first anchor id (sp1:{doc}:{page}:{block}:{start}-{end}) carries its page, and the Text view renders every block with id="anchor-<anchorId>". So a passage link is …/text#anchor-<anchorId> — counsel lands on the exact block, not just the page.
Real data path
GET /app/documents/{doc_id}/understanding (Story-2734) → DocumentUnderstanding.card → parsed at the gateway trust boundary with assertContract (HR-21) → fetched server-side in the Insights route → passed as an RSC prop, exactly as Blake's card is. The endpoint 404s (pramaan.context.understanding_not_found) until Indigo has read the document; then the card is simply absent, no layout shift, and the existing "Not yet read" state is untouched. The read stays valid even if the document was uploaded to the wrong matter — it makes no matter claims.
Review path
| Storybook state | Expected proof |
|---|---|
| Documents / Viewer / IndigoReadCard / High Confidence | Presence dot + "Indigo", the story sentence, three read-first links, and a green "High confidence" badge. |
| Documents / Viewer / IndigoReadCard / Medium & Low Confidence | The badge tone tracks the rung — amber for medium, muted for low, never red. |
| Documents / Viewer / IndigoReadCard / No Confidence | A version-evolved envelope with no confidence: the badge simply disappears, the rest of the card stands. |
| Documents / Viewer / IndigoReadCard / No Summary | Summary absent: the card still shows its read-first passages. |
Files changed
50 file(s), +1695 / -128 lines
| Path | Role | + | - |
|---|---|---|---|
| messages/en.json | Config | +11 | -0 |
| messages/hi.json | Config | +11 | -0 |
| openapi/app-api.json | Config | +246 | -16 |
| openapi/permission-map.json | Config | +9 | -0 |
| src/app/[locale]/(workspace)/matters/[matterId]/record/doc/[documentId]/insights/page.test.tsx | App route | +57 | -0 |
| src/app/[locale]/(workspace)/matters/[matterId]/record/doc/[documentId]/insights/page.tsx | App route | +21 | -0 |
| src/components/documents/viewer/document-insights-dossier.tsx | Component | +30 | -3 |
| src/components/documents/viewer/document-insights-live.tsx | Component | +7 | -1 |
| src/components/documents/viewer/indigo-read-card.stories.tsx | Component | +61 | -0 |
| src/components/documents/viewer/indigo-read-card.tsx | Component | +100 | -0 |
| src/components/documents/viewer/indigo-read-presentation.test.ts | Component | +55 | -0 |
| src/components/documents/viewer/indigo-read-presentation.ts | Component | +60 | -0 |
| src/components/settings/billing/usage-pools-summary.tsx | Component | +2 | -2 |
| src/gen/client/appGetAppMe.ts | Generated contract | +5 | -3 |
| src/gen/client/appGetDocumentUnderstanding.ts | Generated contract | +70 | -0 |
| src/gen/client/index.ts | Generated contract | +1 | -0 |
| src/gen/hooks/index.ts | Generated contract | +8 | -0 |
| src/gen/hooks/useAppGetAppMe.ts | Generated contract | +7 | -3 |
| src/gen/hooks/useAppGetAppMeSuspense.ts | Generated contract | +7 | -3 |
| src/gen/hooks/useAppGetDocumentUnderstanding.ts | Generated contract | +134 | -0 |
| src/gen/hooks/useAppGetDocumentUnderstandingSuspense.ts | Generated contract | +137 | -0 |
| src/gen/index.ts | Generated contract | +38 | -5 |
| src/gen/schemas/documentUnderstanding.json | Generated contract | +88 | -0 |
| src/gen/schemas/firmProfileRead.json | Generated contract | +5 | -5 |
| src/gen/schemas/firmProfileResponse.json | Generated contract | +4 | -4 |
| src/gen/schemas/firmSeatsAndBillingResponse.json | Generated contract | +5 | -5 |
| src/gen/schemas/subscriptionPlan.json | Generated contract | +0 | -7 |
| src/gen/schemas/teamBootstrapResponse.json | Generated contract | +5 | -5 |
| src/gen/schemas/understandingCard.json | Generated contract | +46 | -0 |
| src/gen/types/AppGetAppMe.ts | Generated contract | +7 | -0 |
| src/gen/types/AppGetDocumentUnderstanding.ts | Generated contract | +70 | -0 |
| src/gen/types/DocumentUnderstanding.ts | Generated contract | +51 | -0 |
| src/gen/types/FirmProfileRead.ts | Generated contract | +4 | -3 |
| src/gen/types/FirmProfileResponse.ts | Generated contract | +4 | -3 |
| src/gen/types/FirmSeatsAndBillingResponse.ts | Generated contract | +4 | -3 |
| src/gen/types/SubscriptionPlan.ts | Generated contract | +0 | -17 |
| src/gen/types/UnderstandingCard.ts | Generated contract | +45 | -0 |
| src/gen/types/index.ts | Generated contract | +15 | -4 |
| src/gen/zod/appGetAppMeSchema.ts | Generated contract | +10 | -0 |
| src/gen/zod/appGetDocumentUnderstandingSchema.ts | Generated contract | +88 | -0 |
| src/gen/zod/documentUnderstandingSchema.ts | Generated contract | +48 | -0 |
| src/gen/zod/firmProfileReadSchema.ts | Generated contract | +5 | -6 |
| src/gen/zod/firmProfileResponseSchema.ts | Generated contract | +1 | -6 |
| src/gen/zod/firmSeatsAndBillingResponseSchema.ts | Generated contract | +5 | -6 |
| src/gen/zod/index.ts | Generated contract | +14 | -1 |
| src/gen/zod/subscriptionPlanSchema.ts | Generated contract | +0 | -17 |
| src/gen/zod/understandingCardSchema.ts | Generated contract | +49 | -0 |
| src/lib/documents/gateway.ts | Library | +24 | -0 |
| src/lib/documents/get-anchor-view.ts | Library | +6 | -0 |
| src/lib/documents/understanding-errors.ts | Library | +15 | -0 |