Approve the Effect, Not the Tool Call: Preventing Stale Consent in Tool-Using Agents
Abstract
Tool-using language agents increasingly ask users to approve consequential actions such as sending email, deleting database rows, issuing refunds, or creating calendar invitations. Existing approval interfaces usually bind consent to a tool call, an argument payload, or a permission scope. We argue that this is the wrong boundary: in stateful environments, the same approved call can commit a different effect after alias expansion, query re-evaluation, default-argument resolution, mutable resource pointers, or state drift. We call this failure mode stale consent. We formalize human approval as an effect-level contract and introduce EffectGuard, a model-agnostic runtime wrapper that dry-runs risky actions, obtains approval over resolved effects, and revalidates committed-effect subsumption immediately before execution. We evaluate real LLM-generated tool proposals in four controlled stateful domains under four API designs. Dynamic-handle APIs produce substantially more stale-consent opportunities than concrete-execution APIs. Across 1,377 valid real-agent proposals, tool-, session-, and argument-level approval commit unsafe broadened effects in 7.8% of proposals, while EffectGuard commits none. Snapshot locking also prevents unsafe commits, but overblocks benign non-broadening cases; EffectGuard has 0.0% overblocking. Resolved-argument approval is strong when applicable, but is applicable to only 49.0% of cases and still commits unsafe effects in mutable-pointer and default-argument settings. Our results suggest that safe human approval for agents should be framed as a consent-boundary design problem: approval should bind to the effect that will be committed, not merely to the tool call that requests it.