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)
+6 -9
View File
@@ -42,7 +42,7 @@ COVERS = {
"hub-confirm": "a native confirm() in templates/partials/ (scope was os.listdir)",
"manifest-bearer": "a bearer literal in manifests/overlays/ (scope was os.listdir)",
"observations": "R-419: prose SAYING it carries no marker, plus both genuine markers",
"reuse-refs": "a cited .go path that does not exist; the .md hole is asserted as R-422",
"reuse-refs": "a cited .go path, and (R-422) a cited .md path, that does not exist",
"golden-currency": "R-410: an empty directory with a perfect name, checked by what it COUNTED",
"closed-register": ("a verdict cell reading open, a row with no state cell at all, and (RULE 3, "
"2026-10-03) a FINISHED row left in OPEN-ITEMS.md — with R-87's shape, a READY "
@@ -165,20 +165,17 @@ decoy("observations/genuine-NAF", "observations_gate.py",
u"typo, corrected in the same minute.**\n"), args=(ROOT,), expect="accept")
# --- reuse-refs: a cited path that does not exist ----------------------------------------------
# The .go case is REJECTED. The .md case is a KNOWN HOLE (R-422) and is asserted as such below, so
# this file records the hole rather than pretending it is covered.
# Both the .go and (since R-422, 2026-10-05) the .md case are REJECTED.
decoy("reuse-refs/missing-go", "reuse_refs_check.py",
append_to(os.path.join(ROOT, "REUSE.md"),
u"\n- see `hub/internal/api/does_not_exist.go`\n"), args=(ROOT,))
# --- KNOWN HOLE, asserted so it cannot be forgotten (R-422) ------------------------------------
# reuse_refs_check.py's PATH_RE matches only go|py|html|css|yml|yaml|sh. A rotted .md citation is
# invisible. This asserts the CURRENT behaviour so the day it is fixed, this test fails and is
# updated deliberately — a hole that nothing asserts is a hole nobody remembers.
decoy("reuse-refs/missing-md (KNOWN HOLE R-422)", "reuse_refs_check.py",
# R-422 CLOSED THE HOLE this decoy used to assert (expect="accept"): PATH_RE now includes .md, so a
# rotted document citation is convicted. Updated deliberately, as the old comment asked.
decoy("reuse-refs/missing-md (R-422)", "reuse_refs_check.py",
append_to(os.path.join(ROOT, "REUSE.md"),
u"\n- see `documentation/architecture/99-does-not-exist.md`\n"),
args=(ROOT,), expect="accept")
args=(ROOT,))
# --- golden-currency: R-410's own decoy, re-run here so the sweep owns it too ------------------
def _mkdir_decoy():
+25
View File
@@ -155,6 +155,31 @@ class ReuseRefsCheckTest(unittest.TestCase):
self.assertNotEqual(rc, 0, "an audits/ or documentation/tests/ copy must NOT resolve:\n" + out)
self.assertIn("FAILED 2", out)
# ── R-422: document citations are checked ───────────────────────────────────
def test_absent_md_citation_fails(self):
"""The measured hole: a rotted .md citation passed because .md was not a checked extension."""
self.reuse("see `documentation/architecture/99-does-not-exist.md`\n")
rc, out = self.run_check()
self.assertNotEqual(rc, 0, "a .md citation that exists nowhere must fail:\n" + out)
self.assertIn("99-does-not-exist.md", out)
def test_md_citation_resolves_including_under_audits(self):
"""An audit DOCUMENT is the cited thing, not an evidence copy — it must resolve (the one false
positive the 2026-10-05 walk found, in app-catalog's REUSE.md)."""
write(os.path.join(self.root, "documentation", "architecture", "05-hub.md"), "# x\n")
write(os.path.join(self.root, "documentation", "audits", "SPIKE-x.md"), "# y\n")
self.reuse("see `documentation/architecture/05-hub.md` and `documentation/audits/SPIKE-x.md`\n")
rc, out = self.run_check()
self.assertEqual(rc, 0, out)
def test_audits_still_hide_code_copies_when_docs_are_indexed(self):
"""Indexing .md under audits/ must not let a .go evidence copy there resolve."""
write(os.path.join(self.root, "documentation", "audits", "pkg", "x.go"), "package pkg\n")
write(os.path.join(self.root, "documentation", "audits", "pkg", "notes.md"), "# n\n")
self.reuse("see `pkg/x.go`\n")
rc, out = self.run_check()
self.assertNotEqual(rc, 0, out)
# ── a clone in isolation must still check itself ────────────────────────────
def test_no_siblings_is_not_a_failure(self):
write(os.path.join(self.root, "a", "b.go"), "package a\n")