An approval is meant to say yes to one consequential action. But a provider’s tool-call identifier is not necessarily a permanent name for that action. Microsoft Agent Framework’s public September 2 merge makes the distinction explicit: call_id remains the provider or service correlation value, while a local actionable function call receives a stable Content.id that identifies that one occurrence. The same merge credits Copilot App as a co-author and records a Copilot session. That is credible public evidence of coding-agent use; the more interesting Builder Work is the approval architecture the source exposes.
The first reading could be “give each request a better ID.” The project’s own function-calling contract makes that too shallow. A provider call_id can be reused; the framework must still keep each locally actionable invocation distinct through streaming, serialization, and replay. So the question is not which string looks unique. It is what the runtime can prove a person was approving.
Keep provider correlation separate from local authority
The answer in the inspected repository is a trusted pending snapshot. When a local tool needs approval, its request is keyed by the function call’s occurrence identity. On resume, the runtime looks up that server-held record and rebuilds the executable call from it; the reply cannot replace the recorded tool name, arguments, or provider call ID. The public core implementation stores immutable snapshots, then removes a pending entry only after a matching response has been rebound to it.
That separation leaves the provider identifier useful without making it authority. The code carries both values into middleware: the provider call_id for correlation and the framework occurrence ID for the locally actionable event. Hosted approval request IDs are also left on their service protocol. The change is a boundary design, not a global renaming campaign.
The revealing test is the answer that arrives too late
The focused regression tests create guarded calls that share a provider value such as provider-reused but have different local occurrence IDs. A response aimed at the older occurrence is discarded; the newer pending request remains. The mismatch cases include no ID, the reused provider ID itself, and another occurrence ID. None is allowed to consume the pending state.
Then the test sends a corrected response with the exact current occurrence ID. Only then does the runtime reattach the recorded function call and clear the pending entry. That is a small sequence with a large operational consequence: an invalid approval does not become a denial by accident, and it does not turn a stale yes into permission for the next invocation.
The transferable skill: authorize a stable occurrence
Builders can use this pattern anywhere a person, policy engine, or external approval console must authorize an effect that may be retried or replayed. Give the locally actionable occurrence its own opaque identity when it becomes real. Preserve that identity through stream assembly, persistence, and retries. Store the intended operation in a tenant-scoped, trusted snapshot; let the approval response reference that snapshot rather than supply a replacement action. Consume the snapshot only after the identity matches.
The most valuable test is deliberately awkward: create two writes with the same provider correlation value but distinct occurrence IDs and arguments; let the second one be pending; submit an approval for the first; assert that nothing runs and the second remains available; then submit the exact second ID and assert that only the recorded second write runs. Add the equivalent cases for duplicate answers, a missing ID, a restarted UI, and a legacy stored request. This turns “we have approvals” into a checkable contract about which effect can cross the boundary.
The boundary still stops at the session
The source is unusually candid about its limit: its code/PR does not prove durable exactly-once behavior across crashes, concurrency, mutable storage, or deployment. Consume-on-bind protects one authoritative session state; a durable distributed guarantee needs the host’s authorization, tenant isolation, and transactional coordination. The public code and tests establish an intentional main-branch design, not a production deployment or a universal provider guarantee. The next useful signal is an end-to-end host implementation showing how that trusted snapshot survives—or is safely invalidated by—a restart and competing workers.