The old pairing/delivery scenarios expected a non-zero exit on an
unbound 204 poll — the one-poll-per-invocation design v1.21.0 (R-33)
deliberately removed; against the current script they would hang on a
real sleep. Now: a PATH-faked sleep counts the waits and flips the poll
to 200 after 3 cycles, so one scenario proves the whole v1.21.0 shape
in a single invocation (register -> in-script 204 waits -> delivery ->
host-install -> done-flag, exit 0), plus a 410 crash-window scenario
(still exits non-zero on purpose). Runaway guard: fake sleep kills the
loop after 25 calls. Assistant image gains python3 (the bootstrap's
JSON parsing needs it; PVE ships it on the real box) — the harness runs
in that image.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UuFPHmHNrCJj1VhY6QdDMU
Two jobs, one repack pass.
BRANDING. Every ISO now carries a Felhom boot screen built from the website's
og-image_2.png at repack time (ImageMagick in the assistant container), so the
boot card has ONE source and not a second pre-rendered copy in the repo to
drift. The card is scaled onto a 1024x768 gfxterm canvas, top-centered, and the
card's own subtle background grid is continued across the letterbox fill
PHASE-LOCKED to where the card's grid lands — the fill is seamless rather than a
square of grid floating in flat navy. Menu positioning needs a gfxmenu theme
(plain background_image cannot move the menu off the wordmark), so the stock
pvetheme is replaced by felhomtheme, which puts the menu in the lower third the
layout deliberately leaves empty.
SAFETY — the half that matters. The stock PVE menu offers Graphical, Terminal
UI and serial installers plus an Advanced Options submenu (nomodeset x2, three
debug variants, Rescue Boot, memtest, UEFI settings). Every one of them reaches
the MANUAL installer, whose first question is which disk to wipe. A customer, or
their helpful nephew, must not be able to get there from a boot menu. They are
not hidden and not password-gated: they are NOT EMITTED. What ships is one
entry, 'Felhom telepítés', default, 5s.
Boot behavior is unchanged. The kernel/append and initrd lines are lifted
VERBATIM from the ISO's own 'Install Proxmox VE (Automated)' entry rather than
frozen into a copy here, so a PVE bump tracks automatically; the build fails if
they cannot be found, if the append line has lost proxmox-start-auto-installer,
or if auto-installer-mode.toml is absent (which would mean the one Felhom-
labelled entry boots a manual installer). The rendered menu is then gated for
exactly 1 entry, 0 submenus, and zero references to proxtui/proxdebug/nomodeset/
Rescue Boot/memtest/fwsetup — and re-verified by reading the menu back OUT of
the finished ISO, not merely out of the extract tree.
mkimage-surgery.sh -> iso-repack.sh: branding and the slice-B loader swap need
the same extract -> modify -> re-master cycle, so they share one pass instead of
re-mastering twice. The mkimage recipe is untouched. The embedded module list is
still derived from the STOCK grub.cfg (snapshotted before branding rewrites it),
plus gfxmenu's bitmap/bitmap_scale/trig renderer deps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
Closes N100 F1 (HIGH): cheap AMI (AN3PLUS 0.01-class) UEFI firmware can't
relocate the ISO's stock signed GRUB from USB (relocation 0x0). The run's live
grub-mkimage workaround is now a first-class pipeline mode.
- build-felhom-iso.sh: --loader shim|mkimage (default shim, byte-for-byte
unchanged; profile-settable FELHOM_LOADER; --loader wins). Loud banner +
manifest loader:/grub-mkimage: fields + -mkimage filename suffix.
- mkimage-surgery.sh (new): post-prepare-iso, in the assistant container. Builds
a monolithic grub-mkimage loader from the ISO's own GRUB (module set from its
grub.cfg; embedded search --fs-uuid -> configfile the real menu). Swaps it into
the ISO9660 tree (real lowercase path) + the efi.img ESP; xorriso re-master
preserves BIOS-hybrid + UEFI + GPT-ESP, drops only Apple HFS+/APM. Recipe from
the N100 run evidence, not re-derived.
- Dockerfile.assistant: grub-common + grub-efi-amd64-bin + mtools + dosfstools.
profiles/n100.profile (new, mkimage + SB-off note).
- Validated on nested VM 311 (RUNBOOK-B legs): leg1 shim boots+installs under
OVMF SB-enforcing + SeaBIOS; leg2 mkimage boots+installs under SB-off; leg3
(red-proof) mkimage under SB-enforcing FAILS Access Denied (unsigned -> SB must
be OFF); leg4 surgery byte-identical payload. bash -n + shellcheck clean.
Physical N100 closure folds into the rehearsal (n100-safety match-nothing ISO
built + sha-recorded, unbooted). PXE stays a deferred R-21 note.
scripts/iso/: a DooPlex pipeline (build-felhom-iso.sh + Dockerfile.assistant) that
turns the official PVE ISO into a Felhom auto-install ISO whose first-boot stub
installs a retry-forever felhom-bootstrap unit which unattended-fetches
felhom-host-install.sh from the public felhom.eu/scripts channel and runs it until the
host is enrolled + a guest provisioned. host-install is UNMODIFIED (invoked only).
- build gates the answer on validate-answer OUTPUT text, never $? (spike S1 exit-0 trap)
- stub is from-iso, fully-up, exactly-once; retry unit owns all network work (S8a)
- retry-vs-resume encoded once: plain first, --resume when install state exists (v1.11.3)
- secret-bearing (embeds the retrieval passphrase): supervised/single-use; env shredded on success
Validated on VM 310: build gate + red-proof, disk-filter fail-safe, chain + retry,
resume-decision, exactly-once, no-net retry+recovery. Terminal host-install rc-0 success
operator-gated (drill customer needs the password-gated create-UI). scripts v1.16.0;
ROADMAP R-21 -> in-progress. Detail in REPORT.md.