Story-3443 — boundary evidence and a deterministic combiner
Blake's carve used to decide bundle boundaries with a regex over INDEX OF ANNEXURES
and Annexure A. On a hand-verified 629-page arbitration paperbook it missed all three
of the first real boundaries (application ends p57, affidavit p58-59, Annexure A p60) — on entirely
text-native pages, so scan quality explains nothing. This story replaces the gate with scored
evidence and a deterministic combiner.
The governing rule. Candidate discovery is recall-first. Automatic commitment is precision-first. Ambiguous boundaries abstain to review. Until the manifest is confirmed, segmentation is draft and cannot create a durable citation.
The pipeline, in one picture
kind="page_number" blocks — the sequence, not
just the presence), cause-title block, document-type word, text↔image transition, and the
Story-3442 index location prior. Scores are evidence weights — not calibrated
probabilities, and the code says so.
uncertain — no tie-breaker picks a winner and moves on.
split / continue /
uncertain, and uncertain reaches counsel review and never collapses to continue.
How it reaches the model and the record
- The combiner's split/uncertain pages merge into the carve packet as candidates with their
detector scores in
signals(untrusted evidence, inside the nonce fence), plus a code-derived page-number sequence summary — the geometry reaches the model (prompt v3). - Committed splits mint a
boundary_anchor.v1—(page, bounding box, block id, hash of first line), never a character offset (pramaan-io/pramaan-spec#3441) — onto the family member and itssteps/1-carve.jsonrow. Anchors resolve structurally after a re-OCR; a first-line hash mismatch is reported, never silently accepted. - Uncertain pages the model did not confirm, splits the model declined, and every reconciliation
flag become
review_seamson the family. The source PDF is never physically split.
The measurement — against Story-3442's index-alone baseline
Same corpus, same window, model-free: the committed, allowlist-redacted fixture (no client
content) replays the paperbook's structural signals through the production combiner
(uv run python evals/measure_boundary_combiner.py, receipt
docs/measurements/story-3443-boundary-combiner.json).
| Metric | Index-alone baseline (Story-3442) | Combiner (this story) |
|---|---|---|
| Opening counsel-verified seams (pdf 58 affidavit, pdf 60 Annexure A) | P 1.0 · R 0.5 · F1 0.667 — the affidavit is invisible to the index | P 1.0 · R 1.0 · F1 1.0 — cause-title + document-type evidence finds the seam no index row covers |
| 21 index-claimed member starts | 21/21 localized silently — including the B-to-C mislabel | 18/21 committed with zero mislabels; B flagged (its claimed seat holds a cover reading C), E and M3 flagged (no standalone cover located), E2 flagged surplus |
| Ambiguity handling | Resolved silently by coordinate arithmetic | 30 uncertain pages reach review — incl. the M2 colly member's 13 internal foliation restarts, flagged rather than wrongly split |
Honest framing: on index-start coverage the combiner is deliberately more conservative than the baseline — it commits only what physical evidence carries and flags the rest, where the baseline localized all 21 silently and mislabeled one. On the regression the ticket exists for (the opening seams), it beats the baseline outright.
What shipped
agents/registrar/boundary.py— the pure combiner: detectors, page-number sequence, reconciliation, constrained DP, margin routing, boundary anchors.anchor.py— blocks carry the Bug-3433 geometry (kind/confidence/bbox/anchor_id), optional and degrade-honest on a pre-3433 payload.carve.py—RegistrarCarveInput.index(optional Story-3442 evidence), combiner wired intorun_carve; the geometry-less and index-less branches log that they ran.family_models.py—BoundaryAnchor+BundleMember.anchor;carve_drop.py— the anchor rides the step-drop member row.prompts/carve.py— v3: combiner verdicts + sequence summary inside the fence.- 626 offline tests pass (26 new for the combiner, 4 pinning the measurement); ruff clean.
Honest edges
- The
indexinput is optional; the broker wiring that attaches Story-3442'sanalyse_indexoutput to the carve payload is a follow-up ticket in pramaan-functions. Without it the combiner runs unconstrained and says so. - Bug-3433 is in flight: until it merges, production payloads carry no geometry and the page-number sequence and text↔image detectors report UNAVAILABLE (logged, never faked).
- Detector weights are tuning constants, not calibrated probabilities — they are named, and every decision carries the hits that produced it so counsel can audit why it split there.