NEXT: stream cloud attachment originals from disk to the upload slot

Merged
TE
9d ago
+342-42

Split out of #26409 (it was over the ~800-line limit). This part lands first; #26409 keeps the rest.

Leo's standing order: "Attachments take arbitrarily large files of any type; there is no size cap" (Leo, 2026-10-26: "WHY THE FUCK SHOULD THERE BE A FUCKING SIZE CAP ANYWAYS ... I ALREADY SAID WE NEED ARBITARRILY LARGE FILES OF ANY TYPE").

What changes

The daemon's cloud attachment commit read each staged partial file whole (CloudUpload::bytes, read_to_end) before the PUT, so memory grew with the size of the original. This was blocker 2 in the Codex xhigh review of #26409.

  • CloudBackend::put takes a PutBody: Bytes for derived images (at most 2 MB) or File { file, len } for a staged original.
  • The reqwest backend streams the file 1 MiB at a time (reqwest stream feature) with an explicit Content-Length, so a presigned object PUT never goes out chunked. hyper keeps a user-set Content-Length as a fixed-length encoder.
  • A streamed upload has no total deadline, because any size is allowed. It fails after 2 minutes with no body progress, or 2 minutes waiting for the reply. The stall timer stops when its select! arm loses: a finished upload drops it.
  • Partial files are removed when PartialFiles drops, after both PUTs finish or on error.
  • The cloud video integration test (ws_cloud_conversations::attachments) now uploads 2.5 MB, more than one streamed read, through the real backend. The fake slot reads exactly Content-Length bytes and the test checks the stored hash.

No new O(file size) memory path.

Risk: normal (the cloud attachment upload path in the daemon).

Changelog

Fixed: Large attachments in cloud conversations upload from disk instead of being read into memory.

Observed / Not run

  • Observed: python3 scripts/cmux-next/prepush-gate.py (no new violations), cargo fmt; hyper 1.11 role.rs keeps an explicit Content-Length for a streamed body.
  • Observed on Linux (cmux-ci, 32 vCPU, receipt source_sha 81331561e89f8fb690c4ebdf3bfd633877b50104, run https://github.com/manaflow-ai/cmux/actions/runs/40617996762): cargo test -p cmux-tui-cloud-conversations --features test-support, cargo test -p cmux-tui-core cloud_, cargo test -p cmux-tui --test ws_cloud_conversations and cargo clippy -p cmux-tui -p cmux-tui-core -p cmux-tui-cloud-conversations --all-targets -- -D warnings all passed (exit 0).
  • Not run: a real R2/S3 presigned PUT; the reqwest streaming path is covered only against the loopback fake slot.

No capture: daemon transport only, no UI.

Agent session: agent session

šŸ¤– Generated with Claude Code