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>
75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
import { createProducedWorkItem } from './db.js';
|
|
import { resolveRuntimeAttachmentBaseDirs } from './attachment-base-dirs.js';
|
|
import { logger } from './logger.js';
|
|
import { deliverOpenWorkItem } from './message-runtime-delivery.js';
|
|
import type {
|
|
AgentType,
|
|
Channel,
|
|
OutboundAttachment,
|
|
PairedRoomRole,
|
|
RegisteredGroup,
|
|
} from './types.js';
|
|
|
|
export async function deliverMessageRuntimeFinalText(args: {
|
|
text: string;
|
|
attachments?: OutboundAttachment[];
|
|
chatJid: string;
|
|
runId: string;
|
|
channel: Channel;
|
|
group: RegisteredGroup;
|
|
startSeq: number | null;
|
|
endSeq: number | null;
|
|
forcedAgentType?: AgentType;
|
|
deliveryRole: PairedRoomRole | null;
|
|
deliveryServiceId: string | null;
|
|
replaceMessageId?: string | null;
|
|
hasDirectTerminalDeliveryForRun?: (
|
|
chatJid: string,
|
|
runId: string,
|
|
deliveryRole: PairedRoomRole | null,
|
|
) => boolean;
|
|
isDuplicateOfLastBotFinal: (chatJid: string, text: string) => boolean;
|
|
openContinuation: (chatJid: string) => void;
|
|
}): Promise<boolean> {
|
|
if (
|
|
(args.deliveryRole === 'reviewer' || args.deliveryRole === 'arbiter') &&
|
|
args.hasDirectTerminalDeliveryForRun?.(
|
|
args.chatJid,
|
|
args.runId,
|
|
args.deliveryRole,
|
|
)
|
|
) {
|
|
logger.info(
|
|
{
|
|
chatJid: args.chatJid,
|
|
runId: args.runId,
|
|
deliveryRole: args.deliveryRole,
|
|
},
|
|
'Skipping final work item delivery because this run already sent a direct terminal IPC message',
|
|
);
|
|
return true;
|
|
}
|
|
|
|
const workItem = createProducedWorkItem({
|
|
group_folder: args.group.folder,
|
|
chat_jid: args.chatJid,
|
|
agent_type: args.forcedAgentType ?? args.group.agentType ?? 'claude-code',
|
|
service_id: args.deliveryServiceId ?? undefined,
|
|
delivery_role: args.deliveryRole,
|
|
start_seq: args.startSeq,
|
|
end_seq: args.endSeq,
|
|
result_payload: args.text,
|
|
attachments: args.attachments,
|
|
});
|
|
|
|
return deliverOpenWorkItem({
|
|
channel: args.channel,
|
|
item: workItem,
|
|
log: logger,
|
|
attachmentBaseDirs: resolveRuntimeAttachmentBaseDirs(args.group),
|
|
replaceMessageId: args.replaceMessageId,
|
|
isDuplicateOfLastBotFinal: args.isDuplicateOfLastBotFinal,
|
|
openContinuation: args.openContinuation,
|
|
});
|
|
}
|