acpmux: run a prompt's turn on the heap so awaiting it cannot overflow a stack
Leo, 2026-10-29: "you can't you just deal with this? Like ACPmux can't be this shit. How do swarms work?" (the coordinator inbox work this unblocks).
What
Hub::run_prompt now awaits run_prompt_joined through Box::pin, so a prompt's whole turn is a heap future. Before, every caller that awaited run_prompt in place carried that future on its own stack: a test, steer_queued, and the steer that falls back to a turn.
Why
The inbox digest drain (acpmux-inbox-digest-p1) and the turn cap (acpmux-turn-cap) each make the future larger. On a tree with both merged, a debug build overflows the 2 MB test thread:
hub_integrationaborts withSIGABRT("has overflowed its stack") insteer_now::send_now_for_a_queued_prompt_steers_it_in_at_onceorfork_through::btw::a_codex_side_session_runs_sandboxed_read_only_and_the_adapter_is_refused.- Each branch on its own does not. This lands first, so base never crashes once both are in.
Tests
- Red, on P1 + P3 merged without this change: hub_integration aborts on the stack overflow. Runs 40946939000 and 40945828225.
- Green, the same tree with this change: hub_integration runs to the end with only the 2 base reds (
auto_resume_retry.rs:222,transcript_events.rs:721).steer_nowandfork_through::btwpass 3 times in a row. Run 40950417971. - On this branch (feat-cmux-next plus this commit):
- hub_integration: 553 passed, with the same 2 base reds;
steer_nowandfork_through::btwpass 3 of 3 (fleet job 1ce1ad84d12d2b4bd784ee46); --lib: 1932 passed in one run. In the other runsession_scope::tests::a_real_user_manager_takes_the_slice_limits_oncefailed once and passed on rerun; that file is untouched here (run 40951875419);- clippy is clean.
- hub_integration: 553 passed, with the same 2 base reds;
No capture: no UI change.
Risk
Low. One heap allocation per prompt turn, and no change in behaviour: the same future runs to completion. Its timing is the same, since a Box::pin future is polled where it was before.
Agent session: agent session
š¤ Generated with Claude Code
![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
Hub::run_prompt now awaits run_prompt_joined through Box::pin, moving the whole prompt turn onto the heap instead of the caller's stack. This prevents a stack overflow in debug builds that occurred when the inbox digest drain and turn cap changes were merged together; this branch lands first so the base never crashes.
The same future runs to completion with the same timing, at the cost of one heap allocation per prompt turn. No behavior or UI change.
Tests: hub_integration and --lib pass with the same 2 pre-existing base failures; steer_now and fork_through::btw pass 3 of 3; clippy is clean.