Story 2496: one document read, one serving envelope

Mental model: the card was a cover note. The Deep Read envelope is the full marked reading copy: sections, claims, findings, attention, coverage, and summary tied to one exact extraction version.

Atomic wire cutover

REMOVED  GET /app/documents/{doc_id}/document-card
ADDED    GET /app/documents/{doc_id}/deep-read-envelope
         ?extractionVersion={uuid}

200      deep_read_envelope.v1
404      that document/version has no successful envelope

The old route and its sole database reader are gone. There is no compatibility response and no dual serving truth. The separate live insight-brief route remains until app Story 2501 switches its two current consumers; the caller census found that the brief consumes cards, not the reverse.

Read authority

One RLS-scoped join selects the successful ops.deep_read_jobs authority and its single successful ops.deep_read_runs.envelope for (document_id, extraction_version, deep_read_envelope.v1). The stored JSONB is re-parsed through the existing DeepReadEnvelope contract before FastAPI returns it. Invalid stored JSON fails closed at HR-21.

Envelope contentProof
Sections, typed assertions, findings, attentionThe route integration test round-trips all four discriminated row types.
Examined receipts, mechanical coverage, summaryThe whole response is parsed and compared byte-for-shape with the canonical DTO.
Exact version + tenancyA different extraction version and another firm both receive the same clean 404.
Consumer contractOpenAPI removes appGetDocumentCard and publishes appGetDocumentDeepReadEnvelope.

Wave handoff

App Story 2501 owns codegen plus Insights rendering. Chore 2497 owns the staging upload → envelope liveness smoke and silent-skip census. This endpoint adds no migration, cloud capability, manual span, model call, or deploy workflow.