acpmux: run a prompt's turn on the heap so awaiting it cannot overflow a stack

Merged
TE
7d ago
+5-1

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_integration aborts with SIGABRT ("has overflowed its stack") in steer_now::send_now_for_a_queued_prompt_steers_it_in_at_once or fork_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_now and fork_through::btw pass 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_now and fork_through::btw pass 3 of 3 (fleet job 1ce1ad84d12d2b4bd784ee46);
    • --lib: 1932 passed in one run. In the other run session_scope::tests::a_real_user_manager_takes_the_slice_limits_once failed once and passed on rerun; that file is untouched here (run 40951875419);
    • clippy is clean.

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 Autofix with [code]smith
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.