Skip to content

sm: Walk the platform again after an update activates - #513

Draft
chrysh wants to merge 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:rewalk-after-update
Draft

chrysh wants to merge 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:rewalk-after-update

Conversation

@chrysh

@chrysh chrysh commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Rebased onto ocp-global-demo-wip. One commit, no stack note: #511 and the arm->start rename merged, and #512 (slot re-sync) is independent of this one.

This was a port, not a replay. The old sm/src/lib.rs monolith is now split into model/sink/status/rot, so the state-machine changes moved to rot.rs, and Event::UpdateVerified lost its component id while Event::UpdateRequest gained one.

Activation only proposes the image. The device keeps running the old one until it is reset, so the machine enters PreSupervision instead of returning to Ready: that entry quiesces every live component and verifies each image at rest before releasing it, and the release is the reset that boots the candidate.

It also fixes a stale floor commit. CommitSvnFloor advances to verified_svn, which only the walk's VerifyFirmware records. Without the re-walk a BootConfirmed after an update committed the floor to the previous image's SVN, leaving open the downgrade window the floor exists to close.

The commit window now spans that walk, so every state it passes through has to answer CommitTimeout. PreSupervision is unsupervised and had no arm, and the supervising handler had none either, so a watchdog fire during the walk was dropped and never came again.

Four existing tests needed the walk-completing VerificationPassed before their BootConfirmed, including a_sibling_boot_confirmed_does_not_consume_the_window, which postdates the original branch.

Open, and the reason this is still a draft: the walk re-verifies and reboots every component, not only the one that was updated. The neighbours are reset into byte-identical firmware. Scoping it to the updated component (plus whatever the chain says falls with it) is the next step, and it is not in this commit.

Activation only proposes the image. The device keeps running the old
one until it is reset, so the machine now enters PreSupervision instead
of returning to Ready: that entry quiesces every live component and
verifies each image at rest before releasing it, which is the reset
that boots the candidate.

It also fixes a stale floor commit. CommitSvnFloor advances to
verified_svn, which only the walk's VerifyFirmware records. Without the
re-walk a BootConfirmed after an update committed the floor to the
previous image's SVN, leaving the downgrade window the floor exists to
close. The walk re-verifies the new image first, so the commit takes
its SVN.

The commit window now spans that walk, so every state it passes through
has to answer CommitTimeout. PreSupervision is unsupervised and had no
arm, and the supervising handler had none either, so a watchdog fire
during the walk was dropped and never came again: commit-or-lock went
unenforced for the length of a boot. Both arms added.

The image is judged twice, by the pumped verifier before activation and
by the walk after the reset. That is the point: the second one covers
code at rest, in the slot the device actually booted.

The effect bound still holds: this dispatch emits ActivateUpdate plus N
quiesce asserts plus the entry's two walk effects, N+3 against the
E >= 2N+2 the buffer is sized for. The documented bound came from the
gate cascade, which is the larger path.

Assisted-by: Claude
@chrysh
chrysh force-pushed the rewalk-after-update branch from 03c4797 to 6a27e42 Compare October 5, 2026 09:03

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant