SmartConfig

Review of M4 chunk C (steps 7-10)

Date: 2026-10-04. One reviewer (an AI agent) worked on cbd6483..b6f8dd5. The chunk is:

The reviewer ran 11 boots of a throwaway QEMU guest, 5 UEFI and 6 BIOS, two of them with VGA screendumps. The guest had a separate /boot and the hardest menu settings: hidden, timeout 0, GRUB_RECORDFAIL_TIMEOUT=0. It found nothing high or medium, and 8 low findings and 5 cleanups.

Claude fixed all of them. Before committing, Claude ran an adversarial check: four skeptic agents each tried to refute one group of fixes. They confirmed 11 fixes. They refuted one: the console still overflowed 80×25, through symlink rows and the new-file mv. They also raised 18 smaller issues. All of that was then fixed in the same commit.

The step 11 design workflow, run alongside, found one more bug, in sc status’s mode. Everything is in 683678a.

Findings

Area Finding Severity Fixed in
units ConditionPathIsExecutable= is no systemd key; systemd ignored it with a warning, so “skipped without sc” (chunk B) did nothing. The tests took verify’s exit 0 for clean. low 683678a: ConditionFileIsExecutable=, and the tests fail on any systemd-analyze output
flag grub-editenv rewrites grubenv in place with no lock. Since C4, sc boot seen could run at the same time as grub-common.service (unset recordfail) and grub-initrd-fallback.service, losing writes. A stress test lost 9 flag writes and 21 recordfail unsets in 300 runs. low 683678a: seen runs before both, sc-boot-ok after seen. Those three units now wait for seen, which takes about a second.
grub With GRUB_DISABLE_LINUX_UUID=true, root= was PARTUUID=… or empty, where 10_linux gives the device. low 683678a: GRUB_DISABLE_LINUX_PARTUUID defaults to true, as in 10_linux, tested with this machine’s real UUID and PARTUUID links
grub ro came before GRUB_CMDLINE_LINUX, so an rw there made the rescue root writable. Shown in the lab. low 683678a: ro after it
drop-in The report went to /dev/console alone, which is the last console=. A screen with a serial console got no report. low 683678a: the report goes to every console in /sys/class/tty/console/active, each with a 2 s write deadline, so a stalled console cannot hold up the shell
status The console report went past 80 columns: 20 rows of report plus 5 of prompt filled 80×25 exactly, with no margin. low 683678a: at most 20 screen rows, counting wrapped lines (see the refuted fix below)
restore ReplaceRefused ran before the other refusals. An absent file’s deletion row was refused in a +i directory, a digest row’s message was hidden, and the file was opened before safeDir. low 683678a: it runs last, after the blob read and safeDir, in both Restore and CanReplace
grub GRUB_DISABLE_RECOVERY=true was ignored. low 683678a: no entry is added; the menu flag stays
tests Surviving mutations: version order, the UUID and PARTUUID branches, the timeout rule, Stat instead of Lstat, a failing grub-editenv, +a on the target and +i on the directory. cleanup 683678a: a test for each
fsutil The flags were read into a uint64, which is wrong on big-endian. cleanup 683678a: uint32
plan Section 3.3 named 00_header’s filesystem check; the code checks for a 1024-byte block. cleanup plan change C5
grub A /boot whose kernels have no initrd got no entry, with no word said. cleanup 683678a
plan The rescue boot cannot clear the flag, so the first boot after the fix shows the menu once more. cleanup 683678a: sc status says so, only when this boot has no ok verdict; plan change C5

Adversarial check of the fixes

Refuted, then fixed. The console could still pass 25 rows:

Both now fit:

Issues it raised, fixed:

Found by the step 11 design:

Deferred:

Held up

Tests