Require confirmation for the exact report and recipient the user reviewed. Store approval as an application decision tied to those details, then verify it at execution time. A conversational “yes” detached from its action can authorize the wrong send.
Show the decision the user is making
Present the recipient, report title or reference, relevant attachments, and whether the action sends externally. A report preview that omits its recipient does not provide enough context for this decision. Keep drafting separate from dispatch so the system can be useful before approval.
Bind and validate approval
- Create a pending action with stable identity and a report revision or content digest.
- Record the approving authenticated user, action details, and applicable expiration or cancellation state.
- At dispatch, recheck authorization and compare the pending action with the approved details.
- If the report, recipient, or consequential attachment changes, obtain a new approval rather than inheriting the old one.
Test a change after confirmation
The local example approves report revision R3 for a synthetic internal recipient. It accepts the unchanged action and rejects a changed recipient and an expired approval. It uses no email service and sends nothing. Real systems must also handle replay, concurrent dispatch, durable state, and downstream delivery uncertainty.
Keep the result honest
Record approval, dispatch attempt, and delivery outcome as distinct events. A queued send is not confirmed receipt. A cancellation should stop a pending action where possible, while the UI must explain if an already completed external effect cannot be recalled.
Run the worked example
Save the synthetic Node.js example and run node require-confirmation-before-agent-report-send.mjs with Node.js 22 or newer. The assertions check the illustrated records and calculations; they do not test a deployed provider, SDK, or access control. No credentials or network connection are needed.
// Synthetic teaching fixture. No credentials, network calls, or production verification.
import assert from 'node:assert/strict';
const approved = { user: 'u1', recipient: 'reviewer@example.test', revision: 'r3', expiresAt: 200 };
const canSend = (action, now) => action.user === approved.user &&
action.recipient === approved.recipient && action.revision === approved.revision && now < approved.expiresAt;
const action = { user: 'u1', recipient: 'reviewer@example.test', revision: 'r3' };
assert.equal(canSend(action, 100), true);
assert.equal(canSend({ ...action, recipient: 'changed@example.test' }, 100), false);
assert.equal(canSend(action, 201), false);
assert.equal(canSend({ ...action, revision: 'r4' }, 100), false);
console.log('Approval binds user, recipient, revision, and validity window; no message is sent.');
References and further reading
Maintained by DriftRail. AI assisted the October 2026 content and template revision. Examples are illustrative; they are not measured product benchmarks. Suggest a correction.