diff --git a/docs/re/mission-phase-membership.md b/docs/re/mission-phase-membership.md index 6076583..bf49e47 100644 --- a/docs/re/mission-phase-membership.md +++ b/docs/re/mission-phase-membership.md @@ -206,6 +206,37 @@ The user's correction stands on the data: `UN_e007_ADAN_Turret` is flown by 30-slot craft formation — never `AI_Structure`. It is an enemy the player fights, not a gun bolted to a capital ship. +## 🔴 2026-08-25 — the Turret-biased run was VOID: the guest was frozen + +Ran it: `SYLPH_PREFER=Turret`, escort intact (`ast=100.0%`), 1070 s. The phase +field read **0** throughout and the pilot logged **4029** Turret-targeting +samples. That looked like a clean negative — "hunting the objective squadrons +does not advance the phase" — and it is **worthless**. + +`frozen.py` says `max_pixel_delta=0`: **the guest was frozen**, and the pilot's +very first sample at `t=0.0` already shows `spd=0` with the same yaw, pitch, +target and `d=7186` that it still had at 1070 s. The mission froze on entry to +flight; nothing was ever shot. `screen_id` said `flight` the whole time, which is +precisely the trap [mission-freeze-resume-spin](mission-freeze-resume-spin.md) +documents. + +**I was one step from writing this up as a result about the game.** What saved it +was running the freeze test rather than trusting a plausible-looking log — the +same lesson that note already carries, arrived at again from the other side. + +### ✅ Fixed so it cannot recur silently + +`phase_probe.py` now calls `frozen.py` every 60 s and prints +`*** GUEST FROZEN ***` inline, so a dead-world reading is labelled in the data +rather than discovered afterwards. ⚠️ `frozen.frozen()` returns a **tuple** +`(is_frozen, max_delta)` — testing it directly is always truthy and would have +made the witness fire on every check; it must be unpacked. Verified against the +frozen guest: the banner fires, and the unpacked value is `(True, 0)`. + +**The pilot log is itself a witness** and was not being read as one: identical +yaw/pitch/target across thousands of samples means a dead world, not a patient +pilot. + ### 🟡 The prediction to test If phase 1 clears on those three squadrons dying, then destroying **27 Turrets** diff --git a/tools/re-capture/phase_probe.py b/tools/re-capture/phase_probe.py index 3059432..4460de1 100755 --- a/tools/re-capture/phase_probe.py +++ b/tools/re-capture/phase_probe.py @@ -15,6 +15,16 @@ This is the first DIRECT observation of a phase advance. Everything about phases so far is either static (route names, disassembly) or inferred; nobody has watched the number change. +**It also witnesses the freeze**, because without that a frozen run produces a +perfectly clean-looking negative. Measured 2026-08-25: a run entered flight +already frozen -- `screen_id` said `flight`, the pilot logged 4029 samples, and +every one carried the same yaw, pitch, target and distance from t=0.0. The +phase field read 0 for 1070 s and "no phase advance" was about to be written +down as a result. It was a fact about a dead world, exactly as frozen.py warns. + +So: check `frozen.py` on a cadence and SAY SO in the output. A negative from a +frozen run is not a negative. + Usage: phase_probe.py [secs] [every_s] """ import sys, time @@ -51,9 +61,25 @@ def sample(): if __name__ == '__main__': secs = float(sys.argv[1]) if len(sys.argv) > 1 else 600 every = float(sys.argv[2]) if len(sys.argv) > 2 else 5 + import frozen + next_check = 0.0 t0 = time.time(); last = object() print('singleton ptr 0x%08X, phase at +%d' % (SINGLETON_PTR, PHASE_OFF), flush=True) while time.time() - t0 < secs: + now = time.time() - t0 + if now >= next_check: + next_check = now + 60 + try: + # frozen() returns (is_frozen, max_delta) -- a TUPLE, so testing + # it directly is always truthy and the witness would fire on + # every check. Unpack it. + dead, _delta = frozen.frozen(5.0) + except Exception: + dead = False + if dead: + print(' [%6.1fs] *** GUEST FROZEN -- every reading from here is ' + 'about a dead world, not a fact about the game ***' % now, + flush=True) ph, base = sample() if ph != last: print(' [%6.1fs] singleton=%s phase=%s' % (