For irreversible stuff I like feeding messages into queues. That keeps the semantics clear, and makes the bounds of the reversibility explicit.
Tool calls are the boundary (or at least one of them).
Tool calls are the boundary (or at least one of them).