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.