Story-2493 · functions lane

Deep Read has one durable authority

Mental model: the job says “this document must be read.” Each retry is a new run attempt. Pass and batch receipts record what actually happened; only deterministic code may turn verified judge rulings into the permanent envelope.

The orchestration path

document + extraction version + envelope schema version
        ↓
one durable Deep Read job
        ↓
one run attempt + deterministic batch plan
        ↓
pass / batch receipts
        ↓
untrusted proposer candidates → judge rulings
        ↓
candidate(s) → judge_ruling_id → byte-exact V-CITE
        ↓
deterministic assembler → permanent Deep Read envelope

Retries do not invent a second job

The document, extraction version, and envelope schema version identify one job. A failed attempt keeps its receipt and a retry creates another run under that same authority. Batch identities are deterministic, terminal states are explicit, and stale or duplicate work cannot silently win a race.

Coverage comes from machinery

The planner records the pages submitted to each batch. The scheduler derives pages submitted, batches succeeded or failed, and the omitted list from those durable rows. A model may explain materiality; it cannot claim that pages were read.

The V-CITE wall

Candidate and ruling payloads are untrusted input. Every envelope row must point to a judge ruling, and every quoted span must match the cited character range in canonical document_pages_v2 text byte-for-byte. A missing ruling, wrong offset, or mismatched quote is a validation reject with structured diagnostics; it never becomes an envelope row.

Model-placement boundary

This repository plans work, invokes the agent rail, validates returned payloads, and persists receipts and envelopes. It contains no generative model call. The panel and prompts live in the agents repository; functions only moves data across the typed seam.

Scope boundary: this Story establishes fixture-side orchestration, persistence, validation, and wire contracts. T3d owns the read endpoint. T3e owns live trigger and serving-path wiring. Neither is added here.