CLAUDE.md and README still asserted a state the code had moved past: - JWT "no revocation (B-34)" — token_version implements exactly that revocation, and the tv-claim behaviour (including why the deploy did not log everyone out) is worth stating instead of denying; - /report-bug "a placeholder" — it shipped fully implemented and translated, with an admin triage section, a reporter-side status view and its own audit event; only /guida is still a stub, and /admin has six sections now, not five; - three stale test counts (CLAUDE.md twice, README once); - a code map missing app/auth/rate_limit.py, app/api/client_ip.py and app/api/routes/bug_reports.py; - README linking flowchart.mmd (the diagrams live in flowchart/), the anchor CLAUDE.md#tech-stack-mvp (gone), and describing docs/running-the-server.md as "local venv vs. Docker" after B-44 made Docker the only supported way to run the server. The rate-limiting bullet the audit also flagged already reads correctly. tests/unit/test_docs_current.py pins all of it: the documented counts must equal what the suite actually collects, the retired claims must stay retired, the code map must name those modules, and every relative README link and CLAUDE.md anchor must resolve. None of this is catchable by reading the code, which is how it drifted in the first place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
"""B-68: CLAUDE.md and README must describe the code as it is now.
|
|
|
|
The audit found both files still asserting things the code had moved past —
|
|
JWT "no revocation" after token_version implemented exactly that, /report-bug
|
|
"a placeholder" after it shipped with admin triage, three stale test counts, a
|
|
code map missing three modules, and README links to a file and an anchor that
|
|
no longer exist. None of that is catchable by reading the code, so it is
|
|
pinned here instead.
|
|
"""
|
|
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
_ROOT = Path(__file__).resolve().parents[2]
|
|
CLAUDE_MD = (_ROOT / "CLAUDE.md").read_text(encoding="utf-8")
|
|
README = (_ROOT / "README.md").read_text(encoding="utf-8")
|
|
|
|
|
|
def _collected_test_count() -> int:
|
|
result = subprocess.run(
|
|
[sys.executable, "-m", "pytest", "--collect-only", "-q"],
|
|
cwd=_ROOT,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=300,
|
|
)
|
|
match = re.search(r"(\d+) tests? collected", result.stdout)
|
|
assert match, f"could not parse the collection summary:\n{result.stdout[-2000:]}"
|
|
return int(match.group(1))
|
|
|
|
|
|
def test_documented_test_counts_match_reality():
|
|
actual = _collected_test_count()
|
|
documented = [int(n) for n in re.findall(r"(\d+) tests\b", CLAUDE_MD)]
|
|
documented += [int(n) for n in re.findall(r"(\d+) unit tests\b", README)]
|
|
assert documented, "no test count found in CLAUDE.md or README — did the wording change?"
|
|
for count in documented:
|
|
assert count == actual, (
|
|
f"docs claim {count} tests, the suite collects {actual} — "
|
|
"update the counts in CLAUDE.md (twice) and README.md"
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"stale",
|
|
[
|
|
"no revocation", # token_version implements it (app/auth/dependencies.py)
|
|
"`/report-bug` are placeholders", # /report-bug shipped, only /guida is a stub
|
|
],
|
|
)
|
|
def test_claude_md_has_no_stale_claims(stale):
|
|
assert stale not in CLAUDE_MD
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"module",
|
|
["rate_limit.py", "client_ip.py", "bug_reports"],
|
|
)
|
|
def test_code_map_covers_every_package_member(module):
|
|
code_map = CLAUDE_MD.split("## Code map", 1)[1].split("## Background tasks", 1)[0]
|
|
assert module in code_map
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"link",
|
|
["(flowchart.mmd)", "CLAUDE.md#tech-stack-mvp"],
|
|
)
|
|
def test_readme_has_no_dead_links(link):
|
|
assert link not in README
|
|
|
|
|
|
def test_readme_relative_links_resolve():
|
|
for target in re.findall(r"\]\(([^)#]+)(?:#[^)]*)?\)", README):
|
|
if target.startswith(("http://", "https://", "mailto:")):
|
|
continue
|
|
assert (_ROOT / target).exists(), f"README links {target}, which does not exist"
|
|
|
|
|
|
def test_claude_md_anchors_into_itself_resolve():
|
|
headings = {
|
|
re.sub(r"[^a-z0-9 -]", "", line.lstrip("# ").lower()).replace(" ", "-")
|
|
for line in CLAUDE_MD.splitlines()
|
|
if line.startswith("#")
|
|
}
|
|
for anchor in re.findall(r"\(CLAUDE\.md#([a-z0-9-]+)\)", README + CLAUDE_MD):
|
|
assert anchor in headings, f"anchor #{anchor} matches no CLAUDE.md heading"
|