`os/mini` is the BusyBox image that ships today: everything in RAM, a reflash to update. `os/v2` is the
same appliance - Lemonade Server by AMD on the 1bit engine, our kernel, Secure Boot through the enrolled
MOK - on a minimal Ubuntu 26.04 root filesystem with systemd, where every piece we ship is a `.deb` from
our own signed repository and `apt update && apt upgrade` is the update path. `os/mini` keeps shipping
until v2 passes the same checks on hardware.
Seven packages, built from what a release already produces (no binary is rebuilt): `1bit-engine`,
`1bit-lemonade`, `1bit-kernel-image-<kver>`, `1bit-kernel-modules-<kver>`, `1bit-ryzenadj`,
`1bit-appliance` and `1bit-archive-keyring`. The kernel version is in the package name, so an upgrade keeps
the previous kernel installed - that is the rollback. `mkdebs.sh` refuses a stage whose EC module is
unsigned or built for another kernel, and a kernel image with no signature; it localises the engine's
libraries with `scripts/pack-elf.sh` (the same `pack_localize` a release tarball goes through), because a
package that carries the build machine's RUNPATH is a package that does not load (#549).
The live medium is the root filesystem as a squashfs with a tmpfs overlay: one initramfs-tools script
(`scripts/init-bottom/0-1bit-live`) builds the overlay and hands `rootmnt` back through `/conf/param.conf`,
so userspace has nothing custom at boot and a live boot cannot write the medium. `install.sh` is
`1bit-install`, with the same refusal matrix as #539 and three partitions (ESP, `1BIT-ROOT`, `1BIT-DATA`)
instead of a RAM image; it unpacks the squashfs, writes `fstab` by label, one grub entry per installed
kernel, and leaves `/etc/1bit/live` off the installed disk so `1bit-first-boot.service` writes
`/etc/1bit/installed` after making that machine's own SSH keys.
Two VM tests, both judged from what the guest writes to its own disk rather than from QEMU:
`vmtest-v2.sh` (the appliance, booted through OVMF so the secureboot row answers instead of failing for a
QEMU choice) and `vmtest-install-v2.sh` (builds the medium with a test-only unit inside it, boots it with a
target disk and a USB stick attached, runs the refusals, installs, then boots the installed disk alone).
Bugs this found in the v2 path, all fixed here: the engine package could not load its own libraries
(a dev-built stage carried the build tree's RUNPATH and never shipped libhrx/libloomc/libomp); `1bit`
needed `libgomp1`/`libpcre2-8-0`, which minbase has not; lemond exits at once without `HOME` in a systemd
unit; `ssh.service` enabled while `ssh.socket` was masked starts nothing at all on Ubuntu 26.04 (the socket
is what listens, and it carries RequiredBy=ssh.service) - so the socket is what the package enables; minbase
has no `sfdisk` (Ubuntu's lives in `fdisk`); `root=` in the live entry has to be the squashfs partition, or
`data.mount` fights the initramfs for the data partition; and `1bit-appliance` never shipped the aggregate
`/usr/share/licenses/1bit-os` that release-check reads.
Known gap, named in `os/v2/README.md` rather than papered over: the ROCm userspace (HIP, rocBLAS,
hipBLASLt, the HSA runtime) is the machine's, not the engine package's, and the engine's `Depends` do not
name Ubuntu's packages for it yet - gfx1201 support against the distro's ROCm is a hardware question a VM
cannot settle. `vmtest-v2` therefore asserts the package's own libraries resolve and lets only that set be
missing, which is exactly the check that caught the first bug above.
Evidence: `VMTEST-V2 PASS` (seven packages installed, banner, /data, 1bit --help, our kernel's vmlinuz and
initrd in /boot, sshd on 22, apt from the repository, Lemonade 401 + GGUF + chat, release-check with no
FAIL row but `sealed`, which needs a stage that carries the sealed NPU sets) and `VMTEST-V2-INSTALL PASS`
(six refusals, install, installed disk boots alone: INSTALLED mode, first-boot marker and own SSH keys,
/data on its own partition, Lemonade 401 + GGUF + chat, selftest INSTALLED). Transcripts:
`~/wt/osapt-proto/v2-final.log` and `~/wt/osapt-proto/live-install.log`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
os/v2: the appliance on an Ubuntu base, updated withaptDesign:
~/briefs/TOSAPT-DESIGN.md.os/mini(the BusyBox image that ships today) keeps shipping until v2passes the same checks on hardware; nothing here retires it.
This adds
os/v2/besideos/mini/, a v2 section inos/README.md, and thetools/copyright.pypatternsthe packaged files need (dpkg control/conffiles, the console banner,
*.mount/*.preset/*.network, thesnapshot pin, the power profile).
What is in the tree
pin.txt20261024T000000Z)mkdebs.shKERNEL_STAGE=<dir>adds the three a box needs;ENGINE_BUILD=<dir>localises the engine's librariesmkrepo.shRelease,Release.gpg,InRelease)mkrootfs.shmmdebstrap --variant=minbase+apt install 1bit-appliancefrom that repository;MIRROR=overrides the snapshot for an outagemklive.shPARTLABEL=1BIT-LIVE, tmpfs overlay via one initramfs-tools script, ESP with shim + our MOK-signed grub + kernel + grub.cfg, and the stick's1BIT-DATAinstall.sh1bit-install: the same refusal matrix as #539, three partitions (ESP,1BIT-ROOT,1BIT-DATA)vmtest-v2.sh/datavmtest-install-v2.shproto.sh,diag-v2.shPackages:
1bit-engine(38 MB) ·1bit-lemonade(6.8 MB) ·1bit-kernel-image-<kver>(11.9 MB) ·1bit-kernel-modules-<kver>(74.8 MB) ·1bit-ryzenadj(122 KB) ·1bit-appliance·1bit-archive-keyring.1bit-kernel-image-7.3.0-rc4-1bit-perfoptis the release kernel packaged as it sits on the build machine(
vmlinuz,System.map,config), not rebuilt:sbverify --cert MOK-Kernel.pem→ Signatureverification OK. Its postinst runs
update-initramfs, which took inside the mmdebstrap chroot (the initrdis in the built rootfs). The kver is in the package name, so an upgrade keeps the previous kernel installed —
that is the rollback.
1bit-kernel-modulescarries all 3819 modules plus the signedec_su_axb35.ko(vermagic-checked, signer
strixhalo Secure Boot MOK) and its source under/usr/src/1bit-ec-2026.43.1bit-ryzenadjis built from the pinned v0.19.0 source, which ships beside the binary (LGPL-3.0).Two gates
mkdebs.shenforces, because both failures are silent on a box: an EC module that is unsigned orbuilt for another kernel fails the build, and a
vmlinuzwith no signature fails the build. And a third:the engine's own libraries must resolve from the package —
scripts/pack-elf.sh'spack_localizeruns overthe package tree, so
libllama-server-impl.so,libhrx,libloomc,libomptravel inside it and theRUNPATH is
$ORIGIN(#549). A build-machine path in a package is a package that does not load; that isexactly what the first v2 VM run found.
Evidence
Two runs, both judged from what the guest wrote onto its own disk (no port forwarding, no host-side guess).
Transcripts:
~/wt/osapt-proto/v2-final.log,~/wt/osapt-proto/live-install.log.VMTEST-V2 PASS— the appliance (rootfs from the seven debs, OVMF boot)2026.43-11bit OS, Lemonade Server appliance+Lemonade Server by AMD, running on the 1bit engine/data/dev/vdb, label1BIT-DATA)1bit --help: ok;llama-server's own libraries all resolve from the package/boot/vmlinuz-7.3.0-rc4-1bit-perfoptand/boot/initrd.img-7.3.0-rc4-1bit-perfopt1bit-selftest/etc/1bit/installedwritten, SSH host keys generated on the boxapt-cache policy 1bit-engine→ Installed 2026.43-1); the shipped source ishttps://1bit.gg/aptwithsigned-by=/usr/share/keyrings/1bit-archive-keyring.gpgQwen3-0.6B-Q4_K_M, one chat answered (Paris.)1bit-release-checksealed(a development stage carries no sealed NPU sets)VMTEST-V2-INSTALL PASS— the medium and an installcmdline: live (squashfs + overlay))--yes· a partition · the disk the live boot runs from · a disk in use · no GPT tool — each with its ownREFUSED:line. The removable-device refusal cannot be exercised in QEMU (itsusb-storagereportsremovable=0); the harness prints what the VM reports instead of claiming the row1bit OS is installed on /dev/vdb; three partitions (EFI/1BIT-OS,1BIT-ROOT,1BIT-DATA)/boothas the kernel;fstabmounts by label; no live marker; our kernel package installedmode : INSTALLED,/etc/1bit/installedpresent, own SSH host keys,/dataon/dev/vda3chat: Paris.1bit-release-checkkernel : 7.3.0-rc4-1bit-perfopt with its modules, lemonade PASS, gguf PASS, chat PASS, bench PASS, licences PASS — onlysealedfailsBugs this found and fixes (all in this PR)
RUNPATH and never shipped
libhrx.so.0,libloomc.so.0,libomp.so; they resolved on the build machineand nowhere else (
libllama-server-impl.so: cannot open shared object file). Fixed withpack_localize, plus a loud fallback when no build tree is given.1bitneededlibgomp.so.1, which minbase does not have → the engine package nowDepends: libgomp1, libpcre2-8-0(its two non-base NEEDEDs).HOME is not set; cannot resolve Lemonade cache directory— a systemd unithas no HOME.
Environment=HOME=/data/lemonade.ssh.servicewas enabled whilessh.socketwas masked, and on Ubuntu 26.04 thesocket unit carries
RequiredBy=ssh.service:Failed to start ssh.service: Unit ssh.socket is masked.The package now enables the socket (what listens on 22, as on any Ubuntu box), masks nothing, and does
not start the service.
sfdisk(it lives in Ubuntu'sfdisk) — the installer would have refused on its owntool check. Added to the rootfs include list.
root=must be the squashfs partition. Withroot=on the data partition,data.mountfought the initramfs for the same device and failed.
root=/dev/disk/by-partlabel=1BIT-LIVE rootfstype=squashfs, and the overlay's lower layer is that mount.1bit-appliancenever shipped/usr/share/licenses/1bit-os, which1bit-release-check's licencesrow reads. It does now (
LICENSE,NOTICE,LICENSE-BINARY,NOTICE-BINARY,LICENSES.md).Two initramfs-tools rules are worth knowing before touching
mklive.sh:scripts/local-bottomonly runs ifa local-top/local-premount script ran (so the overlay lives in
scripts/init-bottom/0-1bit-live), and ascript there cannot return a variable by assignment — neither
rootmnt=nor anexportsurvives, becauseORDER runs each script as a command.
/conf/param.confis the channel. Both are comments inmklive.sh.os/mini/release-check.shneeded no change after #597: it reads the key from the running lemond'senvironment, which on v2 is the systemd
EnvironmentFile=/etc/1bit/lemonade.env.Known gaps
llama-serverandds4linklibamdhip64, rocBLAS, hipBLASLt,the HSA runtime and
libamd_comgrfrom the SDK the build machine had. Ubuntu 26.04 has packages for them(
libamdhip64-7,libhipblaslt1,librocblas*), but gfx1201 support against the distro's ROCm is ahardware question, so the engine's
Dependsdo not name them yet.vmtest-v2asserts the package's ownlibraries resolve and lets only that set be missing — which is the check that caught bug 1.
sealedfails by construction in these runs (the VMhas no NPU either). A release stage always carries them.
ca.archive.ubuntu.com, not the pinned snapshot:snapshot.ubuntu.comanswered 503 to everything for about an hour on 25 Oct.
mkrootfs.shnow retries(
Acquire::Retries) and takesMIRROR=, andpin.txtis unchanged. The pinned path itself built twiceearlier in the day (rootfs2 940 MB, rootfs3 1.2 GB).
os/minikeeps shipping until it has,and no tag, release or publish is part of this PR.
🤖 Generated with Claude Code