cmux-next: enforce window cleanup trait coverage
Swift test suites were accumulating NSWindow instances between suites, so later benchmarks inherited stale windows. Leo's instruction was: "But why do you guys not just clean up after yourselves, or at least do your best to?"
This enforcement slice finishes the mechanical cleanup work on the trait-all branch. It adds .closesItsWindows to every top-level test suite that opens a window across the CmuxNext test targets, closes the explicit order-out-only fixtures in the remaining census offenders, and adds WindowCleanupCoverageTests. The source scanner strips comments and string literals, finds window-opening calls and top-level suites with @Test, and fails when a suite lacks the trait. CmuxNextControlTests now links CmuxNextTestSupport so its annotated suites use the shared trait.
The scanner test is blocking: a new suite that opens a window without .closesItsWindows fails CmuxNextAppTests.WindowCleanupCoverageTests with the file, line, and suite name.
| metric | before | after | delta | harness or run link |
|---|---|---|---|---|
| Windows open at process exit | 251 | pending fleet run | pending | same five-step cmux-ci census harness |
| Suites leaking windows | 79 | pending fleet run | pending | same five-step cmux-ci census harness |
The 251-window baseline is the handoff measurement at the trait hook head. The after values will be filled from the exact fleet run before landing.
agent-identity footer --repo manaflow-ai/cmux
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Enforces .closesItsWindows on every CmuxNext test suite that opens a window, so NSWindow and NSPanel instances no longer leak between suites or into later benchmarks. WindowCleanupCoverageTests strips comments and string literals, finds window-opening calls, and fails any top-level @Test suite that opens a window without the trait, including suites merged in from base.
- Teardowns that only called
orderOut(nil)now close viaNSWindow.closeAfterTest(), and windows a test makes in its own body close in deferred teardowns, so an async test can no longer hold one open past the suite's check. - App harnesses share
AppServices.closeWindowsForTest()(the app's windows, browser Page Info and Extensions panels, and the palette panel); overlay-host, hover-card, Extensions-bubble, and browser pane fixtures close their own panels.CommandScrollColumnsTestscloses its child page windows and cancels pending probes on early throws;WindowZoomTestscloses the overlay host panel its window's close creates when the window has no controller. CmuxNextTestSupportnow depends onCmuxNextTestExitTrace, declared in the six test targets that import it, so every test target using the trait links the census that tags windows.- Each base merge since has added window-opening suites; they take the trait and close what each test opens.
WorkspaceTabHoverCardTeststakes it now too, the six sidebar gallery suites base deleted are gone, and base's renamesSidebarRowCloseSpotTestsandSidebarTabMiddleClickTestskeep the trait with base's text.RightColumnEntryPointTests,RightColumnScreenTests, andSettingsLiveAppearanceTestsclose windows they only ordered out or left.