port: build the withdrawal-time hook, and violate the rule it enforces while writing it
They ended with 'it needs a hook at withdrawal time, not a sweep'. Expressible, because a correction here has a shape: a heading carrying WITHDRAWN / CORRECTION / refuted. A correction section containing no registered phrase is a death argued and never indexed. check-claims now reports them, and the first run names more than my 'four of eight' -- the shortfall runs back through earlier work. Reported, not asserted, deliberately: not every correction retires a claim, and forcing rows for those would push rows in to silence the check. Two failures while building it. The first version pasted the register rows into its own heredoc, so every registered phrase became an unmarked quotation and check-claims flagged its own source -- a tool violating the rule it enforces by being written. Fixed by passing the register through the environment. And writing up the previous catch re-introduced three unmarked quotations: describing a refuted claim quotes it, so every correction is a new occurrence needing the token. The cost is recursive, which the header implies but does not say out loud. What the hook does not do: it fires when a correction is written, so it closes the gap between arguing and indexing, not between believing and arguing. Nothing here would have caught me copying their 'structural' claim into my record. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -57,6 +57,43 @@ structural limit, not an unrun experiment
|
||||
ROWS
|
||||
)
|
||||
|
||||
# ─── 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.
|
||||
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):
|
||||
if not re.search(r"WITHDRAWN|CORRECTION|refuted|withdraw", head, re.I):
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user