NEXT: accept phone uploads of any size in the mobile host
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").
Lands with #26959 (order: this PR first, then #26959)
This PR is the Mac (host) half. #26959 removes the iPhone client's caps: LinkUpload.swift (100 MiB maxBytes, refused before the channel opens), ChatComposer.swift readFiles and TerminalComposer.swift loadFiles (the same cap at pick time). Until #26959 lands, a real phone upload over 100 MiB can't reach this host code. Order: this PR lands first, because alone it only accepts more. #26959 alone would send files over 100 MiB to a host that still answers too_large. The proof for the pair is an iPhone-to-host upload over 100 MiB on the simulator, run on the fleet.
The cap
cmux-next-ios/rust/crates/cmux-mobile-host/src/services.rs:1283 (base 3a7653b054e), in receive_upload for the hostd upload service that the iPhone chat and terminal composers use to put an attachment into <cwd>/.cmux/attachments/phone-<session>/:
if size > config.upload_max_bytes {
return Err(Refusal::new("too_large", format!("the file is larger than {} MB", ...)));
}
upload_max_bytes came from CMUX_MOBILE_UPLOAD_MAX_BYTES, default DEFAULT_UPLOAD_MAX_BYTES = 100 MiB (config.rs:69). Any phone attachment over 100 MiB was refused before a byte was read.
The fix
The receive loop already streams each data frame into a .part file, so the cap only refused. This removes the check, the upload_max_bytes config field, the env var, the default constant, and their mentions in PROTOCOL.md, SECURITY.md and rust/README.md. Any declared size is accepted and streamed. The integrity checks stay: more bytes than declared is refused, a short upload is refused, and either leaves no file.
The iOS LinkUpload client's own pre-check is a separate change and is not touched here.
Red / green
- Red f7eed9548f99aca47032c778040418bfd3979919:
an_upload_past_the_old_100_mib_cap_is_saved_wholeintests/host.rsstreams 100 MiB + 1 byte in 256 KiB chunks over the WireGuard link and checks the saved file's length.cmux-ci test -- cargo test -p cmux-mobile-host --test host an_upload_past_the_old_100_mib_cap(run 40767397481) failed:{"error":"too_large","message":"the file is larger than 1 MB"},left: "too_large" right: "eof"(the test fixture set the cap to 1 MiB; production defaulted to 100 MiB). - Green f3d13e25a42a5c0c2f1da66082b483d52195a717:
cmux-ci test -- cargo test -p cmux-mobile-host -p cmux-mobile-link-ffi(run 40771627741) passed, exit 0. That covers the new test, theservices_over_*upload cases and the link-ffi browser tests that buildServiceConfig.
Changelog
- The iPhone app can attach files of any size to a Mac chat or terminal; the Mac no longer refuses ones over 100 MB.
Observed / Not run
- Observed: the red and green runs above, on the org's Linux runners at each commit.
- Not changed: the iOS
LinkUploadclient's own 100 MB pre-check andLiveTests.swift, which only parses a cannedtoo_largereply. A separate change handles the client. - Other
too_largerefusals in this crate stay. They limit single protocol messages (the 4 MiB daemon line, the 32 MiB acpmux message) and the 64 MiBfilepreview read, not attachment uploads.
Agent session: agent session
🤖 Generated with Claude Code