Ticket graphs

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.

← all ticket-graphs

DONE#164 squashpi

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

source (forge tree)

browse congruency source (forge-parked tree)

children

not yet recorded — lands with the ticket-class build