Skip to content

init: prompt-aware status-message redraw and token-unlock confirmation#357

Merged
anatol merged 2 commits into
anatol:masterfrom
pilotstew:pr/plymouth-status-messaging
May 6, 2026
Merged

init: prompt-aware status-message redraw and token-unlock confirmation#357
anatol merged 2 commits into
anatol:masterfrom
pilotstew:pr/plymouth-status-messaging

Conversation

@pilotstew
Copy link
Copy Markdown
Contributor

What this PR does

Two changes that together close out the console UX for booster's concurrent unlock pipeline:

1. Prompt-aware statusMessage redraw. When statusMessage fires during an active console password prompt, the current line is erased, the message prints, and the prompt is reprinted below — cursor stays at the bottom, asterisk count preserved. Without this a status message printed mid-prompt tears through the prompt line.

The new promptVolumeUnlocked helper lets statusMessage skip the redraw when the prompt's volume is already unlocked (its ctx.Done() has fired), avoiding reprinting a stale prompt that the cancellation logic hasn't yet torn down.

readPasswordOn now sets consolePrompt.{active, text, done} during each prompt — fields declared in #355 that become load-bearing only now that statusMessage consumes them.

2. Token-unlock confirmation. recoverTokenPassword fires statusMessageTimed("X unlocked via Y", 3s) on success. After #355 (keyboard prompt cancellation) and #356 (PIN-prompt cancellation) cleanly dismiss prompts when a sibling token wins the race, the user previously saw nothing telling them what happened — boot just continued. This adds the missing confirmation: "cryptroot unlocked via FIDO2", "swap unlocked via TPM2", etc.

tokenFriendlyName provides the short label per token type. statusMessageTimed clears the message after 3 seconds so it doesn't linger on the splash.

Scope

Console UX only. Plymouth users get these messages too (statusMessage routes to plymouthd when enabled), but Plymouth-side polish — splash banner styling, native timed-message support, dismissing prompts on socket hangup — is separate work upstream of plymouthd.

Testing

  • TestPromptVolumeUnlocked: covers all three observable states of the active-prompt's ctx.Done() — nil, open, closed.
  • TestTokenFriendlyName: pins down the labels in the unlock-confirmation message.
  • The redraw protocol's visual correctness (line-erase + reprint with preserved asterisk count) is covered by live test rather than unit test — the relevant output goes through fmt.Print, which the pty harness can't capture.

Live-tested on local tty1: token-unlock confirmation appears after autounlock; status messages don't tear through prompts during PIN-incorrect retry.

pilotstew added 2 commits May 5, 2026 21:34
Two changes that together close out the console UX for booster's
concurrent unlock pipeline:

1. Prompt-aware statusMessage redraw. statusMessage now consults the
   active prompt before printing to console. If a passphrase prompt
   is on screen and its volume hasn't been unlocked yet, the current
   line is erased, the message prints, and the prompt is reprinted
   below — cursor stays at the bottom, asterisk count preserved.
   The new promptVolumeUnlocked helper lets statusMessage skip the
   redraw when the prompt's volume is already unlocked, avoiding
   reprinting a stale prompt that ctx-cancel hasn't yet torn down.
   readPasswordOn now sets consolePrompt.{active,text,done} during
   each prompt — fields declared in anatol#355 that become load-bearing
   only now that statusMessage consumes them.

2. Token-unlock confirmation. recoverTokenPassword fires
   statusMessageTimed("X unlocked via Y", 3s) on success. After
   anatol#355 and anatol#356 cleanly dismiss prompts when a sibling token wins
   the race, the user previously saw nothing telling them what
   happened — boot just continued. This adds the missing
   confirmation. tokenFriendlyName provides the short label per
   token type; statusMessageTimed clears the message after 3s so
   it doesn't linger.
Two unit-test functions in the new init/plymouth_test.go:

- TestPromptVolumeUnlocked: covers all three observable states of
  the active-prompt's ctx.Done() — nil, open, closed. The closed
  case is what statusMessage uses to skip a redraw when the volume's
  already been unlocked.

- TestTokenFriendlyName: table test pinning down the labels in the
  unlock-confirmation status message — these are user-visible
  strings so a typo would ship.

The redraw protocol's visual correctness (line-erase + reprint with
preserved asterisk count) is covered by live test rather than unit
test — the relevant output goes through fmt.Print, which the pty
harness can't capture.
@pilotstew
Copy link
Copy Markdown
Contributor Author

Testing messaging can be hard — would love some more eyes here, likely rough edges in the wording and timing. The strings ("X unlocked via Y"), the 3-second timed-clear duration, and the choice between timed-clear vs ctx-driven clearing are all judgment calls. Would love feedback on anything that reads off.

@anatol
Copy link
Copy Markdown
Owner

anatol commented May 6, 2026

The idea and the code that implements looks good to me. It is a type of a change that improves usability of booster. And it would be good to have it. Thank you for the PR!

@anatol anatol merged commit f98925b into anatol:master May 6, 2026
@pilotstew pilotstew deleted the pr/plymouth-status-messaging branch May 9, 2026 02:53
pilotstew added a commit to pilotstew/booster that referenced this pull request May 14, 2026
Adds a new NOTES subsection covering the concurrent-unlock model that
landed across PRs anatol#350, anatol#353, anatol#355, anatol#356, anatol#357, anatol#358, and anatol#362:
PIN-token serialization in ascending LUKS2 token-ID order, cancel-on-win
semantics for keyboard/FIDO2-PIN/TPM2-PIN prompts on both the console
and the Plymouth splash (with the MR !393 caveat for older Plymouth
builds), and the per-token 3-attempt PIN cap with empty-PIN skip.

Trims two paragraphs from the existing 'Password entry' subsection
(auto-dismiss and PIN attempts) now that the new section covers them
in fuller context. 'Password entry' keeps the Ctrl+W / Ctrl+U / Tab
edit-key reference.
anatol pushed a commit that referenced this pull request May 14, 2026
Adds a new NOTES subsection covering the concurrent-unlock model that
landed across PRs #350, #353, #355, #356, #357, #358, and #362:
PIN-token serialization in ascending LUKS2 token-ID order, cancel-on-win
semantics for keyboard/FIDO2-PIN/TPM2-PIN prompts on both the console
and the Plymouth splash (with the MR !393 caveat for older Plymouth
builds), and the per-token 3-attempt PIN cap with empty-PIN skip.

Trims two paragraphs from the existing 'Password entry' subsection
(auto-dismiss and PIN attempts) now that the new section covers them
in fuller context. 'Password entry' keeps the Ctrl+W / Ctrl+U / Tab
edit-key reference.
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.

2 participants