Files
Sylpheed/tools/port/verify-motion
Sylpheed port agent 8477242656 port: a check that measures CHANGE, run against the defect it was written for
Closes the two items the play-test left after the fix landed.

1. tools/port/verify-motion, wired into check-all with its control.

It films a REAL boot -- no --time, no pinning -- and hands it to
tools/motion-census. The window is the DECLARED build-in (publisher t=0..45,
0.75 s at 60 units/s), so it asks about the interval the disc says is animating
and nothing else.

🔴 BOTH SIDES MEASURED, not one measured and one assumed. I reverted the single
operator in pose_at, ran this check against the defect, and restored it:

  broken (ASSIGNS the settle instant)   40 %   and it FAILED
  fixed  (clamps to it)                 86 %   and it passed

The bar of 60 sits mid-gap: 20 points above the defect, 26 below the fix.

🔴 AND MY FIRST VERSION OF THAT BAR WAS JUSTIFIED BY A NUMBER I HAD NOT
MEASURED. It claimed "~40 points of clearance on both sides"; with a 1.0 s
window the real clearance was 5 points, because that window includes 0.25 s of
legitimate hold and dilutes the signal. A bar defended by an unmeasured number
is this whole check's own defect, one level up. Corrected with the measurements
and the sequence stated.

The control runs FIRST and is not optional: motion-census --selftest drives a
fade, a switch and a frozen film through the same loader and floor. If it cannot
separate those three, every number the check reports is decoration. Then the
--control mode builds a frozen film from the port's own pixels -- one real boot
frame repeated -- and requires it to FAIL. It scores 0 %.

One defect in the check itself, caught by running it: `ls | head` under
`set -o pipefail` exits 141 before asserting anything, and a check that dies
before checking looks a lot like a check that passed.

2. BLOCKED.md H2 corrected from  to 🟡, against myself.

The MECHANISM half stands -- no post-process pass, the blur is a baked companion
texture. The BEHAVIOUR half was false and the row asserted it: I wrote "the port
draws all seven quads -- verified by a frozen sweep". True, and it did not mean
what I used it for. A frozen sweep drives the clock BY HAND. It proves the
renderer can draw pose N and says nothing about the poses being drawn in
sequence while running.

All three of my instruments passed the defect -- frozen sweep, a 0.01 % settled
comparison (a frozen screen matches a settled reference PERFECTLY), and an
achieved-fps counter (identical pixels 25x/s score like animating). Every one
measured throughput or a pose; none measured CHANGE. Same shape as
InputEventAction bypassing the input map.

Not settled: the ~1.0-1.2 menu residual; findings 3 and 4's remaining halves.
Both were explicitly deferred by the human until this was fixed, and it now is.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
2026-09-02 16:00:57 +00:00

153 lines
6.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Does the boot ANIMATE, or does it draw the same picture very fast?
#
# tools/port/verify-motion # assert
# tools/port/verify-motion --control # can it fail?
#
# 🔴 WHY THIS EXISTS. A human on a 140 fps GPU: *"the port does no blur
# animation at all, the logos just switch."* Three checks this port already had
# were green at the time, and all three were blind the same way:
#
# frozen sweep (`--time=`) proves the renderer CAN draw pose N. It drives the
# clock by hand and never runs the animation.
# settled comparison scored 0.01 % against the oracle. A screen frozen
# 84 % of the time matches a settled reference
# PERFECTLY -- that is what frozen means.
# achieved-fps counter counts frames DRAWN. Drawing identical pixels 25
# times a second scores exactly like animating.
#
# Every one measured throughput or a pose. **None measured CHANGE.** Same shape
# as `InputEventAction` bypassing the input map: the instrument sat below the
# thing that was broken, so the breakage could not appear in it.
#
# This films a REAL boot -- no `--time`, no pinning -- and hands it to
# `tools/motion-census`, which measures change and nothing else.
#
# ⚠️ WHAT IT CANNOT DO. It is the liveness half only. A wrong ramp that moves
# every frame passes here. Correctness stays with `verify-capture` against the
# oracle, and the two are complementary: one screen can pass either alone.
set -euo pipefail
cd "${PROJECT_DIR:-/work}"
export DISPLAY="${DISPLAY:-:97}"
OUT="${OUT:-${TMPDIR:-/tmp}/verify-motion}"
INTERVAL=0.05
# The publisher splash declares its whole build-in over t=0..45 -- 0.75 s at
# 60 units/s -- and then holds. So the FIRST second of the boot is where a
# frozen build-in shows up, and it is the only window this asserts on.
#
# The bar is 60 % of adjacent frame-pairs moving in that window, and BOTH SIDES
# WERE MEASURED rather than one measured and one assumed -- the one operator in
# `ScreenView.pose_at` was reverted, this check run against the defect, and the
# operator restored:
#
# broken (pose_at ASSIGNED the settle instant) 40 % -- and it FAILED
# fixed (clamps to it) 86 % -- and it passed
#
# 60 sits mid-gap: 20 points above the defect, 26 below the fix. That is why it
# is a floor and not a tuned threshold, and it is deliberately NOT set near the
# passing value -- a check that only passes at exactly today's number fails on
# the next legitimate change and teaches people to edit the bar.
#
# 🔴 THE FIRST VERSION CLAIMED "~40 POINTS OF CLEARANCE ON BOTH SIDES" AND HAD
# NOT MEASURED THE BROKEN CASE. With a 1.0 s window the real clearance was 5
# points, because that window includes 0.25 s of legitimate hold and dilutes the
# signal. The window is now the DECLARED build-in -- publisher t=0..45, 0.75 s
# at 60 units/s -- so it asks about the interval the disc says is animating and
# nothing else. A bar justified by an unmeasured number is the same defect this
# whole check exists to catch, one level up.
WINDOW=0.75
BAR=60
films() { # $1 = dir
rm -rf "$1"; mkdir -p "$1"
timeout 120 godot --path port -- --boot --skip-at=1 \
--film="$1/f" --film-interval="$INTERVAL" >"$1/boot.log" 2>&1 || true
}
moving_pct_in_window() { # $1 = dir -- % of adjacent pairs that MOVED, first $WINDOW seconds
python3 - "$1" "$INTERVAL" "$WINDOW" <<'PY'
import sys, glob, os, importlib.util, importlib.machinery
d, interval, window = sys.argv[1], float(sys.argv[2]), float(sys.argv[3])
frames = sorted(glob.glob(os.path.join(d, "f_*.png")))
n = int(window / interval) + 1
frames = frames[:n]
if len(frames) < 3:
print("0"); raise SystemExit
# Reuse motion-census's own loader and floor rather than re-deriving them: a
# second implementation of "did it move" is a second thing to be wrong.
sys.path.insert(0, os.path.join(os.environ.get("PROJECT_DIR", "/work"), "tools"))
spec = importlib.util.spec_from_loader(
"mc", importlib.machinery.SourceFileLoader(
"mc", os.path.join(os.environ.get("PROJECT_DIR", "/work"), "tools", "motion-census")))
mc = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mc)
from pathlib import Path
prev, moved, total = None, 0, 0
for f in frames:
cur = mc.load(Path(f))
if prev is not None:
delta = sum(abs(a - b) for a, b in zip(cur, prev)) / len(cur)
total += 1
if delta > mc.MOVED:
moved += 1
prev = cur
print("%d" % (100 * moved / total if total else 0))
PY
}
echo "boot liveness: films a real boot and measures CHANGE, not throughput"
# 🔴 THE CONTROL RUNS FIRST AND IS NOT OPTIONAL. `motion-census --selftest`
# drives a synthetic fade, a switch and a frozen film through the same loader
# and the same floor this check uses. If it cannot separate those three, every
# number below is decoration.
if ! tools/motion-census --selftest >"$OUT.selftest.log" 2>&1; then
echo " 🔴 motion-census --selftest FAILED -- the detector cannot tell a fade"
echo " from a switch, so nothing it reports about the boot means anything."
sed 's/^/ /' "$OUT.selftest.log"
exit 2
fi
echo " census selftest ok (fade / switch / frozen separated)"
if [ "${1:-}" = "--control" ]; then
# A frozen film must FAIL this check. Built by repeating one real boot frame,
# so it has the port's own pixels and differs from a passing run in exactly
# one property: nothing changes.
films "$OUT/live"
ctl="$OUT/frozen"; rm -rf "$ctl"; mkdir -p "$ctl"
# NOT `ls | head`: under `set -o pipefail` head closes the pipe, ls takes
# SIGPIPE and the script exits 141 before it ever asserts anything. Cost one
# run to notice, and a check that dies before checking looks a lot like a
# check that passed.
local_frames=("$OUT"/live/f_*.png)
src="${local_frames[0]}"
for i in $(seq -w 0 24); do cp "$src" "$ctl/f_0$i.png"; done
pct=$(moving_pct_in_window "$ctl")
if [ "$pct" -lt "$BAR" ]; then
echo " frozen film is REJECTED ok ${pct}% moving, bar ${BAR}%"
echo
echo "the check fails on a film that does not move"
exit 0
fi
echo " frozen film is REJECTED 🔴 FAILED ${pct}% moving -- it passed, so"
echo " this check cannot detect the defect it was written for."
exit 1
fi
films "$OUT/live"
grep -m1 -E "fps achieved" "$OUT/live/boot.log" | sed 's/^ */ /' || true
pct=$(moving_pct_in_window "$OUT/live")
printf ' %-25s %s %d%% of pairs moved in the first %.1fs, bar %d%%\n' \
"build-in moves" "$([ "$pct" -ge "$BAR" ] && echo ok || echo '🔴 FAILED')" \
"$pct" "$WINDOW" "$BAR"
[ "$pct" -ge "$BAR" ] || {
echo
echo "🔴 the boot draws its first second without changing. That is the"
echo " 2026-09-02 defect: poses not advancing while the clock does."
echo " Films are in $OUT/live -- run tools/motion-census on them."
exit 1
}
echo
echo "the boot's build-in animates"