An agent that did not write this code audited it against the contract's §9,
§7 and §11.3. Four of its five findings are fixed here (the fifth, the sync()
ordering, landed in the previous commit).
1. QBZ_KIOSK_FULLSCREEN was INERT and the log LIED about it. fullscreen_at_boot()
had exactly one caller -- choosing a log string -- so an appliance boot with
the env set stayed windowed while printing "-> fullscreen-at-boot". The
reference does the real thing at qbz/src/main.rs:8611. Now a seeded-at-
construction QbzShell.kioskFullscreenBoot drives Main.qml's `visibility`
declaratively, so it is part of the FIRST mapped frame. It is one-shot by
construction and requires BOTH the profile and the env, which is what keeps
a desktop user who toggles kiosk and restarts from being trapped in a shell
with no titlebar control (incident 2026-07-11).
2. Shift+I was a reachable DEAD STATE. The rebindable ui.focusMode action
reaches the hotkeys dispatcher from the kiosk root like any other non-nav
key, so QbzImmersive.open went true over the sanctioned EMPTY mount -- and
the kiosk root then rejects every arrow, Enter and Esc while it is true, so
the whole zone model froze against a surface that renders nothing. The
visualizer tile already declined to open it for this exact reason; the
guard now sits in apply_open, the funnel every entry passes through,
because the tile was not the only door. It refuses to OPEN, never to close.
3. Kiosk chrome on the small bar was half-ported. The reference HIDES the
Lyrics and Queue buttons in kiosk (PlayerBarSmall.slint:846, :983); the
port gated only their click handlers, so both still rendered and still
toggled side panels the kiosk shell never mounts -- inert affordances,
which §9.2 forbids.
4. "Kiosk mode" and "Desktop mode" shipped untranslated. My check_msgids.py
compared against the 31 @tr strings in the Slint KIOSK sources, which do
not include the two strings this port adds to the view-mode menu -- the
checker was right and its input was incomplete. Both now in all 7
translated locales.
Verified by driving, in one frame: the small bar's right cluster no longer
carries the Lyrics and Queue glyphs, and after Shift+I two Rights still move
the shelf cursor (scratchpad/kiosk/f-02-after-shiftI.png). The fullscreen arm
is verified only as far as a headless run can go -- both env branches log
correctly and the binding resolves -- since actual fullscreen needs a real
display, which is Pi/owner-smoke territory.
cc