Thanks for calling this out—and for the concrete migration example. I’d fold it into the execution layer’s contract. The article leaves that concurrency requirement underspecified.
You’re right that binding approval to an action hash prevents substitution, but doesn’t make two independently approved actions safe to execute concurrently. The executor should acquire a lock scoped to the affected resource before execution, with conflicting approved actions remaining queued.
I’d add one requirement after acquiring that lock: revalidate the action’s preconditions against the current resource state. If migration A changes the schema that migration B was evaluated against, B’s approval may still be unexpired and correctly bound to its action, while the assumptions behind that approval no longer hold. In that case, the executor should stop and return it for re-evaluation—and renewed approval if the approved assumptions or operation change.
So the contract I’d make explicit is: acquire the resource lock, recheck approval validity and resource preconditions, execute, and record the resulting state before releasing the lock. A queued action gets those checks when it actually reaches execution.
That belongs alongside the credential boundary you highlighted. Approval establishes authority for an operation; the executor also has to establish that the operation is valid against the state it is about to change.
This is a genuinely well-built design, especially the point about production credentials staying unavailable to an unauthorized path even when a hook coordinates the decision - that's the part most agent-permission writeups skip entirely. One gap I don't see addressed: what happens when two independently valid ASK approvals target the same underlying resource within their expiry window - say two on-call engineers approve two different production migrations to the same billing table a few minutes apart, each action individually well-formed and each approval correctly bound to its own action hash. Binding approval to "the exact operation that was evaluated" stops a bait-and-switch on a single pending request, but it doesn't stop two correctly-approved operations from racing each other at execution time. Drawing on our own approval-gated deploy work, that usually ends up needing a resource-scoped lock the executor takes before running any approved action, on top of the action-identity check, so a second approved action against a still-locked resource gets requeued rather than executed. Is that layer intentionally out of scope here, or would you fold it into the execution layer's contract too?