fn cleanup_failed_promote_orphan(state: &Arc<AppState>, label: &str)Expand description
Phase B.5c follow-up — clean up an orphan pool window left behind
when promote_pool_window’s HWND validation fails. Without this,
the popped label sits in state.browsers but is no longer in
unpromoted_pool_labels (promote removed it) and never became a
real user window (no WindowOpened was reported). Host’s
compute_and_report_host_counts then counts it as a window, while
the launcher mirror correctly does not — persistent off-by-one
drift. (Caught by B.4b drift detection during B.5c smoke test on
v0.33.461.)
Contract: this fn is responsible for ALL recovery including pool
refill. The caller MUST NOT call spawn_pool_window itself —
double refill would overshoot POOL_TARGET_SIZE and waste
renderer capacity. (codex P1 PR #582 round-1.)
Two paths:
- Graceful path (browser+host alive in CEF): issue
close_browser(1)and let CEF’son_before_closefire. That path runs the standard cleanup chain — drops fromstate.browsers+window_meta, callson_pool_window_destroyed(which itself triggers refill viaspawn_pool_windowwhen pool size is below target), and triggerscompute_and_report_host_countsfromclient.rs. - Direct path (browser or host already gone):
on_before_closewon’t fire so we do its job inline — drop from browsers + window_meta, sendreport_window_closed(silent no-op in launcher reducer for an unknown label), spawn the refill ourselves, and emit a drift count snapshot so the orphan’s removal is observable on the same tick. (reagent P2 PR #582 round-1 — original direct path skipped the snapshot.)