pub fn compute_and_report_host_counts(state: &Arc<AppState>)Expand description
Phase B.4 follow-up — compute the host’s authoritative counts
from AppState and report them. Callers invoke this AFTER
each window/pool transition.
Atomic snapshot: holds both unpromoted_pool_labels and
browsers simultaneously so the reported (windows, pool)
pair is from one consistent state. Without this, a concurrent
mutation between the two lock acquisitions (CEF lifecycle on
the UI thread vs. IPC handler in commands/drag.rs) could
produce a mismatched snapshot and trigger a spurious
Event::DriftDetected. (codex P2 PR #578 round-1.)
Lock order: unpromoted_pool_labels first, then browsers.
Matches the existing snapshot pattern in
client.rs::on_before_close (line ~418) and is the only place
in the codebase that holds both locks simultaneously, so no
other path can race in the reverse order.
Counts (matching the launcher’s mirror semantics):
windows— top-level user-visible windows inbrowsers, excludingbrowser-pane-*child HWNDs and any label still inunpromoted_pool_labels.pool— pre-promote pool labels (unpromoted_pool_labels.len()).
Why this reads host’s browsers and unpromoted_pool_labels
directly (not the shadow): this fn IS the source for the
launcher’s mirror — its output is what gets compared against
state.windows.len() / state.pool.len() in the drift-detection
path. Reading from the shadow would compare the shadow against
itself (always agrees) and defeat the entire B.4 drift-detection
design. Once the host reducer arrives in Phase F (see
docs/retro/multi-reducer-proposal-2026-04-28.md), this becomes
“report host’s authoritative reducer-state to the launcher.”