Skip to content

v1.108.166 — absence evidence: cite a zero-result scan as proof (#377 phase 3)

Choose a tag to compare

@jgravelle jgravelle released this 24 Jul 03:49

Added

A zero-result search can now be cited as evidence in a handoff (#377 phase 3, proposed by @mightydanp).

Under v1 and v2 it could not: nothing was served, so there was no id to
reference. But "we searched the complete, fresh, non-truncated index and it is
not there" is exactly the claim an audit most needs attested, and the one
agents most often assert with no proof at all.

No new retrieval machinery was needed. build_verdict already reports a state
(ok / low_confidence / absent / degraded), the scan counts backing it,
per-channel status, coverage, and a scorer pin. A search whose verdict is
absent now carries _meta.verdict.evidence_ref; passing that ref to
finalize_handoff attests the absence. The server hands you the token, you
cite it back, exactly as symbol evidence already works.

The refusal rules are the feature, and they are strict. Only absent
proves absence. low_confidence and degraded do not, because a weak or
partial scan is not evidence of nothing. A stale index does not, because it
describes an older tree than the one being audited. A truncated index does
not, because the target may sit in the files the walk dropped. These are the
safety rules from the proposal, adopted as written.

A refused scan is still recorded, so citing one returns the reason rather than
a bare unknown-ref error, and a search that is absent but not citable says so
in-band (absence_citable: false, absence_blocked_by) instead of offering a
token that would fail later.

The rendered proof is the auditable part. The body carries the tool and query,
the scope it was not found in, how many symbols and files were scanned, the
channel status, the coverage with its exclusion counts and generation SHA, and
the scorer version. Unknown coverage renders as "not recorded for this index
(scope unknown)" and is never presented as a complete scope.

Refs are content-addressed over (tool, repo, query, scope), so the same scan
in the same scope is the same proof and a narrowed scope is a different one.
Session-scoped and in-memory, capped, never written to disk. The receipt gains
absence_attested when an absence ref is cited.

New tests/test_v1_108_166.py (23), one per refusal rule. No new tool, no
schema or tool-count change, core_compact unchanged at 3996, no
INDEX_VERSION bump. Suite 5618.

Suite parity: jdocmunch-mcp v1.117.0. jdatamunch-mcp is pending a product
decision, since its verdict does not track index freshness and the stale gate
cannot fire there. #377 stays open; phases 2 and 4 remain deferred.