acpmux: a chat opened on screen reads ahead of agent work
Leo: "but i also wonder how much of this is simply putting the desktop at higher priority?" / "i also like the way it just loads in the subagent stuff instantly :(" / "as in i want ours to load fast too :("
What
cmux#27587 set the daemon's disk I/O, process wide, to IOPOL_UTILITY so agent work yields to the app. That also covers the daemon's reads for a chat being opened on screen: the chat's log load and the first page of a visible _acpmux/attach. Under load those reads wait behind agent compiles, even though they are what the person is waiting on.
This adds Tier::OnScreen (Role::VisibleOpen) to the one QoS policy in qos.rs, and qos::on_screen(work). The calling thread runs at QOS_CLASS_USER_INITIATED with disk I/O at IOPOL_IMPORTANT (thread scope) for the read. Afterwards it is put back to the class and thread I/O policy it had, because tokio reuses the thread. A visible attach runs both its session_log load and its events_page read through it. Hidden attaches, _acpmux/events paging and every other caller are unchanged. ACPMUX_QOS=off turns it off with the rest of the policy. On Linux it does nothing.
Tests
qos::tests::an_on_screen_read_raises_the_thread_and_puts_it_back(macOS): inside the guard the thread reports user-initiated andIOPOL_IMPORTANT, and afterwards it is back where it started.the_daemon_keeps_its_cpu_and_agents_yieldnow covers the new role.
Performance
| metric | before | after | delta | harness |
|---|---|---|---|---|
| visible attach read: thread QoS / disk tier | default / utility (process) | user-initiated / important | the open's reads no longer queue behind agent I/O | unit test above |
| click to first content, all-core load (fleet) | pending | pending | pending | chat-open bench (cmux#27625), loaded condition |
The fleet numbers will be added once the chat-open bench lands on feat-cmux-next.
Risk
Low. The raise is scoped to one synchronous read per visible open and restored in Drop. The daemon's CPU priority and every other path are unchanged.
š¤ Generated with Claude Code
Agent session: agent session
![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
Makes a chat opened on screen read ahead of agent work, so the log load and first page no longer queue behind agent compiles under load.
Marks the daemon's reads for a visible _acpmux/attach (its session_log load and first page) as on-screen work. The calling thread runs at user-initiated QoS with important disk I/O (thread scope) for the read, then returns to its prior class and I/O policy since tokio reuses the thread. Hidden attaches, _acpmux/events paging, and all other paths are unchanged; ACPMUX_QOS=off disables it; Linux is a no-op. macOS only.
- Adds
Tier::OnScreen(Role::VisibleOpen) to the QoS policy inqos.rsand theqos::on_screenguard, with restore-on-drop. - Adds tests covering the thread raise/restore and wires the visible attach's two reads through the guard.