[FIX] Reduction 02: package reduces to 68.6% — the genre reading confirmed, Reduction 01 corrected
Prediction recorded in Reduction 01 BEFORE this census, so it could fail: the
package's Part I is 'Grounding (quoted verbatim)' and quotes CLAUDE.md directly,
so Q should be non-zero where it was zero. Q=9. D=40, where the ruling had none.
ruling package
sound 8.5% 68.6%
PERFORMATIVE 12 0 <- the genre signature
BLEND 9 25
INHERITED 4 0
UNSOURCED-QUOTE 3 0 <- §1's header clause worked
Genre reading confirmed eightfold: a package proposes, a ruling determines.
CORRECTS Reduction 01's strong conclusion that 'the reduction arm collapses into
the synthetic arm'. On package prose repair touches 31.4%, not 91.5% — reduction,
not authoring, and the two arms stay distinct. That conclusion was correctly
bounded at n=1; the bound was the whole of its content and one document collapsed
it. Reduction 01 now carries the correction inline.
BLEND is now the blocker and is genre-independent: 25 of 33 quarantines, 7 of
them rows of the Part IV table, which pairs a quote with an end-state and a
verdict — three primitives by construction.
Two check findings, one good and one bad:
§3.2 CAUGHT A REAL TAGGING ERROR OF MINE. Unit 145 was tagged Q; it is a sentence
ABOUT a quotation, not a quotation, so not verbatim-as-a-unit. Corrected to D.
The check found it, the reading did not — the 'quoted but not traced' defect the
jurist caught on 2026-07-19, mechanised.
§3.3 GAVE A FALSE PASS, found by looking. Part VII 'Disconfirming evidence' IS a
collected limitations section under §2a — the exact section trial 03 showed the
model skipping wholesale — and the screen missed it because it never says
'limitations'. Widened; the package now correctly FAILS §3.3. But no pattern can
decide this: a section titled only 'Part VII' defeats any wordlist, and a control
now asserts that. §3.3 is a SCREEN, not a decision; §2a belongs in §4's judgement
residue. Fourth time in three days a passing check certified the code while the
property failed, and the fourth found by a person looking.
A=0 IN BOTH DOCUMENTS, and it is the same fact as the §2a failure seen from the
other side: we do not name assumptions inline, we collect them into a section.
Our best governance prose is written in exactly the shape that defeats the reader
the section was written for.
Also fixed: the tool was still printing 'NOT checked here: §3.2' after §3.2 was
implemented — under-claiming, but still a false statement about what ran.
Kernel v1.1 candidates are now evidence-backed and remain UNAPPLIED; v1.0 stays
frozen and a revision is a new experiment. The false-positive control remains
unrun and neither reduction produced a usable control document.
This commit is contained in:
@@ -46,7 +46,15 @@ from pathlib import Path
|
||||
# (c) a `?` inside a quotation split a sentence mid-clause, yielding a FRAGMENT
|
||||
# ("…asserts to be true?" | "alone — is less safe…"). Tagging a fragment is
|
||||
# meaningless, so it must not be produced.
|
||||
SPLITTER_VERSION = "1.1.0"
|
||||
# 1.2.0 — two further defects, again found by contact rather than review, this
|
||||
# time on a package rather than a ruling:
|
||||
# (d) a numbered marker ("**1.", "2.") was read as a sentence end, orphaning the
|
||||
# marker as a fragment and decapitating the sentence after it.
|
||||
# (e) YAML frontmatter was treated as flowing prose and shredded mid-key
|
||||
# (`…quoted verbatim below." status: "DRAFT.`). Frontmatter is line-oriented.
|
||||
# It stays TAGGABLE — it carries real assertions about the document, and
|
||||
# excluding it would quietly shrink the quarantine in the author's favour.
|
||||
SPLITTER_VERSION = "1.2.0"
|
||||
|
||||
KERNEL_SHA256 = "67c9b870491db7444e98b680c7c80dcd99de376dda09b3e1758b27b1229ab045"
|
||||
|
||||
@@ -81,8 +89,21 @@ QUARANTINE_REASONS = {
|
||||
}
|
||||
|
||||
# Kernel §3.3 — a control document may not collect its caveats into a section.
|
||||
# Widened after a FALSE PASS on a real package: "Part VII — Disconfirming
|
||||
# evidence, which the steward specifically asked to be carried" is a collected
|
||||
# limitations section in §2a's sense — trial 03 showed the model skipping exactly
|
||||
# that section wholesale — and the original pattern did not match it because it
|
||||
# never says "limitations".
|
||||
#
|
||||
# THIS CHECK IS A SCREEN, NOT A DECISION. No pattern can decide whether a section
|
||||
# collects the author's own caveats; a section titled "Part VII" alone would defeat
|
||||
# any wordlist. §2a compliance therefore belongs in Kernel §4's judgement residue,
|
||||
# and a pass here means only that the obvious namings were absent.
|
||||
FORBIDDEN_HEADING_RE = re.compile(
|
||||
r"limitation|caveat|assumption|what this does not|open question", re.IGNORECASE
|
||||
r"limitation|caveat|assumption|what this does not|open question"
|
||||
r"|disconfirming|evidence against|weakness|objection|counter-?argument"
|
||||
r"|self-?critique|known (?:issue|gap|problem)|shortcoming|scope boundary",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
# Abbreviations after which a period does NOT end a sentence. Deliberately short:
|
||||
@@ -108,6 +129,25 @@ def _is_abbrev(text: str, dot_index: int) -> bool:
|
||||
return text[start:dot_index].rstrip(".") in ABBREVIATIONS
|
||||
|
||||
|
||||
def _is_enumerator(text: str, dot_index: int) -> bool:
|
||||
"""
|
||||
True if the period at dot_index closes a numbered marker such as `1.` or
|
||||
`**2.` rather than a sentence.
|
||||
|
||||
Deliberately narrow: at most two digits, and nothing before them on the line
|
||||
except markdown emphasis or whitespace. A bare numeric token is NOT enough —
|
||||
"…formalized in 2026. The next…" is a real boundary and must stay one.
|
||||
"""
|
||||
start = dot_index
|
||||
while start > 0 and text[start - 1].isdigit():
|
||||
start -= 1
|
||||
digits = text[start:dot_index]
|
||||
if not (1 <= len(digits) <= 2):
|
||||
return False
|
||||
line_start = text.rfind("\n", 0, start) + 1
|
||||
return text[line_start:start].strip(" \t*_>#") == ""
|
||||
|
||||
|
||||
def split_prose(block: str, offset: int) -> list[tuple[int, int]]:
|
||||
"""
|
||||
Split a prose block into sentence spans as (start, end) absolute offsets.
|
||||
@@ -120,7 +160,7 @@ def split_prose(block: str, offset: int) -> list[tuple[int, int]]:
|
||||
cursor = 0
|
||||
for m in _SENT_END.finditer(block):
|
||||
dot = m.start(1)
|
||||
if block[dot] == "." and _is_abbrev(block, dot):
|
||||
if block[dot] == "." and (_is_abbrev(block, dot) or _is_enumerator(block, dot)):
|
||||
continue
|
||||
end = m.end() # include the closing punctuation and the following space
|
||||
# A sentence-ending mark inside a quotation is usually not the end of the
|
||||
@@ -149,6 +189,15 @@ def split_spans(text: str) -> list[dict]:
|
||||
in_fence = False
|
||||
lines = text.splitlines(keepends=True)
|
||||
|
||||
# YAML frontmatter: a `---` on the very first line opens it, the next `---`
|
||||
# closes it. Line-oriented, so it must not flow into the prose splitter.
|
||||
fm_end = -1
|
||||
if lines and lines[0].strip() == "---":
|
||||
for i in range(1, len(lines)):
|
||||
if lines[i].strip() == "---":
|
||||
fm_end = i
|
||||
break
|
||||
|
||||
para: list[str] = []
|
||||
para_start = 0
|
||||
|
||||
@@ -161,8 +210,15 @@ def split_spans(text: str) -> list[dict]:
|
||||
spans.append({"kind": "prose", "start": s, "end": e})
|
||||
para = []
|
||||
|
||||
for line in lines:
|
||||
for lineno, line in enumerate(lines):
|
||||
stripped = line.strip()
|
||||
|
||||
if 0 < lineno < fm_end:
|
||||
flush_para()
|
||||
spans.append({"kind": "frontmatter", "start": pos, "end": pos + len(line)})
|
||||
pos += len(line)
|
||||
continue
|
||||
|
||||
fence = stripped.startswith("```")
|
||||
structural = (
|
||||
fence
|
||||
@@ -227,7 +283,7 @@ def verify_tiling(spans: list[dict], text: str) -> list[str]:
|
||||
# Spans that carry an assertion and therefore require a tag. Headings are
|
||||
# INCLUDED: kernel §4 rules that "Why the current approach fails" asserts that it
|
||||
# fails, so a heading is X only if declarative conversion yields no claim.
|
||||
TAGGABLE = {"prose", "heading", "block"}
|
||||
TAGGABLE = {"prose", "heading", "block", "frontmatter"}
|
||||
|
||||
|
||||
def load_tags(path: Path) -> dict[int, tuple[str, str]]:
|
||||
@@ -300,6 +356,64 @@ def cmd_split(doc: Path) -> None:
|
||||
print("\nTILING GATE PASSED — spans reproduce the source byte-for-byte.")
|
||||
|
||||
|
||||
_MD_NOISE = re.compile(r"[*_`>]+")
|
||||
_WS = re.compile(r"\s+")
|
||||
|
||||
|
||||
def normalise_quote(s: str) -> str:
|
||||
"""
|
||||
Normalise for §3.2 containment.
|
||||
|
||||
'Verbatim' is operationalised as: identical after removing markdown emphasis
|
||||
and collapsing whitespace. This is WEAKER than byte-identity and is declared
|
||||
as such — a blockquote re-wraps its source's lines, and bolding a phrase for
|
||||
emphasis is a presentational act, not a change of words. What it does NOT
|
||||
tolerate is a changed, added or dropped word, which is the failure §3.2 exists
|
||||
to catch.
|
||||
"""
|
||||
s = _MD_NOISE.sub("", s)
|
||||
s = s.replace("…", "...").replace("—", "-").replace("–", "-")
|
||||
s = s.replace("“", '"').replace("”", '"').replace("’", "'").replace("‘", "'")
|
||||
return _WS.sub(" ", s).strip()
|
||||
|
||||
|
||||
def check_q_resolution(
|
||||
spans: list[dict], text: str, tags: dict[int, tuple[str, str]], sources: dict[str, Path]
|
||||
) -> list[str]:
|
||||
"""
|
||||
§3.2 — every `Q` must appear verbatim in a declared §1 source.
|
||||
|
||||
A `Q` whose note names no source, or names one not in the axiom set, fails:
|
||||
an unlocatable quotation is exactly the 'quoted but not traced' defect.
|
||||
"""
|
||||
problems: list[str] = []
|
||||
cache = {k: normalise_quote(p.read_text(encoding="utf-8")) for k, p in sources.items()}
|
||||
for idx, (tag, note) in sorted(tags.items()):
|
||||
if tag != "Q":
|
||||
continue
|
||||
key = note.split(":", 1)[0].strip()
|
||||
if key not in cache:
|
||||
problems.append(f"§3.2 span {idx}: Q names source {key!r}, not in the axiom set")
|
||||
continue
|
||||
quoted = normalise_quote(text[spans[idx]["start"]:spans[idx]["end"]].lstrip("> "))
|
||||
if quoted and quoted not in cache[key]:
|
||||
problems.append(
|
||||
f"§3.2 span {idx}: NOT FOUND verbatim in {key} — {quoted[:70]!r}…"
|
||||
)
|
||||
return problems
|
||||
|
||||
|
||||
# Axiom sources per kernel §1, plus documents a given package names in its header.
|
||||
AXIOM_SOURCES: dict[str, Path] = {
|
||||
"CLAUDE.md": Path.home() / "CLAUDE.md",
|
||||
"REVIEWED.md": Path.home() / "REVIEWED.md",
|
||||
"contamination-problem.md": Path.home()
|
||||
/ "_Dev/CapableMind-AI/docs/thinking/David/methodology/contamination-problem.md",
|
||||
"central-path.md": Path.home()
|
||||
/ ".claude/projects/-Users-davidglidden/memory/feedback-central-path-answerability-not-purity.md",
|
||||
}
|
||||
|
||||
|
||||
def cmd_check(doc: Path, tags_path: Path) -> None:
|
||||
text = doc.read_text(encoding="utf-8")
|
||||
spans = split_spans(text)
|
||||
@@ -323,6 +437,13 @@ def cmd_check(doc: Path, tags_path: Path) -> None:
|
||||
if stray:
|
||||
failures.append(f"§3.1 STRAY TAGS on non-assertive spans: {stray[:12]}")
|
||||
|
||||
# §3.2 — every Q resolves verbatim in a declared axiom source.
|
||||
available = {k: p for k, p in AXIOM_SOURCES.items() if p.is_file()}
|
||||
missing = sorted(set(AXIOM_SOURCES) - set(available))
|
||||
if missing:
|
||||
failures.append(f"§1 SOURCE UNRESOLVABLE: {missing}")
|
||||
failures.extend(check_q_resolution(spans, text, tags, available))
|
||||
|
||||
# §3.3 — no collected limitations section.
|
||||
for i in sorted(taggable_idx):
|
||||
if spans[i]["kind"] != "heading":
|
||||
@@ -360,9 +481,12 @@ def cmd_check(doc: Path, tags_path: Path) -> None:
|
||||
print(f" - {f}")
|
||||
sys.exit(1)
|
||||
|
||||
print("\nMechanical checks passed (§3.1 tagging completeness, §3.3 headings, tiling).")
|
||||
print("NOT checked here: §3.2 Q-resolution, and the whole of §4 — which is")
|
||||
print("judgement and is not mechanisable. This is not a soundness verdict.")
|
||||
print("\nMechanical checks passed: tiling · §3.1 tagging completeness ·")
|
||||
print("§3.2 Q-resolution against the declared axiom sources · §3.3 heading screen.")
|
||||
print("NOT checked, and NOT checkable: the whole of §4 — whether a D demonstrates,")
|
||||
print("an N is inert, an X asserts nothing, a Q sits within its source's scope, a")
|
||||
print("sentence carries one primitive. §3.3 is a SCREEN over obvious namings, not a")
|
||||
print("decision on §2a. This is not a soundness verdict.")
|
||||
if quarantined:
|
||||
print(f"\nThe document is NOT kernel-sound as written: {len(quarantined)} units")
|
||||
print("cannot be typed under Kernel v1.0. The census above is the finding.")
|
||||
|
||||
Reference in New Issue
Block a user