Skip to content

Tahoe 26.6.2: NSStatusItemScene exists in-process, but Control Center never hosts a layer-25 extra (0.56.3) #3377

Description

@NicholasLea

Description

CodexBar 0.56.3 launches, fetches usage, and creates an NSStatusItem / NSStatusItemScene in-process, but Control Center never hosts a layer-25 extra named codexbar-merged or com.steipete.codexbar. The menu bar icon is therefore unreachable. The official Tahoe allow-list toggle is already on, and hasShownTahoeAllowListGuidance never gets written, so the startup recovery / guidance alert never runs.

This is the same user-visible symptom as #1109 / #890 / #988 / #1077, but it still reproduces on current 0.56.3 after those recoveries landed. The new evidence is that AppKit has the scene, while the window server does not.

Environment

  • CodexBar: 0.56.3 (134), official notarized ZIP (Developer ID Application: Peter Steinberger (Y5PE65HELJ)), /Applications/CodexBar.app
  • Previous build on the same machine: 0.56.2 (133), same failure
  • macOS: 26.6.2 (25G83)
  • Bundle: com.steipete.codexbar, LSUIElement=true
  • Displays:
    • LG UltraFine (0, 0, 1920x1080) (primary viewing screen)
    • Built-in Retina (210, -900, 1440x900) (below the LG)
  • Menu-bar manager: iBar Pro is installed, but quitting it does not make a CC extra appear
  • Enabled providers: codex, claude, gemini
  • Menu-bar prefs after cleanup: mergeIcons=1, menuBarDisplayMode=percent, menuBarShowsBrandIconWithPercent=0, menuBarHidesCritters=1 (.bars, not brand-icon-percent)

What I tried

All of these left layer 25 unchanged (no codexbar-* / com.steipete.codexbar extra):

  1. Toggle System Settings → Menu Bar → Allow in the Menu Bar → CodexBar off/on. It stays on.
  2. Quit/relaunch CodexBar; upgrade 0.56.2 → 0.56.3.
  3. Delete leftover NSStatusItem Visible/VisibleCC/Preferred Position Item-0…Item-9, keep VisibleCC codexbar-merged=1.
  4. Force NSStatusItem Visible codexbar-merged=1 and Preferred Position codexbar-merged=180. Launch still rewrites Preferred Position Item-0=1007 and later codexbar-merged=1007.
  5. Set mergeIcons=0 and pre-enable VisibleCC for codexbar-codex / codexbar-claude / codexbar-gemini. Heap then shows 4 NSStatusItemScenes; still no CC extra.
  6. Quit iBar Pro, then launch CodexBar alone. Still no CC extra. iBar was relaunched afterwards.
  7. Restart Control Center once (killall ControlCenter). Layer-25 count changed (other extras reattached); CodexBar still did not appear.
  8. Did not loop removeStatusItem / killall ControlCenter (the source comment about corrupting CC is noted).

Evidence

1. Process and usage are healthy

  • CodexBar process stays running (LSUIElement).
  • Snapshots/CLI usage work (Codex session/weekly quotas update).
  • Gatekeeper: spctl --assess = Notarized Developer ID.

2. AppKit creates the status item; the window server does not host it

heap on the 0.56.3 process with mergeIcons=1:

1  NSStatusBarWindow
1  NSStatusItemScene
1  NSStatusItemSceneSpecification

With mergeIcons=0:

4  NSStatusBarWindow
4  NSStatusItemScene

CGWindowListCopyWindowInfo(.optionAll) for the CodexBar PID only shows the SwiftUI placeholder settings scene:

owner=CodexBar name=CodexBar设置 layer=0  0x0 or 900x450

Control Center layer 25 on this machine has 50–77 extras (Clock, Sound, Wi‑Fi, Surge, WeChat, Chrome, iBar, …). None are:

  • codexbar-merged
  • codexbar-codex / codexbar-claude / codexbar-gemini
  • com.steipete.codexbar

Hidden-but-real extras still keep a layer-25 window (negative x or y=1080 on the laptop bar). CodexBar has no such window, so this is not “overflow / other display / iBar tray”.

3. Defaults say the extra should be shown

NSStatusItem VisibleCC codexbar-merged = 1
NSStatusItem Visible     codexbar-merged = 1
NSStatusItem Preferred Position Item-0 = 1007          # recreated every launch
NSStatusItem Preferred Position codexbar-merged = 1007
hasShownTahoeAllowListGuidance = <unset>

ByHost com.apple.controlcenter.displayablemenuextras:

{"displayableInfos":[],"providerData":"<empty instanceIds NSKeyedArchive>"}

Other third-party extras still host, so an empty displayableInfos is not a global allow-list wipe. System Settings still lists CodexBar as allowed.

4. Startup recovery never fires

After a clean 0.56.3 launch, hasShownTahoeAllowListGuidance / tahoeAllowListGuidanceLastShownAt stay unset. No “CodexBar can't show its menu bar icon” alert.

That matches a gap in MenuBarVisibilityWatcher:

  • TahoeHiddenNoProxy requires expectsVisibility && VisibleCC==true && !isVisible && !hasWindow
  • isBlockedSnapshot requires isVisible && (!hasWindow || buttonWidth <= 0)

If AppKit leaves button.window / NSStatusBarWindow alive in-process (heap shows it) while Control Center never publishes a layer-25 extra, both predicates miss. The 10s startup recreate + allow-list guidance therefore never run.

MenuBarStatusItemWindowProbe only matches CG windows whose name is the autosave name (codexbar-merged). There is no such CC window here, so isTahoeBlockedProxy also does not trip.

5. Identity split on every vend

StatusItemController.makeStatusItem does:

let item = statusBar.statusItem(withLength: .variableLength)
onCreated?(item)
item.autosaveName = identity.autosaveName  // "codexbar-merged"

Launch always recreates NSStatusItem Preferred Position Item-0 = 1007 even when only the merged extra should exist. Tahoe may bind the CC scene to the implicit Item-0 identity, then lose it when autosaveName is renamed.

Expected

After launch, Control Center should host a visible (or at least overflow-listed) extra for codexbar-merged, and/or startup recovery should detect “in-process scene, no CC extra” and recreate + show the Tahoe allow-list alert.

Actual

Related

Suggested probes

  1. Treat “NSStatusItemScene exists but CGWindowList has no CC extra named autosaveName” as a startup recovery candidate, even when button.window != nil.
  2. Set autosaveName before statusItem(withLength:), or create with a named extra so Tahoe never sees a transient Item-0.
  3. Log isVisible, button.window != nil, button.frame, and MenuBarStatusItemWindowProbe names at the 2s startup check. log show --predicate 'process == "CodexBar"' is often empty here because of TCC, so an on-disk startup diagnostic would help.
  4. I can re-run any probe build on this 26.6.2 dual-display + iBar machine.

Notes / non-causes

  • Not a crash, not a dead process, not missing usage data.
  • Not the old 1000px brand-icon-percent layout (menuBarShowsBrandIconWithPercent is off).
  • Not iBar permanently hiding the extra (arrOfForEverHidden has no CodexBar; quitting iBar does not vend a CC window).
  • One Control Center restart was tried; it was not looped.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Urgent regression or broken agent/channel workflow affecting real users now.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExempts this issue from stale automation.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions