evidence · 7.2 KiB

README.md

Committed at docs/evidence/card-composition-board/README.md. This is what grounds the requirements that cite it.

Open raw source

Live card capability probe on the K230

Recorded 2026-09-23. Evidence class: IPC-injected interactions on the physical board, native captures, actual Wayland clients and virtual keyboard events. No real-finger, optical cadence, product card UX or GPU acceptance is claimed. The root coordinator held /tmp/k230-board.lock for every serial operation; no subagent accessed the board.

Artifact and ownership

The opt-in package was imported into the existing Nix store. No image was flashed and no normal-service default changed. The harness stopped normal shell, started one transient Sway session as user shell, and restored the normal service. The checker observed normal shell inactive and exactly one Sway process during the probe. Seatd remained the device broker.

Procedure and observed result

On the reserved board, copy the committed harness to /run/card-session.sh, this directory’s check.py to /run/card-board-check.py, and tests/card_virtual_keyboard.py to /run/card_virtual_keyboard.py. Use the installed Python executable (recorded below) to run the checker while the bounded harness is active:

K230_CARD_DURATION=90 bash /run/card-session.sh \
  --probe /nix/store/wjzw7jw21p8qq4dsbc8b3fky9233pgqq-k230-card-composition-probe/bin/card-composition-probe \
  --restore-shell
# In the same reserved operator session, while the harness runs:
/nix/store/v189xydz6qkcd4cbkixcmv91w8hbc560-python3-riscv64-unknown-linux-gnu-3.14.7/bin/python3 /run/card-board-check.py
# Collection is read-only and also works after restoration:
K230_CARD_JQ=/nix/store/fy9xmga7mbqqiqp6gaj79239a98ssy9g-jq-riscv64-unknown-linux-gnu-1.8.2-bin/bin/jq \
  bash /run/card-session.sh --collect
bash /run/card-session.sh --verify-restored

result.json and check.log record ten passing checks: sole compositor, partial-allocation fallback, both animated parent and desynchronized child surfaces updating while shrunk, second-contact cancellation, stream cancellation, continuous motion, adjacent selection/expansion with keyboard focus, refused close recovery, accepted close/exit with focus fallback, and presentation signals. Expansion means restoration of the original floating app window, not a promise of fullscreen product animation. The coordinator inspected all six retained PNG captures; the fixture content and restored shell match the claimed states.

The final run began at 07:22:21 UTC. After the checker completed, the coordinator sent SIGTERM to the specifically recorded harness PID 6227. Its cleanup stopped the complete probe cgroup and restored normal shell; telemetry.txt records normal_services_active and shell_restored. An earlier successful 60-second run also restored automatically at its deadline; its result and telemetry are retained as card-board-first-pass*.

After each successful restoration, the separate injected uinput checker tested normal Apps Next/Previous/Back, keyboard toggle/reservation and Terminal focus. restore/result.json records PASS for the final interruption case, and card-board-first-restore.json records PASS after the deadline case. Both match the original system and boot ID. To repeat the restoration checker, also install docs/evidence/launcher-gestures/metadata-budget/check.py as /run/rollback_check.py and provide the existing injected touch device and tools/inject-tap.sh at /run/inject-tap.sh. This checks keyboard visibility and focus; it does not repeat or replace the user’s earlier physical typing proof.

Rendering, lifetime and cost observations

The observed output is DSI-1 at 568×1232 with logical scale 1. The committed scanout-format.txt was read from DRM debug state while the probe was active: RG16 little-endian (0x36314752), RGB565. Sway’s selector is render_bit_depth 6. The mode’s 52190 mHz value is advertised mode data, not measured frame cadence.

The source verifies Pixman at entry, and the emitted attachment records name renderer=pixman. Client buffers are SHM XRGB8888 (34325258), with 520×1040 stride 2080 or 480×720 stride 1920 parent buffers, and 128×96 stride 512 child buffers. Mirror buffers remain owned by wlroots scene surfaces. The log records references, mirror releases, commits, sampling, frame-done and output-presented separately. The final close/exit restoration recorded 386 commits, 568 samples, 568 frame-done signals and 142 output-presented signals. These counters are not interchangeable and do not measure optical latency or prove zero-copy.

The final mixed interaction/recovery run collected 22 session samples and 22 Sway process samples over 32.08 seconds. Session CPU increased by 19,030,008,000 ns; sampled session memory peaked at 19,550,208 bytes. Sway process CPU increased by 10 integer seconds and RSS peaked at 29,593,600 bytes. Process CPU uses procps cputimes and therefore has one-second quantization. Session memory accounting and process RSS count shared memory differently. The run includes allocation failure, captures and changing app count, so these are resource observations, not a steady-state benchmark or product performance acceptance. The product’s one/multiple-card benchmark remains required.

Rejected attempts and remaining limits

The retained rejected JSON files document failures rather than being replaced with the passing result:

Continuous real-finger tracking, physical OSK use inside the probe and optical presentation remain UNVERIFIED. Native screenshots and virtual keyboard events cannot prove them. The capability evidence permits continued product adapter work; the horizontal product deck, privacy policy, persistent controls, measured cost and refined webOS-style feel retain their own acceptance gates.