fix(cmux-next checks): clear the package-deps and crash-ratchet base reds

Merged
LA
6d ago
+168-95

Summary

The cmux-next checks job is red on every feat-cmux-next push since 8ac1d731a50, so every PR that merges the base inherits it (83 PRs wait with ready-to-land). This PR fixes two of the three red checks. The third (Check the app FFI pin) needs a published artifact and is not in this PR (see the end).

Package dependency lists sorted. CmuxNextAccounts imports CmuxNextWakeups (DemandTimer in TeamInviteConsentWindow, from a0ee1353f6b) but did not declare it. The target now declares it. ui -> core is an allowed layer edge.

Crash safety (crash ratchet). Six rows rose. Each new hit is fixed in the code:

rowfirst bad commitfix
rust cmux-tui-core unwrap 1149 -> 1150915bab1c6faagent_records.lock() recovers a poisoned lock (unwrap_or_else(PoisonError::into_inner)), like the other 340 sites in the crate
swift CmuxNextSidebar dynamic_dispatch 3 -> 5f97775b558bthe disclosure chevron sets its turn as a typed CATransform3DMakeRotation, not with setValue(_:forKeyPath:). The turn is the glyph's only transform, so the value is the same.
swift MessagesLabHome index_subscript (banned) 0 -> 16ac0d64eb5bthe row bitmap write gets its slot from out.checkedIndex(i) on the same line again
swift MessagesLabHome unchecked 14 -> 16, unchecked.waived 1 -> 46ac0d64eb5bPaletteScope's main-thread slot, process palette and box table, and Fixture.baseGeneration, move from nonisolated(unsafe) statics into one OSAllocatedUnfairLock. Render workers read the process palette and the base generation while the main thread writes them, so this was a real data race. PaletteBox keeps @unchecked Sendable with a reviewed crash-allow (two lets set before the box is published). This is recorded with --record-waivers: waived 1 -> 2.
swift CmuxNextDesign unchecked.waived 3 -> 417d64ea2fd6 (#27385)the Dock policy observation keeps its object in an OSAllocatedUnfairLock(uncheckedState:), not in a hand-made @unchecked Sendable holder. The lifetime does not change: the object stays alive until termination and is then released.

The Patches/ files for Fixture, Transcript and WindowView are made again with sync-messageslab.sh --write-patches. The WindowView patch was already stale on the tip. Now --check passes. The arch ratchet's global_mutable_statics row goes down by three. Its one new lock site has a reviewed exception in arch-ratchet.json.

Owners: the sidebar owner (a590) for DisclosureChevronView (no visual change) and PL-daemon for the one agent_roster_fold.rs line.

Testing

  • python3 scripts/cmux-next/crash_ratchet.py: red on base b3587f50ac4 (6 rows, the same as the CI log of 49d2105a0e4). On the head it prints crash-ratchet: ok.
  • python3 scripts/cmux-next/check-package-dependency-lists.py: red in CI on base (CmuxNextAccounts: imports CmuxNextWakeups but does not declare it). It passes on the head. Its self-test passes too.
  • scripts/cmux-next/check-crash-safety.sh: ok. sync-messageslab.sh --check: ok. python3 scripts/cmux-next/prepush-gate.py: no new violations.
  • Fleet compile-check of head 98a7c2c8e8b: job b9abe4f397655cc8ce7f0615 (cmux-ci compile-check --app --package CmuxNext --recipe-version 2): CmuxNext (with test targets), app and cmux-tui all ok. The first head 9d40107403c also compiled (job 77d862cc17adfe165114e0c0).
  • PaletteBox keeps its reviewed @unchecked Sendable waiver (MessagesLabHome unchecked.waived 1 -> 2): a checked Sendable needs a Sendable FixtureTheme, and FixtureTheme.swift:28 holds a CGGradient, which the SDK does not mark Sendable (Swift 6 probe job e72b1f95374d27da0c9f8e94). The crash-allow names its owner and expires 2026-11-13.

Observed / Not run

Observed: the static check scripts above, red on the base and green on the head, run on cmux-orchestrator-1. Not run: Swift or Rust tests. The changes keep behavior the same (lock-guarded reads of the same values, the same transform value, the same lifetime). DockBadge's lifetime tests and the MessagesLab palette tests run in the next fleet test round.

Not in this PR: Check the app FFI pin. The FFI sources changed after pin 619b1a3c815. The tip's FFI sources are the same as at b02c5645478. The app FFI release run for that commit (40992288584) has been queued for blacksmith-6vcpu-macos-26 since 02:32Z, and 21 jobs wait for that label. When the run builds, its publish job releases cmux-app-ffi-b02c5645478... and its last job opens the re-pin PR. That PR moves the pin. The bot PR #26434 (ff720d825a2) is out of date.

Changelog

none

Proof

No capture: there is no visual change. The chevron gets the same transform through a typed setter, and the other changes are lock and ratchet changes.


Summary by cubic

Fixes the cmux-next checks job, which has been red on every feat-cmux-next push, so every PR that merges the base inherits it (83 PRs wait with ready-to-land). The package-deps and crash-ratchet checks now pass; the third check (app FFI pin) needs a published artifact and is not in this PR.

Package dependencies

CmuxNextAccounts now declares CmuxNextWakeups, which it imports (DemandTimer in TeamInviteConsentWindow) but never declared.

Crash ratchet

  • cmux-tui-core: the roster's agent_records read recovers a poisoned lock with unwrap_or_else(PoisonError::into_inner), matching the other 340 sites in the crate.
  • CmuxNextSidebar: the disclosure chevron sets its turn as a typed CATransform3DMakeRotation instead of setValue(_:forKeyPath:), with no visual change (same transform value).
  • MessagesLabHome: the row bitmap write gets its slot from out.checkedIndex(i) on the same line again.
  • MessagesLabHome: PaletteScope's main-thread slot, process palette, box table, and Fixture.baseGeneration move from nonisolated(unsafe) statics into one OSAllocatedUnfairLock, fixing a real data race where render workers read the process palette and base generation while the main thread writes them.
  • PaletteBox keeps @unchecked Sendable with a reviewed crash-allow (two lets set before the box is published).
  • CmuxNextDesign: the Dock policy observation keeps its object in an OSAllocatedUnfairLock(uncheckedState:) instead of a hand-made @unchecked Sendable holder, with the same lifetime.

The Fixture, Transcript, and WindowView patches were regenerated with sync-messageslab.sh --write-patches (WindowView's was already stale), the arch ratchet's global_mutable_statics row falls by three with one reviewed exception, and the static check scripts are red on the base and green on this head. Swift and Rust tests were not run.