Every ticket as the root of its provenance graph — goal, patch, approval, runs and (as the ticket-class build lands) mandate, manifestations, guarantees, journey, artifacts and children. Rendered through the <<<TicketGraphList>>> tag.
Pi 5 squashfs+toram+g_ether image: initramfs-tools (NOT busybox), working login, fast bmap flash
goal
DELIVERABLE: a squashpi FEATURE (not edits blunted over the core) that emits a Pi 5 boot image:
a read-only squashfs root, copied into RAM at boot (toram), writable via a tmpfs overlay, with
g_ether USB networking and a working login. Add it as `squashpi/pi5.py` (a cohesive module) + a
`pi5` CLI subcommand, driven by a JSON profile. Do NOT fork squashpi and do NOT rewrite the core
build; compose the existing pieces.
WHY (6 prior human attempts failed — do not repeat these):
1. Wrong root type: built ext4-root, not squashfs. -> root MUST be squashfs.
2. g_ether never enabled + `dtoverlay=dwc2,dr_mode=host` BLOCKED gadget mode. -> dwc2 WITHOUT dr_mode=host.
3. cmdline inherited the source image's `root=PARTUUID=...` which does not exist on a rebuilt card.
4. firstboot resizer (init_resize / rpi-resize.service) tried to repartition the deliberate layout.
5. cloud-init + NetworkManager-wait-online + default.target=graphical hung the boot for minutes.
6. `steve` created with NO password -> console login impossible (locked out).
VERIFIED PI 5 FACTS (trixie raspios lite arm64, kernel 6.18.34+rpt-rpi-2712) — build on THESE:
- initramfs-tools is ALREADY installed and `auto_initramfs=1` is ALREADY in config.txt; `initramfs_2712`
is already loaded in the boot chain. So DO NOT build a busybox initramfs. Add a `local-bottom`
overlay+toram script to the EXISTING initramfs-tools setup and run `update-initramfs`.
- squashfs.ko.xz and overlay.ko.xz are COMPRESSED MODULES (not built-in). busybox `insmod` will NOT
load .ko.xz — this is exactly why squashpi's busybox initramfs (validated only on 32-bit QEMU) is
the wrong tool here. initramfs-tools auto-includes the right modules+decompressors for the real kernel.
- Pi 5 kernel = kernel_2712.img; dtb = bcm2712-rpi-5-b.dtb; boot config lives in /boot/firmware/.
REQUIRED BEHAVIOR (the tester must prove each; structural verification only — no Pi hardware here):
A. ROOT = squashfs. mksquashfs the customized rootfs (zstd). Assert `unsquashfs -s` reports a valid fs.
B. TORAM: the initramfs `local-bottom` script copies root.squashfs into a tmpfs, loop-mounts it, and
overlays a tmpfs upper; assert the script is present in the generated initramfs (lsinitramfs) and
references overlay + a RAM copy. cmdline selects it.
C. g_ether ON BY DEFAULT: /boot/firmware/config.txt has `dtoverlay=dwc2` and NO `dr_mode=host`;
cmdline (or modules-load.d) loads `dwc2` and `g_ether`; the root has a usb0 config giving a static
IP (default 10.55.0.1/24) via the NetworkManager already in the image. Assert all three.
D. LOGIN WORKS: user `steve` has BOTH a real password (chpasswd) AND the injected ssh key; sudo;
ssh enabled. Assert /etc/shadow shows a hash (NOT `!`/locked) and authorized_keys has the key.
E. HEADLESS + NO HANGS: default.target=multi-user; cloud-init disabled via /etc/cloud/cloud-init.disabled
(the flag ONLY — do NOT mask cloud-init.target to /dev/null, that degraded multi-user.target last
time); *-wait-online removed from network-online.target.wants. Assert each.
F. NO STALE IDS / NO RESIZE: any inherited cmdline/fstab reference a /dev node or the correct id, never
the source PARTUUID; rpi-resize.service disabled; no init_resize/firstboot in cmdline. Assert.
G. FAST FLASH: emit a MINIMAL image (partition sized to fit boot+squashfs, not padded to card size)
plus a .bmap (bmaptool create) so flashing writes only used blocks; document exFAT-the-rest as the
follow-on. Assert image size ~= data size (not card size).
H. JSON-DRIVEN: all of {hostname, user, password, ssh_key, usb_ip, overlay=tmpfs|persist, root=toram,
squash_comp} come from a profile object; ship a default profile. Assert load+override.
ACCEPTANCE: a dry-run `plan` prints the full sequence; a real build in the privileged squashpi Docker
container produces the image + .bmap; every assertion A-H passes in a loopback mount. HONESTLY NOTE in
the deliverable that Pi-5 boot itself is NOT verifiable in this environment — the structural checks are
the gate; the Pi is the final test. Reuse: squashpi/gether.py, builder.assemble_squash_image (already
has root_src/config_extra/cmdline_extra), initramfs-tools in the source image. note-for-claude: pure
python orchestrator, registry-gated, Variant-A bug report on unexpected outcomes.
patch
none
approval
unapproved
runs
no runs recorded
mandate (clauses)
not yet recorded — lands with the ticket-class build
manifestations
not yet recorded — lands with the ticket-class build
guarantees
not yet recorded — lands with the ticket-class build
journey (blunders & successes)
not yet recorded — lands with the ticket-class build
artifacts (forge)
not yet recorded — lands with the ticket-class build