Run ssh wolf@wolfplex.local uname -a. Expect: output starting Linux wolfplex 6.12.93+rpt-rpi-2712
and ending aarch64 GNU/Linux — verified live 2026-08-07.
wolfplex-migration
Derived from: no commit (this folder is not a git repo — a working folder of one shell
Flows
check each step and final checkThe live box is the migrated Pi, not a stale clone
Closes this folder's own open question — clone.log's last line is VERIFY head: MISMATCH — DO NOT TRUST and nothing in this folder ever re-checked it against live hardware.
Persona / precondition: an operator with SSH access to the Pi (wolf@wolfplex.local or wolf@10.0.0.11), on the same LAN or via Tailscale; the box is powered on.
Run ssh wolf@wolfplex.local lsblk. Expect: the row mounted at / is mmcblk0p2 (the SD
card clone-wolfplex-to-sd.sh wrote to), sized around 953.7G — the box boots off the
cloned SD, not the original ~238GB source NVMe. Verified live 2026-08-07.
Run ssh wolf@wolfplex.local hostname. Expect: wolfplex exactly — the box has assumed
the production hostname the clone carried over. Verified live 2026-08-07.
Final check: ssh wolf@wolfplex.local uptime shows an uptime measured in days, not
minutes — this is the standing production box, not one that just booted for this test.
Observed 2026-08-07: up 13 days.
Root filesystem was expanded to the full card
Proves runbook step 2 (raspi-config --expand-rootfs) actually landed, not that the box is still sitting on a small first-boot default partition.
Persona / precondition: an operator with SSH access to the Pi, box powered on.
Run ssh wolf@wolfplex.local df -h /. Expect: /dev/mmcblk0p2 shows a Size in the
900+ GB range — observed 939G on 2026-08-07 (the runbook's own target after expansion
was "~915G", so this is consistent with expansion having run).
Check the same line's Used column. Expect: a plausible non-trivial number — observed80G on 2026-08-07 — a genuinely-used production filesystem, not a blank re-flash.
Final check: Avail plus Used roughly account for Size on that same df -h / line —
internally consistent output, not truncated or corrupted.
Pironman 5 Pro MAX variant landed correctly
Proves runbook step 3 — re-running the installer and selecting "4) Pironman 5 Pro Max" — actually took, not just that some pironman service happens to be running.
Persona / precondition: an operator with SSH access to the Pi, box powered on.
Run ssh wolf@wolfplex.local cat /opt/pironman5/.variant. Expect: pro_max exactly —
verified live 2026-08-07.
Run ssh wolf@wolfplex.local grep pironman /boot/firmware/config.txt. Expect: the overlay
line reads dtoverlay=sunfounder-pironman5promax (the Pro Max-specific overlay, not the
base sunfounder-pironman5). Verified live 2026-08-07.
Run ssh wolf@wolfplex.local systemctl is-active pironman5. Expect: active — verified
live 2026-08-07.
Final check: the runbook's A12 "Full Power Off" shutdown setting lives in the case's MCU,
not a readable dotfile — it can only be confirmed by physically power-cycling the case and
watching the OLED/RGB go fully dark rather than staying lit. NOT verified this session; marknot verifiable remotely rather than guessing.
Hailo-8 accelerator bring-up over PCIe Gen 3
Runs the runbook's own acceptance line verbatim — hailortcli fw-control identify "should print the Hailo device" — which is currently FAILING on live hardware.
Persona / precondition: an operator with SSH access to the Pi, box powered on.
Run ssh wolf@wolfplex.local dpkg -l | grep hailo. Expect: hailo-all, hailo-dkms, andhailort all report version 4.20.0 (exact strings observed 2026-08-07: hailo-all,
4.20.0+1hailo-dkms 4.20.0-1, hailort 4.20.0-1).
Run ssh wolf@wolfplex.local hailortcli fw-control identify. Expect per the runbook: the
device identity prints cleanly with no error. This currently fails — confirmed live
2026-08-07, exact output includes:[HailoRT] [error] CHECK failed - Driver version (4.21.0) is different from library version (4.20.0)[HailoRT] [error] Driver version mismatch, status HAILO_INVALID_DRIVER_VERSION(76)
This is a real defect: the loaded kernel driver reports itself as 4.21.0 while every
installed Hailo package is pinned at 4.20.0 — a driver/library skew, most likely from anapt full-upgrade that pulled a newer hailo-dkms kernel module without the matching
userspace packages. The correct behavior is a clean identity printout with no [error]
lines.
Run ssh wolf@wolfplex.local grep pciex1_gen /boot/firmware/config.txt. Expect:dtparam=pciex1_gen=3 — the Gen-3 PCIe speed the runbook recommends for Hailo throughput
is set (verified live 2026-08-07), even though the version-mismatch above blocks actually
using the card today.
Final check: once the Hailo package set is reconciled to one consistent version, re-run
step 2 — it should print a clean identity block with zero [error] lines. Not yet true as of
2026-08-07.
Camera module detection
Runs the runbook's literal camera-verify command — which no longer exists on this OS image — then the command that actually works. A documentation defect, found by testing the doc's own instruction.
Persona / precondition: an operator with SSH access to the Pi, box powered on, camera ribbon connected per the runbook's "Attached but not yet enabled" note.
Run ssh wolf@wolfplex.local which libcamera-hello. Expect per FIRST_BOOT_RUNBOOK.md
step 6 ("verify with libcamera-hello --list-cameras"): the command should exist. It
does not — confirmed live 2026-08-07: the command prints nothing (not found). Raspberry
Pi OS bookworm renamed libcamera-apps to rpicam-apps, so this binary is gone; the
runbook's own verify command is stale for the OS it's written against.
Run ssh wolf@wolfplex.local rpicam-hello --list-cameras. Expect (the correct check):
output starting Available cameras followed by a 0 : imx500 [4056x3040 10-bit RGGB]
entry — verified live 2026-08-07; the camera is physically attached and detected.
Final check: FIRST_BOOT_RUNBOOK.md's camera line should be corrected fromlibcamera-hello --list-cameras to rpicam-hello --list-cameras so the next person to run
this runbook isn't told a working camera is missing.
DSI touchscreen overlay present
Confirms the touchscreen's kernel overlay is loaded — the closest thing to proof reachable over SSH; actually seeing the screen light up needs a body in front of the case.
Persona / precondition: an operator with SSH access to the Pi, box powered on.
Run ssh wolf@wolfplex.local grep dsi /boot/firmware/config.txt. Expect:dtoverlay=vc4-kms-dsi-waveshare-800x480 — verified live 2026-08-07, matching the
Waveshare panel noted as fixed post-migration.
Final check: this only proves the overlay is loaded, not that the panel is
displaying — a tester physically at the case should confirm the kiosk UI is actually
visible on screen. NOT verifiable remotely this session.
Plex is serving real libraries off the reattached drives
Proves the runbook's own caveat — "Plex will show empty libraries until its drives are attached" — has been resolved: the drives are back and Plex sees real data.
Persona / precondition: an operator with SSH access to the Pi for steps 1–3; a browser on the LAN or Tailscale for the final check.
Run ssh wolf@wolfplex.local lsblk. Expect: three ~4.5T drives (sdb, sdc, sdd) each
with a partition mounted under /media/plex/ — verified live 2026-08-07 (WolfEntBlue,WolfEntGreen, WolfEntBlack).
Run ssh wolf@wolfplex.local curl -s http://localhost:32400/identity. Expect: an XML
response containing apiVersion="1.2.2" and claimed="1" — the local Plex server answers
rather than connection-refused. Verified live 2026-08-07.
Run ssh wolf@wolfplex.local df -h /media/plex/WolfEntBlue /media/plex/WolfEntGreen /media/plex/WolfEntBlack.
Expect: each mount shows real, non-zero Used space — observed 2026-08-07: 2.8T, 1.9T,3.8T respectively — actual media, not empty freshly-mounted drives.
Final check: from a browser, open Plex's web UI and confirm at least one library shows a
real poster grid rather than an empty-library prompt.
Full service-health sweep
Runs the runbook's own step-1 command — systemctl --failed — which the runbook predicted would show "none, or only units tied to absent external drives." It currently shows more than that.
Persona / precondition: an operator with SSH access to the Pi, box powered on.
Run ssh wolf@wolfplex.local systemctl --failed --no-legend. Expect per the runbook: only
units tied to absent hardware, or nothing at all. Currently shows two failed units —
confirmed live 2026-08-07: influxdb.service and nvmf-autoconnect.service, both listed
as failed.
Run ssh wolf@wolfplex.local systemctl status influxdb --no-pager. Expect (the runbook's
implicit assumption, since influxdb is one of the five services the clone script itself
stops-and-restarts around the copy): active (running). It does not — confirmed live
2026-08-07: Active: failed (Result: protocol), failing since Sat 2026-07-25 21:30:00. This is a real, unflagged defect — InfluxDB has been down roughly two weeks and
EDT
nothing in this folder or the runbook notes it.
Run ssh wolf@wolfplex.local systemctl status nvmf-autoconnect --no-pager. Expect: this
one is plausibly benign — a stock Debian unit for NVMe-over-Fabrics auto-connect, and this
box has no NVMe-oF target configured, so Active: failed (Result: exit-code) here may be
expected-but-undocumented noise rather than a migration regression. NOT confirmed either
way this session — worth a look while fixing influxdb.
Run ssh wolf@wolfplex.local systemctl is-active plexmediaserver ollama smbd nmbd.
Expect: all four print active — verified live 2026-08-07.
Final check: after influxdb is fixed, re-run step 1 — systemctl --failed should drop
to at most the one plausibly-benign nvmf-autoconnect line.
Every advertised reachability lane actually works
The migration is only "done" if the box can be reached the ways its owner actually reaches it — wired LAN, WiFi/mDNS, and Tailscale — not just whichever lane this test happened to try first.
Persona / precondition: an operator on a machine that has both LAN and Tailscale access to the Pi.
Run ssh wolf@wolfplex.local echo ok (mDNS hostname). Expect: ok — verified live
2026-08-07; this currently resolves to the box's wlan0 address, 10.0.0.10.
Run ssh wolf@10.0.0.11 echo ok (static wired address) and compare uname -a against
step 1's target. Expect: ok, with identical uname -a output — same machine, two
interfaces. Verified live 2026-08-07.
Run tailscale ping wolfplex (or ssh wolf@100.79.97.3 echo ok) from a second
Tailscale-joined device. Expect: reaches the same box. This session only confirmed the
interface itself is up (tailscale0 at 100.79.97.3 via ip addr) — end-to-end reachability
from a genuinely separate device was NOT re-tested this session; mark honestly.
Final check: ssh wolf@wolfplex.local ip -brief addr show lists eth0 at 10.0.0.11,wlan0 at 10.0.0.10, and tailscale0 at 100.79.97.3, all UP — matching every address
this flow just exercised. Verified live 2026-08-07.
Old wolfplex hardware is retired, no hostname collision
Proves runbook step 0's precondition ("power the OLD wolfplex OFF first") actually held — because if it didn't, two live wolfplex.local on the LAN would be silently colliding right now.
Persona / precondition: an operator with LAN access to run a ping and SSH to the new box.
Run ping -c 2 10.0.0.9 — the OLD Pi's documented wired address, taken fromclone-wolfplex-to-sd.sh's own PI=wolf@10.0.0.9 line. Expect: no replies — the old
box's old address is dead. Confirmed live 2026-08-07: 100.0% packet loss.
Check this project's own files for a written decision on the old Pi's fate (runbook
section 5, "Old Pi's fate"). Expect: a dated note saying what happened to it (kept
renamed / retired / repurposed). Not present — this folder's own "Aftermath /
deferred" checklist item is still unchecked as of 2026-08-07; step 1 shows the old
address is currently silent, but no one has recorded that as a deliberate decision.
Final check: if the old Pi is ever powered back on, re-run this whole flow before
trusting either machine's identity (duplicate SSH host keys and machine-id were never
deduped per the runbook's own aftermath note).
Power and thermal headroom holds at idle
Proves the runbook's power-budget warning (Hailo + dual-fan case + touchscreen + camera all on one 27W supply) hasn't materialized as a real problem — at idle. Under load is explicitly out of scope for this pass (see Final check).
Persona / precondition: an operator with SSH access to the Pi, box powered on and idle.
Run ssh wolf@wolfplex.local vcgencmd get_throttled. Expect: throttled=0x0 — no
under-voltage or frequency-capping event has ever latched. Verified live 2026-08-07.
Run ssh wolf@wolfplex.local vcgencmd measure_temp. Expect: a double-digit Celsius
reading well under thermal-throttle range — observed 2026-08-07: temp=40.6'C.
Run ssh wolf@wolfplex.local dmesg | grep -i voltage. Expect: no output — no undervoltage
events in the current boot's kernel log. Verified live 2026-08-07.
Final check: this flow only proves idle headroom. A tester who wants to validate under
load should start a Plex transcode and a Hailo inference job simultaneously and re-run steps
1–2; this was deliberately NOT exercised this session (no load was placed on the live
production box for this test).
This folder's own paper trail vs. what's actually true
The _handoff note names its own NEXT STEP as "SSH the new box directly ... this settles whether the MISMATCH was a false alarm or real." Flows F1–F2 above ARE that next step — and this folder has never recorded the answer.
Persona / precondition: a reader of this project's own files; no SSH needed for step 1.
Read clone.log. Expect (current, real state): the file's last line is still[2026-07-14 01:16:59] VERIFY head: MISMATCH — DO NOT TRUST, with no later re-run and no
"tail: MATCH" line anywhere after it. Confirmed by reading the file 2026-08-07.
Cross-reference against this document's F1 and F2 results. Expect: the live evidence
(correct hostname, SD-card root, expanded rootfs, real accumulated data, 13+ days of
uptime) is strong enough to conclude the clone succeeded and the automated verify step's
failure was itself the false alarm — not that the disk data is actually corrupt. This is
an inference from live checks, not a re-run of the script's own byte-for-byte compare.
Defect to flag, not silently fix: neither clone.log, _handoff/wolfplex-migration.md,
nor FIRST_BOOT_RUNBOOK.md has been updated with a closing note since 2026-07-19, even
though the box has had 3+ weeks of real production operation since. The correct behavior
per this project's own _handoff NEXT STEP is a short "clone verified good, first-boot
complete" addendum; the current, incorrect state is silence.
Final check: after this test plan is run once, someone should write that closing
addendum into _handoff/wolfplex-migration.md. This document proves the evidence exists; it
does not substitute for actually closing the loop on paper.
Not covered and why
- Physical A12 shutdown behavior (F3 final check) and touchscreen visible display
(F6 final check): both need a body in front of the case, not SSH.
- Tailscale end-to-end from a second device (F9 step 3): only the local interface was
confirmed up; a genuine second-device round trip wasn't tested this session.
- Under-load power/thermal (F11 final check): deliberately not exercised — no load was
placed on the live production box for this test.
- Old Pi's actual disposition (F10): confirmed off the network, not confirmed
decommissioned-vs-just-off; needs a direct answer from whoever holds that decision.
- SSH host-key / machine-id dedupe: moot while the old Pi stays off (F10); untested
because there is currently only one live box to compare.
- NVMe-off-SD migration (runbook section 5, deferred item): the box has a separate
3.7TB NVMe mounted at /srv/nvme for data, but boot is still from the SD card — no attempt
was made to test a root-migration that hasn't been attempted yet.
- Byte-for-byte re-verification of the original clone (re-running
clone-wolfplex-to-sd.sh's head/tail compare): would require stopping live production
services on the box (plexmediaserver influxdb ollama smbd nmbd) — explicitly out of
scope for a read-only test pass; do this only in a planned maintenance window.
Results
| Flow | Verdict | Failures → tickets |
|---|---|---|
| F1 live box is the migrated Pi | ||
| F2 rootfs expanded | ||
| F3 Pironman Pro MAX variant | ||
| F4 Hailo bring-up | ||
| F5 camera detection | ||
| F6 DSI touchscreen overlay | ||
| F7 Plex real libraries | ||
| F8 service-health sweep | ||
| F9 reachability lanes | ||
| F10 old hardware retired | ||
| F11 power/thermal at idle | ||
| F12 paper trail vs. reality |