handle_report_pool_window_promoted

Function handle_report_pool_window_promoted 

Source
pub(super) fn handle_report_pool_window_promoted(
    state: &mut State,
    label: String,
) -> Vec<Event>
Expand description

Phase F.5 — host-emitted promote signal. The reducer doesn’t mutate state for this command (the windows/pool transitions are carried by the surrounding ReportPoolWindowRemoved + ReportWindowOpened pair); it just translates the wire command into the corresponding typed event so subscribers — most importantly the launcher saga coordinator — can react.

Idempotent / context-free: we don’t validate the label is in the mirror because the host’s own ordering may have the ReportPoolWindowRemoved arrive before this command, after this command, or in either order; the typed event is “host says a promote happened” — subscribers correlate with the surrounding add/remove pair if they need stronger invariants.

WRR side-effect: records the label in state.just_promoted_labels so the subsequent ReportWindowOpened initializes the new mirror with foregrounded_since_open: true. Promote is the user explicitly tearing off a tab — the open-transient corrective logic in apply_hwnd_visibility_changed MUST stop firing for this label, otherwise the post-promote reposition (multiple SetWindowPos calls during HWND placement) re-fires HiddenSinceOpen indefinitely. Each fire is a launcher event broadcast to all renderers; without this guard the host fans the same drift event out across the bridge until the renderer’s V8 isolate runs out of stack and crashes (Crashpad_NotConnectedToHandler, observed v0.33.655).

The actual host emit order is ReportPoolWindowRemoved → ReportPoolWindowPromoted → ReportWindowOpened (agentmux-cef/src/commands/window_pool.rs). At promote-time the launcher has NO mirror for this label — state.pool.contains(label) is also false (removed by the preceding ReportPoolWindowRemoved), so we can’t gate purely on pool membership in handle_report_window_opened either. The just_promoted_labels set bridges the microsecond gap.

Order-tolerant: if the open already arrived (out-of-order IPC, replay, fuzzed sequence), update the existing mirror immediately so we don’t leak a just_promoted_labels entry that will never be drained. The proptest in tests.rs (just_promoted_labels_drained_by_open_or_close) caught this gap on PR #709 round 2.

See docs/specs/ANALYSIS_DRIFT_STORM_RENDERER_CRASH_2026-05-06.md.