Files

50 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# First private ordinary keyboard experiment
`tools/headless_input_proof.py` is opt-in diagnostic tooling. The first native attempt (2026-09-19 16:49:44, nonce `a6c78356cf0847e19404c90ecdf1638e`) delivered W and recorded native movement, then failed the immediate key-release state check before attempting Tab; its guarded finally release was confirmed. It did not complete this experiment. Its automated tests substitute every native display/input operation. It does not qualify normal play, an escape route, multiplayer, or performance.
The helper runs **inside the existing private headless Gamescope**, wrapping the existing read-only display helper unchanged:
```text
python tools/headless_input_proof.py --enable-private-keyboard-proof \
--host-display ORIGINAL_HOST_DISPLAY --prefix PRIVATE_COMPAT/pfx \
--game-executable ABS_GAME_EXE --profile OWNED_PROFILE \
--report OWNED_PROFILE/input-proof-RUNID.json --nonce RUNID -- \
python tools/headless_display_probe.py [its existing exact context/report options] -- \
ABS_INSTALLED_PROTON run ABS_GAME_EXE [existing args including -errOrdinaryInputObserve RUNID]
```
The root runner supplies the real arguments; this is not a command to execute on the user's desktop. The outer wrapper requires the same sibling display helper, interpreter, profile, prefix, game executable and observer nonce, plus the installed private Proton command. It starts no second game. A sidecar form with an explicit `--console` is possible only from the same Gamescope ancestry and still requires all live ownership checks; a host shell cannot qualify.
Before child launch it snapshots existing session directories. It accepts exactly one newly created canonical native `console.log`, pins the inode, starts reading at its current end and accepts only subsequently appended exact-nonce observer records. No old READY can authorize input. Session replacement/truncation, reversed clocks, malformed matching markers, sample bounds, observer cancellation, missing READY or missing inventory acknowledgement refuse the sequence. The actual game process must carry that nonce and exact private profile in its native arguments.
Each event requires the existing Gamescope/Xwayland listener and PID/start binding, native game executable/prefix/display and XRes/client PID agreement, exact original game window, mapped InputOutput geometry and existing same-game keyboard focus. It never focuses, raises, moves, resizes or points at a window, and never uses a host DISPLAY fallback or an input portal. The original explicit X11 connection is retained throughout. No key mapping/settings are changed; default unmodified `w` and Tab keysyms must resolve exactly. An already held private key refuses the experiment.
After fresh READY, the fixed request is W down/up, Tab down/up, wait for native INVENTORY_OPEN, retain a three-second checked open interval for native rendering/capture, then Tab down/up and wait for INVENTORY_CLOSED. Requested hold delays are 300 ms and 50 ms respectively, but ownership checks take time: **recorded per-event monotonic timestamps determine actual request duration**, not the requested sleeps. Native click filtering may reject a slow Tab; the helper preserves that failure. After each key-up, a bounded read-only XQueryKeymap poll must show all keys released. A busy state can be checked again at 25 ms intervals for at most 350 ms with fresh ownership/focus checks before each query; no additional input is sent during polling. Failed native queries and lost ownership/focus abort immediately. Release observations retain attempt counts and times. The unchanged 1.5-second supervisor covers the entire pending press. A final native key-state check is still required before completion. XTest request return/XFlush alone is insufficient.
A separate process supervises the worker before any Xlib connection is opened. A pending press may remain unconfirmed for at most 1.5 seconds before the supervisor interrupts the worker, allows one second for its guarded finally release, stops the exact created display-wrapper child and kills an unresponsive worker. The whole worker is bounded to 190 seconds. Native I/O can hang, so a finally release cannot be guaranteed: the supervisor records `supervision_failed`, `unconfirmed_held_key`, and false `all_attempted_presses_released` when appropriate. It does not open another connection or retry input after lost ownership/focus. The parent runner must immediately perform its existing whole private process-group/prefix cleanup on helper exit/failure; the helper never claims to have cleaned that entire group.
The worker writes its exclusive JSON report as soon as the input sequence completes or refuses, then preserves the wrapped child's lifetime until normal outer-runner shutdown. Expected shutdown after a finished proof does not manufacture a sequence failure. A timeout during the experiment can amend only the exact report inode exclusively created by that worker, preserving an explicit failure even if native code prevented the worker writing it.
Report schema 1, kind `headless-private-keyboard-experiment`, binds helper hashes, child command, report/profile/executable/nonce, live ownership and exact console inode/byte interval. Success requires `hard_supervision`, six correctly ordered events, `sequence_completed`, `all_attempted_presses_released`, no `supervision_failed`/error/unconfirmed key, and the native READY/open/closed sequence. `gameplay_qualified` and `release_qualified` remain false. The runner must independently inspect the native observer's action/input/velocity/displacement records; helper completion is not movement evidence.
Installed primary API evidence is `/usr/include/X11/extensions/XTest.h` (`XTestQueryExtension`, `XTestFakeKeyEvent(Display*, unsigned int, Bool, unsigned long)`) and `/usr/include/X11/Xlib.h` (`XQueryKeymap`, key mapping, flush and existing read-only primitives). The installed default Reforger `CharacterForward` W binding and Tab click action are described in the ordinary observer design. XTest inputs are scoped to the verified nested X server, but focus can change between any read and a server event: repeated checks reduce this race and do not imply atomic focus reservation. No server grab or focus manipulation is used.
The initial report overwrote the worker refusal with a generic unsuccessful-exit error. Later reports retain the original `error` and record the supervisor reason separately as `supervision_error`, preserving any earlier unconfirmed release. Delayed Xwayland state propagation is a diagnosis to test, not a proven explanation of that first failure; the historical failed report is unchanged.
## Native observations and remaining limits
[First attempt](evidence/game-2026-09-19-164944-input-release-refusal/report.json) delivered W and physical movement, but stopped after release-state confirmation refused. Its first supervisor implementation overwrote the underlying error; the archive is retained unchanged, so delayed key-state settlement remains an inference for that run. The corrected helper preserves both worker and supervisor diagnostics, polls read-only key state briefly, and retains all ownership and timeout checks.
[The retry](evidence/game-2026-09-19-165512-input-window-refusal/report.json) confirms W/Tab release and observes actual inventory opening. Two native GUI errors then cause normal parent cleanup; the helper subsequently losing the game window does not establish a separate window-replacement bug.
[The 10-second failure-grace diagnostic](evidence/game-2026-09-19-165832-input-inventory-errors/report.json) completes all six key events, confirms server key release, observes 2.62 m native movement plus exact inventory open/close transitions and later neutral native input. Actual W hold is 0.64995 s; Tab holds are 0.23264 s and 0.23491 s, close to the installed 250 ms click limit. These measured values include guard overhead. The sequence is a bounded mechanism observation, not robust general input automation. Native inventory produces two `OverlayWidget Frame0 ... GridWidgetSlot ... expected: LayoutSlot` errors; the run stays failed, and its 45-second sampler is intentionally cut short by the existing 10-second diagnostic grace. No errors are suppressed and the helper's completed sequence does not override the failed native result.
All three runs confirm owned-prefix cleanup and unchanged 192-file addon sources. Baseline/open/closed native BMPs are archived for the third run. The open-labelled image still shows the prior world frame; the request marker and UI-state observation do not prove visible inventory presentation. A delayed capture must revalidate the exact menu before that visual claim. The subsequent [stock control and source diagnosis](inventory-slot-diagnosis.md) independently reproduce the target pair while preserving the control’s separate nine-error failure.
The [180423 ordinary Chat run](evidence/game-2026-09-19-180423-inventory-ready/runner.json.txt), using the storage-list adapter and settled capture, completes the bounded keyboard experiment with no captured engine/script errors: all six events and releases are verified, the independent native observer records 401 samples and 2.62 m maximum horizontal displacement, and exact inventory open/close plus later neutral input are observed. Private-window ownership and cleanup are verified, with unchanged 193-file addon sources. [Raw input evidence](evidence/game-2026-09-19-180423-inventory-ready/input-proof.json.txt) retains event times and ownership rather than inferring success from the key requests alone.
Native initialization advances from stage 6/five hit-zone points to stage 7/seven points with the loading overlay absent. The settled [open screenshot](evidence/game-2026-09-19-180423-inventory-ready/err-input-a75280fda4494a0ca7b14a693cf310e9-open.bmp) shows the character, vicinity and clothing slots without the overlay. This is first-open presentation evidence, not a finding that the entire interface is readable or every interaction works. The clean 175333 image still had a spinner; the clean 175938 run produced no open image, with no established cause. Those records are not rewritten by this later success.
Storage refresh, reopen cycles, item transfer and multiplayer remain pending. The completed experiment is a short ordinary keyboard movement/open/close path; it does not qualify a full escape route, broad input automation, authenticated multiplayer, FPS improvement or release acceptance.