diff --git a/changelog.d/tsk-2k55kq-witness-gate-near-miss-hardening.md b/changelog.d/tsk-2k55kq-witness-gate-near-miss-hardening.md new file mode 100644 index 00000000..78100372 --- /dev/null +++ b/changelog.d/tsk-2k55kq-witness-gate-near-miss-hardening.md @@ -0,0 +1,8 @@ +### Fixed +- Tightened the witness-gate near-miss detector so ordinary prose that merely + mentions WITNESS (without the ``::`` payload) is no longer flagged, while + de-marked (zero-width) and malformed markers still are. +- Replaced the file-level de-marked-marker exemption in the gate with a + line-level one, so a genuine de-marked marker appended to + ``scripts/check_witness_token.py`` is reported while its three documented + docstring examples are not. diff --git a/scripts/check_witness_token.py b/scripts/check_witness_token.py index 80b1e345..6f9988c7 100644 --- a/scripts/check_witness_token.py +++ b/scripts/check_witness_token.py @@ -63,11 +63,17 @@ _REPO_ROOT = Path(__file__).resolve().parent.parent REPO_ROOT = Path(os.environ.get("WITNESS_GATE_ROOT") or _REPO_ROOT) WITNESS_RE = re.compile(r"#\s*WITNESS:\s*(.+)$") -_NEAR_MISS_RE = re.compile(r"#\s*WITNESS[^:]") -# Files whose docstrings contain de-marked illustrative examples. Greppable name. -_DEMARKED_MARKER_EXEMPTION = frozenset({ - "scripts/check_witness_token.py", -}) +# A near-miss resembles a WITNESS marker whose separator is broken -- a +# zero-width character (e.g. U+200B) lodged between WITNESS and the colon, +# or the colon replaced. Requiring the ``::`` payload keeps ordinary prose +# mentioning WITNESS from being mistaken for a malformed marker. +_NEAR_MISS_RE = re.compile(r"#\s*WITNESS[^:](?=.*::)") +# Documented examples of a de-marked marker in this file's own docstring. +# They are intentionally de-marked and must not be reported; every other line +# in the same file (e.g. an appended genuine marker) still is. Greppable name. +_DEMARKED_MARKER_EXEMPTION = { + "scripts/check_witness_token.py": frozenset({4, 19, 36}), +} @dataclass @@ -120,14 +126,15 @@ def _extract_claims(file_path: Path, repo_root: Path) -> list[WitnessClaim]: def _check_near_misses(file_path: Path, repo_root: Path) -> list[Violation]: rel = _relative_source(file_path, repo_root) - if rel in _DEMARKED_MARKER_EXEMPTION: - return [] + exempt_lines = _DEMARKED_MARKER_EXEMPTION.get(rel, frozenset()) try: source = file_path.read_text(encoding="utf-8") except (OSError, UnicodeDecodeError): return [] violations: list[Violation] = [] for lineno, line in enumerate(source.splitlines(), start=1): + if lineno in exempt_lines: + continue if _NEAR_MISS_RE.search(line): claim = WitnessClaim( source_file=rel, line_number=lineno, raw=line.strip() diff --git a/tests/test_witness_gate.py b/tests/test_witness_gate.py index e389364b..f89859e1 100644 --- a/tests/test_witness_gate.py +++ b/tests/test_witness_gate.py @@ -332,6 +332,73 @@ def test_near_miss_in_scripts_detected(self, tmp_path): rc, out = _run_main(repo) assert rc == 1 + def test_near_miss_regex_spares_prose_arms(self, tmp_path): + # WEAKNESS 1: a tightened near-miss regex must not flag ordinary prose + # that merely mentions WITNESS, while still catching de-marked (ZWSP) + # and malformed markers. All three arms live in one test so a loosening + # that silences the prose cannot silence the de-marked arms either. + # Arm A -- prose in taosmd/ mentioning WITNESS but no ``::`` is clean. + repo = _repo(tmp_path / "a") + _write(repo, TEST_TEST, GREEN_TEST) + _write( + repo, + "taosmd/p.py", + "# WITNESS markers are validated by the gate.\nVALUE = 1\n", + ) + assert check_witnesses(repo) == [] + rc, _out = _run_main(repo) + assert rc == 0 + + # Arm B -- de-marked example (ZWSP) in taosmd/ still exits 1. + repo = _repo(tmp_path / "b") + _write(repo, TEST_TEST, GREEN_TEST) + _write(repo, TEST_SRC, f"# WITNESS\u200b: {TEST_TEST}::{TOKEN}\n") + violations = check_witnesses(repo) + assert len(violations) == 1 + assert violations[0].reason == "de-marked or malformed marker" + rc, _out = _run_main(repo) + assert rc == 1 + + # Arm C -- de-marked example (ZWSP) in scripts/ still exits 1. + repo = _repo(tmp_path / "c") + _write(repo, TEST_TEST, GREEN_TEST) + _write(repo, SCRIPTS_SRC, f"# WITNESS\u200b: {TEST_TEST}::{TOKEN}\nVALUE = 1\n") + violations = check_witnesses(repo) + assert len(violations) == 1 + assert violations[0].claim.source_file == "scripts/gate_demo.py" + assert violations[0].reason == "de-marked or malformed marker" + rc, _out = _run_main(repo) + assert rc == 1 + + def test_gate_does_not_swallow_appended_near_miss(self, tmp_path): + # WEAKNESS 2: the gate's own docstring examples are exempted line by + # line, so a genuine de-marked marker appended to a copy of the gate is + # still reported. The unmodified gate copy must remain clean. + repo = _repo(tmp_path) + _write(repo, TEST_TEST, GREEN_TEST) + gate_copy = _write( + repo, + "scripts/check_witness_token.py", + GATE_SCRIPT.read_text(encoding="utf-8"), + ) + assert check_witnesses(repo) == [] + rc, _out = _run_main(repo) + assert rc == 0 + + appended = gate_copy.read_text(encoding="utf-8") + appended += f"# WITNESS\u200b: {TEST_TEST}::{TOKEN}\n" + gate_copy.write_text(appended) + violations = check_witnesses(repo) + near = [ + v for v in violations + if v.reason == "de-marked or malformed marker" + ] + assert len(near) == 1 + assert near[0].claim.source_file == "scripts/check_witness_token.py" + rc, out = _run_main(repo) + assert rc == 1 + assert "de-marked or malformed marker" in out + # ---------------------------------------------------------------------- # CLI subprocess tests: prove the real script exit codes (Layer A path)