NEXT Home: attach any number of files, sent as messages within the owner's part limit
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" (standing order: "Attachments take arbitrarily large files of any type; there is no size cap"). Item 4 of the pattern audit found count caps on Home attachments as well as size caps.
What changes
A Home message can carry at most 16 parts. That is the owner's protocol bound on one message (MAX_PARTS in cmux-conversation, home-core validateParts). It is a limit per message, not per send, but the clients turned it into a cap on how many files you could attach:
- Channels page (web): the composer stopped adding files at 10 (
MAX_ATTACHMENTS) and greyed out Attach.daemonHome.tsrefused any send that named more than 10 files. - Native Home: the composer refused the 16th file ("too many"), and
HomeStore.sendthrewtooManyParts.
Now a send takes any number of files. Past 16 parts it goes out as several messages, in order. The text goes with the first message. Each message has its own idempotency key and pending row, and they go through the conversation's send queue one after another, so the owner keeps the order.
- Web:
messageGroups(attachmentService.ts),HomeChannelsStore.send/deliverInOrder. The daemon client now checks the owner's real bound on each message (MESSAGE_PARTS, 16 parts) instead of 10 files. - Native:
HomeAttachmentPolicy.messageGroupsandHomeStore.send(conversation:text:attachments:). Every file is checked before anything is logged, so a refused file still gives the whole draft back. All the messages are logged at once and then upload in turn. Offline, they all wait for the reconnect, just as a single send does. The composer's room check (admit) is gone.
Not in this PR: the 100 MB per-file limit in attachmentService.ts / AttachmentPolicy is #27016's change, and those lines are untouched here.
Red / green
Tests drive the real code paths: the real HomeChannelsStore and DaemonHomeClient with a stand-in daemon socket that refuses more than 16 parts, as the owner's reducer does; the real Composer; and the real HomeStore over MockHomeSource. The attachment byte counts in the web store test are above 5 GiB each.
webviews/test/home-channels-any-count.test.tsx: 65 files reach the owner as 16+16+16+16+2 parts, each file once and in order, and the composer takes 65 files and then one more.CmuxHomeCoreTests/AttachmentAnyCountTests.swift: 65 files go as 5 messages, each withinmaxParts, in order, with the text once. PlusmessageGroupsfor 0 to 1000 files.
Red commit 3d9cf56e83ef (tests only) and green commit dc985aefd785. Results are in the comments below.
No capture: the only visible change is that Attach stays enabled past 10 files; the composer test asserts it.
Risk: normal. Home send path; sends with 16 parts or fewer take the same path as before.
š¤ Generated with Claude Code
Agent session: agent session