FIXED: idle CPU 98.8% → 0%. Root cause was the App scene's .commands + MenuBarExtra
rebuilding the macOS main menu on every AppServices publish; fixed by moving menuBarEnabled
to a dedicated low-frequency MenuBarPresence object (see the "ROOT CAUSE — FOUND & CONFIRMED"
section at the bottom for the full story). The narrative below is the investigation as it
unfolded — including several WRONG turns (kept as a record of what was ruled out and why).
This doc supersedes the earlier "scale-driven render storm" framing, which was WRONG.
The corrected diagnosis: it's a macOS-26 SwiftUI LayoutEngine loop, NOT scale/data
Discriminating evidence (sample(1) of the pegged process = ground truth): the main thread is
~100% inside SwiftUI AttributeGraph / LayoutEngine, not parsing/aggregation:
AG::Graph::propagate_dirty / UpdateStack::update
LayoutEngine.explicitAlignment(_:at:) <- #1 hot leaf
LayoutEngineBox.sizeThatFits(_:)
_FlexFrameLayout.sizeThatFits(in:context:child:)
EnvironmentPropertyKey<...glassEffectBackdropObserver> metadata churn
Three facts that kill the scale/data hypothesis:
- MC already HAS the incremental append-only JSONL cache the earlier dossier said to "port from
CodexBar." It's
SessionIndexinSources/MissionControlKit/Stores.swift(~519-590): per-file size+mtime skip,seek(resumeOffset)tail-only reparse, parallel scan, versioned on-disk warm cache (v13),(messageId,requestId)dedup. Nothing to port — it exists. - Aggregations are already cheap.
--selfcheckPERF table on the live 5543-session corpus: sort 12ms, RoutingAudit 8.9ms, AttentionBoard 2ms, burn revision-cached. Single-digit ms. - An empty window with
services.start()fully disabled — no FSEvents watcher, no sidebar, no content, no menu — STILL storms at ~98%. The corpus is irrelevant to the loop.
So the earlier "4 amplifier fixes" (throttle + 5s debounces + composition cache, commits 3a63e44 + dcc6e3f) are harmless but not the cure — they were tuning a symptom-correlation, not the cause. The pre-spree e76594d "stormed worse at 6 cores" observation was real but is the same framework loop amplified by more views, not a data-scale effect.
Bisection — the storm SURVIVED removing every one of these (so none is the cause)
- both
VisualEffectBackgroundblends (→.withinWindow, then plainColor) WindowConfigurator(async styleMask NSViewRepresentable)- the whole
Sidebar; the whole screencontent(→Color.clear) MenuBarExtra(.window).windowStyle(.hiddenTitleBar)→.automatictitled.windowResizability(.contentMinSize)added;.frame(minWidth:1120,minHeight:720)removed (removing it made the storm WORSE)RootViewHStackDivider().ignoresSafeArea()→ fixedRectangle().frame(width:1)ScreenScaffolddouble.framecollapsed- explicit screen-fitted launch frame
services.start()entirely disabled — NOT it
Fixes TESTED under the honest 45s gate — BOTH FAILED (2026-07-08)
NSVisualEffectView.state = .active→.followsWindowActiveState(targets the glassEffectBackdropObserver churn). Gate: 99.0 / 98.5 / 97.6. No effect. Consistent with the bisection (removing the VisualEffect views entirely also didn't help).CMC_PRESENT=1+NSAppSleepDisabled=YES(window.level=.statusBar + explicit frame + 1s re-activation timer). Gate: 0.0 / 100.0 / 97.6. The 0.0 was App Nap masking, not a fix — the sustained samples are ~98%. The earlier claim that "CMC_PRESENT calms to 0%" was almost certainly an App-Nap artifact. So there is currently NO known-working workaround.
Measurement caveat (critical)
Background/&-launched GUI processes on this machine hit macOS App Nap → SUSPENDED → 0% CPU. A
"0%" spot sample is usually App Nap, NOT a fix. Only the sustained 45s gate (15/30/45s, where App Nap
does not engage) or an explicit force-active oracle gives honest numbers. Short 7-8s checks lie.
Next experiments (for a fresh budget — the weekly limit was hit mid-investigation)
- Isolate it in a ~20-line standalone SwiftUI app (empty
WindowGroup,.hiddenTitleBar, backgrounded/not-key). If it reproduces empty → it's Apple's bug; file a Feedback and apply a window-level/activation workaround. This is the highest-value next step: proves it's not MC. - This machine is multi-display (2048x1152 + 1920x1080). Multi-display
visibleFramenegotiation is a classic metastable-layout trigger — test on a single display; the bug may be topology-dependent. - Find the single benign property of a statusBar-level window that avoids the loop (collectionBehavior, non-occlusion) — since even statusBar level didn't hold under the gate, this may be a dead end.
- Try forcing a periodic layout invalidation/settle from an AppKit timer while not key — but CPU-guard it (the whole point is to STOP burning CPU).
Separate, unrelated, ACTIONABLE: the keychain popup on every launch
Not the CPU storm — a background Task. The Quota panel reads Claude Code's keychain credential
(ClaudeQuota.swift:67 runs security find-generic-password -s "Claude Code-credentials"). It
re-prompts every launch because (a) dev builds are re-signed on each swift build, so the ACL
"Always Allow" never sticks, and (b) Claude Code rewrites its keychain item on token refresh,
resetting the ACL. Fixes: stably code-sign the app so "Always Allow" persists; or cache the token in
MC's OWN keychain item after first read; or disable the quota fetch.
Repo state
Clean at HEAD a413e73. No perf fix committed (neither candidate passed the gate). The 4 earlier
amplifier commits remain (harmless). All research/trove docs committed.
ROOT CAUSE — FOUND & CONFIRMED (2026-07-08, awake-proven)
The storm is the App-scene .commands (main menu) + MenuBarExtra, both observing the
frequently-republishing @StateObject services. Every services publish → AppDelegate.scenesDidChange
→ AppDelegate.makeMainMenu(updateImmediately:) (388/2254 samples) + MenuBarExtra rebuild
(DynamicContainerInfo.updateItems). At 2859-session scale each rebuild is so expensive it never
finishes before the next publish → the main thread pegs (a main-runloop Timer can't even fire → HB=0).
The measurement trap that hid it for ~40 builds
macOS App Nap. Background-launched GUI processes get SUSPENDED → ps reads 0% CPU. Every
"calm" baseline in the earlier bisection (pxpipe+sessions=0%, tickonly=0%, empty-window=0%) was
App-Nap suspension, NOT genuine calm. Proven: adding ProcessInfo.beginActivity([.userInitiated, .idleSystemSleepDisabled]) flipped the SAME "pxpipe+sessions only" config from 0% → 63%. The store
bisection was measuring App Nap. Always add beginActivity() for headless perf measurement, or the
numbers lie.
Confirmation matrix (all with beginActivity awake)
- MC, NO
start()→ 0% (genuine) - MC,
start()+ any refresh → ~63% - FULL app → ~98%
.commandsremoved → ~60% (makeMainMenu gone, ~38% drop).commands+MenuBarExtraremoved → 0% idle (after initial scan) ✅ THE FIX TARGET
The sample smoking gun (gutted app)
NSRunLoop.flushObservers → GraphDelegate.beginTransaction → AppGraph.graphDidChange → AppDelegate.scenesDidChange → AppDelegate.makeMainMenu + CommandsBodyAccessor.updateBody.
Why the earlier theories were all wrong
NOT Apple's bug (empty window=0%), NOT scale/parse (SessionIndex cached), NOT objectWillChange rate (4/8s), NOT views/sidebar/buttons/animations/GeometryReader (those were symptoms of the whole tree re-rendering, or App-Nap-confounded). The trigger is scene-level, not view-level.
Fix direction
Decouple the scene-level elements from services's high-frequency publishing: (1) move menuBarEnabled
off services into a tiny dedicated ObservableObject so .commands Toggle + MenuBarExtra(isInserted:)
don't observe services; (2) ensure MenuBarLabel/MenuBarContent don't re-aggregate over all sessions
on every publish (cache / minimal derived model). Preserve the features (⌘R/⌘K shortcuts, palette,
menu-bar strip) — do not just delete them.