b359db72ee
Group rooms were text-only on the ingest side: the composer and
runGroupChatMemberTurn submitted prompt.submit {text} with no attach step,
so a user screenshot could never reach the members' models (community
report from Osiris). The gateway already ships the staging pipeline
(image.attach_bytes -> attached_images -> next prompt.submit) and the 1:1
canonical chat uses it — this wires the group surface to the same path.
- Composer + thread reply boxes: attach button, Ctrl/Cmd-V paste, pending
chips with preview/remove, image-only sends allowed.
- Attachments are downscaled (long edge 1568px) and stored on the room-log
entry, so reloads keep showing what members were shown.
- Turn drive stages the delta's images into EVERY responding member's own
per-group session via image.attach_bytes before its prompt.submit —
works cross-connection through requestForBot; a failed attach degrades
that member to text-only rather than failing the turn. Watermarks
guarantee an image is staged at most once per member.
- formatGroupChatLine names attachments ([attached image: name]) so the
transcript delta and the staged pixels line up for every viewer.
- Room log renders attached images on user entries.
Tests: 6 new vm-harness tests (fan-out staging order, mention-scoped
attachment routing, image-only sends, no re-attach across turns,
transcript naming, invalid-attachment degradation); 276 total pass.