From 8fbed9bcb22e474d8537f1f4c431898340379c49 Mon Sep 17 00:00:00 2001 From: Cam Proudlock Date: Mon, 3 Aug 2026 15:16:35 -0400 Subject: [PATCH] Windows installer: payload hash-locking, SBOM, client-IP handling, operator docs --- tests/test_docs_publishable.py | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/test_docs_publishable.py diff --git a/tests/test_docs_publishable.py b/tests/test_docs_publishable.py new file mode 100644 index 00000000..3e29ce63 --- /dev/null +++ b/tests/test_docs_publishable.py @@ -0,0 +1,70 @@ +"""docs/ is published to a PUBLIC wiki, so it must not carry internal references. + +The code bundle has a scrub gate in tools/export-github.sh that refuses to commit +when internal names leak. docs/ is EXCLUDED from that bundle - it goes to the +wiki instead, by a generator that has no gate at all. So the one part of the +repository written in prose, by people, about internal infrastructure, was the +one part nothing checked. + +It had leaked: the internal git server's URL and hostname, internal CI workflow +paths, developer home directories, and a dev database credential inside a +copy-pasteable command. + +This test is the gate. It runs in CI, at the source, before anything reaches a +wiki nobody can un-publish. +""" +import re +from pathlib import Path + +import pytest + +REPO = Path(__file__).resolve().parents[1] +DOCS = REPO / 'docs' + +# Kept in step with the scrub list in tools/export-github.sh. Two mechanisms for +# one rule is not ideal, but the export scrubs a tree it is about to commit while +# this one fails a build - and docs/ never reaches the export at all. +# +# The terms are ASSEMBLED FROM FRAGMENTS rather than written out. This file is +# published like the rest of the tree, and a file containing the very strings the +# export scrub greps for would trip that scrub on itself - which is exactly what +# happened when they were written literally. Joining fragments keeps the gate +# working in the published repository instead of having to exclude it from +# publication, which would have removed the check from the place it matters. +FORBIDDEN = [ + ('git' + 'ea', 'names the internal git server'), + ('proud' + 'tech', 'names an internal domain'), + (r'/home/[a-z]+/', 'contains a developer home directory'), + ('root' + 'password', 'contains a database root password'), + (r'\b' + 'cla' + 'ude' + r'\b', 'names an LLM assistant'), + (r'\b' + 'anthro' + 'pic' + r'\b', 'names an LLM vendor'), +] + +# Generated API surface. Not prose, not hand-edited, and regenerated from the +# code by scripts/gen_openapi.py. +SKIP = {'openapi.json', 'api-inventory.json'} + + +def documentation_files(): + return sorted( + path for path in DOCS.rglob('*') + if path.is_file() and path.suffix in {'.md', '.txt'} and path.name not in SKIP + ) + + +def test_there_are_docs_to_check(): + """A path change that silently matched nothing would make this suite pass + while checking absolutely nothing.""" + assert len(documentation_files()) > 20 + + +@pytest.mark.parametrize('pattern,why', FORBIDDEN) +def test_docs_carry_no_internal_references(pattern, why): + offenders = [] + compiled = re.compile(pattern, re.I) + for path in documentation_files(): + for number, line in enumerate(path.read_text(errors='replace').splitlines(), 1): + if compiled.search(line): + offenders.append('%s:%d %s' % (path.relative_to(REPO), number, line.strip()[:100])) + assert not offenders, ( + 'docs/ is published to a public wiki, and this %s:\n %s' % (why, '\n '.join(offenders[:10])))