[FIX] Addendum-1: make the central claim checkable; add containment proof
Two defects in the addendum as first filed, both found by checking rather than by reading. First, it asserted a set comparison over documents the jurist cannot read. Its own header promises every clause reasoned about is quoted verbatim, but the claim the addendum rests on -- mutual divergence in 3 of 3 comparable pairs -- was a summary of the executor's own analysis. The appendix now reproduces one pair as an eleven-row side-by-side of extracted claims, verbatim where quoted, so the comparison can be checked independently. The pair chosen is the least confounded rather than the most favourable: the v1 standard prompt is model-agnostic and needs no compressed variant, so both parties demonstrably read the same file. What the jurist still cannot check is stated explicitly. Second, Part E rendered a bullet list from the 2025-01-20 source as running prose with terminal periods the source does not contain, inside a blockquote. A blockquote asserts verbatim. Same family as the truncation that closed a sentence with an invented word on 2026-08-01, and again caught mechanically. Corrected in all three files where it appeared; the fabricated period is now a positive control, so the instrument proves it catches this defect. check_containment.py generalises the check that found it. Positive controls are mandatory -- it exits non-zero if none are declared, because a check reporting all-pass without them cannot be distinguished from one unable to detect absence. Addendum-1 now carries its result: 28/28 contained, 5/5 controls absent. Not filed as satisfying PENDING-86 option (b), which is unruled and concerns whether such a proof should be REQUIRED of every package. This is the executor checking its own work before filing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuMjg3ipEVa3n8CoSzoyvc
This commit is contained in:
co-authored by
Claude Opus 5
parent
7e19eb51d7
commit
bdf24c044b
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Verbatim containment check for jurist packages.
|
||||
|
||||
The packages in this directory are written for a jurist with NO repository access,
|
||||
under a contract stated in their own headers: "every clause reasoned about is quoted
|
||||
verbatim". That contract is only worth what a mechanical check makes it worth. Reading
|
||||
does not catch a fabricated terminal period, an elision presented as contiguous, or a
|
||||
truncation that closes a sentence with a word the source does not contain — all three
|
||||
have occurred in packages from this directory, and all three were caught by a check
|
||||
like this one rather than by careful reading.
|
||||
|
||||
Every run carries POSITIVE CONTROLS: near-miss strings that must be absent. If a control
|
||||
is found, the instrument is not discriminating and its passes mean nothing. An absence
|
||||
is not evidence until the instrument is shown capable of detecting presence.
|
||||
|
||||
USAGE
|
||||
./check_containment.py manifest.json
|
||||
|
||||
MANIFEST
|
||||
{
|
||||
"sources": {"key": "/abs/path/to/source", ...},
|
||||
"claims": [["key", "quoted text"], ...],
|
||||
"controls": [["key", "near-miss that MUST be absent"], ...]
|
||||
}
|
||||
|
||||
EXIT
|
||||
0 all claims contained, no control leaked
|
||||
1 a claim is not contained
|
||||
2 a control leaked — instrument not verified, result unusable
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import unicodedata
|
||||
from pathlib import Path
|
||||
|
||||
# Typographic normalisation. Quotation is compared on content, not on which flavour of
|
||||
# apostrophe an editor inserted — but NOT on punctuation the source does not contain.
|
||||
_SUBS = [
|
||||
("‘", "'"), ("’", "'"),
|
||||
("“", '"'), ("”", '"'),
|
||||
("—", "-"), ("–", "-"), ("‑", "-"),
|
||||
(" ", " "),
|
||||
]
|
||||
|
||||
|
||||
def norm(s: str) -> str:
|
||||
s = unicodedata.normalize("NFKC", s)
|
||||
for a, b in _SUBS:
|
||||
s = s.replace(a, b)
|
||||
return re.sub(r"\s+", " ", s).strip().lower()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit(__doc__)
|
||||
manifest = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
||||
|
||||
bodies = {}
|
||||
for key, path in manifest["sources"].items():
|
||||
p = Path(path).expanduser()
|
||||
if not p.is_file():
|
||||
sys.exit(f"FATAL: source '{key}' not found: {p}")
|
||||
bodies[key] = norm(p.read_text(encoding="utf-8"))
|
||||
|
||||
def contained(key: str, quote: str) -> bool:
|
||||
if key not in bodies:
|
||||
sys.exit(f"FATAL: claim references undeclared source '{key}'")
|
||||
return norm(quote) in bodies[key]
|
||||
|
||||
print("QUOTED CLAIMS")
|
||||
failures = []
|
||||
for key, quote in manifest["claims"]:
|
||||
ok = contained(key, quote)
|
||||
if not ok:
|
||||
failures.append((key, quote))
|
||||
print(f" {'PASS' if ok else 'FAIL'} [{key}] {quote[:70]}")
|
||||
print(f"\n {len(manifest['claims']) - len(failures)}/{len(manifest['claims'])} contained\n")
|
||||
|
||||
print("POSITIVE CONTROLS (must all be absent)")
|
||||
leaked = []
|
||||
for key, quote in manifest.get("controls", []):
|
||||
ok = contained(key, quote)
|
||||
if ok:
|
||||
leaked.append((key, quote))
|
||||
print(f" {'LEAKED' if ok else 'absent'} [{key}] {quote[:70]}")
|
||||
|
||||
if not manifest.get("controls"):
|
||||
print("\nINSTRUMENT NOT VERIFIED — no positive controls declared.")
|
||||
sys.exit(2)
|
||||
|
||||
if leaked:
|
||||
print(f"\nINSTRUMENT NOT VERIFIED — {len(leaked)} control(s) leaked. Passes above are meaningless.")
|
||||
sys.exit(2)
|
||||
|
||||
print("\nINSTRUMENT VERIFIED")
|
||||
if failures:
|
||||
print(f"CONTAINMENT FAILED — {len(failures)} quoted claim(s) not found verbatim in the named source.")
|
||||
sys.exit(1)
|
||||
print("CONTAINMENT PASSED")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user