re: OB hunt second attempt — saving verified, filter fixed, attach was frozen

The incremental-save fix is verified. A fresh mission caught one e010 event at
t=241 s and wrote 1187 candidates to disk immediately; the turn timeout then
fired exactly as before, but this time the data survived. The session also
clears the candidate file at launch, since candidate offsets are only meaningful
within one emulator instance and resuming across launches would intersect
unrelated addresses.

The correlation itself was wrong though. It matched on the delta alone, so any
two float bit patterns whose integer representations differ by the loss count
qualified, and in a heap full of positions and velocities that is thousands of
words. The 1187 survivors were things like 1044450858, about 0.1f, and
3212461993, a negative float. Candidates must now also look like a counter --
a small non-negative integer in both samples -- which removes the noise by
construction instead of hoping the intersection washes it out.

The follow-up attach logged zero events across 520 s, which reads like the
combat-effectiveness limit again. It was not: 25 of its 26 samples were flagged
GUEST STALLED, so the guest was frozen for essentially the whole window. The
witness added last iteration did its job, and the lesson is about reading it --
the run summary quoted "0 events" first and the stall count only surfaced on a
deliberate check. A run's witness result should be the first thing looked at,
before any interpretation of what the run showed.

Still unfinished, with no address identified. What is needed is unchanged, two
or three e010 kill events in non-stalled samples, and the two obstacles are now
clearly separate: the freeze rate, and a pilot that manages about two
marked-fighter kills per five minutes.
This commit is contained in:
Sylpheed RE agent
2026-08-24 22:15:15 +00:00
parent cd473268c9
commit 3be3628468
4 changed files with 69 additions and 1 deletions

View File

@@ -588,6 +588,17 @@ search cannot find a *schedule*.
combat limit. combat limit.
🔴 `SYLPH_HZ=3` refuted as a lever: it gave the LOWEST frame rate (8/s) with the 🔴 `SYLPH_HZ=3` refuted as a lever: it gave the LOWEST frame rate (8/s) with the
most kills, so pilot polling is not the throttle. most kills, so pilot polling is not the throttle.
* ✅🔴 **(2026-08-24) OB hunt, second attempt.** ✅ **Incremental saving verified**
— one `e010` event at t=241 s wrote **1187 candidates** to disk before the turn
timeout fired; session now clears the file at launch since offsets are only
valid within one emulator instance. 🔴 **The correlation had no value filter**:
survivors were float bit patterns (1044450858 ≈ 0.1f) whose integer forms
differed by the loss count. Fixed — candidates must be small non-negative
integers (`0 ≤ v < 1000`) in both samples. 🔴 **The attach was FROZEN**, not
merely unproductive: **25 of 26 samples flagged `GUEST STALLED`**. The witness
worked; the summary just quoted "0 events" before checking it. **Rule: read the
witness FIRST, before interpreting what a run showed.** ❔ Still no address;
needs 23 `e010` events in non-stalled samples.
* ~~🚧 BLOCKER: t=210/240 unreachable in one turn~~ — **superseded, see above**; * ~~🚧 BLOCKER: t=210/240 unreachable in one turn~~ — **superseded, see above**;
it rested on an untested assumption that a turn is one shell call. 595 s shell cap ~220 s boot (a ~190 s title movie that cannot be it rested on an untested assumption that a turn is one shell call. 595 s shell cap ~220 s boot (a ~190 s title movie that cannot be
tapped through) ~25 s startup = **~350 s observation ≈ 193 game-seconds**. tapped through) ~25 s startup = **~350 s observation ≈ 193 game-seconds**.

View File

@@ -61,3 +61,53 @@ needs is a run that catches **two or three** `e010` kill events, which is the sa
combat-effectiveness limit recorded in combat-effectiveness limit recorded in
[mission-objectives-text.md](mission-objectives-text.md) — the preference knob [mission-objectives-text.md](mission-objectives-text.md) — the preference knob
gets about two marked-fighter kills per five minutes against a dozen turrets. gets about two marked-fighter kills per five minutes against a dozen turrets.
---
# Second attempt: saving works, the filter was wrong (2026-08-24)
## ✅ Incremental saving works
A fresh mission caught one `e010` event at t = 241 s and **wrote 1187 candidates
to disk immediately**. The turn timeout then fired, exactly as before — but this
time the data survived it. The fix from the previous iteration is verified.
The session also now clears `/tmp/ob_candidates.json` at launch: candidate
*offsets* are only meaningful within one emulator instance, so resuming across
launches would intersect unrelated addresses.
## 🔴 The correlation had no value filter, and the survivors were floats
The 1187 survivors are not counters:
```
va 0xbd0a42b8 value 1044450858 (~0.1f)
va 0xbd140bc0 value 3200164558 (a negative float)
va 0xbd14a120 value 3212461993
```
The filter matched on the **delta** alone, so any two float bit patterns whose
integer representations differ by exactly `lost` qualified. In a 32 MB heap full
of positions and velocities that is thousands of words.
Fixed: candidates must also *look like a counter* — a small non-negative integer
(`0 ≤ v < 1000`) in both samples. That removes float noise by construction rather
than hoping the intersection washes it out.
## 🔴 The attach was frozen, and the witness said so
The follow-up attach logged **0 events across 520 s**, which reads like the
combat-effectiveness limit again. It was not: **25 of its 26 samples were flagged
`GUEST STALLED`**. The guest was frozen for essentially the whole window.
The witness added last iteration did its job. The lesson is about reading it —
the run summary quoted "0 events" first and the stall count only turned up on a
deliberate check. **A run's witness result should be the first thing looked at,
before any interpretation of what the run "showed".**
## Still unfinished
No address identified. What is needed is unchanged — two or three `e010` kill
events in *non-stalled* samples — and the two obstacles are now clearly separate:
the freeze rate, and the pilot managing roughly two marked-fighter kills per five
minutes.

View File

@@ -26,6 +26,7 @@ if [ "$BOUND" = 1 ]; then
</dev/null >/tmp/live-pilot.log 2>&1 & </dev/null >/tmp/live-pilot.log 2>&1 &
PILOT=$!; echo "--- pilot (SYLPH_HUNT=$HUNT)" PILOT=$!; echo "--- pilot (SYLPH_HUNT=$HUNT)"
else echo "BIND FAILED after 3 attempts -- aborting, an unattended run tests nothing"; exit 4; fi else echo "BIND FAILED after 3 attempts -- aborting, an unattended run tests nothing"; exit 4; fi
rm -f /tmp/ob_candidates.json # offsets are per-emulator-instance; never resume across launches
python3 "$SD/ob_probe2.py" "$SECS" "$EVERY"; rc=$? python3 "$SD/ob_probe2.py" "$SECS" "$EVERY"; rc=$?
[ -n "$PILOT" ] && kill "$PILOT" 2>/dev/null [ -n "$PILOT" ] && kill "$PILOT" 2>/dev/null
echo "LIVENESS DONE rc=$rc" echo "LIVENESS DONE rc=$rc"

View File

@@ -107,8 +107,14 @@ def main():
allo = sum(max(0, prev_s[k] - cur_s.get(k, 0)) for k in prev_s) allo = sum(max(0, prev_s[k] - cur_s.get(k, 0)) for k in prev_s)
if lost: if lost:
events += 1 events += 1
# Filter on VALUE plausibility, not just on the delta. Without this
# the survivors are float bit patterns whose integer representations
# happen to differ by `lost` -- the first run's 1187 "candidates"
# were things like 1044450858 (~0.1f) and 3212461993 (a negative
# float). A remaining-target counter is a small non-negative integer.
d = prev_r - cur_r # positive where a word FELL d = prev_r - cur_r # positive where a word FELL
hit = np.nonzero(d == lost)[0] plausible = (cur_r >= 0) & (cur_r < 1000) & (prev_r < 1000)
hit = np.nonzero((d == lost) & plausible)[0]
s = set(hit.tolist()) s = set(hit.tolist())
cand = s if cand is None else (cand & s) cand = s if cand is None else (cand & s)
json.dump(sorted(cand), open(CAND, 'w')) # save NOW: the previous json.dump(sorted(cand), open(CAND, 'w')) # save NOW: the previous