Files
Sylpheed/tools/port/check-claims
Sylpheed port agent 769ac9a2c7 port: a refuted-claim register, enforced by check-all
The Decoder's audit of their own corpus found four refuted claims standing --
including one they had corrected to me, agreed with, and written a METHOD entry
about, without landing it for a full iteration. A hand audit finds what is there
on the day it runs; it does not stop the next one.

check-claims is a register: every occurrence of a refuted claim must carry an
explicit [refuted] sentinel within 400 characters. It found four more unmarked
occurrences than my manual pass had, including one in authored/audio.json.

The marker is a sentinel rather than a keyword because the first version's every
failure was a quotation inside a correction whose wording lacked the keyword. The
temptation was to widen the window until they passed -- tuning a threshold until
the answer comes out right, in the tool built to catch that. 21 quotations marked
by hand; proved it fails by removing one.

Also fixes the Decoder's other finding in my corpus: BLOCKED's voice row had a
struck heading with three sentences below still asserting in the present tense.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
2026-08-30 10:39:17 +00:00

90 lines
3.5 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
# 🔴 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
ROWS
)
while IFS= read -r claim; do
[ -z "$claim" ] && continue
hits=0; bad=0
while IFS= read -r loc; do
[ -z "$loc" ] && continue
f=${loc%%:*}
hits=$((hits+1))
python3 - "$f" "$claim" "$MARKER" "$WINDOW" <<'PY' || bad=$((bad+1))
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 = 0
while True:
i = s.find(claim, i)
if i < 0:
break
if marker.lower() not in s[max(0, i-w):i+w+len(claim)].lower():
print(" unmarked in %s at char %d" % (f, i))
sys.exit(1)
i += len(claim)
sys.exit(0)
PY
done < <(grep -rl -- "$claim" docs/ crates/ port/ tools/ authored/ 2>/dev/null || true)
if [ "$bad" -eq 0 ]; then
printf ' %-42s %d file(s), all marked\n' "$claim" "$hits"
else
printf ' %-42s 🔴 %d file(s) assert it unmarked\n' "$claim" "$bad"; fail=1
fi
done <<< "$REGISTER"
echo
[ $fail -eq 0 ] && echo "every refuted claim appears only inside its correction" \
|| echo "🔴 a refuted claim is still being asserted"
exit $fail