check-claims --control plants a revival in docs/port/ and requires exit 1. That the plant lands INSIDE a scanned directory was a property I checked manually, one time, and wrote up -- the exact pattern I had criticised in this same tool one iteration earlier. A fifth case now plants the identical text OUTSIDE the scanned root and requires 0, so the pair asserts the boundary is real: same text, 1 inside and 0 outside. Either half alone is consistent with the tool scanning everything, or nothing. Five cases: clean 0, unmarked 1, marked 0, outside-root 0, empty register 2. audit-kinds has always reported what it found and was never asked whether it can find anything, while its clean runs are cited as evidence that fifteen labels are grounded. --selftest pushes three synthetic rows through the real classifier and reads its verdict: citing nothing must read BARE, a real path ok, a missing path DANGLING. Verified two-directionally -- an extractor stubbed to accept everything returns exit 2. Asserting in check-all. All four submenus are now measured to reset -- LOAD GAME, TUTORIAL and OPTIONS joining EXTRAS -- and the main menu remains the only screen that remembers. Three of the four are not in this export, so no authored value changes. NOT promoted to a rule, deliberately. 'Submenus reset' at 4/4 is better evidence than the 2/2 that made wrap a menu-wide rule, and adopting it would change nothing today because the only submenu this port ships is already measured. What it would do is pre-decide the next screen from a generalisation instead of a measurement -- the trap that nearly let a derived rule overwrite EXTRAS' measured opening item. The guard prints the 4/4 finding beside its per-screen values so the evidence is visible without being load-bearing. MISSION-SELECT-versus-top-item stays open: none of the three separates it, each opens on its own first item, and NEW GAME is untested. Remaining without a harness self-test: verify-transcode-fidelity. Every asserting check passes, 13 of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
256 lines
12 KiB
Bash
Executable File
256 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Every refuted claim must appear only inside its own correction.
|
|
#
|
|
# tools/port/check-claims
|
|
#
|
|
# 🔴 WHY THIS IS A CHECK AND NOT AN AUDIT. The Decoder's rule -- *grep the corpus
|
|
# for the claim, not for the file you were working in* -- found a refuted sentence
|
|
# still shipping in this port's `manifest.json`, and a withdrawn one still
|
|
# standing in `DECISIONS.md`. Running that by hand finds the instances present on
|
|
# the day it is run. It does not stop the next one.
|
|
#
|
|
# So: a REGISTER. Each row is a claim this corpus has refuted, plus a marker that
|
|
# must appear near every occurrence. A hit without its marker fails the run.
|
|
#
|
|
# ⚠️ Two things learned building it, both from the other agent:
|
|
#
|
|
# * a "kept for the record" block STILL ASSERTS. Marking the heading superseded
|
|
# does not mark the sentence a reader lands on, so the marker must sit near
|
|
# the CLAIM, not at the top of the section.
|
|
# * naming a refuted claim keeps it greppable, so this check returns its own
|
|
# corrections as hits -- which is the point. The marker is what distinguishes
|
|
# "quoted while being refuted" from "still asserted".
|
|
set -euo pipefail
|
|
cd "${PROJECT_DIR:-/work}"
|
|
WINDOW=400 # characters either side of a hit in which the marker must appear
|
|
fail=0; total_marked=0
|
|
|
|
# 🔴 THE MARKER IS AN EXPLICIT SENTINEL, NOT A KEYWORD.
|
|
#
|
|
# The first version matched a per-claim keyword -- "refuted", "WITHDRAWN" -- near
|
|
# the hit. Every one of its four failures was a quotation sitting INSIDE a
|
|
# correction whose wording happened not to contain the keyword: a table cell
|
|
# reading "standing, unmarked", a sentence reading "the real count was ten".
|
|
#
|
|
# Widening the window or adding synonyms until those passed would have been
|
|
# tuning a threshold until the answer came out right, which is the failure this
|
|
# corpus has spent a fortnight cataloguing. So the marker is a TOKEN THE AUTHOR
|
|
# PLACES: `[refuted]` near any quotation of a registered claim. It cannot be
|
|
# satisfied by phrasing, and its absence means exactly one thing.
|
|
#
|
|
# ⚠️ The cost is honest: every quotation must be marked by hand, and a new
|
|
# refuted claim means a new row plus marking its existing quotations. That work
|
|
# is the check.
|
|
MARKER='[refuted]'
|
|
REGISTER=$(cat <<'ROWS'
|
|
TAIL of the kept stream
|
|
known too fast
|
|
only thing making the plate
|
|
no loop-point field has been identified
|
|
AUDIBLY WRONG AT THE SEAM
|
|
1 of 3 streams
|
|
six expected DIFFERS
|
|
goes against the port
|
|
the capture turns out to determine it
|
|
COMPOSITED rather than standalone
|
|
structural limit, not an unrun experiment
|
|
HANDOFF Q10 says nothing on the disc
|
|
ROWS
|
|
)
|
|
|
|
[ -n "${CLAIMS_REGISTER+x}" ] && REGISTER="$CLAIMS_REGISTER"
|
|
|
|
# 🔴 A REGISTER THAT PARSES NOTHING REPORTED CLEAN, FOREVER. The scan loop runs
|
|
# once per row; with no rows it runs zero times, `fail` stays 0, and the script
|
|
# printed "every refuted claim appears only inside its correction" and exited 0.
|
|
# That is the stub defect -- prints a result, asserts nothing -- sitting in the
|
|
# checker whose clean runs both agents lean on. The Decoder found it in their
|
|
# equivalent the same day; it was here too.
|
|
_rows=$(printf '%s\n' "$REGISTER" | grep -c '[^[:space:]]' || true)
|
|
if [ "$_rows" -eq 0 ]; then
|
|
echo "🔴 the refuted register is EMPTY -- this check would pass everything." >&2
|
|
echo " Exit 2: the harness is broken, not the corpus." >&2
|
|
exit 2
|
|
fi
|
|
|
|
# --------------------------------------------------------------------------
|
|
# `--control`: the known negatives, EXECUTED.
|
|
#
|
|
# 🔴 Until now this check had NO control machinery at all. Every "planted a
|
|
# revival, it failed, removed it, it passed" in `DECISIONS.md` was done BY HAND,
|
|
# once, and never again -- in a repository where two of my own tools carry the
|
|
# line *"a control that does not execute is not a control"*. It was written
|
|
# about somebody else's tool.
|
|
#
|
|
# Four cases, each driving THIS script as a subprocess and reading its real exit
|
|
# code rather than reasoning about what it would do:
|
|
#
|
|
# clean tree -> 0
|
|
# unmarked revival planted -> 1 (the check must catch it)
|
|
# revival planted MARKED -> 0 (and must not false-positive on it)
|
|
# register emptied -> 2 (the harness is broken, not the corpus)
|
|
#
|
|
# The plant lands in a real scanned directory, because a control that runs
|
|
# somewhere the tool does not look proves nothing about the tool.
|
|
if [ "${1:-}" = "--control" ]; then
|
|
probe="docs/port/.claims-control-probe.md"
|
|
trap 'rm -f "$probe"' EXIT INT TERM
|
|
claim=$(printf '%s\n' "$REGISTER" | grep -m1 '[^[:space:]]')
|
|
ok=0
|
|
run() { CLAIMS_CONTROL=1 "$0" >/dev/null 2>&1; echo $?; }
|
|
rm -f "$probe"
|
|
for case in "clean::0" "unmarked:$claim:1" "marked:$claim [refuted]:0"; do
|
|
IFS=: read -r name body want <<<"$case"
|
|
if [ -n "$body" ]; then printf '%s\n' "$body" > "$probe"; else rm -f "$probe"; fi
|
|
got=$(run)
|
|
if [ "$got" = "$want" ]; then
|
|
printf ' %-26s exit %s ✅\n' "$name" "$got"
|
|
else
|
|
printf ' %-26s exit %s, wanted %s 🔴\n' "$name" "$got" "$want"; ok=1
|
|
fi
|
|
done
|
|
rm -f "$probe"
|
|
# 🔴 FIFTH CASE: the same text OUTSIDE the scanned root must give 0.
|
|
#
|
|
# Without it, "the plant is inside a scanned directory" is a property I
|
|
# verified BY HAND, once -- which is the exact pattern I had just finished
|
|
# criticising in this tool one iteration earlier. The pair is what asserts the
|
|
# boundary is real: identical text, exit 1 inside and 0 outside. Either half
|
|
# alone is consistent with the tool scanning everything, or nothing.
|
|
#
|
|
# The Decoder added this to theirs after I raised the boundary; the reason it
|
|
# was worth adding is that their property held *because they had reasoned it*,
|
|
# not because anything asserted it. Mine was in the same state.
|
|
outside="${TMPDIR:-/tmp}/claims-control-outside.md"
|
|
printf '%s\n' "$claim" > "$outside"
|
|
got=$(run)
|
|
rm -f "$outside"
|
|
if [ "$got" = "0" ]; then printf ' %-26s exit 0 ✅\n' "same text outside root"
|
|
else printf ' %-26s exit %s, wanted 0 🔴\n' "same text outside root" "$got"; ok=1; fi
|
|
got=$(CLAIMS_REGISTER="" "$0" >/dev/null 2>&1; echo $?)
|
|
if [ "$got" = "2" ]; then printf ' %-26s exit 2 ✅\n' "empty register"
|
|
else printf ' %-26s exit %s, wanted 2 🔴\n' "empty register" "$got"; ok=1; fi
|
|
echo
|
|
[ $ok -eq 0 ] && echo "the register check fails when it must, and says so distinctly" \
|
|
|| echo "🔴 the control machinery itself is broken"
|
|
exit $ok
|
|
fi
|
|
|
|
|
|
|
|
# ─── THE WITHDRAWAL-TIME HOOK ────────────────────────────────────────────────
|
|
# The register enforces claims it KNOWS ABOUT; knowing about them was manual, and
|
|
# that is how ~8 claims were withdrawn this session and 0 registered. A sweep
|
|
# cannot fix it -- by the time you sweep, the withdrawal is already unpublished.
|
|
# The hook fires where the withdrawal is WRITTEN.
|
|
#
|
|
# A correction in DECISIONS.md has a shape: a heading carrying WITHDRAWN /
|
|
# CORRECTION / "refuted". A section like that containing no registered phrase is
|
|
# a death argued and never indexed.
|
|
#
|
|
# ⚠️ The register is passed in the ENVIRONMENT, not inlined. The first version
|
|
# pasted the rows into this file's own heredoc -- which made every phrase an
|
|
# unmarked quotation, and the checker flagged its own source. A tool that
|
|
# violates the rule it enforces by being written is worth a comment.
|
|
#
|
|
# 🟡 REPORTED, NOT ASSERTED: not every correction retires a CLAIM -- some fix a
|
|
# number, a scope, a wrong floor -- and forcing a row for those would push rows
|
|
# in to silence the check, the failure this file exists to prevent.
|
|
#
|
|
# ⚠️ AND IT WILL ALWAYS OVER-REPORT ON WELL-WRITTEN CORRECTIONS. The detection is
|
|
# "does this section contain a registered phrase", which requires the correction
|
|
# to QUOTE the dead claim. A good correction paraphrases it away: the JP heading
|
|
# now reads "does NOT go against the port", which does not contain the registered
|
|
# "goes against the port" [refuted] and is flagged despite being registered.
|
|
#
|
|
# The Decoder's resolution is the right one and costs the correction nothing:
|
|
# **the register entry is the verbatim home of the dead phrase; prose paraphrases
|
|
# freely.** They are different documents, so the phrase always has one exact
|
|
# place to live without any correction having to carry it. What follows for this
|
|
# hook is that its candidate list mixes "never registered" with "registered and
|
|
# paraphrased", and it cannot separate them -- so the list is a prompt to check,
|
|
# never a defect count.
|
|
echo
|
|
echo "withdrawal-time hook -- correction sections that registered nothing:"
|
|
REG="$REGISTER" python3 - <<'HOOK'
|
|
import os, re
|
|
reg = [r.strip() for r in os.environ["REG"].split("\n") if r.strip()]
|
|
doc = open("docs/port/DECISIONS.md").read()
|
|
heads = [(m.start(), m.group(0)) for m in re.finditer(r"(?m)^##+ .*$", doc)]
|
|
flagged = 0
|
|
for i, (pos, head) in enumerate(heads):
|
|
# 🔴 THE FIRST REGEX MATCHED HEADINGS *ABOUT* CORRECTIONS, NOT HEADINGS
|
|
# MAKING THEM -- "withdraw" caught "rather than withdrawing", "refuted"
|
|
# caught a section discussing the register itself. 33 candidates was a
|
|
# measurement of the regex. Narrowed to headings that RETIRE something:
|
|
# a leading WITHDRAWN/CORRECTION/Refuted, or an explicit "is withdrawn".
|
|
if not re.search(r"^#+\s*(?:[^A-Za-z]*\s*)?(WITHDRAWN|CORRECTION|Refuted)\b"
|
|
r"|\bis withdrawn\b|\bnow refuted\b", head):
|
|
continue
|
|
end = heads[i + 1][0] if i + 1 < len(heads) else len(doc)
|
|
if not any(c in doc[pos:end] for c in reg):
|
|
flagged += 1
|
|
print(" candidate: %s" % head[:92].lstrip("# "))
|
|
print(" none -- every correction section names a registered claim" if not flagged
|
|
else " %d correction section(s) argue a withdrawal the register does not carry" % flagged)
|
|
HOOK
|
|
|
|
while IFS= read -r claim; do
|
|
[ -z "$claim" ] && continue
|
|
hits=0; bad=0; marked=0
|
|
while IFS= read -r loc; do
|
|
[ -z "$loc" ] && continue
|
|
f=${loc%%:*}
|
|
hits=$((hits+1))
|
|
out=$(python3 - "$f" "$claim" "$MARKER" "$WINDOW" <<'PY'
|
|
import sys
|
|
f, claim, marker, w = sys.argv[1], sys.argv[2], sys.argv[3], int(sys.argv[4])
|
|
s = open(f, encoding="utf-8", errors="ignore").read()
|
|
i = n = 0
|
|
low, claim_low = s.lower(), claim.lower()
|
|
while True:
|
|
i = low.find(claim_low, i)
|
|
if i < 0:
|
|
break
|
|
if marker.lower() not in low[max(0, i-w):i+w+len(claim)]:
|
|
print(" unmarked in %s at char %d" % (f, i))
|
|
sys.exit(1)
|
|
n += 1
|
|
i += len(claim)
|
|
# Every suppression, counted. A checker that can discard an occurrence in silence
|
|
# reports the same clean run whether or not a live assertion is hiding among the
|
|
# marked ones, and its zero is unfalsifiable. Reached from the loud end here and
|
|
# from the quiet end by the Decoder on the same day: their marker language was
|
|
# vouching for 8 of 8 mentions, so their 0 was going to be 0 either way.
|
|
print(n)
|
|
sys.exit(0)
|
|
PY
|
|
) && marked=$((marked + out)) || { printf '%s\n' "$out"; bad=$((bad+1)); }
|
|
# 🔴 CASE-INSENSITIVE since 2026-08-30, and the reason is a live miss. The
|
|
# register held "no loop-point field has been identified" [refuted]; `BLOCKED.md`
|
|
# it capitalised at the start of a sentence, and the check reported clean while
|
|
# a refuted claim stood unmarked in the file whose whole job is to say what is
|
|
# still open. The Decoder found the same class the same day from the other end
|
|
# -- their register missed a revival that kept the claim and changed the second
|
|
# clause. A register matching EXACT wording does not protect the documents that
|
|
# rewrite most, and a capital letter is the cheapest rewrite there is.
|
|
done < <(grep -ril -- "$claim" docs/ crates/ port/ tools/ authored/ 2>/dev/null || true)
|
|
if [ "$bad" -eq 0 ]; then
|
|
printf ' %-42s %d file(s), %d occurrence(s) suppressed\n' "$claim" "$hits" "$marked"
|
|
total_marked=$((total_marked + marked))
|
|
else
|
|
printf ' %-42s 🔴 %d file(s) assert it unmarked\n' "$claim" "$bad"; fail=1
|
|
fi
|
|
done <<< "$REGISTER"
|
|
|
|
echo
|
|
printf ' %d occurrence(s) were SUPPRESSED by a neighbouring `%s`.\n' "$total_marked" "$MARKER"
|
|
echo " That number is the size of what this check chose not to look at. A"
|
|
echo " detector that can discard a candidate without saying how many has an"
|
|
echo " unfalsifiable clean run -- its zero reads the same whether or not a live"
|
|
echo " assertion is hiding among the marked ones."
|
|
echo
|
|
[ $fail -eq 0 ] && echo "every refuted claim appears only inside its correction" \
|
|
|| echo "🔴 a refuted claim is still being asserted"
|
|
exit $fail
|