Repository navigation
fix(ios): classify the keyboard dismiss refusal by what it dispatched - #4536
Conversation
`keyboard dismiss` refused two different things with one untyped message, so a caller had to match prose to tell them apart. A keyboard that exposes no dismiss key and a dismiss control that was tapped and left the keys up are different verdicts: the first sent nothing, the second dispatched. The runner now answers the no-dismiss-key refusal with its own wire code, KEYBOARD_DISMISS_UNAVAILABLE, declared in RunnerWireErrorCode and classified by the existing runner-code table. It keeps the code the command already refused with, UNSUPPORTED_OPERATION, through a wireCode row, so the published code contract is unchanged, and it gains details.reason keyboard_dismiss_unavailable with dispatched: no. dismissKeyboard answers a RunnerKeyboardDismissOutcome carrying dismissControlFound, which also decides which of the two verdicts a tvOS keyboard stayed up for. Help, the runner protocol, and the command docs state which refusal sends nothing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
All reported issues were addressed across 14 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
I reviewed b46ac6d. The change has no live device run yet, and it rewrites the iOS keyboard dismiss dispatch path, so it needs one before merge. The PR changes the return type of The two inline threads on the help text in Not blocking, and you can take or leave these: I read the code only and did not run xcodebuild, vitest or the CLI. The Coverage failed, and I could not tell from the log whether this diff causes it. The diff touches code that the coverage run executes, so please check that job. Smoke Tests, Smoke Tests (ios) and Smoke Tests (macos) were still running. The iOS and macOS lanes build the runner this PR changes, so a failure there would relate to it. No conflicts were reported. Before merge, please add the live simulator evidence above and get Smoke Tests (ios and macos) and Coverage green at the head. |
Apex Sentinel · ✅ ApproveSince the last review: 0 new · 0 still open · 1 no longer raised No open findings. 1 finding below 💬 Talking to SentinelIn a finding's thread, reply with:
On this conversation, comment Earlier reviewsReview of
|
| Where | Finding |
|---|---|
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift:222 |
🆕 tvOS dispatchedDismissal contradicts its own comment and can report the nothing-was-sent code |
1 finding below minor hidden (user_settings.min_severity).
Reviewed with this repository's own Sentinel configuration (ddbfc855661f).
Review of 579ad97b · 13.11.2026 23:55 UTC
Apex Sentinel · ✅ Approve
No open findings.
1 finding below minor hidden (user_settings.min_severity).
Reviewed with this repository's own Sentinel configuration (ddbfc855661f).
…code map Rename the dismiss outcome flag to dispatchedDismissal, since it also covers the tvOS Menu press. Move the keyboard-dismiss wire-code rename out of the diagnostic-only list into its own map, and name the iOS reason in the workflow help. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Thanks for the review. I pushed Recommendations applied:
Live evidence at
The commands and the JSON are in the new "Live simulator evidence" section of the PR body. Coverage passed on The new head needs its own CI run, including Smoke Tests (ios and macos). |
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
Apex Sentinel: 1 new finding on c742a00. The verdict and the full list are in the summary comment.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Final head is The live simulator evidence in the PR body was recorded at
|
|
This PR is ready at a0c5aec. I found no problems in the code, and all 22 checks pass, including the iOS and macOS smoke tests that build the runner this diff changes and the coverage check. Not blocking: the only Swift test calls The live runs in the PR body were recorded at 306352c, not the final head. From the diff, the two later commits touch only Of the earlier review threads, none still applies. These are fixed at this head, so please resolve them: #4536 (comment) (help wording, both platforms), #4536 (comment) (tapped-key outcome), #4536 (comment) (keyboard occlusion wording) and #4536 (comment) (tvOS dispatch flag). This one is benign, because nothing in the line is false and the command help lists both outcomes: #4536 (comment). Nothing else must happen before merge. |
* origin/main: fix(android): carry an empty text on a node labelled by its content description (#4531) fix(ios): restore the back swipe's pre-swipe still span (#4515) fix(daemon-client): type the remote daemon refusal with its dispatch fact (#4532) fix: prepare reinstall artifacts before removing apps (#4533) fix(ios): classify the keyboard dismiss refusal by what it dispatched (#4536) fix(ios): press the navigation bar back button and speed up the back swipe (#4508) refactor(gestures): one owner for the densified gesture path; drop the unproven sendevent transport (#4239) fix(host-kit): keep Linux process identity stable across clock steps (#4438) fix(ios): bound the idle wait of keyboard dismiss and keyboard enter (#4454) fix(device-selection): fail an ambiguous device request with only the tied devices (#4506)
Summary
keyboard dismissrefused two different verdicts with one untyped message, so a caller had to match prose to tell them apart: a keyboard that exposes no dismiss control (nothing was sent) and a dismiss control that was tapped and left the keys up (it dispatched). The refusal behavior is unchanged; only its classification becomes typed.The runner answers the no-dismiss-key case with its own wire code
KEYBOARD_DISMISS_UNAVAILABLE, classified by the existing runner-code table. The published code contract is unchanged — it still travels underUNSUPPORTED_OPERATIONthrough its own wire-code map — and the failure now carriesdetails.reason: keyboard_dismiss_unavailable,details.runnerErrorCode, anddispatched: no, all visible in--json.dismissKeyboardanswers aRunnerKeyboardDismissOutcomecarryingdispatchedDismissal, which also decides which verdict a tvOS keyboard stayed up for.14 files: Swift runner + protocol doc, the Apple runner classification and its tests, the dispatch-disclosure fixture, command help, and the command docs. No scope expansion beyond keyboard dismiss; no CHANGELOG.
Live simulator evidence
Head
306352ce2a. iPhone 17, iOS 27.0, UDID0E0FCBDC-88E2-4CB6-A1DA-E148F77743F4, Xcode 27.1 (27A9275). Runner rebuilt from this branch withpnpm build && pnpm build:xcuitest; fresh state dir, so a new daemon.No dismiss control — Agent Device Tester, Form tab, Full name field, software keyboard up with no Done/Hide key:
A screenshot taken right after shows the full QWERTY keyboard still visible, and
snapshot -istill lists the key nodes.With dismiss control — Safari,
https://the-internet.herokuapp.com/login, Password field, accessory bar with Previous/Next/Done:snapshot -iafterwards no longer lists the Previous/Next/Done toolbar.Cleanup:
close --shutdown,daemon stop --clean --state-dir /private/tmp/ad-4536-state.Validation
Base
ddbfc85566, functional headb46ac6d761;3231d4448cand579ad97b28are doc/help-sentence follow-ups on review;306352ce2aapplies the review recommendations (flag rename, separate wire-code map, help sentence).pnpm check:affected --run --head b46ac6d76170efc6867e22acb773d0f57afd2c14— all runnable checks passed,exactCommit=true(format, lint, typecheck, layering, fallow, native-dupes, build, vitest-related, unit, command-docs, docs-links, docs-prose, xctest-selection, packaged-runner-swift).3231d4448cand579ad97b28touch only thekeyboardhelp sentence and its docs counterpart. For those:cli-help-command-usage.test.ts,cli-help-topics.test.ts,command-doc-coverage.test.ts,check:doc-prose, and the MCP-metadata check pass locally; the serialized gate for the head is owned by CI.pnpm build:xcuitest(iOS + macOS) succeeded;pnpm check:xctest-selectionreports the new Swift test reachable from the host lane.306352ce2a: focused vitest (runner-error-classification, runner-contract-response, index-dispatch-disclosure,src/commands/schema, help-conformance),pnpm check:xctest-selection,pnpm build && pnpm build:xcuitestpass.579ad97.detailsshape, and new optional keys inside the opendetailsrecord are already declared additive in the wire-compat ledger, so no ledger entry was added.🤖 Generated with Claude Code