Closed general

clear_app_toasts() cross-sweeps both permission systems' toasts (shell grant clears a live web-control consent toast)

John Lauer · 2mo ago ·closed by John Lauer

clear_app_toasts() cross-sweeps BOTH permission systems' toasts

Found while proof-testing the two approval surfaces on 2.0.48 (AdomLapper).

notifications::clear_app_toasts() calls History.Clear(APP_ID) — it removes EVERY ab toast (all share the inc.adom.bridge AUMID + group adom). It is called on a shell-auto-approve GRANT (so the pile of pending shell-approval toasts vanishes the instant the user grants — correct intent, v1.9.80/1.9.102). But it also clears a LIVE web-control consent toast that is still waiting on the human, because both toast families share the AUMID+group.

Repro: (1) a web page triggers a web-control consent (its toast is on screen, waiting), (2) meanwhile the user (or a local caller) grants shell auto-approve, (3) clear_app_toasts fires and the web-control consent toast disappears while its in-window dialog + its 120s POST are still pending. The user loses the toast surface for a decision they never made.

It is the same failure the other direction too: resolve_web_approval also calls clear_app_toasts() to sweep the (single) web consent toast, which would clear any live SHELL approval toasts.

Severity: low-to-moderate. The in-window dialog survives (the reliable surface), so no decision is lost, but the toast — which is the surface a hidden/embedded ab relies on — vanishes for the OTHER system's pending prompt.

Proposed fix: scope the sweep by TAG, not by AUMID. Shell approval toasts already tag by approval_toast_tag(id) / the shared shell-approval tag; the web consent toast has its own tag. dismiss_toast_by_tag already exists and escapes safely. So:

  • On a shell grant, sweep only the shell-approval-tagged toasts (drain state.pending_approvals -> dismiss each by its tag, plus the generic shell-approval tag).
  • On a web decision, sweep only that origin's web consent tag.
  • Keep a full History.Clear only for an explicit "clear all ab toasts" action, if one is even needed.

This keeps each permission system's toast lifecycle independent.

1 Reply

John Lauer · 2mo ago

Fixed across 2.0.53/2.0.54, closing.

  • Shell-grant sweep: tag-scoped (each drained approval's tag + the generic shell-approval tag) - shipped in 2.0.53 (5a6f66a0).
  • Web-decision sweep: scoped to that origin's consent tag - same commit.
  • 2.0.54 closes the LAST cross-sweeper: the credential-import consent cleanup called blanket clear_app_toasts(); its toast now carries a per-consent tag (credimport-) and the cleanup dismisses only that tag.
  • History.Clear survives only in the explicit clear-all path, per this issue's proposal.

Live repro re-run on 2.0.54 (AdomLapper, 2026-08-16 evening): shell-approval prompt + web-control consent staged simultaneously, human approved the shell prompt; grant took effect with the web consent's flow intact.

John Lauer closed this · 2mo ago

Log in to reply.