112 โ One quote resolver for grounding and analysis evidence
Type: reference/types/adr.md ยท Status: accepted
Status: accepted Date: 2026-10-06 Extends: ADR 072 and ADR 073, whose local-bytes policy now also governs analysis evidence; ADR 111, whose boundary member supplies the analysis pin.
Context
Two paths resolved the same kind of citation: a blockquote with a > ---
attribution, matched once within its range. Ingest validation resolved
## Quotes extracts against the name-paired snapshot pinned by
snapshot_sha256, and reported missing bytes as unverified. Analysis code
resolved member quotations against the frozen source recorded in run state,
only during a run and at run-state completion. Standing validation of an
analysis set checked quotation form and nothing else, because the frozen
checkout lives outside the KB on the machine that ran the analysis.
ADR 111 made the boundary a member whose source declares the frozen
checkout or capture, so the set itself now carries its pin.
Decision
One resolver, resolve_citations in commonplace.lib.quote_grounding,
resolves citations against a pinned source with three implementations: an
ingest snapshot pinned by checksum, a Git checkout pinned at a commit, and a
capture file pinned by digest. Each citation resolves to match, mismatch
(the attribution does not name the pin, or the quote is absent, ambiguous or
outside its range) or unverified (the pinned bytes are not here).
A Git pin reads files from the recorded checkout itself, not from the object store. Freezing leaves the checkout exactly at the frozen commit; the resolver confirms once that HEAD is that commit and nothing is changed, and otherwise treats the pinned bytes as absent. A checkout that is missing, at another commit or locally edited therefore makes quotations unverified, and a cited path missing from a confirmed checkout is a mismatch.
The analysis set rule resolves every member's quotations against the
boundary's source. Standing validation reports unverified quotations once
per member as information, as it does for ingest extracts. The analysis
workflow holds the source, so its acceptance treats the same finding as a
refusal; it no longer reads run state to resolve quotations, and run-state
completion relies on set validation for them. Run state still requires its
frozen source to be present.
Considered alternatives
Fail standing validation when the frozen checkout is missing. Retained sets would fail on every machine but the one that ran them, which ADR 072 already rejected for ingest snapshots.
Store analysis sources as KB ingests with snapshots. A checkout at a commit is many files, not one snapshot; one resolver interface over distinct pins keeps both shapes without converting either.
Read each cited file from the commit with git cat-file. It tolerates a
checkout at another commit or with local edits, which no workflow produces,
at the cost of one Git process per citation on every validation.
Keep a run-state path for analysis quotations. It would leave standing validation and draft feedback without quotation checks, and two resolvers whose messages and policies drift.
Consequences
commonplace-validate on an analysis set reports quotation mismatches by
member wherever the frozen source is present, and validating a working
output/ gives analysts the same quotation findings acceptance does.
Reconciliation and overview quotations are now resolved at acceptance and in
standing validation, not only at completion. Messages share one wording, and
ambiguity advice proposing candidate ranges is available to ingest extracts.
A set without a boundary cannot resolve its quotations and fails.