@@ -259,10 +259,21 @@ for `/status` or an operator question mid-run.
259259## How pop-ups should feel
260260
261261A blocking surface (permissions, an operator question, the model/provider
262- accounting (` src/tui/geometry/resolve.ts ` ,
263- ` src/tui/shell.ts:openListOverlay ` ). Opening a second surface either
264- replaces the one that was open or stacks over it; either way Escape always
265- walks back along a single path to the prompt.
262+ picker, help) occupies the shell's ** single overlay host**
263+ (` src/tui/geometry/resolve.ts ` ,
264+ ` src/tui/shell.ts:openListOverlay ` ). A second command surface replaces a
265+ non-gate list on that host, or waits with a system line while a live
266+ gate holds it. Palette may stack over a primary; Escape always walks
267+ back along a single path to the prompt.
268+
269+ Accepting a ` / ` command or palette row keeps that host until dispatch
270+ settles: the list closes without advertising idle, the command runs, and
271+ the host advertises idle only when no list, deferred slot, or reservation
272+ remains. A command surface (` /help ` , ` /model ` ) requested while a live
273+ gate still holds the host does not steal it and does not silently no-op
274+ — it waits until that gate closes, with a system line so the wait is
275+ visible. A gate that was only queued (never shown) stays queued while
276+ the command surface is up; its display timeout does not run.
266277
267278An open overlay reserves a real minimum for its own border, title, and at
268279least one content row before anything else — including the transcript floor
@@ -346,11 +357,18 @@ showing (`repaintPalette`).
346357
347358` / ` at an empty prompt opens the command list, narrowed by name prefix as
348359more is typed (` cmd.id ` in ` openSlashCommands ` ); Tab completes the name so
349- arguments can be typed, Enter runs it. The query lives in the prompt — list
350- chrome is in How selectors should work above. When the prefix matches
351- nothing, the overlay closes and the prompt is left as typed: ` / ` then ` z `
352- with no ` z… ` command vanishes the list and leaves ` /z ` . Slash never paints
353- a ` (no matches) ` row. Every entry is backed by the live command registry
360+ arguments can be typed, Enter runs it. Enter on a matching command keeps
361+ the overlay host until dispatch settles, so a queued permission gate cannot
362+ open in the gap between closing the list and opening ` /help ` or ` /model ` .
363+ If the command list is stacked over a live permission or operator prompt,
364+ that prompt stays; the command surface waits until it closes, and a system
365+ line says so rather than dropping the selection. Tab, Escape, and Enter
366+ with no matches are genuine dismisses and still release the host. The query
367+ lives in the prompt — list chrome is in How selectors should work above.
368+ When the prefix matches nothing, the list stays open and paints a
369+ ` (no matches) ` row (CL-6699: a close-and-reopen refresh would drain a
370+ queued gate); Enter then dismisses and leaves the prompt as typed (` /z ` ).
371+ Every entry is backed by the live command registry
354372(` src/tui/command-catalog.ts:commandItemsFromRegistry ` ) — there is no
355373separate palette overlay and no shell-owned action outside the registry. The
356374overlay this reuses is still internally called ` "palette" ` (` shell.ts ` 's
0 commit comments