Updates fix forward (owner ruling, 2026-11-05). #1196 took the death-driven
fallback out; this takes out the verification fallback, the last one.
A pass verifies the slot the table marks and no other. Where it is refused
for its signature, a hash, its version against the floor or anything else,
the loader names the refusal, says that no other slot is booted and that the
remedy is a newer image, on the console and in loader.log, and ends as its
panic does: the machine powers off, or resets where a BootNext bought this
boot and the firmware's default entry is another. The other slot is not read.
Gone with it: policy::order and its test; Refusal::word, its test and
Refusal::Absent, which nothing constructed; Chosen::refused; the
slot-refused= boot parameter in toyos-abi, the kernel's claim on it and the
kernel's record of a refused marked slot; the metal row
bent_supervisor_falls_back with the metal profile's bent arms.
a_bent_supervisor_is_refused_and_the_other_slot_boots becomes
a_bent_supervisor_is_refused_and_nothing_boots: slot A's supervisor bent
beside a whole slot B, on a machine of each architecture whose console is the
loader's serial port. It waits for the loader's line, then for QEMU to exit,
and holds that the loader read nothing of slot B and no kernel said a line.
It has no metal row: the metal loop refuses a boot that left no stop mark, so
a refused slot on the T14 stays the bench stage's exit.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Problem
Updates fix forward (owner ruling, 2026-11-05): the loader boots the slot the table marks and never the other one. #1196 removed the death-driven fallback. The verification fallback was still there:
policy::ordernamed the other slot after the marked one, andslot::choosebooted it when the marked slot failed its signature, a hash or the anti-rollback floor, telling the kernel throughslot-refused=.Resulting behavior
slot::provenverifies its signed header to raise the floor, and nothing of it boots.loader.log:Slot A: REFUSED, its supervisor is not the bytes its signed header names, thenSlots: the marked slot A is refused, and no other slot is booted; the remedy is a newer image.BootNextbought this boot and the firmware's default entry is another (the development bench, whose default is its own system). No kernel is handed the machine. The design, now in the manual by the orchestrator's ruling on this PR, is power off and reset into nothing else; the reset that remains is recorded in the update track with the loader track's stage 4 as its exit.Removed
toyos_update::policy::orderand its test;Refusal::wordand its test (its only reader wasslot-refused=);Refusal::Absent, which nothing constructed.Chosen::refusedand the loop inloader/src/slot.rs;slot::chooseisslot::marked.toyos_abi::boot::SLOT_REFUSED_PARAM, the kernel's claim on it, the build'sVALUED_PARAMSrow and the kernel's two "because the marked slot was refused" records. This is a removal fromtoyos-abi; its consumers are the loader, the kernel and the build, all changed here. No fork names it.bent_supervisor_falls_back, withmetal::Arm::bentand the metal profile's bent-image build, which only that row used.Payload::free,BootServices::free_pagesand their call sites): it gave pages back so the next slot could be tried, and every refusal now ends the pass.update --onceis not in the tree (it is the loader track's stage 5), so there was no request semantics to keep. The bench's loader-binary trial is untouched.Decisions worth a reviewer's eye
ordergone,toyos-update's policy has no slot decision left: the loader readstable.marked, andTable::decodealready refuses a table marking a slot it does not carry (a_table_reads_back_and_a_bent_one_is_refused). What remains, that a refused marked slot boots nothing, is in the UEFI loader and is held by the guest row; the purepass::decidethat would make it host-testable is the loader track's stage 5. The one host addition isthe_loader_writes_the_lines_the_host_readsholding the test's marker to the loader's constant.loader.log).issues/an-unreadable-newest-slot-table-copy-boots-the-previous-mark-unreported.md, the one path left by which a pass can boot the previous slot, found in review and older than this branch.Tests
a_bent_supervisor_is_refused_and_nothing_bootsreplacesa_bent_supervisor_is_refused_and_the_other_slot_boots. It needs a guest because the check runs in the UEFI loader beforeExitBootServices. Slot A's supervisor is bent beside a whole slot B; it runs onHeadlessNoConsolePort(x86-64) andVirt(AArch64), the machines whose console is the serial port the loader writes. It waits for the loader's refusal line, then for QEMU to exit, and holds that the loader verified nothing of slot B and that no kernel said a line. Its boot has no proof record, so nothing of slot B is read at all.Checks
Commands, exit codes and logs are in the evidence. Head is
3231f4125; round one wasdd736982b.3231f4125(guest runner, run 42919063497):a_bent_supervisor_is_refused_and_nothing_boots(x86-64 and AArch64),a_clean_stop_proves_its_imageandvirt_first_entry: 3 passed. log. The same three passed atdd736982b(run 42910883434).dd736982b(run 42910889983): with the other slot put back into the pass (control.diff), the image builds and the row fails: the loader refuses slot A, verifies slot B and boots it. log. Not repeated: round two did not touchslot::marked.dd736982b: one boot of thetestcasesimage, run by the orchestrator. The loop's verdict passed, andcontrol_regsandmemory_overwrite_requestedpass on its readback. judge log. The boot is of round one's loader; round two only removes calls on refusal paths.dd736982b's tree:cargo run -- --ci hostexits 1 with 1 of 110 steps red:llvm::tests::the_caller_s_environment_reaches_neither_the_build_nor_the_key, which fails on every macOS host (issues/the-llvm-environment-test-breaks-git-on-macos.md) and is in code this branch does not touch. log3231f4125's tree:cargo run -- --clippyexits 0, andcargo test -p toyos-update -p toyos-abiexits 0. The whole host run was not repeated.Risks
ResetSystemafter a refusal; none did before.🤖 Generated with Claude Code