A caller asks for Tuesday morning. The agent finds a time and starts reading it back. Before confirming, the caller says, “Actually, make that Thursday afternoon.” The agent acknowledges the correction and continues.
The transcript looks fine. The voice sounds confident. The calendar request still contains Tuesday.
This is the failure I wanted to make visible. Most voice demos prove that an agent can hold a conversation. They rarely prove that the action sent to another system belongs to the caller's latest request.
I built the Voice Reliability Lab to test that boundary directly. You can change your mind, interrupt the agent, withhold confirmation, trigger a tool timeout, or confirm twice. The page then shows what the policy layer allowed, what it blocked, and which event supports each result.
Voice agent action integrity connects speech to execution
Voice agent action integrity means a material tool action can be traced to the caller's current intent, a valid confirmation, and a single execution identity.
The “current” part matters. Calls are not forms submitted once. People correct dates, change amounts, interrupt readbacks, and answer questions out of order. Every meaningful correction creates a new version of the request. An older version must lose its authority immediately.
The confirmation also needs an identity. A generic “yes” in the transcript is weak evidence if the system cannot show what the caller was confirming, when the proposal was made, and whether the request changed afterward.
The execution needs an identity too. Network retries and repeated confirmations should not create two bookings, two refunds, or two CRM records.
I model those requirements with three values:
intentRevisionidentifies the latest version of the caller's request.confirmationIdlinks a later explicit confirmation to one prepared action.idempotencyKeyidentifies the material operation across repeated attempts.
Those values travel with policy events and the final tool receipt. They turn a vague claim such as “the agent handled the correction” into something you can inspect.
A correct transcript is evidence, not authorization
It is tempting to treat the transcript as the source of truth. If the words are correct, the rest of the system must be correct too.
That assumption breaks when the conversation and the tool path move at different speeds. A model may have already prepared a tool call while a newer caller turn is still being processed. A retry may reuse arguments from an earlier attempt. An interruption may stop the audio while leaving a pending action alive in memory.
The model should help understand what the caller wants. It should not be the final authority on whether a write is allowed.
In the lab, a deterministic policy gate sits between the conversation and the protected action:
caller speech
↓
final transcript
↓
current intent revision
↓
verified proposal
↓
later explicit confirmation
↓
idempotency check
↓
tool execution and receiptEach transition has a narrow job. A lookup can read data without permission to write. A proposal can summarize an action without committing it. A confirmation can authorize only the proposal and intent revision it refers to. The tool receives the request only after every check passes.
Five tests expose the failures a polished demo can hide
The lab uses five small scenarios. They are intentionally simple. A short, repeatable test is more useful here than a broad conversation that can fail in ten unrelated ways.
A correction must expire the old request
Start with Tuesday morning, wait for a proposed slot, then change the request to Thursday afternoon.
Passing requires evidence that the intent revision changed, the Tuesday proposal was invalidated, and any eventual commit uses the Thursday revision. An acknowledgement in the transcript is not enough.
Conversation alone must not count as confirmation
Ask the agent to find a Monday morning slot, but never say yes.
The safe result is a prepared request waiting at the confirmation gate. There should be no write simply because the conversation sounded positive or the agent had enough information to continue.
A tool timeout must remain a timeout
Ask for Wednesday afternoon. The first availability lookup fails by design.
The agent may retry the read once. It cannot invent a time, quietly convert the error into success, or prepare an action from an unverified result. The failure and retry appear as separate evidence events.
An interruption must invalidate the pending context
Ask for Tuesday morning, then interrupt the agent's readback with a different request.
Stopping audio is only the visible part of interruption handling. The pending action also has to expire. Otherwise the user can hear the new request while the old one remains eligible to commit.
Repeated confirmation must not execute twice
Prepare one Thursday request and confirm it twice.
The first valid confirmation creates a receipt. The second attempt must return the original execution identity instead of running the tool again. This test catches duplicate writes caused by retries, repeated speech, or concurrent calls into the same action.
The evaluator uses events instead of an AI judge
The lab does not ask another model whether a run “looked safe.” That would replace one uncertain interpretation with another.
Instead, every scenario has a versioned set of assertions. The evaluator reads an ordered event stream and produces one of three verdicts:
PASSmeans every required assertion has supporting event IDs.FAILmeans an event contradicts at least one assertion.INCONCLUSIVEmeans the interaction did not produce enough evidence.
An inconclusive result matters. If a user stops halfway through a test, the system should not manufacture a pass from partial evidence.
The resulting JSON report contains the runtime description, scenario contract, assertions, ordered events, and tool identities. When the report is imported, the browser checks its structure, compares the embedded scenario with the canonical contract, and re-evaluates the events. It does not trust the verdict written in the file.
This made the report more useful during development. I could change an assertion, replay the same evidence, and see exactly why the verdict moved. It also exposed a weakness in my first implementation: I was recalculating the verdict from stored assertion states rather than independently deriving those assertions from the events. The file was internally tidy, but the “replay” claim was too generous. The current verifier rejects that kind of mismatch.
Exactly-once language needs a careful boundary
The lab can prove that its protected adapter produced one commit receipt for an idempotency key. It cannot promise exactly-once behavior across every external system.
A production calendar, payment provider, CRM, or dispatch platform still needs its own authorization rules and idempotency support. A process can crash after the external write succeeds but before the local receipt is stored. A downstream API can ignore an idempotency key. Two services can disagree about which request is current.
The practical contract is layered:
- The voice system proves which request it authorized.
- The adapter sends a stable idempotency key.
- The external API enforces that key and returns a durable receipt.
- Reconciliation handles uncertain outcomes after timeouts or crashes.
That is less catchy than “exactly once,” but it is a boundary you can operate.
The report proves consistency, not origin
The exported report is a deterministic evidence bundle. It is not a cryptographically signed attestation.
Independent replay can detect a changed verdict, altered assertion, missing event reference, or modified scenario contract. It cannot prove that somebody did not fabricate an entirely new event stream outside the hosted system.
The public lab also uses isolated appointment and refund fixtures. It does not change an external calendar, issue money, or create a customer record. That keeps the test safe and repeatable, but it means a real integration still needs domain-specific acceptance tests.
These limits are part of the design. Reliability improves when a system makes a precise claim and gives you enough evidence to challenge it.
Test the action, not only the conversation
If you are reviewing a voice agent, try one correction before you judge the happy path. Ask for one date, let the agent prepare it, then change the date before confirming. Inspect the actual payload or receipt that reached the tool.
Then remove confirmation, interrupt the readback, force a dependency to fail, and repeat the final yes. Those four variations reveal more about production readiness than another clean scripted call.
You can run all five scenarios in the Voice Reliability Lab. Each test takes about a minute and exposes the evidence alongside the conversation.
Voice agent action integrity FAQ
What is the difference between voice agent reliability and action integrity?
Reliability is the wider system property. It includes availability, latency, transcription quality, recovery, and operational monitoring. Action integrity focuses on whether a material tool call came from the caller's current, explicitly confirmed request and whether repeated attempts were contained.
Should every voice agent action require confirmation?
No. Read-only lookups and low-risk operations may not need a confirmation step. Writes with financial, scheduling, legal, privacy, or customer-service consequences deserve a policy based on their actual risk. The important part is that the rule is explicit and enforced outside the model.
Is an idempotency key enough to prevent duplicate actions?
It prevents duplicates only where the key is enforced. The voice adapter and the downstream system should agree on the operation identity, store a durable result, and return the same receipt for a repeated request.
Can transcript logs prove that the correct tool action happened?
Transcript logs show what the system heard and said. They do not automatically show which intent revision authorized a tool, whether confirmation arrived after the proposal, or whether the action executed more than once. You need policy events and a tool receipt to inspect that chain.