re: Stage 02 is lost at ~11 minutes, and the pilot's survival rule is what guarantees it

First session whose deliverable was the mission's ENDING rather than a
measurement (mission_run.sh, 500 s, hull of every entity at 2 Hz). The ACROPOLIS
is untouched to t=170 s then falls at ~53 HP/s with no let-up, reaching zero at
t=640-720 s — so "no mission completed" is not an artifact of the 240 s
time-boxes, and not of the 600 s cap on a blocking tool call. A longer session
would only watch the loss arrive.

Attributing the damage by co-presence, exactly two classes are ever near the
asset: e007 turrets (8483) and e010 bombers (8334). pilot.py treats turrets as
keep-out zones at 2500 units and never as targets — the rule that made it
survive — so roughly half the escort damage comes from the one class it is
designed to avoid. Survival and the objective are in direct conflict and the
pilot resolves it entirely for survival: WARSHIPS 0000, WARPLANES 0009,
REMAINING OB rising 004 -> 008, our hull untouched at 1500/1500 with 120
missiles spent. That is unspent risk budget, not a good run.

Also corrects launch_mission.sh: a harness-tracked BACKGROUND task does not keep
the display alive (lost 11 s in, at the turn boundary) — the
one-blocking-foreground-call rule stands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-10 20:57:43 +00:00
parent 530555de9f
commit f4d59c5783
4 changed files with 152 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -0,0 +1,89 @@
# Why Stage 02 is never won — the escort sinks at ~11 minutes (2026-08-10)
**Status: ✅ measured, one 500 s run.** The standing open item since 2026-07-29 was
"no mission completed". This is the first session whose deliverable was the
*ending* rather than a measurement, and it settles why: **the mission is lost
before it can be won, and the pilot's survival policy is what guarantees it.**
Run: `tools/re-capture/mission_run.sh 500 mission01` — boot → Stage 02 in flight →
`pilot.py` (escort-weighted targeting, target commitment, guided missiles) for
500 s, with every entity's hull sampled at 2 Hz and a screenshot every 30 s.
Artifacts at `/sylph-home/re/mission01/` (9 MB `mission.jsonl`, not committed).
## The escort's decay is linear, and it ends the mission
| t (s) | ACROPOLIS hull | % |
|---|---|---|
| 0160 | 25000 | 100 % |
| 180 | 24510 | 98.0 |
| 280 | 20279 | 81.1 |
| 380 | 13799 | 55.2 |
| 480 | 8541 | 34.2 |
| 485 (end) | 8182 | 32.7 |
Untouched until **t ≈ 170 s**, then **≈53 HP/s** with no let-up — so the asset
reaches zero at **t ≈ 640 s**, and the whole-run average rate puts it at 722 s.
Either way the escort is dead at **1012 minutes**, and "the ACROPOLIS is sunk"
is a defeat condition ([mission-escort-state](mission-escort-state.md)).
This also retires a suspicion: the 240 s time-box of earlier runs was *not*
hiding a win, and the ~500 s ceiling of a single blocking tool call is **not**
the binding constraint. A longer session would simply watch the loss arrive.
## What is actually killing it — and the conflict that follows
Attributing damage by co-presence (which hostiles are within 3000 units of the
asset in the sample where its hull drops, damage split evenly among the classes
present — suggestive, not per-shot proof), only **two** classes are ever near it:
| class | samples present | attributed damage |
|---|---|---|
| `UN_e007_ADAN_Turret` | 200 | 8483 |
| `UN_e010_ADAN_Attacker_S` | 194 | 8334 |
Roughly half the damage comes from **turrets** — and `pilot.py` treats turrets as
**keep-out zones at 2500 units, never as targets**. That rule is not arbitrary: a
turret is what shot down every pilot before 2026-07-30, and it is why the craft
now survives. But it means **the policy that keeps the pilot alive also
guarantees the escort dies.** Survival and the objective are in direct conflict,
and the pilot currently resolves it entirely in favour of survival.
The HUD at t≈485 s says the same thing from the game's side:
- `YOU KILLED WARSHIPS` **0000** — not one warship in 500 s, across every run ever;
- `YOU KILLED WARPLANES` **0009** — fighters only;
- `REMAINING OB` **004 → 008** — objectives are being *added* by waves faster than
any are cleared, so the pilot is not touching the objective set at all;
- SHIELD and ARMOR bars full, hull **1500/1500**, 120 missiles spent.
![Stage 02 at t≈485 s](captures/mission01-t485.png)
## The conclusion that matters
The pilot optimises the wrong thing. It maximises survival and fighter kills;
the mission scores **objectives** and **the escort**, and the fighter population
(134 → 92) is close to irrelevant to both. An untouched 1500/1500 hull at the
moment the escort passes 33 % is not a good run — it is **unspent risk budget**.
Concretely, for the next attempt, in priority order:
1. **Turrets near the asset must become targets**, not keep-out zones — accepting
hull damage is the only way to cut ~50 % of the incoming escort damage. The
keep-out rule should be scoped to turrets that are *not* threatening the
asset, rather than applied globally.
2. **Engage warships.** `WARSHIPS 0000` forever means the objective class has
never been attacked; `REMAINING OB` rising is the scoreboard saying so.
3. Re-check whether the escort damage rate actually falls once turrets die —
that is the experiment that tells us whether (1) is sufficient or whether the
bombers need dedicated intercept too.
## Method note, learned the hard way
A harness-tracked **background** task does *not* protect the display: the same
run launched in the background lost Xvfb 11 s in, at the turn boundary
(`skip_intro` exit 3, "DISPLAY LOST"). The comment in `launch_mission.sh` saying
the script may be run as a tracked background task is **wrong**; the
one-blocking-foreground-call rule still stands, which caps a single attempt at
the tool's 600 s timeout. And do not pipe a long run through `tail` — the first
attempt printed nothing because `timeout` killed the pipeline before it flushed;
the on-disk artifacts are what survived.