PR: #695: feat(documents): Indigo read this card on document Insights [Story-2737] by @ankitmaheshwari-com
View PR →
Story-2737 · parent Epic-2624

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

The story

One sentence: what this document is and what happens in it (UnderstandingCard.summary), shown as returned.

Read first

The three read-first passages, each a one-click deep link straight to that passage in the document's Text view.

Confidence

A single rung — high, medium, or low — telling counsel how sure Indigo is of this read. Never an alarm colour.

Ambient presence

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 stateExpected proof
Documents / Viewer / IndigoReadCard / High ConfidencePresence dot + "Indigo", the story sentence, three read-first links, and a green "High confidence" badge.
Documents / Viewer / IndigoReadCard / Medium & Low ConfidenceThe badge tone tracks the rung — amber for medium, muted for low, never red.
Documents / Viewer / IndigoReadCard / No ConfidenceA version-evolved envelope with no confidence: the badge simply disappears, the rest of the card stands.
Documents / Viewer / IndigoReadCard / No SummarySummary absent: the card still shows its read-first passages.

Files changed

50 file(s), +1695 / -128 lines

Path Role + -
messages/en.jsonConfig+11-0
messages/hi.jsonConfig+11-0
openapi/app-api.jsonConfig+246-16
openapi/permission-map.jsonConfig+9-0
src/app/[locale]/(workspace)/matters/[matterId]/record/doc/[documentId]/insights/page.test.tsxApp route+57-0
src/app/[locale]/(workspace)/matters/[matterId]/record/doc/[documentId]/insights/page.tsxApp route+21-0
src/components/documents/viewer/document-insights-dossier.tsxComponent+30-3
src/components/documents/viewer/document-insights-live.tsxComponent+7-1
src/components/documents/viewer/indigo-read-card.stories.tsxComponent+61-0
src/components/documents/viewer/indigo-read-card.tsxComponent+100-0
src/components/documents/viewer/indigo-read-presentation.test.tsComponent+55-0
src/components/documents/viewer/indigo-read-presentation.tsComponent+60-0
src/components/settings/billing/usage-pools-summary.tsxComponent+2-2
src/gen/client/appGetAppMe.tsGenerated contract+5-3
src/gen/client/appGetDocumentUnderstanding.tsGenerated contract+70-0
src/gen/client/index.tsGenerated contract+1-0
src/gen/hooks/index.tsGenerated contract+8-0
src/gen/hooks/useAppGetAppMe.tsGenerated contract+7-3
src/gen/hooks/useAppGetAppMeSuspense.tsGenerated contract+7-3
src/gen/hooks/useAppGetDocumentUnderstanding.tsGenerated contract+134-0
src/gen/hooks/useAppGetDocumentUnderstandingSuspense.tsGenerated contract+137-0
src/gen/index.tsGenerated contract+38-5
src/gen/schemas/documentUnderstanding.jsonGenerated contract+88-0
src/gen/schemas/firmProfileRead.jsonGenerated contract+5-5
src/gen/schemas/firmProfileResponse.jsonGenerated contract+4-4
src/gen/schemas/firmSeatsAndBillingResponse.jsonGenerated contract+5-5
src/gen/schemas/subscriptionPlan.jsonGenerated contract+0-7
src/gen/schemas/teamBootstrapResponse.jsonGenerated contract+5-5
src/gen/schemas/understandingCard.jsonGenerated contract+46-0
src/gen/types/AppGetAppMe.tsGenerated contract+7-0
src/gen/types/AppGetDocumentUnderstanding.tsGenerated contract+70-0
src/gen/types/DocumentUnderstanding.tsGenerated contract+51-0
src/gen/types/FirmProfileRead.tsGenerated contract+4-3
src/gen/types/FirmProfileResponse.tsGenerated contract+4-3
src/gen/types/FirmSeatsAndBillingResponse.tsGenerated contract+4-3
src/gen/types/SubscriptionPlan.tsGenerated contract+0-17
src/gen/types/UnderstandingCard.tsGenerated contract+45-0
src/gen/types/index.tsGenerated contract+15-4
src/gen/zod/appGetAppMeSchema.tsGenerated contract+10-0
src/gen/zod/appGetDocumentUnderstandingSchema.tsGenerated contract+88-0
src/gen/zod/documentUnderstandingSchema.tsGenerated contract+48-0
src/gen/zod/firmProfileReadSchema.tsGenerated contract+5-6
src/gen/zod/firmProfileResponseSchema.tsGenerated contract+1-6
src/gen/zod/firmSeatsAndBillingResponseSchema.tsGenerated contract+5-6
src/gen/zod/index.tsGenerated contract+14-1
src/gen/zod/subscriptionPlanSchema.tsGenerated contract+0-17
src/gen/zod/understandingCardSchema.tsGenerated contract+49-0
src/lib/documents/gateway.tsLibrary+24-0
src/lib/documents/get-anchor-view.tsLibrary+6-0
src/lib/documents/understanding-errors.tsLibrary+15-0