ADR-021: Native Sudo Prompting and Probe-Gated Preflight

Status

Accepted

Related: ADR-014 (shared SIGINT handler wraps the sudo -v preflight too).

Date

2026-09-10

Context

Two problems with privileged operations:

  1. NOPASSWD is ignored by stamp update. update unconditionally printed its own ▪ sudo password: and cached the password for the parallel run phase (promptSudoPassword + manager.SetSudoPassword). On hosts configured with sudo NOPASSWD, or with a valid credential cache, it prompted anyway — while every other command relied on sudo’s own prompt and stayed silent.

  2. Parallel restore had no pre-auth. restorePackages runs one goroutine per manager. On a password-protected host with an empty cache, concurrent sudo children could prompt at the same time, garbling the terminal.

The stamp-managed password path was also the riskiest part of the code: the password lived in a package global and was written to each sudo child’s stdin via -S, where it could starve the child’s real stdin or be captured by an I/O-logging plugin.

Decision

Stamp never handles the password. sudo prompts natively for every command. Add a probe-gated preflight for the commands with a parallel privileged phase.

Probe and preflight

update and restore call sudoPreflight immediately before each privileged phase (refresh, then again right before the parallel run) to keep the auth window minimal. restore derives the adapter set from the repositories and packages actually being restored, so a brew-only restore never probes sudo.

Removed

manager.SetSudoPassword / ClearSudoPassword, the sudoPassword global, the -S branch in sudoCmd, and the stdin-piping block in defaultExecutor. The cli.promptSudoPassword function is deleted.

Alternatives Considered

Keep the stamp prompt, add the probe (Option B)

Probe, then -S-cached fallback only when a password is needed (Option C)

Always run sudo -v (no probe)

Consequences