- Engineering
Thinking or leaving? Design progressive no-input prompts
Design bounded no-input prompts with playback-aware timers, caller resumption, explicit wait states, and deterministic race tests.
- Author
Udit Goenka- Editorial date
- Reading time
- 25 min

TL;DR: Silence does not reveal whether a caller is thinking, disconnected, or leaving. Build a bounded no-input ladder that starts from an explicit listening boundary, honors wait requests, cancels stale prompts when speech resumes, and ends with an honest fallback instead of repeated pressure or assumed consent.
The agent asks for a reference code. The caller searches for a message, and the agent repeats the question before the caller has found it. The next reminder overlaps the answer, so a recoverable pause becomes a failed capture.
Waiting indefinitely creates another failure. A caller who cannot hear the agent, has left the call, or needs another channel can remain attached to a silent session with no useful next step. More patience alone does not fix a broken input path.
A no-input policy needs a small state machine and a clear observation boundary. This guide provides a bounded silence ladder, a runnable timer-generation model, synthetic abandonment and resumption fixtures, and a reporting method that keeps uncertainty visible.
All timings in the executable example are synthetic test units, not production recommendations. Figures are conceptual. Public documentation was reviewed on November 9, 2026, and the guide makes no claim about private implementation or measured behavior of 60db Agent.
Table of contents
- Treat silence as an observation
- Define the listening boundary
- Build a bounded prompt ladder
- Honor wait and resumption
- Implement stale-timer protection
- Test abandonment without inventing intent
- Measure prompts and recovery
- Operate the fallback honestly
- Frequently asked questions
- Ship a silence contract
Treat silence as an observation
No input means that the application did not receive usable input within a defined window. It does not identify the cause, and the cause determines which recovery is helpful.
The caller may be searching for information, deciding what to say, speaking too quietly, using an unavailable microphone, or no longer participating. A recognizer can also fail to return text even when audio contains speech.
Keep those possibilities separate from the event you observed. no_usable_input is a defensible event name; caller_abandoned is an inference that needs a stated definition and often additional evidence.
Dialogflow CX state-handler documentation describes no-input events that can arise from empty input, no recognized speech, or a no-speech timeout. That public contract is a useful reminder that one event type can combine several different observations.
Your adapter should preserve the distinction where the provider exposes it. A media disconnect, recognizer error, and silent but healthy stream should not all become the same timer callback with no reason attached.
Start each no-input event with the pending question identity, task phase, listening-window origin, and transport status. This small context often explains a failure more directly than another global timeout setting.
Keep three questions separate
First, is the input path healthy enough to receive speech? Second, has the caller produced a usable answer? Third, what should the agent do next? A no-input policy combines evidence for these questions without collapsing them into a guess about the caller's mental state.
A connected call does not prove working two-way audio. Use the SIP audio troubleshooting guide when silence coincides with media symptoms rather than treating a signaling success as evidence that the caller heard the prompt.
A valid speech segment does not prove a complete answer either. If the caller is listing items or spelling a name, the structured endpointing contract should keep collection open rather than sending a generic no-input apology between fragments.
Finally, an unanswered confirmation must remain unanswered. Silence cannot accept a proposal, complete a consent step, or authorize a tool operation. Put that invariant in the business controller as well as the dialogue policy.

A no-input reminder and a tool progress message respond to different owners of the delay.
Define the listening boundary
A silence window should begin at a named event that matches the question being asked. Starting at text generation can spend the caller's response budget while the prompt is still being synthesized, queued, or played.
Prefer an observed playback-completion boundary where the transport provides one, and name its limitation. Completion at a client or media endpoint does not prove audibility, attention, comprehension, or informed consent.
If playback evidence is missing, record the timer origin as an estimate and choose a conservative fallback. Do not rename a send timestamp as "question heard" merely because it is the easiest event to obtain.
The Amazon Lex streaming conversation guide describes playback-completion and interruption events in its client protocol. Use that as a concrete example of a public media contract, while checking the exact events available in your own integration.
The playback evidence ledger explains why generated, sent, scheduled, and acknowledged audio should remain separate states. A no-input timer can only be interpreted when its origin is explicit.
Track local time consistently
Use a monotonic clock for elapsed waits inside one process. Python's time documentation defines a monotonic clock as unaffected by system-clock updates and notes that its reference point is undefined; compare differences rather than treating the value as a wall-clock date.
A client playback timestamp and a server timer timestamp belong to different clock domains unless you have an explicit correlation method. Do not subtract them and publish the result as caller waiting time.
Log wall-clock time for human navigation and monotonic elapsed time for local scheduling, keeping the purpose of each field clear. The latency benchmark guide gives a broader treatment of observation points and clocks.
On a process restart, an in-memory timer cannot simply continue from its old monotonic value. Reconstruct the task from durable state using a documented recovery policy, or close the listening window and ask a fresh question with a fresh identity.
Separate prompt scheduling from prompt playback
When a timer expires, the policy requests a prompt. That prompt may still wait behind audio already queued or a tool response that has become obsolete.
Track prompt_requested, prompt_started, and prompt_completed separately where observable. If the caller begins speaking before playback starts, invalidate the prompt rather than allowing it to interrupt the resumed answer.
The next listening window should be armed from the appropriate boundary for that prompt, not from the earlier timer expiry. Otherwise queue delay can consume the next stage's budget and create a burst of reminders.
This separation also supports truthful metrics. A requested reminder that was canceled before playback should not count as a reminder the caller experienced.
Build a bounded prompt ladder
A silence ladder is a finite sequence of responses to continued missing input. Each stage should add a useful option rather than repeat the original question with increasing urgency.
A practical conceptual ladder starts with quiet waiting, then a gentle check, then an alternative route, and finally a safe close or handoff. The exact count and timing should come from the task, caller population, accessibility needs, and available fallback channels.

The figure shows the ladder as finite. Caller resumption returns to listening under a new timer generation, so an already-scheduled reminder cannot continue advancing the old silence episode.
For a synthetic reference-code task, a gentle check could ask whether the caller needs more time. An alternative-route prompt could offer to continue without the code if the workflow permits it, or offer a real available transfer path.
Do not invent a fallback capability. If the application cannot send a secure link, arrange a callback, or transfer to a person, the prompt must not promise that it will.
Use a criteria table to review the ladder. ✓ means the stage supports the stated property under this proposed contract; ✗ means that behavior is prohibited. Conditional entries depend on the actual deployment capability.
| Stage | Preserves pending answer | Can authorize action | Can repeat forever | Useful next option |
|---|---|---|---|---|
| Quiet wait | ✓ | ✗ | ✗ | Caller can resume |
| Gentle check | ✓ | ✗ | ✗ | Ask for more time or repeat |
| Alternative route | ✓ where safe | ✗ | ✗ | Real channel or handoff |
| Safe close | Conditional retention | ✗ | ✗ | Explain incomplete status |
| Transport failure recovery | Conditional | ✗ | ✗ | Repair channel or end safely |
The table keeps every stage from authorizing a business action. A no-input ladder manages conversational availability; it does not decide whether a booking, payment, or disclosure is permitted.
Write stage-specific prompts
The first reminder should recognize the uncertainty without accusing the caller of failing. A short question about needing time is usually more informative than a louder repetition of the original request.
The next stage should reduce the caller's burden. Offer a repeat, a different capture method, or a way to skip an optional field, but only when the workflow supports that choice and its consequences are clear.
The final stage should state what remains incomplete. If nothing was committed, say so. If a tool operation is still pending, keep its outcome separate rather than claiming the call ended with either success or failure.
Dialogflow CX parameter documentation describes parameter-level reprompt handlers and transitions after unsuccessful attempts. That supports a scoped recovery design rather than one global message reused across every question.
Bound both repetition and total duration
A finite prompt count is not enough if each stage can rearm indefinitely. Bound the silence episode as well as the number of reminders, and define which events reset those bounds.
A genuine answer can start a new question and a new episode. Ambient noise should not reset the whole ladder forever; an explicit wait request may extend a bounded hold without erasing the total resource limit.
Keep task abandonment separate from call termination. You may abandon collection of an optional field while continuing the conversation, or end a call while a durable business operation remains pending and recoverable.
The shutdown semantics guide explains why ending media and finishing work are different lifecycle events. A silence policy should use that distinction when it closes a session.
Honor wait and resumption
An explicit "give me a moment" is input. It changes the expected continuation state even though it does not fill the requested field.
The Amazon Lex wait-and-continue documentation provides a public example of slot-scoped waiting during streaming conversations. Its documented availability depends on the supported locale and interface, so verify those conditions before promising the behavior in an integration.
Represent an explicit hold separately from unexplained silence. The hold should preserve the pending question, the collected provisional answer, and the remaining ladder state under a bounded waiting contract.
When the caller resumes, cancel pending no-input output and invalidate its timers. Continue from the current task state rather than restarting the original question and discarding what was already captured.
Keep a resumption path at every stage
A caller can begin speaking during a reminder, during the alternative-route prompt, or just before safe closure. Define whether each stage is interruptible and which event wins when speech and closure arrive together.
Use one serialized controller for those events. If closure has not committed, caller speech can invalidate the prompt and return to collection; if closure already committed, the application needs an explicit reopen or new-session policy.
The interruption-safe voice guide covers output invalidation. For no-input prompts, the same rule applies: stopping generation is insufficient if stale audio remains queued for playback.
A short listener cue during a reminder is not necessarily a complete answer. Apply the backchannel floor policy so that "mm-hmm" does not fill the pending field or reset the entire silence episode without useful progress.
Preserve progress without granting infinite extensions
Differentiate meaningful progress from activity. A partial code or a request to repeat can justify a new bounded collection window; a recurring noise event cannot keep the call alive indefinitely.
Document reset rules in a decision table or configuration owned by the controller. Operators should be able to tell whether a wait request extends the current hold, starts a new episode, or consumes one of the remaining options.
A caller who needs more time may require a different channel rather than a longer loop. Offer the actual available route, and keep accessibility accommodations distinct from a generic abandonment threshold.
The policy must remain humane without inventing certainty about why the caller is silent. You can provide time and choice while still stating that the requested answer has not yet arrived.
Implement stale-timer protection
Timer cancellation alone is insufficient because a callback may already be queued when cancellation happens. Attach a generation token to each armed window, and reject callbacks whose token no longer matches the current window.
The following program models scheduling with synthetic integer ticks. It intentionally avoids real sleeping, network calls, or audio playback so the race schedules can be exercised deterministically.
Save it as silence_ladder.py and run python3 silence_ladder.py. A real integration must serialize controller events and arm the next listening window after the observed playback boundary, rather than treating fire as proof that the prompt was heard.
from dataclasses import dataclass
@dataclass(frozen=True)
class Timer:
generation: int
due: int
class Ladder:
def __init__(self, deadline=100):
self.deadline = deadline
self.prompt_token = None
self.generation = 0
self.stage = 0
self.state = "collecting"
self.current = None
self.actions = []
def arm(self, now, wait):
if wait <= 0 or self.state != "collecting":
raise ValueError("arm requires positive wait and collecting state")
self.generation += 1
self.current = Timer(self.generation, now + wait)
return self.current
def speech(self):
if self.state == "closed":
return "closed"
self.generation += 1
self.current = None
self.state = "collecting"
self.prompt_token = None
return "cancel_prompt_and_collect"
def hold(self):
if self.state == "closed":
return "closed"
self.generation += 1
self.current = None
self.state = "held"
self.prompt_token = None
return "hold"
def resume(self):
if self.state == "closed":
return "closed"
self.generation += 1
self.current = None
self.state = "collecting"
return "collect"
def fire(self, timer, now):
if (self.state != "collecting" or self.current != timer
or timer.generation != self.generation or now < timer.due):
return "ignore"
self.current = None
self.generation += 1
actions = ("gentle_check", "offer_route", "close_incomplete")
action = actions[self.stage]
self.stage += 1
self.state = "closed" if self.stage == len(actions) else "prompting"
self.prompt_token = self.generation if self.state == "prompting" else None
self.actions.append(action)
return action
def playback_complete(self, token):
if self.state == "prompting" and token == self.prompt_token:
self.prompt_token = None
self.state = "collecting"
def expire(self, now):
if now >= self.deadline and self.state != "closed":
self.generation += 1
self.current = None
self.prompt_token = None
self.state = "closed"
self.actions.append("close_incomplete")
return self.state
if __name__ == "__main__":
l = Ladder()
old = l.arm(0, 10)
assert l.fire(old, 9) == "ignore"
assert l.speech() == "cancel_prompt_and_collect"
assert l.fire(old, 10) == "ignore"
t = l.arm(10, 10)
assert l.fire(t, 20) == "gentle_check"
assert l.fire(t, 20) == "ignore"
l.playback_complete(l.prompt_token)
held = l.arm(20, 10)
assert l.hold() == "hold"
assert l.fire(held, 30) == "ignore"
l.resume()
t2 = l.arm(30, 10)
assert l.fire(t2, 40) == "offer_route"
l.playback_complete(l.prompt_token)
t3 = l.arm(40, 10)
assert l.fire(t3, 50) == "close_incomplete"
assert l.speech() == "closed"
assert l.fire(t3, 60) == "ignore"
assert l.actions == ["gentle_check", "offer_route", "close_incomplete"]
h = Ladder(deadline=15)
h.hold()
assert h.expire(15) == "closed"
x = Ladder()
a = x.arm(0, 1)
x.fire(a, 1)
prior = x.prompt_token
x.speech()
b = x.arm(2, 1)
x.fire(b, 3)
x.playback_complete(prior)
assert x.state == "prompting"
x.playback_complete(x.prompt_token)
assert x.state == "collecting"
print("Synthetic silence-ladder checks passed")
The generation check prevents an old timer from advancing the ladder after speech or a hold request invalidates it. Clearing current also makes repeated delivery of the same timer harmless.
The example keeps stage count across resumption. That is a deliberate bounded policy for this exercise, not a universal recommendation. In a real task, advancing to a new question would create a new ladder with its own identity and limits.
playback_complete is an adapter boundary, not proof of hearing. A production event must include the prompt identity or generation so that a late completion from an obsolete prompt cannot affect a newer prompt state.
The example checks a prompt token before accepting playback completion. A late completion for an obsolete prompt cannot arm collection for the newer one. The external scheduler must call expire at the overall episode deadline, including during a hold; the deadline is a separate resource bound from the stage timers.

The old timer can still fire, but its generation no longer matches. It is discarded instead of producing a reminder over the resumed caller speech. This is a correctness rule about event identity, independent of how long the wait lasts.
Keep closure semantics explicit
The example closes at the final action request. A real system may need a closing state while the final message is queued and a later terminal state after transport closure.
Choose the point where caller resumption can still prevent closure, then test both sides of that boundary. Do not accidentally reopen a completed session through a late speech callback or close an active answer through a stale timer.
If a durable task remains pending, session closure must not delete its business state. The call lifecycle and task lifecycle need separate identities and recovery paths.

Reject obsolete prompt completion as well as stale timers after the caller resumes.
Test abandonment without inventing intent
A fixture can establish that no usable input arrived before closure. It cannot establish that the caller was bored, confused, or deliberately abandoning the task unless that information is part of the labeled evidence.
Use outcome labels that match observations. resumed_after_check, explicit_wait, input_path_failed, closed_incomplete, and caller_disconnected describe events more faithfully than a universal abandoned label.
Amazon Lex analytics definitions define dropped conversations and slots within a particular analytics model. If you use vendor analytics, preserve that definition instead of treating it as direct evidence of caller intent.
Build a synthetic fixture matrix before changing production timing. Include speech just before expiry, speech after a prompt is requested but before playback, an explicit hold, a media failure, and a duplicate timeout.
| Synthetic schedule | Expected state | Prohibited result |
|---|---|---|
| Speech invalidates timer before expiry | Collecting | Old reminder plays |
| Timer requests reminder, caller resumes | Collecting after invalidation | Reminder talks over answer |
| Explicit hold then old timeout | Held | Ladder advances |
| Duplicate timeout delivery | One stage advancement | Repeated prompt |
| Missing playback completion | Recovery or bounded uncertainty | Assumed hearing |
| Final closure committed then late speech | Closed or explicit reopen path | Silent accidental resurrection |
| Input transport fails | Media recovery | Caller blamed for silence |
Test the prompt wording as well as the state. A technically bounded ladder can still pressure callers if every message implies they are doing something wrong or promises an unavailable option.
Include device and language slices
A caller on speakerphone may produce quiet speech that the system misses. A browser in the background may deliver delayed control events. Those failures can look like hesitation unless the fixture includes media and client state.
Use the mobile browser latency guide for device-state coverage. Keep capture failure, timer delay, and transcript delay separate so that the fix reaches the correct owner.
Language and task change the time needed to answer. Reading an identifier, translating a question internally, or asking a nearby person for information can produce legitimate pauses without indicating disengagement.
Evaluate intended caller populations with appropriate consent and governance. Synthetic fixtures prove the controller's event rules, while real interaction review is needed to judge whether the prompts and waits fit the task.
Measure prompts and recovery
Measure what the caller experienced, not only what the policy requested. Count requested, canceled-before-playback, started, and completed reminders separately when the media interface exposes those boundaries.
Define the denominator for recovery. A resumption rate after a reminder should use the silence episodes eligible for that reminder, and the report should state how disconnects, transport failures, and unresolved sessions were handled.
A reminder followed by speech does not prove that the reminder caused the speech. The caller may have been about to answer anyway. Use controlled comparisons when making causal claims, and keep descriptive operational counts separate from experiments.
The voice outcome metrics guide helps connect recovery to task completion. A resumed caller can still provide an invalid field, decline the action, or ask for a human; those are different outcomes.
Compare policies on the same episodes
Use paired replay for deterministic event rules and controlled exposure for interaction effects. Freeze prompt text, task contract, and event schedules when testing a timer-generation fix; change one timing or wording choice at a time when evaluating caller behavior.
Report counts alongside summaries. A policy that reduces reminders by ending more calls early has not necessarily improved the experience, and a policy that increases resumption can still extend calls with repeated failed capture.
Track the sequence of prompts per episode and the final state. This reveals infinite rearming or loops that aggregate prompt counters can hide.
The voice observability guide provides a trace structure for these transitions. Prefer small event records with reason codes and identities over unrestricted transcript logging.
Separate silence cost from tool waiting
A caller waiting for an external operation is a different state from an agent waiting for caller input. Sending a no-input reminder while a tool is running asks the caller to solve the wrong problem.
Use the truthful waiting-speech policy for tool progress messages. Tie those messages to observed operation state and do not imply completion before a result exists.
A tool timeout can leave an unknown business outcome even after the call closes. The silence ladder must not relabel that unknown outcome as failure or retry a potentially completed action without its own idempotency contract.

Requested reminders and played reminders need separate counts; resumption alone does not prove a reminder helped.
Operate the fallback honestly
A fallback is useful only if it exists and preserves the task boundary. A transfer requires an available route and enough context to continue; a callback requires permission and scheduling capability; a text alternative requires an appropriate channel and data policy.
Do not promise that a person is joining until the handoff state supports that claim. The warm handoff guide separates transfer initiation, acceptance, and successful continuation.
If the only available outcome is a safe close, state that the requested information was not captured and the action remains incomplete. Avoid language that sounds like a successful booking or saved request when no such durable result exists.
A close prompt should also respect pending work. If the business operation is already committed, explain the confirmed result using its authoritative evidence; if it is pending, use an honest pending state and the supported recovery route.
Protect the evidence trail
No-input traces can reveal sensitive context through the pending question even when no transcript is stored. A field name such as an account recovery secret should not become an unrestricted metric label.
Use allowlisted task categories and opaque governed identifiers. Keep the question text and caller content in the appropriately protected evidence store only when needed and permitted.
Record why the ladder advanced, which timer generation fired, whether the prompt began playback, and how the episode ended. That is enough to diagnose many races without copying sensitive answers into operational logs.
Distinguish prompt usefulness from prompt delivery
A delivered reminder can still be unhelpful. Review whether its question matches the caller's current task, whether it interrupts information retrieval, and whether its offered route is usable. These judgments need a scoped interaction review rather than an automatic success label attached to a playback event.
Use separate annotation fields for delivery and usefulness. A prompt canceled before playback has no caller-experienced wording outcome; a played prompt after the caller already resumed is a scheduling error even if the words are polite. Keeping these cases distinct prevents a wording experiment from concealing a media or controller regression.
Prepare the on-call decision
Keep a short release note with the ladder version, timer origin, reset rules, supported fallback routes, and known unmeasured slices. Include the exact rollback configuration and the fixture that exposed the original failure.
When a silence metric changes, inspect its composition before tuning. More no-input events can reflect a broken recognizer or delayed browser callbacks, while more explicit wait requests can reflect a task that asks callers to retrieve information.
For 60db Agent or another voice platform, verify the available public interfaces against this contract. The goal is a testable caller experience with honest limits, not a claim that a model can infer attention or intent directly from missing input.
Rehearse a recovery incident
Use a synthetic incident to test whether the operational evidence is enough. Start with a question whose playback completes, arm a silence timer, then deliver caller speech just before the callback. Queue the old callback anyway. The trace should show the generation mismatch, no reminder playback, and continued collection under the same pending question.
Repeat the schedule with the reminder already requested. This time the controller must invalidate queued output as well as its timer. If the media adapter reports completion for that canceled reminder later, the prompt token must prevent that callback from opening a listening window for a different prompt.
Now fail the input transport while the caller is in an explicit hold. The application should leave the semantic waiting policy and enter channel recovery, preserving the fact that the requested field is incomplete. A reminder that asks for the code again would hide the channel failure and give the caller no useful action.
Finally, reach the total episode deadline while no stage timer is armed. This verifies that a hold or missing playback acknowledgment cannot reserve the session forever. The terminal record should identify the deadline, the pending task state, and whether any business operation remains unresolved.
Keep the resulting trace as a regression fixture. It tests the whole boundary among scheduler, dialogue controller, and output adapter without needing real caller content or a production outage. When a later refactor changes one component, the fixture should still prove that obsolete reminders cannot become audible after resumption.
The exercise also exposes an operational ownership question: which process watches the overall deadline if the dialogue worker dies? A service can use its existing session supervisor or durable lease mechanism, but that owner must be named. Do not add a new watchdog solely because the article contains a deadline; reuse the deployment's existing lifecycle boundary and verify its behavior under worker loss.
Frequently asked questions
What is a no-input prompt?
A no-input prompt is an application response to missing usable input within a defined listening window. It should help the caller resume or choose another route. The event does not identify why input is missing, so the controller needs task context and media status before deciding whether to wait, clarify, recover the channel, or close safely.
Can silence tell the agent that the caller has left?
Silence alone cannot establish that intent. The caller may be thinking, finding information, unable to hear, or affected by capture failure. Use observation-based labels and a bounded policy. If the transport reports a disconnect, record that fact separately rather than treating every expired timer as proof that the caller deliberately abandoned the task.
When should the silence timer start?
Start from a named listening boundary tied to the current question, preferably an observed playback-completion event when available. State what the endpoint proves and what it does not. Starting when text is generated can consume the response window before the prompt finishes, while a send timestamp remains an estimate rather than evidence of hearing.
Does playback completion prove that the caller heard the question?
No. It establishes the provider or client observation defined by the interface. It does not prove acoustic audibility, attention, comprehension, or consent. Keep those limits in the trace and avoid naming a field question_heard unless you explicitly describe it as an inference. Missing playback evidence should remain visible uncertainty.
How many reminders should a voice agent send?
Use a finite task-specific ladder with a total episode bound. There is no universal count justified for every caller and workflow. Each reminder should add a useful option, and the final stage should reach a real fallback or safe close. Test whether the actual population needs different timing or accessibility accommodations.
What should the first reminder say?
It should ask a concise question that resolves the current uncertainty, such as whether the caller needs more time or wants the question repeated. Avoid implying that the caller failed. Keep the wording attached to the pending task, and do not promise a transfer, callback, or alternative channel that the deployment cannot provide.
How should "give me a moment" change the policy?
Treat it as explicit input that requests a bounded hold. Preserve the pending question and provisional answer, invalidate the ordinary silence timer, and define the hold's extension and expiry rules. It should not fill the requested business field or grant an unlimited resource reservation simply because the caller asked the agent to wait.
Should a short acknowledgment reset the whole ladder?
Only if the task contract treats that acknowledgment as meaningful progress. A listener cue can show attention without answering the pending question. Keep floor handling separate from field completion, and avoid letting recurring incidental sound or brief cues rearm the episode forever. Reset rules should be explicit and testable.
Why is timer cancellation alone insufficient?
A canceled timer callback may already be queued for execution. A generation token lets the controller reject that callback after speech, a hold, or a new question invalidates its window. Test the old callback after each invalidation event; otherwise a rare scheduling race can still produce a prompt over a resumed answer.
How should duplicate timeout events behave?
They should advance the ladder at most once for the current timer. Clear or invalidate the armed token when the first event is accepted, and make later delivery a no-op. A duplicate event must not produce another reminder or consume another stage, even if it carries the same due time and question identity.
What happens if the caller resumes during a reminder?
The controller should invalidate the reminder's queued output and return to the appropriate collection state when the contract permits interruption. Keep the new speech and pending answer together. Stopping generation alone is insufficient if old audio remains queued, so connect the decision to the actual media invalidation path and test it.
What if speech arrives just after closure?
Use an explicit boundary. Before terminal closure commits, the application may cancel closing and resume collection; afterward it should follow a documented reopen or new-session path. A late callback must not silently resurrect the old session. Preserve any durable task state independently so that call closure does not discard business evidence.
Should no input be treated as a negative answer?
No. Missing input is different from a caller declining a proposal. Keep an unanswered confirmation pending or close it as incomplete under the workflow contract. Never turn silence into acceptance, rejection, consent, or a tool command just to make a state machine reach a terminal status with a convenient label.
How is no-input recovery different from tool waiting?
No-input recovery waits for the caller to supply information. Tool waiting waits for an external operation to produce a result. The prompts should reflect the correct owner of the delay. Asking the caller to answer while a tool is running is confusing, and claiming tool progress without evidence can misrepresent the business outcome.
Can an empty transcript mean microphone failure?
It can reflect several causes, including silence, poor capture, configuration mismatch, or recognition failure. Preserve media and recognizer status rather than treating empty text as a complete diagnosis. If the input path is broken, repair or close that channel; repeating a question cannot make unavailable audio arrive.
Which metrics show whether reminders help?
Track eligible silence episodes, prompts requested, canceled prompts, observed playback, caller resumption, final task state, and failure reasons. Publish counts and definitions. Speech after a reminder is descriptive evidence, not automatic proof of causation, so use controlled comparisons before claiming that wording or timing improved recovery.
How should multilingual silence policies be tested?
Use speakers and reviewers familiar with the intended task and language. Include information retrieval pauses, code-switching, clarification, and explicit wait requests. Report per-language evidence and omissions rather than borrowing one population's timeout. Synthetic event tests cover controller correctness, while interaction review is needed to judge whether the prompt fits the caller.
What should a safe close message claim?
It should state only the confirmed task status and the real available next step. If the information was not captured and no action committed, say the request remains incomplete. If a durable operation is pending, preserve that uncertainty. Avoid implying that a booking, callback, or handoff succeeded merely because the call is ending.
What belongs in a no-input trace?
Record the question identity, task phase, timer origin and generation, media status, prompt lifecycle, reason for advancement, and final episode state. Keep sensitive question content and raw answers out of ordinary metric labels. Govern deeper replay evidence separately so diagnosis remains possible without distributing caller data across every operational system.
What is the smallest useful implementation?
Use one owner for the listening window, a finite ladder, explicit reset rules, generation checks for stale callbacks, and a truthful terminal outcome. Add deterministic fixtures for speech-before-timeout, hold, duplicate delivery, and late closure. That gives a complete correctness boundary before you tune live timing or add optional fallback channels.
Ship a silence contract
Choose a question that requires callers to retrieve information, write its timer origin and reset rules, and run the synthetic race schedules before changing live waits. Verify the prompt wording against the fallback routes that exist today.
Keep the result tied to observable behavior and task status. Use the regression testing guide to preserve the schedules, and review real caller interaction only through the deployment's consented, governed evidence process.
