evidence · 6.0 KiB

README.md

Committed at docs/evidence/card-shell/throw-fixture-sync/README.md. This is what grounds the requirements that cite it.

Open raw source

Wait for fixture classification before the close throw

The board-injected repaint-stage run at revision 58461f518821 recorded 12 of 13 acceptance checks. Its upward-throw-close-request check failed. The source artifacts are ../repaint-stages/board/run-1/public/acceptance.json and ../repaint-stages/board/run-1/public/telemetry.log, collected 2026-09-23 23:55–23:56 UTC. The run used normal system gnr36q… and package xv8x9…. The subsequent persistent Close control did request close; the client explicitly refused it. This does not prove the throw requested close.

The acceptance fixture removed k230_card_unavailable and immediately started the throw. The retained shell telemetry is newest first. In event order, lines 50, 49 and 46 show deck message 3 (unavailable), then dragging with message 3, then deck message 0 (live) with actions 33 (reconcile and redraw). The source policy cancels a pressed drag when its card changes content class. The prior successful injected run’s same segment has the live reconciliation before its series of drag motions and close request (../throw-sampling/board/run-1/public/telemetry.log, lines 67–41).

The fixture now records the selected client’s compositor card ID and its current mirror-event count before clearing the unavailable mark. It waits up to three seconds for a new mirror event for that exact card, which occurs only after live classification and scene synchronization. If none appears, setup fails before the throw instead of reporting a gesture outcome. Raw Sway journal lines carry a timestamp and source prefix, so the count uses the existing strict telemetry normalizer before matching mirror events. Counting is independent of the journal’s output order and ignores prior mirror events and other cards. The policy’s content-change cancellation, throw thresholds, twenty-frame input sequence and acceptance cases are unchanged.

Run the narrow host check with python3 tests/test_card_shell_board_tools.py. This is host fixture proof only. The coordinator-owned board repeat below observes all thirteen checks; this change does not establish real-finger behavior or repair the separate performance budget failures.

Retained setup failures and runtime correction

Two coordinator attempts stopped before acceptance and are retained here:

Neither attempt ran the corrected throw fixture. Their transfer reports retain archive hashes; these are setup failures, not failed gesture observations.

Revision a3fecb7c generates a unique /run/k230-card-shell- directory with an alphanumeric suffix and checks it against the session helper’s actual guard before creating or arming it. That same helper is copied into the protected runtime for both compositor/input execution guards and the restore watchdog. python3 tests/test_card_repaint_runner.py passes two host checks covering unique valid names, socket path length, and continued rejection of the invalid prefix. The 27 existing session/fixture tests and four cache policy tests also pass. An independent source review found no new safety gap. These checks do not substitute for the board repeat below.

Board repeat after correction

board/result.json records the published tools at a3fecb7c, running the same xv8x9… compositor package on the normal system from 2026-09-24 00:23:39 to 00:25:23 UTC. All 13 injected checks were observed, including the upward throw, explicit refusal, timeout recovery, accepted source exit, live parent and child surfaces, and persistent control routes. This supports the fixture classification-race diagnosis; one passing repeat does not prove universal throw reliability or physical-finger acceptance.

The cost reports still fail:

CardsSubmitted framesUpdate CPU p95 / maxTracking interval p95
One13716.531 / 49.230 ms57.481 ms
Two14023.855 / 25.644 ms57.485 ms

The declared CPU limits are 16.667 ms p95 / 33.334 ms maximum; tracking is 33.334 ms p95. Input-to-submit/present, release, and incremental-memory checks pass, with no missing benchmark evidence. board/profile.json correlates all 277 submitted frames to repaint-stage accounting. It is diagnostic profiling, not an optimization comparison. board/verification.json records coordinator reproduction of the budget and all producer hashes against the published source. The paired scaled-cache trial is the next performance experiment.

normal-restoration.json and its serial transcript independently confirm the same installed system, normal shell and seatd, associated Wi-Fi and HTTPS, protected credential permissions, storage capacity and protected boot-file hashes. The boot ID is unchanged: this check did not reboot or flash. Raw native captures remain protected on the board; this repeat adds behavioral traces, not a new visual or camera acceptance claim. Tasks 4.2, 5.1 and 5.3 stay open.

Independent coordinator review reproduced the staged producer hashes and checked trace ordering: in the newest-first telemetry, unavailable state at line 69 is followed chronologically by new mirror events for card 7 at lines 66/65, live state at line 64, drag at lines 62–42, and close request at line 41. This establishes reconciliation before this injected throw.

The one-card CPU outlier is frame 167: 49.230 ms total includes 33.468 ms of aggregate input work across five coalesced motion events and 15.537 ms of render work. It does not identify a single slow motion callback. A next input profile should subdivide policy and scene synchronization inside the existing charged interval, preserving the total CPU accounting and declared limits.