The notification transport seam (email, Slack, pager — flowsafe ships NO
transport). Fire-and-forget with the same availability-over-delivery policy
as ApprovalAuditSink: a sink that throws or rejects never fails the
approval action that fired it — the failure is recorded to the AUDIT sink
as approval.notify/'error' and the action proceeds. Workers hosts whose
transport must outlive the response wrap it in ctx.waitUntil themselves
(the hostAuditSink keepAlive pattern): the service does not await the sink.
EXPOSURE: the event carries the FULL ApprovalRecord — including the
workflow-authored payload (typically the suspend payload) and summary.
That is deliberately MORE than the audit trail ever emits (audit details
are scoped to ids), because a useful notification needs reviewer context.
A transport addressing a lower-trust channel (email, chat) must project
or redact the record itself — title/ids/priority/SLA usually suffice.
The notification transport seam (email, Slack, pager — flowsafe ships NO transport). Fire-and-forget with the same availability-over-delivery policy as ApprovalAuditSink: a sink that throws or rejects never fails the approval action that fired it — the failure is recorded to the AUDIT sink as
approval.notify/'error' and the action proceeds. Workers hosts whose transport must outlive the response wrap it in ctx.waitUntil themselves (the hostAuditSink keepAlive pattern): the service does not await the sink.EXPOSURE: the event carries the FULL ApprovalRecord — including the workflow-authored
payload(typically the suspend payload) andsummary. That is deliberately MORE than the audit trail ever emits (auditdetails are scoped to ids), because a useful notification needs reviewer context. A transport addressing a lower-trust channel (email, chat) must project or redact the record itself — title/ids/priority/SLA usually suffice.