A HITL step shows a tool name and a truncated preview.
The executor receives the payload. Nothing compares them.
The agent asks for a $100 refund, gets approved, decides mid-execution the situation is worse, retries at $200.
Different action, same approval.
Keying on an approval ID does not help.
The handle proves who approved, not what they saw.
Close the seam by recomputing a digest at execution time and consuming the grant atomically:
UPDATE approvals SET state = 'consumed', consumed_at = now() WHERE id = :approval_id AND state = 'approved' AND expires_at > now() AND digest = :live_digest RETURNING id; One statement, four preconditions, zero rows means refuse.
The read-then-write version passes every test and lets forty workers through.
Full writeup with the field-classification problem:
https://nullrun.io/blog/human-approval-is-not-authorization