port: a leak that was not mine, a second narrow anchor, and a result recovered
Three findings, one of them a withdrawal of my own fix. The ObjectDB leak line on every run is engine-side. The leaked objects are the Ogg streams and playbacks of exactly the cues that sounded, which reads as MenuAudio holding references past teardown. It does not: releasing every reference the port owns -- stop each player, null every stream, clear _players, clear cues/beds/voices -- moved the count not at all, 8 before and 8 after, with a debug print confirming _exit_tree runs. The cleanup is REVERTED rather than kept, because code that changes nothing under a comment claiming to fix a leak is worse than none: the next reader sees it handled and stops looking. Filed as a negative result so nobody re-investigates. check_focus_persists gets a SECOND NARROW ANCHOR, repairing a weakness I recorded last iteration and did not act on. It anchored on the heading -- the conclusion -- so when the Decoder corrected the run's item names it sailed past, surviving by luck rather than design. It now also rests on the evidence, the ring at y 384.0 before the round trip and 385.5 after, which is the geometry-free equality the conclusion stands on. The two anchors are checked AGAINST EACH OTHER: if one matches and the other does not it reports ANCHOR SPLIT. The second anchor has its own known negative, perturbing only the evidence line -- without that it would be decorative and the check would still rest on the conclusion alone. And their skippability rule recovers a result I had over-withdrawn. Frames can be skipped, bytes consumed cannot; that is why my withdrawal reaches my test and not their read-offset one. Applied backwards: the OVERRUN IS the evidence nothing was skipped. A player that drops frames finishes on schedule; mine took 146.6 s for 137.44 s of media, so ADV +6.7% and S00A -0.5% are time-to-consume measurements after all. The withdrawal stands for the pacing-audit use; the load-starvation result is recovered. Standing caveat recorded: every timing this port publishes is frame-derived, and the only reason those seconds mean anything is that this player demonstrably does not skip -- an empirical property, not a guarantee, and nothing checks it. Reported: the 'do not hardcode the menu's initial focus' HANDOFF section still reads as live while two later sections have overtaken both its claims. Every asserting check passes; 14 controls fire. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -277,9 +277,31 @@ def check_focus_persists(h):
|
||||
positive assertion of the negative. Now only the measured half is asserted
|
||||
against the contract; the scope is a guard, below.
|
||||
"""
|
||||
want = bool(re.search(r"the main menu remembers its cursor; re-entry is not a reset", h))
|
||||
heading = bool(re.search(r"the main menu remembers its cursor; re-entry is not a reset", h))
|
||||
# 🔴 SECOND NARROW ANCHOR, added 2026-08-30 on the Decoder's advice, and it
|
||||
# repairs a weakness I had already identified and not acted on. The heading
|
||||
# anchor is on the CONCLUSION; when they corrected the run's item names --
|
||||
# `TUTORIAL → EXTRAS → EXTRAS` was actually `NEW GAME → TUTORIAL → TUTORIAL`
|
||||
# -- this check sailed past it, because the conclusion was above the part
|
||||
# that was wrong. It survived by luck, not by design.
|
||||
#
|
||||
# So the check now also rests on the EVIDENCE: the ring at y 384.0 before the
|
||||
# round trip and 385.5 after. That pair is the geometry-free equality the
|
||||
# conclusion actually stands on, and it is what a future correction to the
|
||||
# measurement would have to touch.
|
||||
#
|
||||
# Two narrow anchors, NOT one loosened one. Their words: after a specific
|
||||
# instrument fails the general one feels safer, and its failure mode is only
|
||||
# one you have not met yet.
|
||||
evidence = bool(re.search(r"ring sits at y 384\.0 before the round trip and 385\.5 after", h))
|
||||
want = heading and evidence
|
||||
got = (((jload("authored/flow.json") or {}).get("screens") or {})
|
||||
.get("main_menu", {}).get("focus_persists"))
|
||||
if heading != evidence:
|
||||
print(f" {'menu remembers its cursor':<30} 🔴 ANCHOR SPLIT -- heading"
|
||||
f" {heading}, evidence {evidence}: one moved without the other")
|
||||
globals()["FAIL"] = FAIL + 1
|
||||
return
|
||||
report("menu remembers its cursor", want or None, got, want and got is True)
|
||||
|
||||
|
||||
@@ -367,6 +389,11 @@ CONTROLS = [
|
||||
(check_splash_dwell, "the splashes are 190 and 145", "the splashes are 191 and 145"),
|
||||
(check_focus_persists, "the main menu remembers its cursor; re-entry is not a reset",
|
||||
"the main menu forgets its cursor; re-entry is a reset"),
|
||||
# The SECOND anchor gets its own known negative. Perturbing only the evidence
|
||||
# must trip ANCHOR SPLIT -- otherwise the second anchor is decorative and the
|
||||
# check is still resting on the conclusion alone.
|
||||
(check_focus_persists, "ring sits at y 384.0 before the round trip and 385.5 after",
|
||||
"ring sits at y 384.0 before the round trip and 999.9 after"),
|
||||
# The list sits on the line AFTER "times are", so the perturbation has to
|
||||
# carry the newline the check's `\s*` spans. A control whose own anchor is
|
||||
# written from memory of the prose rather than from the prose is the same
|
||||
|
||||
Reference in New Issue
Block a user