Box cancelled-turn settlement out of the resume_task future
Class
API futures over budget. The future-size budget is 4,096 bytes (task_runtime/tests/future_sizes.rs). On main, resume_task is 9,296 bytes, so the existing future-size test fails.
Invariant
Cancelled-turn settlement is the cold path. Its state (host.cancel plus settle_task, a 6,480-byte future) lives in its own bounded allocation, never inline in the resume_task state machine. Every resume future therefore stays within the 4,096-byte API budget.
Root cause (bisect)
The growth came from #626 (d5b0f17d0, "Rewrite GraphCoder…"). It was not #875, #864 or #804. #626 added an inline async { cancel; settle_task } block to resume_task.
Future (windows-gnu, -Zprint-type-sizes) | Merge base 3b62cd1c4 | Main |
|---|---|---|
resume_task | 2,440 | 9,296 |
settle_task | 6,480 | 6,480 |
verify_owner | 4,736 | 4,736 |
Error / WorkLease | 104 / 1,032 | 104 / 1,032 |
#626's block is the only change to worker.rs in that range.
Fix
- The block becomes
settle_cancelled. It is awaited throughBoundedContentFuture::new(io, …), the existing boxed-and-accounted future wrapper, so the allocation is charged like other cold-path content futures. resume_taskdrops from 9,296 to 2,616 bytes.- The limit is unchanged.
Why it can't recur
The existing future_size test pins resume_task under the 4,096-byte budget. It fails on main at 9,296, which is the negative control, and passes here.
Settlement now has a single entry point (settle_cancelled), so it can't be reinlined into the resume future without the test catching it.
Validation (bb1)
| Check | Result |
|---|---|
| Build | 1,354 s |
future_size | 2 passed, 38 ms |
filesystem::task_runtime:: | 36 passed, 1.2 s |
client::local_headless | 8 passed, 300 ms |
local::tests::live_ui (tui) | 2 passed |
Windows check (x86_64-pc-windows-gnu) | passed, 259 s |
canonical_chunks_render_before_completion_and_cancel_settles still fails with the render timeout it shows on main (main-health/latest.txt; it depends on #823/#839). The test times out before it reaches the cancel step.
Finding: future-size regression on main (resume_task at 9,296 bytes against a 4,096-byte limit).
Deletions: the 14-line inline settle block is removed.
🤖 Generated with Claude Code
Summary by cubic
Fixes the resume_task future exceeding the 4,096-byte API budget. The GraphCoder rewrite (#626) grew it from 2,440 to 9,296 bytes by inlining cancelled-turn settlement; that block now runs as settle_cancelled behind BoundedContentFuture::new, so settlement state is boxed instead of carried in every resume future. resume_task drops to 2,616 bytes.
- Settlement now has a single entry point,
settle_cancelled. canonical_chunks_render_before_completion_and_cancel_settlesstill fails with a pre-existing render timeout on main (depends on #823/#839).