# M6 cartridge software validation Verified on 2026-09-21 on the x86_64 Arch build host. These results use actual AArch64 binaries, kernel USB events, s6 services and filesystem mounts in QEMU 11.1.1. Physical Pi wiring, bay calibration, simultaneous physical devices and USB electrical behavior remain deferred. Twelve-device virtual stress follows in M11; this milestone does not claim that test has already run. ## Behavior verified `make cartridge-test` passed in `out/m6-vm.u4w9b7pl/`: - The unconfigured production image reports twelve UNCONFIGURED bays. A probe discovers the virtual controller's actual topology; the fixture then maps its USB 2/3 companion ports explicitly. No `/dev/sdX` name selects a bay. - The SYSTEM image boots from virtual USB and is reported PROTECTED. Eject fails. - A virtual keyboard is recognized by the hardware catalog without a filesystem. - The ordinary FDS user can query the daemon. A different UID is rejected even when the test temporarily relaxes socket file permissions. Slow and oversized clients do not prevent another control request from completing. - Inserting ENVIRONMENT media triggers a validated read-only mount. Writes fail. Metadata is inspected privately before the mount becomes publicly accessible. - A shell inside the mount and an additional bind mount each prevent SAFE. After those uses end, eject unmounts successfully and reports SAFE. A service restart preserves that ejected state until removal and reinsertion. - Reinsertion into another port follows that bay. Wrong manifest classes, symlink metadata, and multiple named partitions are rejected without choosing a first candidate. Surprise removal clears inventory; restart remounts valid, nonejected read-only media. - Holding cartridged before its readiness notification does not prevent the ordinary UID-1000 FDS console from accepting a command. Every VM disk used read-only remained byte-identical. Tests use disposable image files and virtual USB devices, never host disks or physical USB passthrough. VM test helpers and the temporary root test console do not ship in SYSTEM. Shared unit tests also cover USB bus renumbering, mapping aliases and overlapping mappings, manifest symlinks/FIFOs, malformed contracts, and absent USB subsystems. The older native-init VM revealed the absent-USB case; its corrected empty-inventory behavior passed a new unit test and the complete native-init boot afterward. ## Final artifacts and regression evidence | Artifact | SHA-256 | | --- | --- | | Rootfs TAR, `out/rootfs-build.FpSNiJ/` | `00fc851affe0f1c42d289cc05ae376788beae9a6b0dce39c6a1f3b86687d1baf` | | SYSTEM, `out/system-build.df52fwqj/` | `908645b47bfe207470eeb82436f8a644d34cf3703156a7bdcbf2a3534e9346fe` | | Production boot FAT, `out/boot-build.bka9vs1y/` | `fb54582a9bd3bb393299002a65a5b0035e806e6733e81a437369a0b152b297e2` | The rootfs contains 112 packages and 1,170 AArch64 ELF files; its TAR is 408,248,320 bytes. `fds-cartridged` is statically linked, installed by its own mandatory base package and supervised by native s6. No external Rust dependency or locked external version changed; the lockfile change only adds the workspace member. Existing libc, serde, serde_json and toml provide the required interfaces. The final pipeline exited zero: fresh rootfs and initramfs, tooling tests, `make check`, rootfs checks, native-init boot, SYSTEM/boot-volume construction, the nine-case stage0 matrix, console tests and cartridge tests. Logs are `out/logs/m6-verified-*.log`. M0 bootstrap and smoke-test also passed in `out/logs/m6-final-bootstrap.log` and `out/logs/m6-final-smoke-test.log`. The optional M0 host-PATH emulator skip remains explicit; project-local ARM execution and full-system tests actually ran. Native-init evidence is in `out/m2-vm.S16Noo/`; stage0 cases are in `out/m4-vm.XBTVEW/`; ordinary-console traces are in `out/m5-vm.51n612y3/`. The normal trace measured 1,753.878 ms from the kernel clock to console, versus 1,669.027 ms in the final M5 normal trace: +84.851 ms, below the 100 ms explanation threshold. The actual ARM comparison tool passed; see `out/logs/m6-boot-regression.log`. These are individual emulator observations, not proof of physical Pi latency or a statistically established timing change. Writable DATA, consumer shutdown and syncfs follow in M7; desktop/profile activation follows in M8. Read [Cartridge usage](cartridges.md) for exact commands, configuration syntax, current states and safe-eject boundaries.