R-422: reuse_refs_check checks .md citations too

PATH_RE gains .md. The false-positive walk across all four repos found one: an audit document cited
by app-catalog's REUSE.md, hidden by the evidence-copy exclusion — excluded trees are now walked for
.md documents only, so a .go evidence copy there still never satisfies a citation. The KNOWN HOLE
decoy now expects a conviction.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-05 21:37:22 +02:00
parent 7ee00d59a8
commit bf1798479d
3 changed files with 54 additions and 14 deletions
+23 -5
View File
@@ -37,13 +37,21 @@ scripts/test_reuse_refs_check.py: a citation that exists nowhere still FAILS.
"""
import io, os, re, sys
# path-looking tokens ending in a checked extension; globs (*) are conventions, not refs
PATH_RE = re.compile(r'[A-Za-z0-9_][A-Za-z0-9_./\-]*/[A-Za-z0-9_./\-]*\.(?:go|py|html|css|yml|yaml|sh)\b')
# path-looking tokens ending in a checked extension; globs (*) are conventions, not refs.
# R-422: `.md` joined the list — a rotted document citation was invisible (measured 2026-09-01:
# `documentation/architecture/99-does-not-exist.md` passed). The false-positive walk across all four
# repos found ONE: an audit document, which the evidence-copy exclusion below hid. See DOC_EXT.
PATH_RE = re.compile(r'[A-Za-z0-9_][A-Za-z0-9_./\-]*/[A-Za-z0-9_./\-]*\.(?:go|py|html|css|yml|yaml|sh|md)\b')
# An EVIDENCE COPY of a file is not the file — never let an audit or a test-findings tree satisfy
# a citation. `.git`/`vendor`/`node_modules` are excluded as noise.
EXCLUDE_NAMES = {".git", "node_modules", "vendor", "audits"}
EXCLUDE_RELPATHS = {"documentation/tests"}
# R-422: the exclusion exists so an evidence COPY of a code file cannot satisfy a citation. A document
# under audits/ or documentation/tests is not a copy of anything — it is the cited thing — so `.md`
# files in the excluded trees ARE indexed (and only they). `.git`/`vendor`/`node_modules` stay out.
DOC_EXT = ".md"
NEVER_WALK = {".git", "node_modules", "vendor"}
fails = 0
_index_cache = {}
@@ -57,14 +65,24 @@ class RepoIndex(object):
self.name = os.path.basename(root)
self.files = set() # posix-style relpaths
self.by_base = {} # basename -> [relpath, ...]
doc_only = set() # excluded trees, walked for .md documents only
for dirpath, dirs, filenames in os.walk(root):
rel = os.path.relpath(dirpath, root).replace(os.sep, "/")
if rel == ".":
rel = ""
dirs[:] = [d for d in dirs
if d not in EXCLUDE_NAMES
and ((rel + "/" + d).lstrip("/") not in EXCLUDE_RELPATHS)]
doc_only_here = any(rel == d or rel.startswith(d + "/") for d in doc_only)
keep = []
for d in dirs:
if d in NEVER_WALK:
continue
drel = (rel + "/" + d).lstrip("/")
if d in EXCLUDE_NAMES or drel in EXCLUDE_RELPATHS:
doc_only.add(drel) # walked for documents only (R-422)
keep.append(d)
dirs[:] = keep
for fn in filenames:
if doc_only_here and not fn.endswith(DOC_EXT):
continue
p = (rel + "/" + fn).lstrip("/")
self.files.add(p)
self.by_base.setdefault(fn, []).append(p)