The direct answer
Retire the application’s voice-input attempt before accepting any later stream result, and keep that result associated with its original attempt. Review cleanup of every owned returned track separately from browser permission, physical-device activity and data already obtained; closing a view does not establish that a pending permission request was cancelled.
A closed voice panel can leave an unresolved request
A fictional console lets a user start a short spoken maintenance note. The user opens its voice panel, then closes it before answering the browser’s microphone prompt. Later, the user grants access while a different console view is visible. Which attempt may receive the resulting stream?
MDN documents getUserMedia() as returning a promise for a media stream. It can remain neither resolved nor rejected if the user ignores the permission request. The API requires a secure context; actual browser support still needs review. Neither a hidden panel nor an application label supplies evidence that the browser request settled.
This worksheet selects a deliberate microphone-only request in a trusted top-level console, with no recording, transcription, transmission, camera, embedded frame or automatic reacquisition. All eight cards are PROPOSED_UNRUN; no microphone, permission prompt or stream was exercised.
Keep attempt retirement separate from acquisition outcome
Use invented labels M-A for the request attempt and V-A for its initiating voice panel. Trusted application setup owns their association and current authorization. Record application eligibility as active or retired, independently of acquisition outcome: unresolved, rejected or stream returned. A retired attempt can still have an unresolved outcome; do not collapse those fields into a green “microphone off” status.
For the proposed controller, closing the panel first retires M-A and prevents new adapter admission under it. A later completion must consult that original record before any attachment to a view or consumer. If it belongs to retired M-A, it goes to the supported owned-resource cleanup path, not to the newest panel. A new M-B is a separate deliberate request, never a label substituted onto M-A.
This is an application design obligation, not browser-provided cancellation. Actual coordination across close, completion and attachment remains unimplemented here. Unknown ownership or ordering blocks the positive; the worksheet proves no race-free controller or capture deadline.
Review all returned tracks under a stable ownership boundary
The selected request documentation says audio and video constraints choose required or excluded media types. The proposed plan requests audio and excludes video. That does not establish our stricter application expectation of exactly one audio track or the ownership of every returned reference.
getTracks() returns all track objects in a stream regardless of kind. Review the whole returned inventory, not only a convenient first entry. The controller must retain control of the owned references until admission or cleanup is complete.
This profile excludes sharing those track objects with another component, cloning or transferring references, and modifying the stream’s track inventory during the decision. These are separately verified prerequisites, not guarantees supplied by enumeration. The declared sources establish no future-inventory coverage from one returned array. Unknown mutation or handle sharing leaves cleanup coverage unresolved; do not claim an application-wide capture stop.
Use the documented stop result without expanding its meaning
MDN’s track.stop() reference documents no return value. It sets that track’s readyState to ended immediately; the ended event does not fire for this path. A cleanup design must not wait for that event as its sole acknowledgement.
The same reference explains that the track is disassociated from its source, while other tracks may still use that source. Stopping this track therefore does not establish immediate physical microphone shutdown. The source is distinct from the application-owned track references.
For the proposed retirement path, apply supported stop handling to every owned returned track and release the controller’s attachment/reference associations under a reviewed lifecycle. Track state alone does not establish permission revocation, erasure or recall of data already acquired. Acquisition may have happened before the application handles a late result; withholding adapter admission is not proof that no audio was captured.
Walk eight inert voice-input cards
| Card | Proposed condition | Decision and evidence limit |
|---|---|---|
| 1. Ordinary current note | M-A/V-A active; intended single audio track and all prerequisites established. | Conditionally admit only the owned local input association, not a model request. |
| 2. Unanswered prompt | Panel closes while acquisition remains unresolved. | Retire M-A locally; keep browser-request outcome unresolved. |
| 3. Late stream | Retired M-A later returns a stream. | No adapter attachment; clean up every owned returned track through the supported path. |
| 4. New panel exists | M-B/V-B is current when old M-A resolves. | Never relabel or route the older acquisition into M-B. |
| 5. Inventory mismatch | Unexpected track, mutation or unclear reference ownership. | Withhold admission; supported owned-track cleanup is distinct from unresolved coverage. |
| 6. Event-only cleanup | Controller waits exclusively for ended after calling stop. | Reject that completion rule; use the documented stop-path state contract. |
| 7. Source still shared | Another independent track may use the microphone source. | Report only local track disposition, not universal device shutdown. |
| 8. Rejection or unknown | Permission fails, support is unknown, or adapter/cleanup association is unverified. | No automatic fallback or reacquisition; preserve the specific unresolved boundary. |
Keep a useful positive and an honest stopped status
The ordinary positive is one user deliberately opening a current voice panel to dictate a maintenance note. Only after actual browser support, exclusive handle ownership, stable inventory, attempt coordination, a bounded trusted adapter and current rights are independently established could that stream become eligible for local input. None of those prerequisites is implemented or verified here.
Capture permission is not permission to transmit audio or retain a transcript. The separate data-minimization guide governs the later payload decision. Keep status precise: local input retired, acquisition unresolved, or owned tracks stopped with device-source activity unknown. Avoid logging audio or complete device details to explain a failure.
No browser, DOM, audio fixture, timer, API or model experiment occurred. Boundary remains prelaunch with planned request-path checks; this article describes no shipped microphone lifecycle controller, recording feature or voice-transmission guard.
Primary sources
Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.