A few weeks ago we shipped a general command tool for a local agent, with a deny-list in front of it and a human approval gate behind it. I wrote at the time that the deny-list is the part that looks like engineering and does not hold, because you cannot enumerate the dangerous set. The gate is the part that holds.
Someone pushed back with a good refinement. The gate only holds if approval is real state with a lifecycle: requested, then approved or rejected, then consumed, then expired. A confirmation step living inside the agent loop cannot survive the process dying while it waits, so it is not a control, it is a prompt.
He is right, and most implementations skip it. What I want to add is that making approval durable does not finish the job. It moves the failure somewhere quieter.
An approval is granted against a world, not a string
When someone clicks approve, they are approving the specific thing they were shown: this file, with this content, going to these two people. What you persist is usually a record that a decision happened, plus an identifier. That is not a record of what was decided.







