Skip to content

fix(mobile): start iOS dictation after native gesture begin - #2592

Merged
DoodleBears merged 1 commit into
mainfrom
codex/2591-ios-dictation-start
Oct 22, 2026
Merged

DoodleBears merged 1 commit into
mainfrom
codex/2591-ios-dictation-start

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Closes #2591 · Agent claim · Follow-up to #2576

Why the change

iOS dictation taps and holds can reach the release callback without starting speech because the manual gesture requests activation before the native handler has begun.

Special things to note

  • Merge risk: two-way door — revert this commit; small blast radius — iOS dictation touch activation only, with missed starts or premature activation as the main risks. Review event ordering, single-touch rejection, repeated taps and interruption cleanup.
  • JavaScript-only change; no dependency, native configuration, permission or speech-backend changes. Current main inherits newer native inputs, so the unified runner must qualify its combined batch and binary independently. Android stays unchanged.
  • Human authorized merge after green CI and before unified native retest. All applicable CI39760447467 checks passed; merged on 2026-10-22 as 419a72578be52f7e4333c27b2c0f6fcb76908f2b. Batch54 proves missing onStart on actual taps/holds, not the earlier immediate native-stop report; recording lifecycle, real microphone and VoiceOver remain unaccepted.

Change outline

Batch56 — native startup reached; recording still fails

Latest native follow-up on candidate 914bfa57ed048 containing merged #2595, not a rerun of the earlier gesture-only heads. iOS 27 Simulator, English, signed Debug binary 55de08577ac5, strict native fingerprint b3e74315f0c2; full identities and image hashes are in the provenance report.

actual center / edge tap → native Button → available + permission granted
  → native start / audiostart
  → audio-capture after 21 / 22 ms → end at 30 / 31 ms from call:start
  → failure notice; no app stop or abort

FAIL: sustained recording. The centered button now reaches speech startup, but the native task ends immediately; root cause remains undetermined. An uninstrumented real tap reaches the same failure UI. Valid v2 observations stayed current and fully restored. Initial Batch56 traces from the withdrawn v1 observer were contaminated by Hermes eval loop-closure binding and are excluded. No Simulator-wide limitation is inferred from the remaining failure.

Actual candidate failure — light, large, 402 × 874, software keyboard absent. The microphone is centered. This is not a successful Listening state or a matched failure-state Before/After pair; the earlier Batch55 baseline above/below retains its own source, fixture and missing-start result.

Batch56 actual recording failure after startup; centered native microphone

Scoped interaction result: a synthetic three-line draft survived expand/done, attachment-tray open/close and six theme/text-size changes, then was sent once with exact canonical Host text and a real direct DeepSeek reply 42. The software keyboard did not appear, so keyboard avoidance is UNTESTED. Later draft lines are visible in the larger-text fields; full editing, caret and scroll acceptance is not inferred.

Batch56 synthetic multiline draft sent once; real reply 42

Six candidate draft captures — keyboard absent; no matched Batch56 Before matrix

Light: large, accessibility-large, accessibility-extra-extra-extra-large, respectively.

Candidate light large draft; keyboard absent Candidate light accessibility-large draft; keyboard absent Candidate light maximum accessibility text draft; keyboard absent

Dark: the same three OS text sizes, respectively.

Candidate dark large draft; keyboard absent Candidate dark accessibility-large draft; keyboard absent Candidate dark maximum accessibility text draft; keyboard absent

Still unaccepted: stable Listening, second-tap Stop, explicit Cancel, recording interruption/retry, keyboard clearance, full matched Before/After, physical microphone, VoiceOver and Android. The bounded exact-app-PID native log read parsed 1003 records but yielded no allowlisted error facts; that does not locate the native cause. New source repairs, if required, need their own branch/PR and a new owner-cut test batch. No product source change or new merge/release authorization is implied by this evidence update.

Evidence follow-up: t3code/local/mcp:dbfb1c61-ea88-4449-82fe-bce3ae129811, successor claim. Earlier Batch54/55 reports below remain historical and retain their stated limits.

 iOS native Manual gesture
   touch-down → validate one touch, record origin/time
-  touch-down → activate while UNDETERMINED → native request ignored
+  BEGAN → activate the same handler → onStart → existing speech owner
   release / drag / interruption → existing stop, lock or cancel logic

The regression harness now reproduces the pinned RNGH 3.3 iOS ordering: touch-down precedes BEGAN, and early activation is ignored. The old implementation failed eight interaction assertions with zero starts; the repair passes all 47 focused composer/dictation tests. Mobile typecheck, repository lint (existing unrelated warnings), touched-file formatting and iOS Babel transformation of nine worklets pass. No production diagnostic instrumentation is included.

Native evidence pending: the exclusive shared runner is completing frozen Batch54. Merged main containing this repair is submitted for a new owner-cut batch, with real taps/holds and bounded callback/native-event counts before any success claim. Review path: empty composer → tap Dictate → observe onStart, availability/permission and native start/audio events → tap stop; repeat hold/release, left cancel, up lock and interruption. Capture real before/after recording states and report native error code/domain without transcript/audio. Existing #2576 composer screenshots do not prove this repair works.

The single activation transition is fully shown above; a separate HTML explainer is omitted.

Task: codex/local/01a1621c-a81b-7670-86be-1ddaf404c2e2.

Batch55 update — recording startup still fails

This result supersedes the earlier pending-retest status: native Batch55 on source 87724a3b58d5 (including #2592) still produced only onHeld/finalize on real short tap and 800ms hold, with no onStart, availability/permission calls or native speech events. The observer stayed installed/current, the loaded Hermes code contains #2592, and both observers were stopped/restored. Historical immediate-end remains a separate unlocated symptom; no successful recording state is claimed.

The Human also reported the offset/clipped microphone. Merged repair #2595, issue #2594, replaces the iOS manual gesture with a centered native SwiftUI button (tap start / tap stop, explicit cancel). Its Batch56 native result is recorded above; sustained recording remains unaccepted.

Actual failure state — light, large text, 402 × 874 pt, keyboard hidden; Debug strict fingerprint b3e74315f0c2, final signed executable 55de08577ac5. This image is a failure baseline, not an After-success comparison. Provenance.

Batch55 failure: microphone remains idle and clipped after actual tap and hold

RNGH 3.3 ignores activation while UNDETERMINED; iOS manual touch-down precedes BEGAN. Activate from onBegin and make the regression harness honor that ordering.

Issue: #2591
Agent-Task: codex/local/01a1621c-a81b-7670-86be-1ddaf404c2e2
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 26 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4dac47d2-cddc-4f7c-9e1a-85394fc14b45
📥 Commits

Reviewing files that changed from the base of the PR and between c9e7ae6 and 9793d55.

📒 Files selected for processing: 3
  • apps/mobile/src/ui/chat/voice-button.ios.tsx
  • apps/mobile/test/voice-button-ios.test.tsx
  • changes/2591-ios-dictation-start.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DoodleBears
DoodleBears marked this pull request as ready for review October 22, 2026 10:10
@DoodleBears
DoodleBears merged commit 419a725 into main Oct 22, 2026
10 checks passed
@DoodleBears

Copy link
Copy Markdown
Contributor Author

Batch55 native recheck: FAIL on frozen acceptance candidate 87724a3b58d556807ef1ba860adcbb96bda6d92f, which contains #2592.

Existing iOS27 Simulator, fresh candidate Debug native build; strict fingerprint b3e74315f0c2d639dd1c1ff73e56182e0fb86c0e, signed executable SHA-256 55de08577ac5ddb38fb0221427750b8d5096dfe10b55a1561bb438c3bf95807a. Actual loaded Hermes VoiceButton definition contains onBegin, activate, and handlerTag; this is not a source-only check.

Real short tap and800ms long press on the empty-chat microphone each produced onHeld, with zero onStart. The callback observer remained installed/current for both. Concurrent bounded native probe saw no availability/permission/start/audio/error/end calls. Both observers were explicitly stopped and restored; no audio/transcription/secrets captured.

Stop/cancel/lock/interruption and the historical immediate-stop symptom remain untested because this path never starts. This does not validate the repair or release candidate. Source composer owner retains the fix; no product source edits in the QA batch. Private local evidence index: .humanlayer/tasks/qa-batch55/recording-result.md (not a public screenshot link). Matched public evidence follows after review. Independent Batch55 acceptance is still active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mobile): activate iOS dictation after the manual gesture begins

1 participant