The staging logic in 9c46cf6 copied any agent-declared file from outside the
room's allowed directories into a safe folder and attached it, which bypassed
the attachment directory allowlist (cross-room isolation / sensitive-file
protection). Removing it.
Kept: appendRejectionNotice / describeRejectedAttachments so rejected
attachments are surfaced in the visible message instead of being silently
dropped. This changes no security behavior — it only adds text when an
attachment was already going to be rejected.
Verified: outbound-attachments + final-delivery + discord tests 70/70, tsc clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Agent-generated files written to an arbitrary working path (e.g. TTS audio
under /home/claude/jarvis-tts) were rejected by validateOutboundAttachments as
"outside-allowed-dirs". The rejection was only logged; the MEDIA: directive had
already been stripped from the text, so the user got a message claiming a file
was attached with no file and no error.
- Stage attachments outside the room's allowed dirs into a safe per-group dir
(data/attachments/outbound/<group>) at the universal delivery choke point, so
the path delivery uses and revalidates is one the validator accepts. Files
already inside an allowed dir are untouched, preserving isolation checks.
- Surface any still-rejected attachment in the visible Discord body via
appendRejectionNotice, so delivery can never again silently drop a file.
Verified: outbound-attachments 22/22, discord 46/46 (incl. new integration test
asserting the notice lands in the sent body), final-delivery 5/5, tsc clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>