Closed general

request_shell_approval should be awaitable (wait:true) and grants should appear in notify_events

John Lauer · 2mo ago ·closed by John Lauer

Context (2026-09-11, adom-vscode 1.1.49 rollout across four boxes): wsl_exec on arav-rog and winvm returned needs_approval, the dialog and toast showed, and the human clicked Approve 1 hr a few minutes later. The AI thread learned that only when it happened to re-read status.permissions.shell twenty minutes on. A relay caller is turn-based: nothing on ab's side tells it the grant landed, so the retry the refusal asks for happens whenever the caller next looks.

Two additions would close the loop, both modelled on what notify_user already does for its buttons:

  1. request_shell_approval {wait:true, timeoutSec:N} blocks up to N seconds and returns {granted:true, source:"timed"|"auto", expiresInSec} when the human clicks, or {granted:false, pending:true} on timeout. Same shape as notify_user wait:true.
  2. A shell_granted event (with expiresInSec and who granted, dialog or toast or settings) in notify_events, so a caller with several machines pending gets every grant in one poll instead of a status call per box.

Today's workaround on the caller side is a background poll of status.permissions.shell.autoApproved every 30 s; the two above make that unnecessary.

3 Replies

John Lauer · 2mo ago

Both asks shipped in 2.1.100 (insiders, on winvm, ConfRoomROG and AdomLapper; Linux CLI 2.1.100 published). (1) request_shell_approval {wait:true, timeoutSec:N} blocks up to N and returns {granted:true, source, expiresInSec, permanent} the moment a grant lands on ANY surface, or {granted:false, pending:true, timedOut:true} on timeout; each command runs in its own task so the wait stalls nothing. (2) every grant and revoke lands in notify_events as {event:'shell_granted'|'shell_revoked', source, permanent, expiresInSec, at} - one drain sees every box. The surface is named at the one grant core: dialog | toast | settings | card-or-hydrogen | decided-on: | api:. The CLI stretches its budget to timeoutSec+15 s for a waiting call, like notify_user. Proof on winvm (transcript attached), the human decision made on the LAPTOP by verb on the mirrored card: the blocked call returned granted:true 12 s in, expiresInSec 3599; notify_events on winvm shows shell_granted with source decided-on:AdomLapper; the already-active shape answers alreadyApproved:true + source already-active; with nobody clicking, a 15 s wait returns pending:true timedOut:true in 17 s. One defect in that run, fixed in 2.1.101 (building): the INLINE source read 'unknown' because the grant core wrote the record after its toast cleanup, a second or two behind the state flip the waiter polls; the record now follows the state update directly and the waiter allows a short grace. Your 30 s status poll can go as soon as 2.1.101 lands; wait:true or a notify_events drain replaces it.

proof-21100.txt

John Lauer · 2mo ago

2.1.101 (insiders, whole fleet, Linux CLI published) closes the one gap from the 2.1.100 run: the waiting call now names the surface inline. Same proof on winvm, decision made on the laptop by verb (transcript attached): the blocked request_shell_approval {wait:true, timeoutSec:120} returned after 12.4 s with granted:true, source 'decided-on:AdomLapper', expiresInSec 3599; notify_events on winvm shows shell_granted with the same source; the already-active shape answers alreadyApproved:true + source already-active + expiresInSec 3587; with nobody clicking, a 15 s wait returns pending:true timedOut:true in 17 s. Root cause of the 2.1.100 'unknown': the record was written after the grant core's toast cleanup (1-2 s of PowerShell), behind the state a waiter polls every 400 ms; it now follows the state update directly, and the waiter allows a short grace. Closing once the smoke suite is green.

proof-21101.txt

John Lauer · 2mo ago

Closing: 2.1.101 insiders on the whole fleet (winvm canary through the real embedded update path, then ConfRoomROG and AdomLapper; Linux CLI 2.1.101 published); both asks proven on winvm with the decision made from the laptop (see the transcripts above); smoke suite on 2.1.101: 60/60 executed, 0 unexpected failures.

John Lauer closed this · 2mo ago

Log in to reply.