SmartConfig

Review of M4 chunk E (steps 12-13)

Date: 2026-10-06. Two reviewers (AI agents) read 6ce3263..8f071ed, read-only, with no root and no QEMU. The chunk is:

Reviewer A took the script. Reviewer B took the docs. Their reports are kept outside the repo (~/smartconfig-work/review-m4e/findings-{a,b}.md).

They found 1 high, 4 medium, 12 low and 6 cleanups. The high one is in the README’s GRUB password recipe, which had not shipped to anyone. One medium one is a product bug in sc status, older than this chunk.

Findings

# Area Finding Sev Fix
B1 README The GRUB password recipe marks only the “Ubuntu” entry --unrestricted. With GRUB_DEFAULT=saved, a default under “Advanced options”, GRUB_SAVEDEFAULT, GRUB_DISABLE_SUBMENU or a ZFS root, every unattended boot stops at the password prompt. The grep -c check did not show which entry boots, and there was no way back. high Use it only when the defaults show GRUB_DEFAULT=0 alone; check that exactly one line, the Ubuntu entry, is marked; if not, do not reboot, and how to undo it; what to type at the prompt.
B2 README 10_linux is a grub-common conffile: taking the new one at an update drops --unrestricted while the password stays, and unattended-upgrades skips such updates. medium Say to keep yours (N), what happens otherwise, and to install that update by hand.
B4 sc status The undo was for the newest change with a blocker or an error. With an older fstab blocker and a newer error elsewhere, the console listed the blocker first and its commands restored the other file: the next boot fails again. Plan 3.1 and chunk B say “the newest blocker”. medium 654ee7f: the newest blocker, else the newest error; a test with both, which fails on the old code.
A1 accept-m4 systemd unloads a finished oneshot that nothing refers to, so the units’ invocation id came back empty. The journal read was empty, so step 2 would FAIL on “sc boot verdict said:”. The seen unit’s checks and Result could not fail, and the run time read 0 ms. medium 4b91d97: RemainAfterExit=yes on the runtime units; the id and times must be there; stop before removal.
A2 accept-m4 Section 8 opened the real store read-write: the validators’ scratch went to /var/lib/smartconfig/tmp, and the read-only path was never run on the store S3’s rescue shell will read. medium 4b91d97: the real store is bound read-only over itself in a private namespace; --console must fit 80x20 on it.
B3 README What the password closes was listed in part: older kernels, every other entry, GRUB’s command line, grub-reboot; GRUB reads the password with a US layout. low Listed.
B5 README, plan The rescue boot mounts only /: a separate /var or /usr/local means no report and no sc; a separate /boot needs mount /boot before restoring under /boot/grub. Plan section 8 said sc status says so; it does not. low README and PROJECT_LOG say what to mount; plan change C7; in MILESTONES as open.
B6 MILESTONES “The boot is tested … never on the dev VM”: S2 and S3 test it there. low Corrected.
B7 MILESTONES, plan “At most 5 files (C4)”, but C4 says 6: chunk C’s fixes made it 5 without a plan change. low C7 records it.
B8 sc status, PROJECT_LOG “The menu shows once more” was promised in every rescue boot, also one picked by hand after a healthy boot, when no flag is set. low 654ee7f: only while the flag is set (a failed boot since the last healthy one, or this boot’s own seen line: the emergency shell); C7; PROJECT_LOG says “after a failed boot”.
A3 accept-m4 The “no flag after ok” check passed when grub-editenv list itself failed. low 4b91d97: the copy must equal the real block byte for byte.
A4 accept-m4 Nothing checked that the sed put SC_HOME and BindPaths= into the runtime units; without them sc would write the real grubenv and store. low 4b91d97: checked, and a symlinked unit file is refused.
A5 accept-m4 GRUB_DISABLE_OS_PROBER=true in the environment did nothing: grub-mkconfig sets it to “auto” itself. low 4b91d97: a copy of /etc/default/grub.d with one more file, bound in the namespace.
A6 accept-m4 A second Ctrl-C cut the cleanup short, and the cleanup said nothing about what it left. low 4b91d97: signals ignored in cleanup; a WARN line for leftovers and changed real files.
A7 accept-m4 The initrd check could pass with no initrd line, and -w took a prefix. low 4b91d97: the lines must be there and match exactly.
A8 accept-m4 The checksums left out /etc/default/grub.d and the rest of /boot/grub, and were compared only on success. low 4b91d97: added; compared in cleanup too.
A9 accept-m4 No “bad” verdict on the real system; no word on what S2’s update-grub will change. low 4b91d97: step 2b with a fake systemctl bound in a namespace; a note comparing grub.cfg with what grub-mkconfig makes.
B9 README The removal left the two .service.d directories. cleanup rmdir --ignore-fail-on-non-empty; the boots file stays with the store.
B10 README “A verdict for every boot” (the rescue boot gets none); “the same report as a table” (one row per file, validators too); “its sign-off runs are next” (the review first). cleanup Corrected.
B11 MILESTONES, sc Two chunk D open items missing; “a hung sc shows nothing” (it shows the stop line since C6); the stop line said “1m0s”. cleanup Added; corrected; 654ee7f says “60 s”.
B12 docs Stale lines: the worklog’s “Kernel 7.0.0-38 boots at your next restart”, PROJECT_LOG’s backup list. cleanup Corrected.
B13 README The GRUB manual says to export superusers for submenus. cleanup The recipe has the third line.
A10 accept-m4 Comments that overstated: TMPDIR does nothing for root; two checks could not fail on a read-only mount; “Nothing real is written” with daemon-reloads. cleanup 4b91d97: comments corrected, the two checks dropped.

Held up

Not verified

Tests