Fix the #405 boot regressions, add the Launchpad, and install the crates.io tool suite - #430
Merged
Conversation
Dropping the pid<=64 caller shortcut left init unable to register the endpoints it publishes for each capsule at spawn. It holds only the ambient caps and no RegisterService, so register_endpoint refused every one and no capsule reached the run queue. register_endpoint now checks only that the owner holds the caps the endpoint advertises, which is all the trusted spawn path needs. MkServiceRegister keeps the register-right gate for a new name and lets a capsule re-assert the endpoint the kernel already published for it, so a runtime squat is still refused.
mk_ipc_reply took the correlation token from a per-client queue kept separately from the pending-reply table it validated the reply against. With several callers waiting on one server the two orders diverged, replies went out under the wrong token, and callers discarded them and blocked forever. The whole desktop stalled at the compositor handshake. The pending-reply entry, matched by the caller's own inbox, already carries that call's token, so return it from remove() and use it directly. The separate correlation table is gone. A forged mk_ipc_send reply still carries token 0 and no pending entry, so it is still dropped.
A dock button opens a full-screen grid of every desktop app and installed tool, so the dock stays short instead of growing a tile per app. The grid is built from the launcher and tool tables, so adding an app or installing a tool fills a cell with no layout change. A click launches the service, or focuses the window when it is already open. Tools that ship no artwork get an icon drawn from the name.
grex, dotenv-linter, pastel, jsonxf, choose, tokei, huniq and csview, cross-compiled unmodified for x86_64-nonos against the std PAL, each signed and enrolled under the transparent STARK policy root and spawned after the desktop. userland/apps.list is the single source of truth: tools/nonos-app cross-compiles a crate, mints its publisher keys, writes its Capsule.mk and regenerates both the kernel registry and the Launchpad tool table from it. The vendored shims under upstream-src carry the target arms these crates need on nonos: getrandom over the CRND syscall, byte-based OsStr, a thread-local errno, advisory fd-lock, HOME-based dirs.
The eight tools shipped a hued letter-tile from the generator; give each a 48x48 glyph mask drawn in the same cyan line-art language as the desktop apps (a regex star for grex, a bar chart for tokei, a table for csview, braces for jsonxf, and so on). A tool with no shipped artwork still falls back to the generated tile. Also wire the tool_capsules module the generated registry needs: the macro and the spec were present but never declared, so the embedded-tool list did not compile.
A command-line tool has nothing to do until it is invoked, so the eight tools no longer spawn at boot. A new MkToolRun syscall runs one baked, attested tool by name, parented to the caller so the caller feeds its stdin and drains its stdout through the existing MkProcInput and MkProcOutput path. Only the baked set can be named, and the gate is IPC, so an ordinary capsule cannot point it at an arbitrary binary. The shell recognizes each tool as a bare command (tokei, grex foo, ...) and streams its output through the same async drain job the store installs use. A Launchpad tool tile opens the terminal, where the tool runs by name.
The nonos-app pipeline left grex, dotenv-linter, jsonxf and csview as prebuilt binaries with no rule to rebuild them, so a clean checkout (and CI) could not reproduce them. Vendor the byte-identical crates.io source for the four under upstream-src, like sd and choose, and add one templated rule that cross-compiles every installed tool to target/upstream-<bin>/bin/<bin>. grex and tokei gate their binary behind a cli feature, so those two re-enable it; the rest strip default features (unix-only pagers, update checks) the same way the shimmed tools already did.
Gate the baked tool set behind a nonos-tool-capsules feature so a core kernel check, which does not cross-compile the tool binaries, no longer tries to include_bytes them; the desktop profile turns it on. Drop the os_str_bytes shim's dependency on std::os::unix: the byte-based OsStr round-trips losslessly through the stable encoded-bytes API, so the four clap-based tools (huniq, choose, pastel, tokei) build against the plain byte std without the unix module being present.
choose pins clap 2.34, which reaches for OsStr::as_bytes through os::unix::ffi::OsStrExt behind a cfg(unix) that the os=none nonos target does not satisfy, so it cannot cross-compile without a real clap port. The other seven tools use clap 4 (encoded-bytes), clap 3 through the fixed os_str_bytes shim, or getopts, and all build from vendored source hermetically. Also make tools/nonos-app regenerate the registry with the nonos-tool-capsules feature gate and the run_named entry point, so a future add no longer clobbers them, and add an off-by-default nonos-tool-selftest that spawns each tool at boot (output capture through a waiting parent is a follow-up).
# Conflicts: # src/syscall/microkernel/ipc/pending_reply/remove.rs # userland/capsule_desktop_shell/src/server/handlers/launcher_request.rs
The virtio-vga device advertised its resolution through xres/yres but without an EDID, so OVMF kept negotiating an oversized fallback mode after a fresh boot and the desktop came up scaled up. Turning on the device EDID (edid=on) makes the firmware read the advertised mode and settle on the native size every boot. Add two screenshots of the booted desktop: the Launchpad grid with the installed tools and their line-art icons, and the desktop with the app dock.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A clean checkout of main does not reach the desktop: two changes from #405 broke the boot path. This branch fixes both, adds the Launchpad, and installs seven unmodified crates.io command-line tools as signed, STARK-attested capsules.
Boot fixes
registry: boot-time service registration
The #405 service-squat hardening dropped the
pid <= 64caller shortcut. Init spawns every capsule with only the ambient capability set and noRegisterService, so the kernel's own spawn-timeregister_endpointbegan refusing each one and no capsule reached the run queue. The system froze on the verified-boot splash.register_endpointnow enforces only that the owner holds the capabilities the endpoint advertises, which is all the trusted spawn path needs. TheMkServiceRegistersyscall keeps the register-right check for a genuinely new name and lets a capsule re-assert the endpoint the kernel already published for it. A runtime squat is still refused.ipc: reply correlation
mk_ipc_replytook its correlation token from a per-client queue kept separately from the pending-reply table it validated the reply against. With several callers waiting on one server the two orders diverged, replies went out under the wrong token, and callers discarded them and blocked. Every desktop client stalled at the compositor handshake, so after the registration fix the screen came up black.The pending-reply entry, matched by the caller's own inbox, already carries that call's token.
remove()returns it and the reply is stamped from it directly. The separate correlation table is gone. A forgedmk_ipc_sendreply still carries token 0 with no pending entry, so it is still dropped.Launchpad
A dock button opens a full-screen grid of every desktop app and installed tool, so the dock stays short instead of growing a tile per app. The grid is built from the launcher and tool tables, so adding an app or installing a tool fills a cell with no layout change. A click launches the service or focuses it when it is already open. Each tool ships a 48x48 line-art glyph drawn in the same cyan tile language as the desktop apps.
Installed tools
grex, dotenv-linter, pastel, jsonxf, tokei, huniq and csview: unmodified crates.io source cross-compiled for x86_64-nonos against the std PAL, each signed with its own publisher keys and enrolled under the transparent STARK policy root.
userland/apps.listis the single source of truth;tools/nonos-appcross-compiles a crate, mints its keys, writes itsCapsule.mk, and regenerates both the kernel registry and the Launchpad table from it. Every tool source is byte-identical to its crates.io release; only the foundational-crate shims underupstream-srcadd the nonos target arm (getrandom over the CRND syscall, byte-based OsStr, a thread-local errno, advisory fd-lock, HOME-based dirs).A new
MkToolRunsyscall runs a baked tool by name, parented to the caller so it drives the tool's stdin and stdout through the existingMkProcInputandMkProcOutputpath. The shell recognizes each tool as a bare command and streams its output the same way a store install does.Testing
Boots to the full desktop in QEMU at 1920x1080 over virtio-gpu. All capsules reach the run queue, the compositor handshake completes, app windows spawn, and every tool cross-compiles from vendored source in CI. Before the fixes the run-queue count was zero; the registration fix alone left a black screen until the ipc fix landed.
Display
The virtio-vga device advertised its resolution through xres/yres but without an EDID, so OVMF negotiated an oversized fallback mode on a fresh boot and the desktop came up scaled up. Turning on the device EDID makes the firmware read the advertised mode and settle on the native size every boot.
Screenshots
The Launchpad grid, with the installed tools next to the desktop apps, each drawn in the same cyan line-art tile language:
The desktop with the app dock: