The index stops being evidence nobody delivers
analyse_index's only caller was a measurement script, so every
carve ran with index_status="ABSENT" — no cardinality
constraint, no location prior, no cover/index reconciliation — and said so
in a carve log line that reads exactly like an honest no-index bundle. This
change puts the evidence on the wire as
RegistrarCarveInput.index.
The seam, and why the ORDER is the whole change
document_pages_v2 rows (persisted — blocks[].cells intact)
│
├─► carve_index_evidence(rows) ──► input.index ← analysed HERE
│ cardinality · identities · printed_range + pdf_range · anomalies
│
└─► wire_page(row) ─────────────► input.pages
block_index · text · kind · confidence ← cells DROPPED (Bug-3433)
wire_block drops cells by measurement (Bug-3433:
keeping the full block record took the 432-page packet from +17% to +61%).
The index tables live in exactly those cells, and analyse_index
reads nothing else. Analysed one line later — after the strip rather than
before it — the function returns UNAVAILABLE for every bundle
that ever existed: no error, no exception, no failed test, and a log line a
reviewer would read as correct. One list_card_pages read
produces both outputs, so the spine and the index can never describe two
different extractions.
UNAVAILABLE is a value, not an omission
| Bundle | input.index | Combiner |
|---|---|---|
| Indexed paperbook | status="AVAILABLE", cardinality, identities, both coordinate systems |
index_status=AVAILABLE; cardinality constraint and location prior active |
| No index page | status="UNAVAILABLE" carrying the analyser's reason |
index_status=UNAVAILABLE; index_location_prior named as an unavailable detector |
An empty identities list under AVAILABLE would tell
the combiner this bundle HAS no annexures — a claim the broker is not
entitled to make. The founder ruling on Spike-3447 holds throughout: the
cover is authoritative for a member's IDENTITY, the index for CARDINALITY,
and a disagreement is flagged in both directions, never silently resolved.
Proven against the brain, not against a mock
Byte-parity on tests/vendor/ proves the vendored copies match
pramaan-agents; it does not prove the broker's output parses under them.
Treating those as one claim is how every carve invoke since 2026-08-02 was
refused while both repos stayed green (Bug-3491). So
tests/unit/shared/context/test_carve_index_wire.py takes what
build_carve_invoke_payload actually emits and pushes it through
the REAL CarveIndexEvidence, the REAL AnchoredPage,
and the REAL analyze_boundaries — asserting on the combiner's
own index_status. Parsing is necessary and not sufficient: a
payload can validate and still leave the combiner unconstrained.
agents/registrar/boundary.py is vendored for this and pinned
byte-for-byte by the renamed Carve contract parity (pramaan-agents)
job, which now guards both halves of one lane — the carve INPUT contract and
the carve DROP contract — with per-file remediation, so a boundary drift no
longer reports under a message about member numbering.
Red first — three planted negatives, three different failures
| Planted defect | What goes red |
|---|---|
Drop "index": index from the payload |
3 failed — the two round-trip cases and the combiner case |
| Analyse the wire pages instead of the persisted rows | 1 failed — test_the_spine_loader_analyses_the_persisted_rows_not_the_wire |
Report a missing index as an empty AVAILABLE |
3 failed — including ..._never_an_empty_identity_list |
What did not change
No migration, no route, no DTO, no new cloud capability, no IAM. The field is
additive and optional brain-side, so a pre-wire runtime ignores it and a
wired one constrains the combiner — a broker/brain deploy in either order is
safe. The broker's own bundle_trigger.carve_invoked line now
carries index_status and index_cardinality: read
beside the combiner's report, a disagreement between the two is the only way
to tell "no index in the bundle" from "the index never crossed the wire".