diff options
Diffstat (limited to 'scripts/windows_input/README.md')
| -rw-r--r-- | scripts/windows_input/README.md | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/scripts/windows_input/README.md b/scripts/windows_input/README.md new file mode 100644 index 00000000..340ecb0e --- /dev/null +++ b/scripts/windows_input/README.md @@ -0,0 +1,213 @@ +# Local Windows input gauntlet (experimental) + +This is local Windows qualification infrastructure, not a claim that all Windows +input works. It sends real scan-code gestures through a new Windows Terminal +window, both directly to an observer and through an attached Herdr client. It +does not substitute `pane send-keys` for host input. + +## Safety and prerequisites + +Use an **unlocked, isolated interactive desktop** where you will not do other +work during automated input. The runner changes foreground focus and window +size. `SendInput` has an unavoidable check-to-use focus race; a foreground check +is not an OS security boundary. The runner rejects an elevated controller and +checks the target Terminal process token before focus, resize, and injection. +An elevation-query failure is also a refusal, not permission to proceed. Start +PowerShell and Terminal **without Run as administrator**, on a dedicated desktop. There is no unattended CI job or runner permission +change in this implementation. + +Required: Windows, PowerShell **7** (`pwsh`), Python 3, Rust/Cargo, and at least +one Windows Terminal channel. Stable and Preview are discovered independently +through their installed packages. Explicit paths are available when discovery +does not work. No software is installed or updated. The actual Terminal process path/version is recorded, +not inferred from the requested channel or bundled OpenConsole version. Stable +and Preview must resolve to distinct installations: the runner compares Windows +file/directory identities before launch, then checks actual image, installation, +and PID/start-time identities after activation. Aliases cannot count one install +twice. The portable report validator rejects duplicate identities too. + +**F12** aborts before the next automatic gesture. Moving focus away also aborts +further automatic input. Each injected chord contains its own releases; there +are no intentionally held modifiers between calls. Do not hold physical modifiers +or mouse buttons while starting a run. Normal controller cancellation runs cleanup; +bootstrap/probe leases also expire if the controller disappears. Lease expiry is +not a replacement for a secure isolated desktop. + +Clipboard tests require an **empty clipboard**. Clear it yourself only after +saving anything you need. The runner will not replace existing text, images, +rich formats, or files. It writes its synthetic text while holding the clipboard +lock and clears it afterward only if its sequence number is unchanged. A later +user clipboard update is left alone. No original clipboard contents are logged. + +## Run + +From the repository in PowerShell 7: + +```powershell +just test-windows-input +``` + +The full catalogue normally exits `2` because operator-assisted and explicitly +unimplemented qualification cases remain. That is incomplete coverage, not an +automated test failure; inspect the printed matrix and retained `report.json`. + +The recipe itself is the explicit opt-in to foreground input injection. It builds +the current checkout in release mode, stages that exact binary with the pinned +ConPTY runtime, and prints its path and hash. Use `-ExePath` only to compare a +specific old/new packaged binary. + +Or invoke the script directly: + +```powershell +pwsh -NoProfile -File scripts/test_windows_input.ps1 ` + -ExePath 'C:\test-app\herdr.exe' -AllowInputInjection ` + -StablePath 'C:\TerminalStable\WindowsTerminal.exe' ` + -PreviewPath 'C:\TerminalPreview\WindowsTerminal.exe' +``` + +The default tests current Herdr's **default** input policy. Diagnostic runs may +use `-Profile win32` or `-Profile vt`; they do not replace the default run. +`-Modes native,legacy,mok2,kitty`, `-Channels`, `-Paths`, `-Cases`, `-Widths`, and +`-Heights` select a focused campaign. In a direct PowerShell invocation, supply +arrays normally: + +```powershell +.\scripts\test_windows_input.ps1 -ExePath 'C:\test-app\herdr.exe' ` + -AllowInputInjection -Modes legacy,kitty -Cases mouse-interleave,mode-transitions ` + -Widths 120 -Heights 30 +``` + +Dead-key acute composition is automatic when the target Terminal thread's +active layout exposes that physical mapping. The runner discovers and injects +the real scan-code chord; it never substitutes pasted or Unicode-packet text. +`-Manual` enables AltGr, IME, and the remaining guided composition cases. The operator must activate the +indicated layout/IME, perform the gesture in the test window, then return to the +controller and press Enter. Finish each prompt within the 90-second lease. +Record the layout you actually selected in your qualification notes; the report +also includes the observed foreground thread layout handle. Do not paste text +for a composition case. The runner does not install/change global layouts. + +You can inspect the full catalogue without Windows or desktop interaction: + +```powershell +pwsh -NoProfile -File scripts/test_windows_input.ps1 -ExePath unused -MatrixOnly +``` + +Every run needs a **new** output directory. By default it is +`.local/windows-input/<unique-id>/`. Do not reuse an old report directory. + +## What the implementation measures + +- Native console records, including down/up, repeat, virtual/scan codes, Unicode, + modifier state, and raw payloads for other native record types. +- Legacy VT, modifyOtherKeys level 2, and Kitty disambiguation observer modes. + These are **pane consumer modes**, not names for Herdr's outer reader. +- Physical-style Enter/Shift+Enter and other modifier chords, navigation and word + movement chords, control keys, and editing keys. The oracle checks bytes or + records; it does not claim that a particular editor implements word selection + correctly merely because Ctrl+Shift+Right reached it. +- Actual Windows clipboard paste via Ctrl+V, including LF/CRLF/CR, whitespace, + BMP Unicode/combining characters, and escape-looking text. + A host binding or multiline-paste confirmation dialog can intercept the gesture; + the runner does not dismiss unexpected dialogs or rebind Terminal shortcuts. +- A full case pass at an observed 120×30 host size; keyboard/paste sentinels at + **80, 119, 120, 121, 132, 160, 240 columns**, at 24 and 50 rows; then return to + 80 columns. This exercises narrow→wide→narrow resizing of the actual outer + window. Both outer and pane dimensions are captured. Herdr chrome means pane + width is not the same as outer width. An unreachable size is not a pass. +- Automatic active-layout dead-key acute input, plus guided AltGr, extended + accent, and IME commits, with exact expected committed text. +- Ordered typing, mouse-motion reports, and bracketed paste in one capture, plus + click/wheel reporting before and after a real focus cycle, the same mouse + sentinel after resize, and legacy→modifyOtherKeys→Kitty→modifyOtherKeys→legacy + transitions without restart. + +The focus/resize mouse check runs in Windows Terminal. It guards Herdr's recovery +sequence but does not certify the Tabby/Alacritty host-specific report in #4284. +The catalogue also lists explicit **qualification gaps**: mouse drag and +right-edge coordinate mapping; visual reflow/wrapping; native held-key repeat; +lock/keypad combinations; dead-key cancellation; IME cancellation; capture/config +reload and attach cycles; injected setup/recovery faults; supplementary-plane and +confirmation-triggering burst paste; image/file clipboard integrations; and +positive host-scrollback evidence for native PageUp/PageDown. These are recorded +`not_run` or `inconclusive`, not fabricated successes. They need +separate fixtures/oracles before becoming automated assertions. The catalogue is +broad; the automated run does **not cover every row**. + +Injected PageUp/PageDown remains `inconclusive` through Herdr. On Windows +Terminal 1.24, both `SendInput` and `keybd_event` produced zeroed non-key records +even in the direct-host baseline, so absence of pane input cannot prove that +Herdr consumed the key. Conclusive qualification requires literal physical input +plus a positive pane scroll-offset change; that guided check is not automated yet. + +## Evidence and verdicts + +The retained directory contains: + +- `matrix.json`: all cases, profiles, and declared byte/record expectations; +- `observations.json`: raw captures, per-case identity, measured dimensions, + readiness/focus flags, errors, and cleanup results; +- `report.json`: interpreted verdicts and counts; +- per-window plans, nonce-bound observer acknowledgements, initial/final console + modes, and bootstrap/probe error records. + +The console ends with a capability matrix derived only from that run's captured +observations. Filtered, unavailable, or operator-assisted cases remain +`NOT TESTED` or `MANUAL`; the full evidence and reasons remain in `report.json`. +The Herdr column is labelled Win32 only after the current binary's selected +reader decodes a real nonce-owned Win32 serialized record. Configuration defaults +alone do not select the label; missing runtime evidence prints `UNKNOWN`. + +Direct-host and through-Herdr observations are labelled separately. A direct-host +failure is **not automatically a Herdr bug**. Each row labels its failure scope as +`direct_host` or `through_herdr_not_yet_attributed`. For example, a terminal may +intercept Alt+Enter or use a different control-key encoding. + +One explicit known-gap rule labels nonce-bound, complete **WT 1.24/1.25 +direct-host mOK captures** of Shift/Ctrl/Ctrl+Shift+Enter or Shift+Tab as +`unsupported` only when they contain the exact legacy bytes. It does not exempt +other tests or versions, an empty/malformed capture, Kitty, or any through-Herdr +failure. Through-Herdr still must preserve the requested gesture. +Unsupported remains incomplete coverage, not green. Review captures before +adding other capability exceptions; never bless lost Shift information in Herdr +just to make a report green. + +Comparisons consume the **complete captured sequence**, including a quiet interval +to catch trailing duplicates/releases. Paste must have one intact bracketed +wrapper and the complete payload. CR/LF variants are compared as logical newlines; +this is not proof of byte-exact line-ending policy. Native keys require their +non-modifier down/up pair, modifier state, and repeat count. + +Exit codes: + +- `0`: all observed assertions passed and no recorded coverage gaps/errors; +- `1`: an assertion, harness, or cleanup failed; +- `2`: coverage is incomplete (including deliberately unimplemented catalogue + rows, missing hosts, or unavailable geometry). + +An empty or missing report never means success. None of these statuses certifies +an entire Windows host. + +## Cleanup and native handoff + +Every window has a fresh nonce, named session, isolated config root, known +PowerShell pane shell, and observer acknowledgement. Inherited Herdr socket, +backend, session, and SSH variables are cleared in the actual launched process, +not just in the controller. Setup APIs only create/focus the observer pane. + +Cleanup targets the named session, retained child-process handles, and the exact +nonce-bearing Terminal window. There is no process-name-wide kill or sweep of +newly appeared OpenConsole processes. Artifacts are retained. Forced cleanup and +console-mode mismatches are reported, not hidden behind a passing key test. + +For release-risk input changes, qualify Stable and Preview, real focus-loss/F12 +interruption, partial startup, clipboard changes, cleanup, and measured width +boundaries. Use old and new Herdr binaries in **separate runs** to establish that +a known regression is caught. Do not overwrite installations or reuse an earlier +server. Portable unit tests validate the catalogue and verdict logic; they do not +replace native Windows evidence. + +The existing `windows_conpty_enhanced_input_probe.ps1` remains the downstream API +control. Existing Rust keyboard/Windows-translator tests remain the deterministic +parser controls. This runner complements them rather than cross-producting their +fixtures or pretending they establish host behavior. |
