No-input boot interstitial
Contents
- Purpose
- Display architecture
- Progress contract
- Build and test
- Installation contract
- Failure behavior
- Remaining hardware gate
Purpose
opemos-interstitial is a dedicated, no-input graphical session displayed
while the boot guardian checks exact-kernel NVIDIA support. It is not KDE,
Gamescope, a window manager, or a replacement desktop. The service completes,
releases the display, and allows SteamOS to continue to the Gaming or Desktop
session it had already selected.
This component is separate from the windowed SteamOS desktop companion. The companion runs after a desktop exists; the interstitial is designed specifically not to require one.
Display architecture
The Linux executable opens only a DRM primary node whose kernel driver reports
simpledrm, finds a connected bounded mode, creates an XRGB8888 dumb buffer,
draws the OPEMOS interface entirely in software, and applies a legacy KMS
modeset. This preserves the UEFI GOP-selected display during recovery without
binding or selecting a vendor GPU. It does not initialize OpenGL, Vulkan, CUDA,
X11, Wayland, Gamescope, or any input device.
The renderer scans only /dev/dri/card0 through card15, caps a mode at
8192×8192 and 33,554,432 pixels, accounts for the device pitch, and restores
the prior CRTC/framebuffer state before destroying its own framebuffer. SIGINT
and SIGTERM are converted into a normal cleanup path. A 300-second application
watchdog and a 315-second service ceiling keep a broken display path from
holding graphical boot indefinitely.
The systemd service is ordered before display-manager.service and
graphical.target. The guardian starts after the interstitial process has
launched and writes its status through a root-owned runtime document. Renderer
failure is deliberately fail-open for presentation: it is recorded in the
journal, DRM is released, and the authoritative guardian continues through the
existing framebuffer/text console where one is available, or headlessly when
firmware exposes no local framebuffer.
Progress contract
The renderer accepts only a bounded schema-1 document at:
/run/opemos/interstitial/progress.json
The canonical fields are schemaVersion, sequence, status, phase,
completed, total, stepCompleted, and stepTotal. The first counter pair
drives the labeled blue, operation-wide bar. Once these counters become known,
they cannot return to indeterminate state or decrease during that run. The
optional second pair drives the separately labeled green current-stage bar; an
absent pair is rendered as bounded indeterminate motion. This keeps unknown
stage totals honest without making a phase transition look like the whole
operation moved backward.
Step progress may reset only when the enumerated phase changes. Schema-1
consumers accept documents produced before the optional step pair was added,
while current producers always emit both step fields. There are no
caller-controlled labels, paths, shell
commands, URLs, or error messages. Phases are enumerated in the Rust model and
the Python writer; interstitial/progress-schema-v1.json is the versioned
consumer fixture. Sequence numbers must increase, terminal states are
immutable, and determinate counters must be paired and internally consistent.
The file is opened with O_NOFOLLOW, bounded to 64 KiB, and in production must
be root-owned and not group- or world-writable. interstitial_progress.py
serializes concurrent writers with a private lock and publishes each update by
fsync followed by atomic replacement.
Unknown totals render as a stationary striped track. This preserves an honest indeterminate state without making either bar travel backward, jump to its starting edge, or imply a measured fraction that Core does not have.
Build and test
Build the SteamOS/Arch x86_64 binary:
cargo build --locked --release --manifest-path interstitial/Cargo.toml
Portable model and rasterizer tests remain separate from the browser preview:
cargo test --locked --manifest-path interstitial/Cargo.toml
python3 tests/interstitial.py
The root launchers provide the same 5–600 second, loopback-only browser simulation and assert the health response, bounded phase content, progress tracks, and canonical pill before reporting success:
| Preview host | Browser command | Headless contract check | Scope |
|---|---|---|---|
| macOS | ./test_update_macos.sh |
./test_update_macos.sh --no-open --duration 5 |
Previews the Linux/SteamOS interstitial; it does not update macOS drivers. |
| Linux | ./test_update_linux.sh |
./test_update_linux.sh --no-open --duration 5 |
Native loopback browser preview of the Linux/SteamOS interstitial; it performs no driver update. |
| Windows PowerShell | .\test_update_windows.ps1 |
.\test_update_windows.ps1 -NoOpen -Duration 5 |
Previews the Linux/SteamOS interstitial; it does not update Windows drivers. |
Use --headless as an alias for --no-open in the shell launchers, or -Headless as an alias for -NoOpen in PowerShell. Each launcher
owns and cleans its temporary directory and server process. These commands
install nothing and perform no disk, privilege, QEMU, driver, signing, release,
trust, or production action. Windows and macOS display the Linux/SteamOS
interstitial in the platform browser; they do not update native drivers or
establish SteamOS runtime compatibility.
The Fedora x86_64 appliance compiles the Linux DRM implementation and attempts the real KMS path when QEMU exposes a connected scanout:
./tests/vm/run.sh --no-image-download --interstitial
If headless QEMU exposes a DRM node without a connected connector, the VM requires the bounded fail-open result and proves that no renderer remains.
Installation contract
The recovery guardian installer accepts an optional authenticated executable:
./bootstrap/install_recovery_guardian_to_root.sh \
--root /mounted/root \
--persistent-home-root /mounted/persistent-home \
--persistent-etc-root /mounted/persistent-etc \
--support-revision FULL_40_CHARACTER_COMMIT \
--nvidia 575.64.05 \
--interstitial-binary /staging/opemos-interstitial \
--interstitial-sha256 EXACT_SHA256
The two persistent roots are required. They must be the mounted filesystems or
overlays that appear as /home and /etc after boot and remain active across
a normal SteamOS A/B update. The installer deliberately refuses to infer them
from the inactive slot root: files written to that slot’s /home can be masked
at boot, and files written to its /etc disappear when the other slot becomes
active.
The binary and hash must be supplied together. The installer snapshots the input into a private directory, validates the exact hash and x86_64 ELF identity, and installs it mode 0755. Without the optional binary, the service unit remains conditionally inactive and the existing guardian behavior is unchanged.
The checksum is an installation binding, not an independent trust anchor. A normal-user release remains disabled until the binary, checksum, support revision, and release identity are bound by the reviewed desktop/update signing policy. CI output is a development artifact.
Failure behavior
- Missing
simpledrm, no connected firmware mode, invalid pitch, or a modeset error releases resources and lets boot continue through the existing framebuffer/text console or headlessly. - Missing, malformed, excessive, writable, regressed, or contradictory progress stops the renderer and leaves the guardian authoritative.
- A failed guardian state is shown as
RECOVERY NEEDS ATTENTION; the guardian selects its console-safe fallback independently. - The renderer refuses vendor DRM drivers and never enables a driver, changes a systemd default target, runs a repair command, or accepts user input.
Remaining hardware gate
The portable and Fedora contracts do not replace physical validation. Before enabling the service in a normal-user release, test simpledrm on real SteamOS hardware, display hotplug, internal/external displays, suspend/resume boundaries, abrupt power loss, renderer SIGKILL, and verified handoff into both Gaming and Desktop Mode.