What
real_targets/quotecheck.py fetches a cited public document and looks for the quoted text, so a pack can say the harness found the quote rather than the target said it did. It lives outside the package and only the three adapters call it. Make it a gate any suite can use.
A case declares verify_quotes: true; the target reports quotes: [{citation, url, text}] (directly or via annotations, see the annotations issue). By default the gate looks quotes up in a committed snapshot directory (--sources-dir) whose manifest records URL, sha256, fetched_at, and the tool used. A separate gauntlet snapshot verb populates that directory over the network, outside CI. --fetch on run is explicit opt-in for live lookups.
Why it matters
The 2026-08-28 correction made unverified quotes leave the accepted context. That rule exists only in the adapters, and a team gating its own feature cannot use it. With a snapshot, the gate is deterministic and offline, which is what a merge gate has to be; an unverifiable quote is reported and excluded, never counted as grounded.
Scope
src/gauntlet/gates/quote_check.py, case fields, and the snapshot manifest format.
gauntlet snapshot --cases DIR --out DIR (network, records tool: stdlib, curl, pdftotext).
- Pack section per quote:
verified, not_found, unverifiable with the reason.
- A paired toy defect (
alter_quote_one_word) so the self-test doctrine covers it.
Out of scope
- Paraphrase judgement; that is the
judge gate.
- Document formats beyond HTML text and
pdftotext output.
Done when
- With a snapshot present the run opens no socket (test blocks
socket.socket) and the toy passes.
- A quote altered by one word fails as
not_found and names the case.
- A missing snapshot entry is
unverifiable, excluded from the pass count, listed in the pack, and a 100% threshold turns the gate red.
gauntlet inventory counts the new gate and the README block regenerates.
Pointers
Proposed with AI assistance.
What
real_targets/quotecheck.pyfetches a cited public document and looks for the quoted text, so a pack can say the harness found the quote rather than the target said it did. It lives outside the package and only the three adapters call it. Make it a gate any suite can use.A case declares
verify_quotes: true; the target reportsquotes: [{citation, url, text}](directly or via annotations, see the annotations issue). By default the gate looks quotes up in a committed snapshot directory (--sources-dir) whose manifest records URL, sha256,fetched_at, and the tool used. A separategauntlet snapshotverb populates that directory over the network, outside CI.--fetchonrunis explicit opt-in for live lookups.Why it matters
The 2026-08-28 correction made unverified quotes leave the accepted context. That rule exists only in the adapters, and a team gating its own feature cannot use it. With a snapshot, the gate is deterministic and offline, which is what a merge gate has to be; an unverifiable quote is reported and excluded, never counted as grounded.
Scope
src/gauntlet/gates/quote_check.py, case fields, and the snapshot manifest format.gauntlet snapshot --cases DIR --out DIR(network, records tool: stdlib,curl,pdftotext).verified,not_found,unverifiablewith the reason.alter_quote_one_word) so the self-test doctrine covers it.Out of scope
judgegate.pdftotextoutput.Done when
socket.socket) and the toy passes.not_foundand names the case.unverifiable, excluded from the pass count, listed in the pack, and a 100% threshold turns the gate red.gauntlet inventorycounts the new gate and the README block regenerates.Pointers
real_targets/quotecheck.py(counts_as_grounded),src/gauntlet/gates/grounding.py,src/gauntlet/gates/base.pysrc/gauntlet/toy/,tests/test_self_test_doctrine.pyProposed with AI assistance.