forked from unom/punktfunk
All in the same ~120 lines, all the same shape: a recovery leg gated on the wrong flag, so the path that turned something off had no path that turned it back on. **The DDC wake was nested inside the CCD-restore arm.** Panels are commanded dark over DDC/CI *before* the isolate, but `panel_on_all()` sat inside `if let Some(saved) = ccd_saved.take()` — and `isolate_displays_ccd` returns `None` whenever its `query_active_config` fails. So a failed isolate meant the panels were never woken, and because the link stays live there is no returning signal to trigger a DPMS wake either: dark for the rest of the host's life. Hoisted out of that arm, next to the `pnp_disabled` restore which was already outside it for exactly this reason. **A later member's isolate could deactivate the physicals with nothing able to restore them.** If the FIRST member's isolate failed, `ccd_saved` stayed `None` and `ccd_exclusive` `false`; a second member's isolate then succeeded, blanked the physicals, and discarded its snapshot as "the group restores the first member's" — except there wasn't one. Teardown's restore is gated on `ccd_saved`, and the re-assert watchdog never started. The group now adopts the first SUCCESSFUL isolate's snapshot. **A non-last-member teardown ran the exclusive isolate on a Primary group.** The gate was `ccd_saved.is_some()`, but `Topology::Primary` stores a snapshot too (from `set_virtual_primary_ccd`) — so a shrink cleared `DISPLAYCONFIG_PATH_ACTIVE` on every non-kept path, blanking precisely the physical displays `Primary` exists to keep lit. It keys off `ccd_exclusive` now (what the re-assert watchdog already checks), and a Primary shrink re-promotes a survivor instead, since the departing member may have been the one holding primary. Also: `apply_group_layout` had only ever run from `acquire`, so a member LEAVING never re-arranged the survivors — they kept the origins computed while the departing monitor was still between them, leaving a dead gap in the desktop until the next acquire. Now called at the end of `teardown_removed`, which is where the slot map has already shrunk and after the REMOVE, so it covers all six teardown paths at once. The shrink gate is extracted as `shrink_action` so it can be pinned without a driver or a desktop — manager.rs had no tests at all, which is how a gate keyed on the wrong flag survived. Verified on the Windows runner: 48 passed (was 46), and both new tests FAIL against the old gate, so they are not vacuous. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>