"""Audit a stoplist for entries that are actually CHARACTERS. ⭐ WHY THIS IS A SEPARATE INSTRUMENT. A stoplist entry is an assertion the leak gate can no longer check. Stoplisting a surface removes it from the entity map, so rename never touches it and the gate never scans for it — which is exactly what a stoplist is FOR when the surface is a real-world referent, and exactly how a wrongly stoplisted CHARACTER becomes an undetectable leak. The gate will report 0 of N surviving and be telling the truth about the set it was given. Found on lv-bronte 2026-09-16, and found by luck: a generated beat said "Mrs. Leaven", and `Leaven` had been filed under scripture (the bread noun). Reading it back: "Robert Leaven, the coachman" — Bessie's married surname. Running this audit instead of trusting the luck then caught two more, `Pierrot` ("Madame Pierrot: she comes from Lisle") and `Samuel` ("Mr. Samuel Wynne"), and correctly cleared `Wellington` ("that Baal of a Lord Wellington" — the real Duke). THE SIGNAL: an honorific in front of it. Real-world referents are not addressed as Mr/Mrs/Miss/Madame/Lord. It is a heuristic, not a proof — `Lord Wellington` is a real person and `Rev. Moses Barraclough` is a genuine dual-use — so every hit is REPORTED FOR READING, never auto-removed. Deciding what a surface is requires reading it in context, which is the lesson this whole line keeps relearning. Exit 1 when anything is flagged, so it can gate a pipeline: a clean run is silence. """ from __future__ import annotations import argparse, json, re from pathlib import Path HONORIFIC = (r"(?:Mr|Mrs|Miss|Misses|Madame|Mdlle|Mademoiselle|Monsieur|Lord|Lady|Sir|Dr" r"|Doctor|Captain|Colonel|Major|General|Aunt|Uncle|Rev|Reverend|Professor" r"|Master|Saint|St)\.?\s+") def load_text(corpus: Path) -> str: man = json.loads((corpus / "manifest.json").read_text()) parts = [] for w in man["works"]: for line in (corpus / w["path"]).read_text(encoding="utf-8").splitlines(): if line.strip(): parts.append(json.loads(line)["text"]) return "\n\n".join(parts) def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("corpus") ap.add_argument("--stoplist", required=True) ap.add_argument("--allow", default="", help="comma-separated surfaces already READ and confirmed real-world " "or accepted dual-use; they are still shown, but do not fail the run") ap.add_argument("--context", type=int, default=46) a = ap.parse_args() text = load_text(Path(a.corpus)) blob = json.loads(Path(a.stoplist).read_text()) # ⚠ SKIP `_`-PREFIXED KEYS. By convention a stoplist carries its rationale in `_why` and # `_caught_by_reading_in_context`, and `_why` is a LIST OF PROSE LINES. Scanning it as # surfaces put every sentence of the rationale into the matcher, and its empty separator # line matched the honorific pattern 139 times on McCarthy -- a flag with no surface name # attached, at the top of the report, above the one real catch. A metadata key is not a # surface set; found 2026-09-17 and latent for every corpus before it. surfaces = sorted({s for k, v in blob.items() if not k.startswith("_") and isinstance(v, list) for s in v if s}) cleared = {s.strip() for s in a.allow.split(",") if s.strip()} flagged = [] for s in surfaces: pat = re.compile(HONORIFIC + re.escape(s) + r"\b") hits = list(pat.finditer(text)) if hits: flagged.append((len(hits), s, hits[0])) print(f" {len(surfaces)} stoplisted surfaces scanned for a preceding honorific") if not flagged: print(" [PASS] none of them is ever addressed as a person") return 0 unresolved = 0 for n, s, m in sorted(flagged, reverse=True): mark = "cleared" if s in cleared else "⚠ READ THIS" if s not in cleared: unresolved += 1 ctx = text[max(0, m.start() - a.context): m.end() + a.context].replace("\n", " ") print(f" {mark:<12} {s:<16} {n:>4} honorific hits …{ctx}…") if unresolved: print(f"\n== {unresolved} stoplisted surface(s) look like PEOPLE and are not on --allow.") print(" Read each in context. If it is a character, take it OUT of the stoplist and") print(" re-run the rename — the leak gate cannot see it while it is stoplisted.") return 1 print("\n [PASS] every honorific hit is on the read-and-cleared list") return 0 if __name__ == "__main__": raise SystemExit(main())