Change: Blake's Job 1 carve engine now runs in the real
agent runtime. One uploaded physical bundle (a compound filing — one Main Document plus a stack
of Annexures/Exhibits stitched into one PDF) is carved into a navigable family:
a head, N members, and a materialized Index — via the locked code → LLM → code
sandwich. The already-merged canonical prompt (prompts/carve.py) is reused verbatim;
this Story is the plumbing around it.
| Step | Where | What it does |
|---|---|---|
| 0 · Header strip | carve.build_header_strip | One line per page (page# + top line). The full map at ~19–30 tokens/page — the proof measured 307 pages = 5,786 tokens, 34× smaller than the 197k-token full text. |
| 0.5 · Scheme-adaptive detection | carve.detect_schemes | Detects the filing's OWN dominant repeating marker family (Annexure P-1 / Exhibit A / CW1/91 / NFRA/16 / Schedule II / Appendix) and proposes standalone-marker candidates. NOT a fixed regex — the real-bundle finding. |
| 1 · Candidates + packet | carve.build_carve_prompt_for_pages | Strip (all pages) + Index page(s) + main-document opening window + first page of each candidate member + the candidate skeleton, wrapped in a random per-run nonce fence. |
| 2 · One carve call | carve._run_carve_model | The merged canonical prompt, one seat from llm.yaml (primary + 2 fallbacks) with a failover loop: timeout / transport error / empty family / bad-JSON → next model. |
| 3 · Monotonic assembly | family_models.assemble_carve_family | Model START pages → increasing, non-overlapping ranges → the family (head + N members + Index). Code owns every end; a stray/duplicate/out-of-range start is retained for counsel, never overlapped. |
| 4 · Effect | events.document_family_event | The typed document.family effect on the frozen agent_event_stream.v1, mirroring the document.card/document.sections builders. |
| 5 · Runtime | runtime._handle_carve_request | A new mode="carve" path, fail-isolated like the card (D13): run_carve never raises, so a failed carve is a status="error" effect, never a stuck bundle. |
The proof-of-concept ran on a real 307-page NFRA complaint bundle whose members key on
NFRA/N. A fixed ANNEXURE|EXHIBIT regex under-detected — 6 hits, all
intra-document noise ("Annexure A to the Auditor's Report", a section inside an annual
report). A raw model with a generic prompt over-split into 164 "members".
Deterministic detection on the filing's own NFRA/N scheme + the scheme-teaching
prompt yields 16. The engine keeps the scheme detection generous (code proposes)
and lets the prompt reject the intra-document false-positive class (the model rules).
| Immutable source | Members are LOGICAL page ranges over the original file — the PDF is never rewritten. |
| No model-emitted coordinates | The model emits START pages only; code derives every end and certifies the partition (_assert_family_partition: contiguous, no gap, no overlap, no dropped page). |
| declared_side | Counsel truth; the carve pass is a side-check only and originates nothing. |
| Writes nothing | The pass emits a document.family effect the broker persists (ADR-110 / ADR-128); the model call (OpenRouter, ZDR-pinned) is the only egress. |
The carve seat is config data, not Python (ADR-151), on the same llm.yaml surface
the sibling agents (Mira, Vega) use. Primary google/gemini-2.5-flash-lite +
two different-vendor fallbacks; REGISTRAR_CARVE_MODEL overrides the whole list per
deploy. The eval_candidates.carve pool is what Spike-2643 runs the bakeoff over —
this Story wires the live seat + failover so that bakeoff has a real path to measure.
Offline, no live model, no PDF: the deterministic halves reproduce the hand-verified
NFRA_COMPLAINT_BUNDLE manifest — 1 complaint (pp 1–34) + NFRA/2…NFRA/16
= 16 logical documents, an exhaustive non-overlapping partition of all 307 pages
with none dropped. Scheme detection yields the 16 member starts and rejects a mid-sentence
"Annexure A" mention. The whole run_carve orchestration + the effect are covered
with a stubbed model.
uv run ruff check agents/registrar uv run --package registrar pytest agents/registrar/tests/test_registrar_carve.py -q # live bakeoff harness (needs the gold PDF + OPENROUTER_API_KEY, not a per-PR gate): cd agents/registrar && uv run python -m evals.carve_eval # then the full repository Verify gate from .github/workflows/ci.yml
Focused result: 20 carve tests passed; ruff clean; the error-contract gate green. Gold bundle #1 reproduces the 16-member family and certifies the partition.
In scope: the agents-lane carve engine + the carve runtime mode + the seat. Out of
scope (sibling children): Job 2 (the Card), Indigo, the registrar→blake rename (Chore-2649),
the functions-lane processor.py routing / family fanout, and the Terraform deploy.
The counsel-facing Bundle UX is a separate design track — internal family vocabulary
never surfaces to counsel (Bundle / Main Document / Annexure / Index).