# Cartridge and desktop revision This work replaces the custom software bundle workflow and separates the user manual from development history. The accepted 0.1.0 release stays unchanged. ## Required outcomes 1. Professional user documentation contains installation, usage and reference material. Milestone history, measurements, test gaps and implementation notes live separately under `docs/developer/`. 2. `fds-cartridge` builds Void source packages with `xbps-src`, installs their runtime dependencies on the workstation, and writes installed program trees directly into EROFS payloads. New cartridges require no guest extraction. Existing cartridge reading stays available. 3. The grayscale E-Ink WindowMaker appearance is the default desktop theme on every display, with normal user customization still possible. 4. Validated cartridge commands become available in existing shells through a stable PATH directory. Direct launches retain terminal behavior, arguments, exit status, dependency paths and managed eject/unplug cleanup. Command name collisions have deterministic, documented behavior. 5. A native Rust X11 control panel with a matching retro appearance manages bay status, cartridge details, program launch and safe eject from WindowMaker. ## Implementation and acceptance - Replace creation of custom xz bundles with typed Clap source-package options, installed-tree metadata, deterministic integrity checks and direct mounts. - Verify real Void builds, dependency installation and resulting image contents; retain corruption, filesystem and write/readback rejection coverage. - Add managed PATH launch registration and exercise foreground commands, collisions, eject, surprise removal and service restart in the ARM guest. - Package and integrate the X11 panel and defaults. Exercise the actual window, input actions and rendered appearance in the guest desktop. - Rebuild CLI and development images. Run workstation/emulator, rootfs/init and relevant cartridge/DATA/desktop/shutdown regressions against changed sources. - Rewrite and relocate documentation after the final interfaces are verified. Keep hardware-specific validation procedures and limits in developer notes. - Use `make clean-preview` and `make clean` between completed validation batches to avoid retaining hundreds of GiB of obsolete images again. Current status: all five changes are implemented and the fresh host/ARM VM acceptance below has passed. Physical checks remain a separate hardware task. ## Fresh acceptance The validation logs are retained under `out/logs/cartridge-desktop-revision/`. `out/manifests/cartridge-desktop-revision.json` records the actual working-tree source hashes, artifact hashes, fixture identities and log hashes. The source revision is uncommitted; HEAD alone does not identify these changes. These checks ran against this revision, independently of the frozen release. | Check | Evidence and scope | | --- | --- | | Build host | `make bootstrap`, `make smoke-test`, `make check`; all passed. The optional host-native `qemu-aarch64` shortcut was skipped; ARM execution uses the prepared Void environment. | | Root filesystems | `make rootfs PROFILE=cli` and `PROFILE=development`, with `make rootfs-test` for each: passed. Archives `rootfs-build.9f2sNj` and `rootfs-build.PIumlA` contain byte-identical copies of the exported FDS tools and Dasung daemon. | | Boot / tools | `make init-test`, `out/m2-vm.ATiMG0`: native s6 PID 1, service control and orderly poweroff passed. `make tooling-test` passed shared contracts and real ARM diagnostic execution. Both SYSTEM images and initramfs were rebuilt. | | Rust | Host tests for common contracts, software, workstation tools, cartridge service, CLI and X11 panel; static-musl ARM compilation passed. | | Software creation | `make workstation-test`, `out/workstation-images.f6tq1mya`: actual xbps-src builds, installed dependencies, EROFS trees, deterministic image bytes, malformed-content rejection and confirmed file write/readback. | | Emulator / foreground commands | `out/emu-test.tqxiaglf`: direct PATH and qualified names, literal arguments, pipes, exit status, cwd permissions, interactive input, Ctrl-C, suspend/resume, terminal restoration, collisions, unplug, daemon restart and legacy format-1 archive compatibility passed. | | Cartridge control | `make cartridge-test`, `out/m6-vm.e5j5n3q5`: active SYSTEM protection, unprivileged IPC, bounded clients, mounts, busy/safe eject, hotplug, removal and restart passed. | | DATA | `make data-test`, `out/m7-vm.oiam2j2z`: sustained writes, privilege drop, descendant cleanup, sync/unmount, persistence, multiple candidates, interrupted media and surprise removal passed. | | Desktop | `make desktop-test`, `out/m8-vm.zgk_yiyn`: real ARM Xvfb/WindowMaker, authentication, UID 1000 panel, global grayscale defaults, mouse launch of legacy and Void programs, keyboard rescan, safe eject and session cleanup passed. ENVIRONMENT and isolated DHCP regressions also passed. | | Shutdown | `make power-test`, `out/m10-vm.rx6kz1zd`: ordered poweroff/reboot, writeback, active preparation, quarantine and refusal on unsafe storage passed. | | Documentation | User instructions and development history are separated; all 66 Markdown documents had balanced code fences and valid relative file links. The actual panel screenshot was visually reviewed. | The [desktop screenshot](../images/fds-control.png) comes from the ARM guest, not a mockup. Additional shell/where commands in its example cartridge belong to the test fixture; the ordinary example publishes hello and report. ## Validation limits The host used for acceptance is x86_64 Arch Linux with the prepared Void runner. The native tool interface supports other Linux workstations with the documented prerequisites, but this run does not establish coverage of every distribution. No physical Raspberry Pi boot, USB bay calibration, flash power-loss durability, Dasung power-cycle recovery, E-Ink refresh quality or hardware latency was tested. Use the existing hardware procedures for those checks. VM timings are VM observations only. The independent s6/Dasung base integration remains mandatory. The saved 0.1.0 release and its frozen inputs were not modified. ## Implementation notes The X11 panel uses `x11rb` 0.13.2 and its pure-Rust connection, with core X11 requests and no optional extensions or C GUI toolkit. The protocol companion crate generates requests; `gethostname` and `rustix` support X11 authentication and OS access. Versions are locked in Cargo.lock, and their licenses are included by the existing Rust notice generator. This keeps the GUI compatible with the static-musl target. Reference: https://docs.rs/x11rb/0.13.2/x11rb/. Foreground commands pass their already-open stdio descriptors to the privileged service. The service creates the child, joins its root-owned bay cgroup, drops to UID/GID 1000, and only then resolves the requested working directory. A pidfd and exit status return to the launcher; interactive sessions use a PTY proxy. No writable cgroup descriptor or permission to migrate arbitrary PIDs is exposed to a client. This matters because Linux cgroup writes use open-file credentials. Reference: Linux 6.12 kernel/cgroup/cgroup.c, cgroup_procs_write_start(). The first ARM compilation exposed musl/glibc differences in msghdr field widths; portable field casts fixed those. Final acceptance uses rebuilt binaries and images, rather than the intermediate builds that preceded that correction. The first emulator run found that Clap's multicall implementation uses `Path::file_stem()`, truncating dotted aliases such as `b01:demo.report:shell`. The launcher now lets Clap parse the invocation path as a typed positional and uses a second typed external-subcommand parser for explicit `fds-program` calls. Application help/version flags and dotted names have a regression test. This keeps the no-manual-argument-parser rule while preserving the actual alias. The initial X11 click test raced the desktop terminal appearing above the panel. The test now waits for that terminal and raises the panel before each real mouse click. Actual program output, consumer tracking and SAFE state are still checked; window existence alone is not treated as successful launch. The shutdown suite now publishes `out/m10-vm-latest` after successful completion. That pointer was also installed for the successful run above. Cleanup retains that evidence using the same published-link rule as the other runtime suites. After validation, `make clean` removed 52 obsolete workspaces and Rust build output. The filesystem reported 62.17 GiB of newly available space. Current images, latest runtime fixtures, caches, personal outputs and frozen release inputs were retained; the complete cleanup log accompanies this revision.