SmartConfig

Final review of M4 (sign-off S4)

Date: 2026-10-07, after sign-off runs S1-S3 on the real system (S3: a bad fstab line, two failed boots, the rescue boot and the restore on this VM, the owner at the console). Three reviewers (AI agents), each in its own clone of 81319d8 with its own sc build and throwaway stores: A on boot integration (the units, the GRUB script, the menu flag, every kind of boot), B on the rescue-time CLI and its data (sc status, the boots file, the read-only store, restore), C on security and the docs against the code and the real runs. No QEMU, nothing installed, nothing written to /etc, /boot or the real store; the journals of S2 and S3 were read as root. Claude reproduced each high and medium finding before fixing it. Reports: ~/smartconfig-work/review-m4final/findings-{a,b,c}.md.

Gate: no high-severity finding open. B found two high ones; both are fixed (69ea585, 4a8f7b4). All 6 medium findings are fixed (one found by A and C alike), and so are 13 of the low ones and the docs’ cleanups. The rest go on the M4 follow-up list in MILESTONES.md.

Departures from the review rules, all read-only or contained:

What held up

Findings

Area Finding Severity Fixed in
console (B1) With the only console stopped (Scroll Lock, XOFF, a serial line with flow control and no peer), each console was given up after 5 s and then the report went to stdout, /dev/console, the same stopped device, with no limit, after the 60 s timer had been stopped. systemd ends rescue.service at 90 s: no shell. Reproduced with a stopped pty: still blocked at 15 s. high 69ea585: stdout only when no console opens, and even then bounded; one deadline, 80 s from the start, for every write; the store note goes into the report
status (B2) A path with no recorded version at the line was “new”. An fstab whose first row was scd’s baseline (no healthy boot yet, or a verdict given before the baseline) got mv /etc/fstab /etc/fstab.sc-off. Without a healthy boot, a blocker added by the oldest row listed was “no problem found”, no undo. Both reproduced. high (narrow) 4a8f7b4: new only with proof of absence; first seen after the line, compared with that first version; with none, “fix it by hand”; without a healthy boot, the version before the rows listed
units (A1, C2) After mount -o remount,rw /, “exit” or Control-D in the rescue shell isolates default.target: the boot goes on with fstab ignored, both units run, and the verdict is “ok”, which clears the flag and makes the next failure’s report start after the bad edit, with no undo. Found by A and C alike; reasoned from systemd’s source and the units, not booted. medium 8c6f30e: both units need a command line without fstab=no
grub (A2) The rescue entry kept only console= of GRUB_CMDLINE_LINUX_DEFAULT: a nomodeset the screen needs was dropped. The lab’s check 0.5 stated the opposite rule. medium 580edca: every token but quiet splash, unglobbed
status (B3) Deleting /etc/nologin or sshd_not_to_be_run, what their findings ask for, was “error: deleted”, with an undo that put them back. medium 734b670: no error for the flag checker or ld.so.preload
status (B4) With /var on its own filesystem, the rescue report said “run: sc init”, which would make a new store under the mount point. medium 734b670: in a rescue or emergency boot, mount /var
docs (C1) “A root shell without a password”: only while root is locked. With a root password, sulogin asks for it (probed). medium docs commit: the README and plan section 5
docs (C3) On a desktop the failed boot comes up to the login screen, ssh up, the report hidden behind it; the README said “stop in emergency mode” and “over SSH the machine is gone”. medium docs commit: README, PROJECT_LOG, docs/README
units (A3) systemctl rescue or emergency, or an isolate, starts the finished sc-boot-seen again: a seen line after “ok” and the flag set, so the menu shows for nothing. S3’s double seen (a sound card’s transaction while sysinit waited 90 s) is the harmless form. low 03ec9ca: a boot with a verdict is not seen again
grub (A4) On a desktop, Ubuntu’s grub-initrd-fallback.service is in rescue.target.wants; it cannot write grubenv on the read-only root: a red FAILED line right above the report (S3’s photo). low 580edca: the entry masks it for that boot
boot (A6, C7) A seen line that could not be written cost the flag too; a /var that failed to mount left neither. low 03ec9ca: the flag first; a bad verdict sets it too
boots (B5) A torn last line glued the next boot’s “seen” to it, and that boot was lost; zeros after a power cut made a phantom boot. low 03ec9ca: the line is ended first; an unended last line and leading zeros are skipped
boots (C6) The file root writes at boot followed a symlink, and a trim rewrote its target. low 03ec9ca: O_NOFOLLOW, regular files only
status (B6) The 60 s stop exits with os.Exit: the repaired store copy and the scratch stayed in /run. low d9c8817
status (B7, C8) mv and cd printed paths raw: a space broke the command, a ; ran another. low d9c8817: shell words, $'...' for control characters
docs (C4, C5, C9-C13) The FAILED line, the rescue boot’s journal, the recipe’s grep on an empty grub.d, “40 s” and “30 s” as the lab’s and the default’s, removing the watcher before the rescue path, stale status lines and backups, plan changes as built. low, cleanup docs commit; C13 is plan change C8
tests (A7) 21 of 31 boot mutations survived the Go tests; an ordering cycle was caught by nothing faster than the lab. low 8c6f30e: a whole-boot systemd-analyze verify; the rest deferred (6)
status (B8) A restore under an unmounted separate /boot can write the root filesystem’s shadow /boot/grub. low deferred (1)
status (B9) A checked file replaced by a symlink is not judged. low deferred (2)
grub (A9) GRUB_TOP_LEVEL is ignored. low deferred (3)
boots (A5) A soft-reboot’s new session has the boot id of its verdict. low deferred (4)
units (C14) The units run as full root; a test knob in 42_smartconfig. cleanup deferred (5)
lab (A8) Check 1.8 cannot fail: critical-chain skips oneshots that never become active. low open; S2’s conclusion stands on its timings
status (B cleanups) Times with no date, $SC_HOME/tmp made by status, the WAL message on a read-only root, ioctl numbers on mips and sparc. cleanup deferred (7)

A3 was fixed in sc (seen reads the boots file) rather than with RemainAfterExit=yes on the unit: an active seen would enter critical-chain, and the lab’s check 1.8 would then fail on a host pause.

Tests

New or changed:

Each new test fails on the code before its fix. All tests pass as a user, as root and under race, make lab-test (326) and make m1-compat pass, and CI is green on each commit. Not yet run on the fixed build: accept-m4.sh as root and make lab-e2e, which boots the changed entry and units in QEMU.