port: every one of my checkers passed on an empty input

The Decoder generalised my empty-band case into the rule I now keep: a control
that only compares two things cannot tell you the comparison is happening. An
empty band list, a blank frame, an empty register -- each makes a checker
agreeable rather than wrong, and agreeable is indistinguishable from correct in a
log.

Swept my tools against inputs containing nothing. audit-kinds exited 0 on a tree
with no authored/*.json, having printed '0 kind label(s)' and reported clean.
verify-transcode-fidelity would call every transcode faithful with no videos in
the manifest, having compared none. check-claims exited 1 from a FileNotFoundError
inside the withdrawal hook -- which in that script's own vocabulary means 'a
refuted claim is still being asserted', so a wrong directory got diagnosed as a
dirty corpus. A real failure with a fabricated reason, the third instance of that
family after my control anchoring at the wrong document.

All three now exit 2, check-claims via a preflight that names the roots it needs.
Both self-tests gained the liveness case driven as subprocesses: audit-kinds
--selftest runs itself in an empty directory and requires 2, and check-claims
--control is now six cases -- clean 0, unmarked 1, marked 0, outside-root 0, empty
register 2, nothing to scan 2.

What makes this worth an iteration rather than tidying: none of these tools was
ever wrong on real input. What none of them could do was tell 'I checked and it
was fine' from 'I checked nothing', and every green line I have quoted was the
first of those only because the directory happened to be right.

Also recorded: their ring_row.py used 'main_menu_item(ring_row(f)) is not None' as
a main-menu test, and a TITLE frame passes it -- the gutter carries a bright
cluster at y=243 inside tolerance of row 0. No result they sent me is affected,
for a structural reason rather than a lucky one: (B) from a submenu goes to the
menu, never the title, so the weak test was never shown the frame that breaks it.
I have not re-derived their focus results and am not treating this as a reason to;
what I have is their statement of the exposure and the structural argument,
recorded as that rather than as verification.

Every asserting check passes, 14 of them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-31 02:12:56 +00:00
parent 5be071f9cf
commit 3a048de536
5 changed files with 135 additions and 3 deletions

View File

@@ -147,6 +147,12 @@ HANDOFF.
| ~~P1P7 — the keyframe record layout~~ | ~~adopt the corrected pose/time pairing~~ | — | ✅ **ADOPTED 2026-08-29 by pinning `formats-pin-2026-08-29c`.** This row was wrong twice: it said the change *"cannot be taken yet"* and that it *"reaches the port only when that branch lands on `main`"*. **It arrives when the tag is pinned**, which is what MISSION §2's tagging rule exists for. ⚠️ And the knob I tested first, `SYLPHEED_KF_TIME_SHIFT`, is a **retired partial fix** that left pose 0 untimed — the real correction is the tagged crate's default, with the old reading behind `SYLPHEED_KF_TIME_LEGACY=1`. **The blast radius was far smaller than this row predicted**: under the correction *every pose is timed* (866 keyframes, 0 untimed), so `pose_at`'s synthetic-exit branch became dead code rather than wrong code and nothing needed re-deriving. Oracle: `publisher_logo` 1.00 %→**0.75 %**, `developer_logos` 0.39 %→**0.33 %**, `extras`' differing region collapsing from 736×525 to **398×295 at the sweep position**. 🔴 Open cost: `sylpheed-cli` builds from the workspace crate, so `verify-screen` compares two decoder eras until the tag reaches `main`. Revert to the path dependency then. |
| ~~P7 / naming — the four unnamed builds~~ | ~~which locale and variant is each of entries 0, 1, 12, 15?~~ | — | ✅ **answered 2026-08-29** (`docs/re/ui-title-build-map.md`): all four are the loading screen, two variants — plain (7 elements) and dressed (10) — decoded from their own `pgloading_*` element names. ⚠️ **Not adopted as names yet, for two reasons the RE agent gave and one the port found.** Theirs: the executable names exactly two, and *which* bundle takes which name is 🟡 undecided, so `LOADING`/`LOADING2` must not go in an asset path; and locale is 🟡 — the English member of a pair is the one in the first half of `GP_TITLE.p00`, 8/8 structurally but only 3/3 where a capture can check, and the three pairs that matter are the three no capture can check. Mine: **the message gives the bundles as "0/1 and 10/11", which is the `is_build` ordinal, and `authored/screen_names.json` is keyed by PAK ENTRY** — in entry space 10 and 11 are `palogo_sqex` and `palogo_gamearts`, the splashes. See the refutation section in `DECISIONS.md`. |
## Closed on my own tooling, 2026-08-31 — derived from HANDOFF `abeea3b`
| Milestone | Needs | HANDOFF | State |
|---|---|---|---|
| ~~all — checkers that pass on an empty input~~ | ~~liveness guards~~ | `abeea3b` | ✅ **SWEPT AND FIXED.** Every one of my tools reported clean when it examined **nothing**: `audit-kinds` exited **0** on a tree with no `authored/*.json`; `verify-transcode-fidelity` would call every transcode faithful with no videos in the manifest; `check-claims` exited **1** from a `FileNotFoundError` in the withdrawal hook — *"a refuted claim is still being asserted"* as the diagnosis for **a wrong directory**, a real failure with a fabricated reason and the third of that family. All three now exit **2**, and both self-tests assert the liveness case as subprocesses (`check-claims --control` is six cases). 📌 None of these tools was ever wrong on real input; what none could do was tell *"I checked and it was fine"* from *"I checked nothing"*. |
## Half-answered, 2026-08-31 — derived from HANDOFF (today's `DIFFICULTY` delivery)
| Milestone | Needs | HANDOFF | State |

View File

@@ -9,7 +9,7 @@ dies, which is what this file is for.
<!-- INDEX: generated by tools/port/index-decisions -- do not hand-edit -->
274 sections. Search this before re-deriving anything.
276 sections. Search this before re-deriving anything.
* [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28)
* [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28)
@@ -285,6 +285,8 @@ dies, which is what this file is for.
* [Settled: a submenu resets to its OWN OPENING ITEM, not to its top item](#settled-a-submenu-resets-to-its-own-opening-item-not-to-its-top-item)
* [Their refutation attempt on `extras/initial_focus` — checked against the bytes, twice](#their-refutation-attempt-on-extrasinitial_focus--checked-against-the-bytes-twice)
* [Menu focus does not survive a reboot — and the reach matters more than the result](#menu-focus-does-not-survive-a-reboot--and-the-reach-matters-more-than-the-result)
* [Liveness: every one of my tools passed on an empty input](#liveness-every-one-of-my-tools-passed-on-an-empty-input)
* [Their `ring_row.py` defect, and why it did not reach me](#their-ring_rowpy-defect-and-why-it-did-not-reach-me)
<!-- /INDEX -->
## P0 — the exporter, 2026-08-28
@@ -13909,3 +13911,58 @@ an offset, essentially no scaling). **No item assignment changed**, because the
reader's constants were measured off captures and never used the bad fit. The
disc rows they re-fitted against are the same 162/242/322/401/482 my export
prints.
## Liveness: every one of my tools passed on an empty input
The Decoder generalised my empty-band case into the rule I now keep: **a control
that only compares two things cannot tell you the comparison is happening.** An
empty band list, a blank frame, an empty register — each makes a checker
**agreeable rather than wrong**, and agreeable is indistinguishable from correct
in a log.
Swept my own tools against inputs that contain nothing:
| tool | before | now |
|---|---|---|
| `audit-kinds` | **exit 0** — printed *"0 kind label(s)"* and reported clean | **exit 2** |
| `check-claims` | **exit 1** from a `FileNotFoundError` inside the withdrawal hook | **exit 2**, via a preflight |
| `verify-transcode-fidelity` | manifest with no videos → loop never runs, *"every transcode faithful"* having compared none | **exit 2** |
🔴 **The `check-claims` case is the one worth naming.** Run from the wrong
directory it died in the hook and exited **1** — which in that script's own
vocabulary means *"a refuted claim is still being asserted"*. **A real failure
with a fabricated diagnosis**, the same shape as my control anchoring at the
wrong document two iterations ago, and the third instance of that family. A
preflight now names the roots it needs and calls their absence a **harness**
fault.
✅ Both self-tests gained the liveness case, driven as subprocesses so the real
exit code is read: `audit-kinds --selftest` runs itself in an empty directory and
requires 2; `check-claims --control` is now **six** cases — clean 0, unmarked 1,
marked 0, outside-root 0, empty register 2, **nothing to scan 2**.
📌 What makes this worth an iteration rather than tidying: **none of these tools
was wrong.** Each produced correct output on real input, every time it ran. What
they could not do is tell the difference between *"I checked and it was fine"* and
*"I checked nothing"* — and every green line I have quoted in this file was the
first of those only because the directory happened to be right.
## Their `ring_row.py` defect, and why it did not reach me
Their liveness self-test found that `main_menu_item(ring_row(f)) is not None` was
being used as a main-menu test, and **a TITLE frame passes it** — the gutter
carries a bright cluster at y=243, inside tolerance of row 0, so the title reads
as `NEW GAME`. Glyph count separates them cleanly (714 against the menu's 327);
the ring row alone does not.
**No result they sent me is affected**, and the reason is structural rather
than lucky: Ⓑ from a submenu goes to the menu, never the title, so the weak test
was never presented with the frame that breaks it. **The test was weaker than
they were trusting it to be, not wrong in what it produced** — which is precisely
the state a self-test exists to expose *before* a screen sequence changes and it
starts mattering.
⚠️ I have not re-derived their focus results, and I am not treating this as a
reason to. Several of my authored values rest on them; what I have instead is
their statement of the exposure and the structural argument for why it did not
fire. Recorded as that, not as verification.

View File

@@ -139,6 +139,15 @@ def selftest():
means anything.
"""
paths = known_paths()
# The liveness case belongs in the self-test too, driven as a subprocess so
# its real exit code is read rather than reasoned about.
empty = os.path.join(os.environ.get("TMPDIR", "/tmp"), "audit-kinds-liveness")
os.makedirs(empty, exist_ok=True)
got = subprocess.run([sys.executable, os.path.abspath(__file__)], cwd=empty,
capture_output=True).returncode
print(f" harness: an empty tree -> exit {got} (want 2) "
f"{'✅' if got == 2 else '🔴 examined nothing and reported clean'}")
live_ok = got == 2
cases = [
("bare", "no citation of any kind here, just prose", "BARE"),
("ok", "see tools/port/audit-kinds for the method", "ok"),
@@ -158,8 +167,11 @@ def selftest():
if got != want:
bad += 1
print()
if not live_ok:
bad += 1
if bad:
print("🔴 the classifier cannot tell grounded labels from ungrounded ones.")
print("🔴 the classifier cannot tell grounded labels from ungrounded ones,")
print(" or it reports clean on an empty tree.")
print(" Exit 2: nothing this tool has reported clean is trustworthy.")
return 2
print("the classifier separates bare, dangling and grounded citations")
@@ -172,6 +184,18 @@ def main():
rows = []
for f in sorted(glob.glob("authored/*.json")):
walk(json.load(open(f)), f, "", rows)
# 🔴 LIVENESS. Run against a tree with no `authored/*.json` this printed
# "0 kind label(s)" and exited 0 -- examined nothing, reported clean. The
# Decoder's generalisation of my empty-band case, which is more general than
# either instance: **a control that only compares two things cannot tell you
# the comparison is happening.** An empty input makes a checker AGREEABLE
# rather than wrong, and agreeable is indistinguishable from correct in a
# log.
if not rows:
print("🔴 no `kind` labels found at all -- this audit examined NOTHING.")
print(" Exit 2: the harness is broken (wrong directory, renamed files),")
print(" not the corpus.")
return 2
paths = known_paths()
bare = dangling = 0
kinds = {}

View File

@@ -23,7 +23,7 @@
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
fail=0; total_marked=0; scanned=0
# 🔴 THE MARKER IS AN EXPLICIT SENTINEL, NOT A KEYWORD.
#
@@ -130,6 +130,13 @@ if [ "${1:-}" = "--control" ]; then
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
# Sixth case: a tree with nothing to scan. It used to die in the withdrawal
# hook and exit 1 -- "a refuted claim is still being asserted" -- for a wrong
# directory. Liveness and diagnosis are both asserted here.
_empty="${TMPDIR:-/tmp}/claims-liveness-root"; mkdir -p "$_empty"
got=$(cd "$_empty" && PROJECT_DIR="$_empty" "$OLDPWD/$0" >/dev/null 2>&1; echo $?)
if [ "$got" = "2" ]; then printf ' %-26s exit 2 ✅\n' "nothing to scan"
else printf ' %-26s exit %s, wanted 2 🔴\n' "nothing to scan" "$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"
@@ -172,6 +179,25 @@ fi
# never a defect count.
echo
echo "withdrawal-time hook -- correction sections that registered nothing:"
# 🔴 PREFLIGHT. Run from the wrong directory this used to die inside the
# withdrawal hook with a FileNotFoundError and exit **1** -- which in this
# script's own vocabulary means "a refuted claim is still being asserted". A real
# failure with a fabricated diagnosis, the same shape as my control anchoring at
# the wrong document. The roots it needs are named here and their absence is a
# HARNESS fault with its own code.
for _root in docs docs/port authored tools/port; do
[ -d "$_root" ] || {
echo "🔴 \`$_root\` is not here -- this check cannot scan anything." >&2
echo " Exit 2: wrong directory or a bad checkout, not a dirty corpus." >&2
exit 2
}
done
[ -f docs/port/DECISIONS.md ] || {
echo "🔴 docs/port/DECISIONS.md is missing -- the withdrawal hook has nothing" >&2
echo " to read. Exit 2: the harness is broken, not the corpus." >&2
exit 2
}
REG="$REGISTER" python3 - <<'HOOK'
import os, re
reg = [r.strip() for r in os.environ["REG"].split("\n") if r.strip()]
@@ -235,6 +261,7 @@ PY
# 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)
scanned=$((scanned + hits))
if [ "$bad" -eq 0 ]; then
printf ' %-42s %d file(s), %d occurrence(s) suppressed\n' "$claim" "$hits" "$marked"
total_marked=$((total_marked + marked))
@@ -243,6 +270,17 @@ PY
fi
done <<< "$REGISTER"
# 🔴 LIVENESS. A register full of claims and a tree with nothing in it reports
# clean: the grep matches no files, every row scores 0, and the run passes having
# READ NOTHING. Wrong directory, renamed docs, a bad checkout -- all produce a
# green line. The Decoder's rule for the family: a control that only compares two
# things cannot tell you the comparison is happening.
if [ "$scanned" -eq 0 ]; then
echo "🔴 no file anywhere contains any registered claim -- this check READ" >&2
echo " NOTHING. Exit 2: the harness is broken, not the corpus." >&2
exit 2
fi
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"

View File

@@ -338,6 +338,13 @@ def main():
return 2
man = json.load(open("export/manifest.json"))
names = [v["name"] for v in man.get("videos", [])]
# 🔴 LIVENESS, the same shape as the empty band list one line up. With no
# videos in the manifest the loop never runs, `fail` stays 0 and this reports
# every transcode faithful -- having compared none.
if not names:
print("🔴 the manifest lists NO videos -- nothing was compared.")
print(" Exit 2: the harness is broken, not the transcodes.")
return 2
control = "--control" in sys.argv
fail = 0
print(f" window {WINDOW_S:.0f} s from t=2 s, mono {RATE} Hz, pass at "