fix(cmux-tui-core): the surface admission budget reserves with atomics on the input lane (R-DAEMON-STATE S1 step 3)
Summary
R-DAEMON-STATE stage S1 step 3 (handoff/rewrites/R-DAEMON-STATE/DESIGN.md, section 3 and Appendix A.2 step 11). #34014 (stage S1 step 1) merged at 21:52:58Z (squash 4bb12b86ecd); this PR now targets feat-cmux-next directly. Head e2a052e6059 merges feat 8880dae3652 (through ff04cf67b63, then a no-change merge that records the squash, whose content the branch already had from 590cb119161). The PR's own diff is unchanged: the same patch-id (be5d75f4106) against the review head's base and against feat now.
Every request of every connection, the person's key included, reserves its retained bytes from one daemon-wide budget (ServerSurfaceOperationAdmission) on the connection's reader thread before it is queued, and releases them after it ran. The reservation took one mutex that all connections share, so a key waited for any other connection's reservation or release. The S1 census measured a full wait: 300.3 ms while another thread held it 300 ms (hosted run 41648095321).
With the stage switch on (CMUX_TUI_RDS_INPUT=1, per mux, default off), the two counters are AtomicUsize with a compare-and-swap reservation (fetch_update with checked_add and the same capacity filter: 16 workers, 16 MiB), so a reservation never waits. A permit records the arm it reserved from and releases to the same one. With the switch off, the old mutex counts run unchanged; they go with the switch when the stage passes.
Testing
a_key_waits_for_no_surface_admission_lock (cmux-tui/crates/cmux-tui-core/src/server/tests/rds_input_lane.rs): two keys through the real line path while another thread holds the old arm's lock 300 ms. A control first proves the hold reaches the old path (switch off: the key must wait), so the lane's pass is not a test that holds nothing. The step-1 control (a_key_waits_for_no_client_registry_lock) gets the same control arm.
Focused command: ./scripts/verify-cmux-tui-hosted.sh --filter rds_input_lane.
- Red at 5d0e4a0e2c1 (
test/rds-s13-red-never-merge, the test without the fix), hosted run https://github.com/manaflow-ai/cmux/actions/runs/41685706056, Linux:a_key_waits_for_no_surface_admission_lockFAILED: control (lane off) 300.26 ms, lane 300.27 ms; the other 3 passed. - Green at the head 8e5c8a21191, hosted run https://github.com/manaflow-ai/cmux/actions/runs/41685706038, Linux:
rds_input_lane4 of 4 passed.
Both runs also show base reds that this branch's older base still has: lint (linux) and the macOS build fail on acpmux/src/login_env/watch.rs unused imports (fixed on feat by #33664 and #33690), and macOS acpmux --test web_image_attachments aborts at tests/support/daemon_env.rs:464 (node on the test's PATH). This PR touches none of those files.
Observed / Not run
- Observed: the two hosted runs above (Linux test job).
- Observed: fleet compile job 189bde14160772147cb9455f at 8e5c8a21191 passed (CmuxNext 344 s, app 114 s, cmux-tui 61 s). At e2a052e6059: compile job 1548c3c24c244948c7b8f356 and the focused hosted run (below) are running.
- Not run: macOS execution of the test (the macOS job stops at the acpmux base red before it); the real-app A/B (after S1 lands, with the measurement owner).
Review
Review (claude-reviewer-rds-s13): SHIP at 8e5c8a21191de2f7c594631d172687ae6133e638 (comment 6613345630). Its notes are taken in #34261's branch (831686b8c79): the budget tests on both arms, a lost-key control, private fields, the doc wording.
Changelog
none
Proof
No capture: daemon-only change behind a default-off switch, no UI.