Skip to content

fix: prevent Voice Wake crash after Talk audio capture#99137

Merged
steipete merged 4 commits into
openclaw:mainfrom
PollyBot13:fix-ios-voicewake-audio-restart-race
Jul 2, 2026
Merged

fix: prevent Voice Wake crash after Talk audio capture#99137
steipete merged 4 commits into
openclaw:mainfrom
PollyBot13:fix-ios-voicewake-audio-restart-race

Conversation

@PollyBot13

@PollyBot13 PollyBot13 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Related: #99093

What Problem This Solves

Fixes an issue where iOS users with Voice Wake enabled could hit a foreground crash after using Talk or other microphone capture, including screen recording with microphone enabled. The observed crashes abort while Voice Wake is reinstalling its microphone tap after another audio path releases capture.

Why This Change Was Made

Voice Wake restarts now go through one scheduled-start path that cancels stale pending starts, prevents overlapping start() attempts, and debounces restarts after external audio capture. External-capture suspension now covers listening, queued, and already in-flight starts so push-to-talk, camera/audio capture, backgrounding, and Talk teardown cannot leave a start racing toward installTap.

Talk suppression tears down Voice Wake without marking it as externally suspended, so the existing Talk enable/disable caller sequence can restart Voice Wake normally when Talk is disabled. The manager also rechecks suppression/enabled/external-suspension state before rebuilding the AVAudioEngine pipeline and rejects invalid microphone input formats before installing a tap.

This is intentionally limited to the Voice Wake restart/audio-tap lifecycle; it does not change Talk routing, push, share extension, widget, or watch behavior.

User Impact

Voice Wake should resume more reliably after Talk, push-to-talk, camera/audio capture, foregrounding, and screen-recording-adjacent audio-session changes instead of racing into a duplicate or invalid mic tap install.

Evidence

AI-assisted: yes (Codex)

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 2, 2026, 1:46 PM ET / 17:46 UTC.

Summary
This PR updates iOS VoiceWakeManager to serialize and debounce starts, suspend queued and in-flight starts during external audio capture, validate microphone formats before tap install, and adds focused suppression regression tests plus native i18n metadata.

PR surface: Other +149. Total +149 across 3 files.

Reproducibility: no. high-confidence standalone reproduction path was established in this read-only review; the linked issue provides physical iPhone crash logs and before-fix context, and current main still matches the failing restart/tap-install source path.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #99093
Summary: This PR is the candidate fix for the canonical iOS Voice Wake mic tap crash report; the nearby native WebRTC Talk PR is adjacent context from the same proof area but solves a different routing problem.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] This patch changes a crash-prone iOS microphone lifecycle path that CI cannot fully simulate; the linked physical-device smoke is positive but not a full stress matrix across Talk, PTT, camera clips, backgrounding, and screen recording.
  • [P1] The new availability behavior intentionally pauses Voice Wake while external audio owns or races the microphone, so maintainers should land it as a targeted crash mitigation with the linked issue as follow-through context.

Maintainer options:

  1. Land with crash-fix context (recommended)
    Accept the residual physical-device coverage risk and land the focused Voice Wake scheduling fix with the linked crash issue as the canonical follow-up target.
  2. Request broader hardware stress proof
    If maintainers want extra assurance before merge, ask for one more physical-device pass covering PTT, camera clip audio, background/foreground, and Talk teardown with Voice Wake enabled.

Next step before merge

  • No ClawSweeper repair is queued; the remaining action is maintainer review and landing decision for a focused crash fix with sufficient proof.

Security
Cleared: No concrete security or supply-chain regression was found; the diff is limited to iOS Swift runtime logic, a Swift test file, and generated native i18n metadata.

Review details

Best possible solution:

Land this focused VoiceWakeManager lifecycle hardening after maintainer review, keeping the linked crash issue open until this PR or an equivalent fix merges.

Do we have a high-confidence way to reproduce the issue?

No high-confidence standalone reproduction path was established in this read-only review; the linked issue provides physical iPhone crash logs and before-fix context, and current main still matches the failing restart/tap-install source path.

Is this the best way to solve the issue?

Yes: after the follow-up commit, the PR fixes the issue at the VoiceWakeManager lifecycle boundary, covers pending and in-flight starts, leaves Talk routing unchanged, and adds focused regression coverage.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 55ed57a4e39b.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
  • add proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (recording): The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P1: The PR addresses a foreground iOS app crash during real Voice Wake plus Talk or external microphone workflows.
  • merge-risk: 🚨 availability: Merging changes Voice Wake's microphone restart scheduling and suspension behavior in an app-crashing AVAudioEngine lifecycle path that green CI cannot fully exercise on physical hardware.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (recording): The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
  • proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The PR now has sufficient real behavior proof: a linked physical iPhone recording/contact sheet was hash-verified, and the contact sheet shows the patched Talk and Voice Wake flow completing without a visible crash.
Evidence reviewed

PR surface:

Other +149. Total +149 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 3 168 19 +149
Total 3 168 19 +149

What I checked:

  • Root policy read: Root AGENTS.md was read fully and its PR review requirements drove the caller/callee, proof, sibling-surface, and history checks. (AGENTS.md:1, 55ed57a4e39b)
  • Scoped iOS policy read: apps/ios/AGENTS.md was read fully; it is release-upload focused and did not add a Voice Wake code constraint beyond root policy. (apps/ios/AGENTS.md:1, 55ed57a4e39b)
  • Current-main crash path: Current main still starts Voice Wake directly from Talk unsuppression and external-audio resume paths, then installs the AVAudioEngine input tap without the PR's scheduling and suspension guards. (apps/ios/Sources/Voice/VoiceWakeManager.swift:146, 55ed57a4e39b)
  • Talk caller path: NodeAppModel still calls setSuppressedByTalk(false) and resumeAfterExternalAudioCapture when Talk is disabled, matching the duplicate restart concern in the linked issue. (apps/ios/Sources/Model/NodeAppModel.swift:673, 55ed57a4e39b)
  • PR start/suspension fix: On PR head, scheduleStart/cancelScheduledStart funnel restarts, start() rejects external suspension, and suspendForExternalAudioCapture now treats listening, starting, or pending starts as suspendable before resume schedules a delayed restart. (apps/ios/Sources/Voice/VoiceWakeManager.swift:178, c9f532bffaee)
  • Regression coverage: The added tests cover canceled pending starts, external audio resuming pending starts, in-flight start suspension, and Talk suppression not leaving Voice Wake externally suspended. (apps/ios/Tests/VoiceWakeManagerSuppressionTests.swift:21, c9f532bffaee)

Likely related people:

  • steipete: Git history and GitHub commit metadata show steipete introduced the iOS app scaffold containing VoiceWakeManager and later touched Talk/camera audio paths and Voice Wake stabilization. (role: historical Voice Wake and iOS audio-flow contributor; confidence: high; commits: 6d6c3ad2c45d, 3863fe641245, 20d7882033a0; files: apps/ios/Sources/Voice/VoiceWakeManager.swift, apps/ios/Sources/Model/NodeAppModel.swift)
  • mbelinky: History shows mbelinky carried substantial iOS NodeAppModel/VoiceWakeManager work and added the push-to-talk Voice Wake suspension path that shares this invariant. (role: adjacent external-audio suspension contributor; confidence: medium; commits: 6aedc54bd733, 17b18971f17c, 1a48bce2947e; files: apps/ios/Sources/Voice/VoiceWakeManager.swift, apps/ios/Sources/Model/NodeAppModel.swift)
  • sahilsatralkar: Current-line blame for the implicated VoiceWakeManager and NodeAppModel lines maps to a recent broad iOS cleanup commit, so this is useful routing context but weaker feature ownership evidence. (role: recent current-main toucher; confidence: low; commits: 574604e3dae6; files: apps/ios/Sources/Voice/VoiceWakeManager.swift, apps/ios/Sources/Model/NodeAppModel.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 2, 2026
@PollyBot13

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed the prior findings in c9f532b:

  • external audio suspension now covers queued and in-flight Voice Wake starts
  • added focused regression coverage for in-flight external capture and Talk suppression toggling
  • linked the patched iPhone stability video/contact sheet in the PR body
  • regenerated native i18n metadata; native-i18n is green on CI

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 2, 2026
@steipete steipete self-assigned this Jul 2, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: telegram Channel integration: telegram app: android App: android gateway Gateway runtime scripts Repository scripts commands Command implementations agents Agent runtime and tooling channel: feishu Channel integration: feishu extensions: google size: XL and removed size: S labels Jul 2, 2026
@steipete
steipete requested a review from a team as a code owner July 2, 2026 20:56
@steipete
steipete force-pushed the fix-ios-voicewake-audio-restart-race branch from f751286 to 520aa10 Compare July 2, 2026 21:13
@openclaw-barnacle openclaw-barnacle Bot added size: M and removed docs Improvements or additions to documentation channel: telegram Channel integration: telegram app: android App: android gateway Gateway runtime scripts Repository scripts commands Command implementations agents Agent runtime and tooling channel: feishu Channel integration: feishu extensions: google size: XL labels Jul 2, 2026
@steipete

steipete commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Maintainer fixup complete and land-ready at rebased exact head 933a88cdc66dc407bb2d246a9d14e34c834da7dc.

  • Serialized every Voice Wake start through one cancelable scheduled-start path; external microphone owners now suspend pending and permission-in-flight starts before capture changes.
  • Added failed-start tap, request, engine, and shared-audio-session cleanup plus invalid-input-format rejection.
  • Before: physical iPhone reproduction captured the microphone-tap crash during Voice Wake/Talk/screen-recording interaction. After: the same interaction ran 69.48 seconds without a crash; the PR links both artifacts.
  • iPhone 17 Pro / iOS 26.5 simulator: 7 focused lifecycle tests passed in 0.331s. UI E2E passed Voice Wake → Talk on → Talk off → Diagnostics and asserted the exact resumed Voice Wake isn’t supported on Simulator state.
  • Changed SwiftFormat and strict SwiftLint clean; native i18n synchronized.
  • Fresh Codex autoreview: no accepted or actionable findings.
  • Repository merge guard: exact-head hosted CI/Testbox gates passed, including iOS build, macOS Swift, lint, native i18n, build artifacts, and QA smoke.

Simulator microphone capture is intentionally unavailable; the physical-iPhone run remains the authoritative AVAudioNode after-proof.

@steipete
steipete force-pushed the fix-ios-voicewake-audio-restart-race branch from 520aa10 to 933a88c Compare July 2, 2026 21:29
@steipete
steipete merged commit 2f707f9 into openclaw:main Jul 2, 2026
72 checks passed
@steipete

steipete commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 3, 2026
* fix: prevent Voice Wake audio restart race

* fix: handle in-flight Voice Wake suspension

* test(ios): harden Voice Wake lifecycle proof

* fix(ios): remove Voice Wake tap after failed start

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: ios App: ios merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants