evidence · 4.5 KiB

reveal-stream-host.md

Committed at docs/evidence/coherent-shell/reveal-stream-host.md. This is what grounds the requirements that cite it.

Open raw source

Compositor-to-Rust reveal stream: host and QEMU checkpoint

Source branch impl/card-reveal-stream, based on 99ac8e48cc3147a736fb7ba2366bb0cb6eb0b9d9. Sender revisions ea920846ae44d602c21953b0cbb97f2289662590 and e185c9d7ee9314688a9dce3ffe9c5a6de0e4c4ae implement the compositor sender and runtime fixture. The Rust client owns the separately developed receiver/rendering half. The existing coherent-shell tasks 1.1, 1.2, 2.1, 4.2 and 4.4 still require integrated runtime and board proof; no task is completed by this host check.

SWAY_K230_CARD_REVEAL_STREAM=1 opts the touch-first card route into one nonblocking Unix stream per bottom drawer or top shade gesture. The configured SWAY_K230_CARD_SURFACE_SOCKET must equal $XDG_RUNTIME_DIR/k230-shell-rust.sock; the runtime directory must be owned and private and the socket must be owned, mode 0600. Without this flag the fixed-argv SWAY_K230_CARD_SURFACE_HELPER route remains the separate rollback behavior. The stream never forks a helper on each movement.

Each newline JSON message is at most 128 bytes with exact bounded fields:

{"v":1,"kind":"reveal","surface":"drawer","phase":"update","seq":123,"progress":350}

surface is drawer or shade; phase is begin, update, finish, or cancel; seq is unique per gesture stream. Progress is an integer 0–1000 following vertical travel, including reversal. A qualified release sends finish target 1000; an early release sends target 0. The client settles from the latest update. The compositor owns touch classification, live app/deck pixels, and focus; the Rust client owns only its transparent overlay pixels and local settle. Its layer can map during tracking with an empty input region; the card adapter keeps that same layer above live cards without treating its own reveal as a takeover. Once settled open, the normal overlay gate applies.

Writes and connection checks are nonblocking. A bounded current frame, latest coalesced update, and terminal frame preserve begin→latest update→finish/cancel order under backpressure; no unbounded motion queue forms. A connection or write failure closes the stream, drains the owned contact and leaves the live app/deck scene available. EOF after a complete terminal message is normal for the client; EOF before it is a client-side cancel. The host test covers exact fields, frame bounds, sequence separation, private socket rejection, and an idle finger pause longer than the connection/write deadline.

Commands and results from the exact sender revision:

python3 tests/test_card_shell_reveal.py       PASS 1 native stream/socket case
python3 tests/test_card_shell_route.py        PASS 1 fixed-helper regression case
python3 tests/test_card_shell_chrome.py       PASS 1 chrome case
python3 tests/test_card_shell_state.py        PASS 25 native policy cases
git diff --check                        PASS
nix build .#card-shell --max-jobs 1 --cores 4 --no-link --print-out-paths
                                      PASS /nix/store/13mxaxxmldpmcx418d6cq9bjvcc72ifb-k230-card-shell
CARD_SHELL_SWAY=/nix/store/6a0jd8i6sg8ix6j9mkhz72wnb4h5diyg-sway-unwrapped-riscv64-unknown-linux-gnu-1.12/bin/sway CARD_SHELL_CLIENT=/nix/store/6nskh3ldk3ya7mwxbb258qszrxhw2i61-card-composition-probe-client-0.1/bin/card-composition-probe-client python3 tests/test_card_shell_touch_first_runtime.py
                                      PASS 1 actual cross-built Sway under headless QEMU

The QEMU test observed three separate streams (drawer finish open, shade finish closed after reversal, shade second-contact cancel), no per-motion helper invocation, and an actual k230-shell-drawer layer painted above the live card during tracking. The sender’s built unwrapped Sway is the ELF path above; the card package’s .sway-wrapped is a shell script and cannot be passed directly to qemu-riscv64-static. The fixture uses a native socket collector and magenta layer fixture, not the Rust receiver. Build log: /tmp/k230-card-reveal-build.log; retained local headless log: /tmp/k230-card-reveal-e185-qemu/sway.log. These /tmp files are local diagnostics, not committed artifacts.

Remaining gates: integrated Rust client mapping and captured pixels on begin, intermediate movement, reversal, and settle; client disconnect, source-unmap/privacy and keyboard ownership tests; then reserved real-finger/panel presentation and existing frame CPU/cadence budgets. The current QEMU test proves stream semantics and overlay stacking, not Rust pixels, actual output presentation, physical touch, or final shell acceptance.