[FIX] source_has: close the polarity source_lacks missed (PENDING-180)

PENDING-180's own order — (c) census, (b) counterpart, (a) instance.

The census swept 15 positive-form source assertions across 8 governed scripts
and found exactly one self-planted needle: the one the item filed.
tarbuckle-seam.py:165 searched its OWN source for a string that lives only in
tarbuckle-mumble.py:142, so it could never have found it and could only ever
pass on the copy it had planted in itself. The polarity argument predicted
siblings; there are none. The sweep bounds the problem from below — a needle
assembled from parts inside a defective control is invisible to it.

source_has() joins its needle from parts exactly as source_lacks() does, and
ships with the must-fail arm the negative form has had since it was written.
The seam control is re-aimed at the writer's file and split into two arms that
assert different things, plus S3nn.

Verified by mutation rather than by a green selftest: the repaired control
FAILS on both mutations, the old form PASSES the one that matters. 136 controls
green across the five surfaces.

The first mutation did not fail on its first run. The repair's own explanatory
comment named the truncation literally and planted a contiguous copy in the
file being searched — the bug re-created inside the sentence explaining it.
source_lacks/source_has cover the ASSERTION's needle, never the file; prose can
plant one. Warned at the site, and filed as a separate decidable question.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BsN7nKHjKBsn5bfNRRCNmo
This commit is contained in:
David F Glidden
2026-09-09 21:55:51 +02:00
co-authored by Claude Opus 5
parent bf1bd802a2
commit 049ca57a35
2 changed files with 46 additions and 3 deletions
+27
View File
@@ -191,6 +191,26 @@ def source_lacks(path: str, *parts: str) -> bool:
return "".join(parts) not in open(path, encoding="utf-8").read()
def source_has(path: str, *parts: str) -> bool:
"""True if the joined needle DOES appear in `path`. The positive counterpart.
⚠ THIS IS THE POLARITY `source_lacks()` DOES NOT COVER, AND IT IS THE ONE THAT
HIDES. Both bugs come from writing a needle as a literal, which plants it in the
file being searched. In the NEGATIVE form that makes the control always FAIL —
loudly, so it gets fixed. In the POSITIVE form it makes the control always PASS —
silently, forever. The louder failure got the mechanism first; this is the quieter
one. Assembling from parts is the whole protection, exactly as above.
⚠ WHAT IT STILL CANNOT SEE: whether the code it finds ever RUNS. A source control
is a claim about text, never about behaviour — `tarbuckle-seam.py:165` asserted the
rejection log keeps evidence and did not move when condition G made every rejection
write path inert (15/15 before, 15/15 after). Aim it at the file that holds the
code, and pair it with a behavioural control where activation is the question.
PENDING-180.
"""
return "".join(parts) in open(path, encoding="utf-8").read()
def soul_register() -> str | None:
"""The soul, verbatim, from the filed artifact. None if unreadable."""
try:
@@ -466,6 +486,13 @@ def selftest() -> int:
ck("A4n the predicate can fail",
any(("PENDING" in q) for q in paths + ("/x/PENDING.md",)))
# A10 — the positive-form source predicate, with the arm the negative form has had
# since it was built. A control that cannot be shown to fail is not evidence.
ck("A10 source_has finds a needle that is really there",
source_has(__file__, "def source_", "lacks("))
ck("A10n the predicate can fail",
not source_has(__file__, "def source_", "nowhere("))
for name in checks:
print(f" {'FAIL' if name in failed else 'ok '} {name}")
print(f"{len(checks) - len(failed)}/{len(checks)} controls passed")