173 lines
12 KiB
Markdown
173 lines
12 KiB
Markdown
# Prison approach reliability audit
|
||
|
||
Read-only comparison of three immutable ordinary-game captures. No retries, input,
|
||
engine launches, gameplay changes or relaxed limits were used for this audit.
|
||
The approach policy hash recorded in all three input reports matches the current
|
||
`tools/prison_approach_proof.py`. The 19:39 and 19:41 captures also share the exact
|
||
input-helper hash; 19:17 used an earlier helper. This is a small diagnostic sample,
|
||
not a reliability rate or performance benchmark.
|
||
|
||
| Archive | Approach outcome | W pulses / yaw requests | Native observed duration | Recorded W hold min / median / max | Largest stopped displacement | Final target error |
|
||
| --- | --- | --- | --- | --- | --- | --- |
|
||
| [19:39:24](evidence/game-2026-09-19-193924-approach-stopping-reserve/input-proof.json.txt) | Stopping-reserve refusal | 8 / 14 | 25.899 s | 241.581 / 247.062 / 313.187 ms | 0.906973 m | 0.982344 m |
|
||
| [19:41:28](evidence/game-2026-09-19-194128-gate-context-unselected/input-proof.json.txt) | Approach completed; later alignment refused | 10 / 14 | 28.456 s | 240.434 / 247.307 / 261.644 ms | 0.572014 m | 0.475079 m |
|
||
| [19:17:50](evidence/game-2026-09-19-191750-prison-approach/input-proof.json.txt) | Approach completed | 9 / 14 | 27.199 s | 244.823 / 247.146 / 264.882 ms | 0.585235 m | 0.490408 m |
|
||
|
||
Durations use the first and last native samples retained by the approach report;
|
||
key holds use the actual helper key-down/up event timestamps. Paths were
|
||
4.246073, 4.760125 and 4.741409 m respectively. The failed approach still had
|
||
6.164 s of its original 35-second approach allowance: it did not time out.
|
||
The successful approaches left 3.633 and 4.734 s. None proves gate operation.
|
||
|
||
## What caused the refusal
|
||
|
||
The policy ends only at target error `r <= 0.75 m`, but permits another pulse only
|
||
when `r > largest_stop + 0.25 m` (`perform_approach`, lines 255–268). Therefore any
|
||
`largest_stop > 0.50 m` creates an unreachable decision interval:
|
||
|
||
`0.75 < r <= largest_stop + 0.25`.
|
||
|
||
For 19:39 the interval was `(0.75, 1.156973] m`, width 0.406973 m. Pulse 7 moved
|
||
0.906973 m, leaving 1.420035 m. Pulse 8 was correctly permitted at that point,
|
||
moved 0.438292 m and left 0.982344 m: outside the completion radius but inside the
|
||
refusal interval. Waiting cannot change this while fully stopped. The earlier
|
||
large stop is correctly retained; dropping it merely to allow another pulse would
|
||
remove evidence from the safety decision.
|
||
|
||
Both successful runs also had a smaller decision interval, but their final
|
||
pulses crossed it: 19:41 moved from 1.046375 to 0.475079 m; 19:17 moved from
|
||
1.062121 to 0.490408 m. Their success does not prove the policy can always finish.
|
||
|
||
## Input timing versus native movement
|
||
|
||
The policy currently sleeps 50 ms after W-down, **then runs the complete private
|
||
ownership/focus guard while W remains held**, and finally sends W-up
|
||
(`perform_approach` lines 229–245, 276–281). The helper's `Guard.check()` validates
|
||
display binding, window/process identity, native arguments, focus/mapping and a
|
||
second display binding. Those checks must remain intact.
|
||
|
||
Measured down-to-up durations were approximately 240–265 ms in both successful
|
||
runs. Thus the nominal 50 ms sleep is not the actual pulse duration: roughly
|
||
190–215 ms was spent in the release path and scheduling. The largest failed-run
|
||
pulse lasted 313.187 ms, leaving 263.187 ms beyond the requested sleep. This is
|
||
consistent with extra guard/IPC or OS scheduling latency. The archives do not
|
||
contain guard start/end or XTest timing breakdowns, so they cannot identify which
|
||
operation caused that excess. All recorded holds remain below the 400 ms cap.
|
||
|
||
The large stop is physical, not just a helper distance calculation. In the
|
||
[19:39 console](evidence/game-2026-09-19-193924-approach-stopping-reserve/console.log.txt),
|
||
pulse 7 spans samples 240–252. Sample 240 at 57,156 ms is stopped at
|
||
`6090.89,211.331,7156.87`. Native forward is positive at samples 241–243;
|
||
movement input is positive at 242–243. At sample 244 (57,653 ms), forward and
|
||
movement input are already zero, but velocity is approximately 2.149 m/s and the
|
||
body is at `6091.44,211.323,7156.50`. It travels another **0.244 m** before the
|
||
stopped position `6091.64,211.319,7156.36`, first zero-velocity sample 247.
|
||
Thus native momentum after observed release contributes materially. Sparse
|
||
100–138 ms samples cannot locate the exact engine receipt of W-up.
|
||
|
||
Comparable holds also produce different stops: 19:41's 240.434 ms pulse moved
|
||
0.568595 m, while its 261.644 ms pulse moved 0.432666 m. A linear duration-to-distance
|
||
model is not justified. Every accepted pulse retained both positive native input
|
||
acknowledgement and at least 0.05 m physical movement/progress; full-stop observation
|
||
was required afterward.
|
||
|
||
## Smallest next improvement, still unqualified
|
||
|
||
First record bounded monotonic guard-entry/return, W-up request and final native
|
||
stop timestamps in a future experiment. This isolates release latency without
|
||
changing input or authority. A small subsequent algorithm candidate is to perform
|
||
the **same full release guard during the initial 50 ms hold interval**, rather
|
||
than always adding it afterward. If that guard returns before 50 ms, wait the
|
||
remainder and recheck it immediately before W-up. If it already consumed 50 ms,
|
||
release immediately after its successful return. Keep emergency cleanup and the
|
||
1.5-second hard key lease unchanged; never release from a stale cached guard.
|
||
|
||
This could remove the unconditional extra 50 ms when validation already takes
|
||
~200 ms, without weakening the 0.75 m target, 0.25 m reserve, 400 ms actual-hold
|
||
cap, positive native input/0.05 m movement acknowledgement, full stop, original
|
||
35-second approach allowance or 45-second native lifetime. It is only a bounded
|
||
candidate: shorter pulses may be missed by native sampling and must then refuse;
|
||
extra pulses could exhaust the existing count or time budget. A slow guard can
|
||
still dominate the hold. Tests must cover fast/slow/refused guards, real elapsed
|
||
hold, release cleanup, missing native acknowledgement and unchanged reserve.
|
||
|
||
There is **no source-proven safe completion fix for an already reached deadzone**
|
||
under the current maximum-stop rule. Do not substitute the latest smaller stop,
|
||
ignore the outlier, silently reset the maximum for a shorter pulse, cross the
|
||
reserve, enlarge the target or extend the lifetime. Any future shorter-pulse
|
||
strategy needs its own measured conservative stopping bound before it can safely
|
||
address that remaining limitation. No such bound or improved runtime outcome is
|
||
claimed here.
|
||
|
||
|
||
## Implemented timing candidate, not yet native-qualified
|
||
|
||
The candidate now performs the same full ownership guard immediately after W-down.
|
||
If it finishes before50ms, the policy waits only the remaining time and then
|
||
performs another full guard. W-up follows the latest successful full guard; no
|
||
cached authority authorizes a later release. Bounded `release_timings` records
|
||
retain guard entry/return and key-up attempt/return times. Failure still follows
|
||
the independent guarded finally-release path. No safety or completion limit was
|
||
changed. The input helper also waits for the native READY event before initially
|
||
binding a game window; after binding, any replacement still refuses.
|
||
|
||
The25 approach,11 independent evidence and79 helper checks pass, including the
|
||
actual-main startup race. Shorter pulses can require more steps: the old synthetic
|
||
180ms-guard scene now reaches the unchanged12-pulse limit and is explicitly tested
|
||
as a safe refusal; a separate220ms-guard scene completes. This is neither evidence
|
||
of native improvement nor a resolution of the stopping-reserve deadzone. A new
|
||
source-bound native trial remains necessary; prior approach successes do not
|
||
qualify the changed timing.
|
||
|
||
The first [native timing candidate202949](evidence/approach-timing-review-2026-09-19-202949/review.json) passed camera calibration but failed its original approach deadline. It sent12 paired W pulses and14 yaw requests;11 full stops were completed before expiry. Actual holds were 195.1–236.3ms (median200.9ms), and largest completed stop was0.438m. Observed path was3.965m. All releases and owned cleanup were confirmed. The improved release latency therefore did not produce a completed route within the existing budget. No wheel/F was sent; the failure remains archived.
|
||
|
||
## Separate coarse-heading experiment (native pending)
|
||
|
||
The failed 202949 timing run spent its original budget on 14 small yaw requests
|
||
and 12 forward pulses despite shorter measured holds. A new **explicit**
|
||
`--exercise-prison-coarse-approach` runner flag requires the existing approach,
|
||
relative-look, gate-observation and private-display/input flags. Its matching
|
||
helper flag is `--enable-private-coarse-approach-proof`. Neither flag enables F,
|
||
pitch, a gate operation or any new native observer lifetime.
|
||
|
||
| Bound | Default `standard` | Explicit `coarse` |
|
||
| --- | ---: | ---: |
|
||
| Relative horizontal mouse request | 128 px | 384 px |
|
||
| Desired yaw proposal before pixel rounding | 10° | 25° |
|
||
| Actual native turn, including every intermediate sample | 15° | 35° |
|
||
| Maximum paired W pulses | 12 | 16 |
|
||
|
||
Both retain 16 total turns, 2,048 total pixels, the exact private pointer's current
|
||
and proposed clipped bounds, fresh full ownership/focus checks, stationary body
|
||
requirements, directional native acknowledgement and full settling. A coarse
|
||
request can still be refused because it does not fit the owned pointer area.
|
||
Both retain the 35-second absolute READY deadline and 45-second QUEUED observer
|
||
window, 1.5-second supervised key lease, 400ms actual W hold limit, positive
|
||
sampled native forward input, full native stops, 0.75m endpoint tolerance, 0.25m
|
||
reserve added to the largest measured stopping distance, six-metre total path,
|
||
and the existing interior/velocity bounds. No limit renews when heading finishes
|
||
or an input is refused. The known stopping-reserve deadzone remains a refusal.
|
||
|
||
The route report records `profile`; omitted profiles in historical reports mean
|
||
`standard`, never coarse. Only those two names are accepted. Runner launch context
|
||
and helper report independently bind `coarse_approach_requested`, while the existing
|
||
exact helper and approach-module SHA-256 records bind the implementation. Final
|
||
qualification rejects an unrequested coarse flag/profile, changed module hashes,
|
||
or helper-only completion, and rechecks actual native intermediate turns under
|
||
the selected profile. Default commands retain the previous capability limits.
|
||
|
||
Offline tests cover default compatibility, an attainable simulated coarse route,
|
||
exact 16-pulse exhaustion, intermediate overshoot, unknown/unrequested profiles,
|
||
private pointer/focus/expiry refusal and retained stopping/hold rules. These are
|
||
policy and adapter tests, not evidence of improved ordinary gameplay. Previous
|
||
failed runs keep their original profile and result; the new experiment requires
|
||
its own source-bound native run before any success claim.
|
||
|
||
## Native selection checkpoint, 21:06
|
||
|
||
The facing-only redundant-read correction passes the [ordinary private input trial](evidence/game-2026-09-19-210642-lock-selection/runner.json.txt). Independent raw validators accept the coarse approach (15 W pairs, seven yaw requests, 4.553 m path, 0.697 m final target error), stationary facing and exactly one wheel-button 5 pair. The original lock ID 0 is selected at samples 331/332; the original 8-second facing/selection and 45-second observer clocks were preserved. Native source and helper bindings remain archived with confirmed cleanup. This does not prove held F, unlock, physical door motion, walking through the gate, a full escape or multiplayer behavior.
|
||
|
||
## Native coarse-facing checkpoint,21:21
|
||
|
||
The [explicit coarse-facing trial](evidence/game-2026-09-19-212117-coarse-facing-selection/runner.json.txt) passes the full ordinary approach, facing and one-wheel selection chain. Facing took2.726seconds and two requests, compared with5.178seconds and four requests in the21:06 standard-facing run. Selection took1.500seconds;7.772seconds remained in the conservative original observer budget afterward. This comparison concerns two local trials, not a reliability or FPS benchmark. No F was sent. The separate [held-action experiment](prison-held-action.md) uses that unchanged original observation budget.
|