Skip to content

fix(ios): recognize and answer the localized Open in launch confirmation - #4160

Open
thymikee wants to merge 7 commits into
mainfrom
maint/3922-localized-open-in-confirmation
Open

thymikee wants to merge 7 commits into
mainfrom
maint/3922-localized-open-in-confirmation

Conversation

@thymikee

@thymikee thymikee commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes #3922. On a non-English iOS simulator, the Open in "<App>"? confirmation raised by open --launch-url stayed alert-unrecognized, and alert accept refused Ouvrir with ALERT_BUTTON_NOT_FOUND. This extends #4006's mechanism to that prompt. No new flag or command.

  • SpringBoard's strings live in CoreServices.framework, table SchemeApproval. The runner already reads that framework's simulated-OS root, so the table is readable. It holds the title format (SCHEME_APPROVAL_PROMPT_TITLE_NO_SOURCE) and the open and cancel labels.
  • The table joins the vocabulary tables of fix(ios): match alert labels through the OS prompt strings of the preferred languages #4006. Ouvrir and Annuler now translate Open and Cancel in every preferred language, so alert accept and alert dismiss answer the prompt. Matching stays exact and fix(ios): alert dismiss picks a listed decline, never a guessed one #3715's rule holds: no guessed label.
  • New RunnerLaunchConfirmationPrompt recognizes the prompt from the OS's own title format and both buttons of one language. The runner sets launchConfirmationPrompt: true on that alert read, and open accepts a marked prompt. This replaces the TypeScript English title and button match. Unreadable strings recognize nothing, so the prompt stays alert-unrecognized.
  • A shared RunnerSystemPromptStrings reader serves both consumers.

Behavior to know: alert get now also prints launchConfirmationPrompt: true for this prompt, because the runner payload passes through. It is documented in the alert section of commands.md. Say so if you want it stripped.

Tests

  • Swift (UnitTests/RunnerTests+LaunchConfirmationPromptTests.swift), run on the iPhone 17e simulator:
    • pure wordings (English, French, Japanese) are recognized, with negatives for foreign buttons, mixed languages, and extra buttons;
    • OS strings for fr-FR and ja-JP recognize the prompt, and accept picks Ouvrir and 開く while dismiss picks Annuler; German is not recognized, because it is not a preferred language;
    • English stays recognized and accepted.
  • Before the fix (table removed), the same test fails: accept returns nil for ["Annuler", "Ouvrir"].
  • TypeScript: French and Japanese marked prompts are accepted. Before the fix, the same two cases fail. An unmarked launch-like alert stays unrecognized.

Live check (iPhone 17e, F25C7515, iOS 27.0)

French set per simulator (AppleLanguages ("fr"), AppleLocale fr_FR) and rebooted, with a copy of the test app that has a fresh URL scheme (the lab app's schemes were already approved):

  • open <app> --launch-url adt3922fr://x --relaunch returned launchConfirmation: "accepted".
  • With xcrun simctl openurl raising the prompt again, alert get returned message: "Ouvrir dans « Agent Device Tester » ?", items: ["Ouvrir", "Annuler"], launchConfirmationPrompt: true. alert accept returned accepted, and the next alert get found no alert.
  • The language was restored to the original en-US, pl-US, es-PL, zh-Hans-PL, fi-PL and en_US@rg=plzzzz, the test copy was uninstalled, the session was closed, and the simulator was shut down.

iOS and macOS runner builds pass. check:xctest-selection and check:packaged-runner-swift pass.

Validation

pnpm check:affected --run --head 9435060405 (exactCommit=true, run-wZWELW): every stage passed, including unit, xctest-selection, and packaged-runner-swift. Earlier runs failed only on host-load timeouts (load average above 200) in unrelated tests, which pass alone.

Review round 3 (Finnish %[tt]@, SpringBoard-only mark, missing-table test) is covered by new simulator tests: one loads every installed SchemeApproval localization and checks each rendered title is recognized, one covers the missing-table branch, and one checks an app-owned alert with identical text is not marked. Before the fix, the Finnish, every-localization, and app-owned cases fail.

Live on the iPhone 17e with fresh unapproved schemes, French and Finnish: open --launch-url returned launchConfirmation: "accepted", alert get returned launchConfirmationPrompt: true (Ouvrir dans « Agent Device Tester » ? with Ouvrir/Annuler; Avataanko Agent Device Tester-apissa? with Avaa/Kumoa), and alert accept answered it. The language list was restored afterwards.

CI owns the rest.

Risks: the string-table location is undocumented, as in #4006. A runner older than this change does not set launchConfirmation, so open reports its prompt as unrecognized until the runner is rebuilt.

🤖 Generated with Claude Code

On a non-English iOS simulator, the `Open in "<App>"?` confirmation that
`open --launch-url` raises stayed unrecognized (`alert-unrecognized`), and
`alert accept` refused its button (`Ouvrir`) with ALERT_BUTTON_NOT_FOUND.

The runner now reads SpringBoard's own SchemeApproval strings
(CoreServices.framework) with the strings it already reads for permission
prompts. Their open and cancel labels join the alert vocabulary, so
`alert accept` and `dismiss` answer the prompt in each preferred language.
The runner also marks an alert read as the launch confirmation when its title
and both buttons are the OS's wording of one language, and `open` accepts a
marked prompt instead of matching English text. Unreadable strings recognize
nothing, as before.

Fixes #3922

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agent-device-website Ready Ready Preview Nov 2, 2026 12:44pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 13 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.69 MB 5.67 MB -16.5 kB
Package (unpacked) 5.69 MB 5.67 MB -16.5 kB
Package (download) 1.73 MB 1.73 MB -6.5 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 25.0 ms 25.0 ms +0.0 ms
CLI --help 52.8 ms 53.1 ms +0.3 ms

@apex-sentinel-staging

apex-sentinel-staging Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Apex Sentinel

Verdict: approve

Since the last review: 4 new · 4 still open · 4 no longer raised

8 finding(s): 3 minor, 5 nit. Verdict: approve.

🟡 Minor (3)

Where Finding
packages/platform-apple/src/launch-confirmation.ts:185 Recognition moved entirely into the runner: any reader that does not set launchConfirmationPrompt now recognizes nothing, where the host used to match English itself
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertLabelVocabulary.swift:52 A failed permission read discards the launch-confirmation labels it was read independently for
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift:140 🆕 Only the handleAlert read branch marks the prompt; the awaitAlert/probe read paths publish no mark
🔵 Nit (5)
Where Finding
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemPromptStrings.swift:18 🆕 /// The only keys … comment sits under the promptTables doc block on launchConfirmationLabelKeys
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertLabelVocabulary.swift:41 SchemeApproval is read twice and the unavailable log marker was renamed
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:17 Constant regex compiled with try? silently disables recognition if it ever fails
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemPromptStrings.swift:28 🆕 read takes a table list but throws away every table that did read on the first failure
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift:140 🆕 The launch-confirmation matcher is initialized lazily on the alert-read path and can be built twice

Reply under an inline comment with @apex-sentinel-staging note ... or @apex-sentinel-staging pivot ... to re-check that finding.
Comment @apex-sentinel-staging review on this conversation to run a full review.

Earlier reviews

Review of f862d9ef · 02.11.2026 12:14 UTC

Apex Sentinel

Verdict: approve

Since the last review: 5 new · 3 still open · 5 no longer raised

8 finding(s): 3 minor, 5 nit. Verdict: approve.

🟡 Minor (3)

Where Finding
packages/platform-apple/src/launch-confirmation.ts:191 Launch-confirmation recognition now depends entirely on a runner-side field: older or non-updated runners silently stop answering even the English prompt
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:56 🆕 Localized launch confirmations are recognized only when the Simulator's languages match SchemeApproval's localization names exactly
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:62 🆕 RunnerSystemPromptStrings.read now drops the whole launch-confirmation wording when any one preferred language lacks SchemeApproval.strings
🔵 Nit (5)
Where Finding
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertLabelVocabulary.swift:41 SchemeApproval is read twice and the fallback path drops the launch-confirmation log
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertLabelVocabulary.swift:49 🆕 composed assumes the whole SchemeApproval table contributes only Open/Cancel labels; that invariant is nowhere enforced
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:21 🆕 try! on a regex literal in a new file
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemPromptStrings.swift:58 Runner log marker renamed, and the new subsystems are inline literals
packages/platform-apple/src/launch-confirmation.fixtures.ts:5 🆕 Marking the shared CONFIRMATION fixture inverts negative cases that spread it
Review of 232f6fc6 · time not recorded

Apex Sentinel

Verdict: request_changes

8 finding(s): 1 major, 4 minor, 3 nit. Verdict: request_changes. reached max rounds (1).

Required fixes

  • Adding SchemeApproval to promptTables makes the whole localized alert vocabulary depend on a table only the launch confirmation needs

🟠 Major (1)

Where Finding
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemPromptStrings.swift:10 Adding SchemeApproval to promptTables makes the whole localized alert vocabulary depend on a table only the launch confirmation needs

🟡 Minor (4)

Where Finding
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:19 A title format without %@ silently matches an empty app name
packages/platform-apple/src/launch-confirmation.ts:185 Host-side English recognition removed: an open against a runner built before this PR no longer recognizes any launch confirmation, English included
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift:140 alert get now returns a new undocumented launchConfirmation: true field
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift:448 launchConfirmation is now a boolean in alert get data and a string enum in open data
🔵 Nit (3)
Where Finding
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemPromptStrings.swift:57 One log marker now covers two different failures
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift:14 Duplicated empty recognizer: unavailable and the non-simulator system
apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift:448 New runner payload field reaches alert get undocumented

@apex-sentinel-staging apex-sentinel-staging Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apex Sentinel: 8 new findings on 232f6fc. The verdict and the full list are in the summary comment.

@thymikee

thymikee commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

Reviewed 232f6fc. The fix is incomplete: the Finnish launch confirmation is still not recognized. CI is pending, because Smoke Tests is still running. No conflicts. Before merge, the matcher needs the fix below and the pending pnpm check:affected receipt needs to be posted.

RunnerLaunchConfirmationPrompt.swift:19 escapes the OS title format, then replaces only the literal token %@ with .+. The Finnish SchemeApproval title on iOS 27.0 and 27.1 is "Avataanko %[tt]@-apissa?". It becomes %\[tt\]@ after escaping, the replace misses it, and the regex then requires that literal text, which no real title contains. So recognizes() is always false on a Finnish simulator. There, open --launch-url still reports alert-unrecognized and leaves the prompt up. That contradicts the new help and commands.md text, and fi-PL is in your own simulator language list. alert accept still works through the vocabulary, so this is an incomplete fix for #3922, not a regression. The rule: every SchemeApproval localization's title format must give a matcher that matches a title rendered from it. Treat every object format specifier (%@, %1$@, %[tt]@) as the app-name wildcard, for example by replacing %(\d+\$)?(\[[^\]]*\])?@ with .+. A simulator unit test should enumerate every .lproj under CoreServices.framework, render the format with a sample name, and assert recognizes() is true. Please also add fi-FI to testSystemStringsRecognizeAndAnswerTheLocalizedLaunchConfirmation.

Not blocking, take or leave: once the Finnish case is fixed, the commands.md line at website/docs/docs/commands.md:112 is accurate, and one clause in the alert get docs could say that on an iOS simulator it reports launchConfirmation: true when the alert is the Open in confirmation.

On the other threads: the cubic P3 thread on the duplicated CONFIRMATION fixture (#4160 (comment)) still applies, and so does the undocumented alert get field (#4160 (comment) and #4160 (comment)), which one docs clause resolves. The naming-nit thread (#4160 (comment)) still applies, as a nit. These do not apply and can be resolved: the all-or-none read is the existing invariant, and the table is present in all 55 localizations on iOS 27.0 and 27.1 (#4160 (comment)); the premise that only the confirmation needs SchemeApproval is wrong, because alert accept and dismiss need its translations (#4160 (comment)); a format without %@ yields a literal regex, and the real defect is the one above (#4160 (comment)); the prebuilt runner is keyed by the source fingerprint, so changed Swift sources force a rebuild (#4160 (comment)); one marker already names the failing table (#4160 (comment)); and static let system = unavailable reuses the one recognizer (#4160 (comment)).

Evidence limits: the French live run is author-reported and I could not reproduce it read-only. I checked SchemeApproval formats only on the installed iOS 27.0 and 27.1 runtimes. I did not run the claim that the Swift vocabulary test fails without the table.

…ion prompts

A runtime without the SchemeApproval table no longer drops the notification,
tracking, and location vocabulary. The test shares the CONFIRMATION fixture.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@apex-sentinel-staging

Copy link
Copy Markdown

Apex Sentinel could not review commit 1511ffbf. No review ran, so there are no findings; this is not a verdict on the change.

Apex Sentinel could not read or check out this pull request, which is usually temporary (GitHub was slow, or the branch moved while the review waited). If it keeps failing, tell whoever runs Sentinel for this repository, or check that the App still has access to it. Push a new commit or comment @apex-sentinel-staging review to try again.

Rename the runner's alert mark to launchConfirmationPrompt so it cannot be read
as open's launchConfirmation outcome, and document it. Accept positional
app-name placeholders in the OS title format, skip a wording with no
placeholder, and name the failing subsystem in the unavailable-strings log.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 10 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread website/docs/docs/commands.md Resolved
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@thymikee

thymikee commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

Thanks for the update. At 36b85c9 the slot-less wording guard is in place, but the Finnish problem from the earlier review (#4160 (comment)) is still there, and the regression test I asked for is still missing. The rename to launchConfirmationPrompt, the split table read and the shared fixtures are fixed.

The slot regex at https://github.com/callstack/agent-device/blob/36b85c9/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerLaunchConfirmationPrompt.swift#L21 is %(?:\d+\$)?@. It does not match the Finnish title format "Avataanko %[tt]@-apissa?" (fi.lproj on the iOS 27.0 and 27.1 simulator runtimes). The new guard at line 25 then drops the Finnish wording. On a Finnish simulator recognizes() is always false, so alert get never sets launchConfirmationPrompt, and open --launch-url reports alert-unrecognized and leaves the prompt up. #3922 stays unfixed for Finnish, which is in your own simulator language list (fi-PL), and the help and commands.md say every preferred language is recognized. The rule: every SchemeApproval localization's title format must give a matcher that matches a title rendered from that format. Treat every object format specifier as the app-name slot, for example %(?:\d+\$)?(?:\[[^\]]*\])?@. Please also replace the doc comment at line 18, because it names only %@ and %1$@.

The test at https://github.com/callstack/agent-device/blob/36b85c9/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+LaunchConfirmationPromptTests.swift#L67 covers only %@-less and %1$@ formats, and testSystemStringsRecognizeAndAnswerTheLocalizedLaunchConfirmation still uses only fr-FR and ja-JP. I read both as passing at this head, where Finnish is dropped, so no test enforces the rule above. Please add a simulator unit test that enumerates every .lproj under the runtime's CoreServices.framework. For each one it should render SCHEME_APPROVAL_PROMPT_TITLE_NO_SOURCE with a sample app name and assert that recognizes(title:buttons:) is true with that language's open and cancel labels. Please also add fi-FI to the system-strings test.

The cubic-dev-ai thread on the unscoped launchConfirmationPrompt clause in commands.md (#4160 (comment)) is addressed by the newer commit 81577da, which scopes it to local iOS simulators. These threads no longer apply, so you can resolve them: the split table read (#4160 (comment)), the shared fixtures import (#4160 (comment)), the permission-only prompt tables (#4160 (comment)), the commands.md documentation (#4160 (comment)), the Models rename (#4160 (comment)), the unavailable-strings log (#4160 (comment)) and the field name collision (#4160 (comment)). These are fine as is: the older-runner thread (#4160 (comment)), because the runner and daemon ship in one package and the prebuilt runner is keyed by the Swift source fingerprint, and the unavailable naming nit (#4160 (comment)), which has no behavior effect. The slot guard thread (#4160 (comment)) is fixed in spirit, but its narrow regex now causes the Finnish drop above.

Not blocking, and fine to take or leave: the PR body still names the alert field launchConfirmation: true and cites the earlier check:affected receipt, while the head renamed the field to launchConfirmationPrompt.

There are no conflicts. Smoke Tests (apple.yml, macos-26) is still in progress. It builds and drives the iOS XCUITest runner, and this diff changes runner Swift sources and the launch-confirmation answer, so a failure there would likely be related until shown otherwise.

I checked the SchemeApproval formats only on the installed iOS 27.0 and 27.1 simulator runtimes. I did not run the Swift unit tests or the runner build, so the claim that the tests pass at the head comes from reading them. I did not reproduce the French live run. It is author-reported, and it predates the field rename and the split table read.

Before merge, please match every object specifier such as %[tt]@ in RunnerLaunchConfirmationPrompt, and add the every-.lproj test and fi-FI. Then please post a live run on a Finnish simulator (AppleLanguages fi, rebooted) with a fresh, unapproved URL scheme. open <app> --launch-url <scheme>://x --relaunch must return launchConfirmation: "accepted". After the prompt is raised again with simctl openurl, alert get must return the message "Avataanko …-apissa?", the Finnish open and cancel items, and launchConfirmationPrompt: true. Please re-run the French case too, and post the pnpm check:affected receipt for the head.

This review covers 36b85c9. The newer head 81577da changes only that commands.md line, so the Finnish matcher and test points above still apply.

thymikee and others added 2 commits November 2, 2026 12:58
The launch-confirmation mark now needs the SpringBoard blocking-modal source, so
an app alert with the same wording and buttons is not auto-accepted by open.
The title placeholder accepts Apple's bracketed object format (Finnish
`%[tt]@`). Tests load every installed SchemeApproval localization, cover the
missing-table branch, and cover the app-owned alert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@apex-sentinel-staging apex-sentinel-staging Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apex Sentinel: 5 new findings on f862d9e. The verdict and the full list are in the summary comment.

…table

Another key of that undocumented table cannot join the accept or dismiss labels.
The placeholder regex no longer force-unwraps.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@apex-sentinel-staging apex-sentinel-staging Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apex Sentinel: 4 new findings on 9435060. The verdict and the full list are in the summary comment.

}
}

let title = preferredAlertTitle(alert.root, buttons: alert.buttons)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆕 🟡 Minor · Only the handleAlert read branch marks the prompt; the awaitAlert/probe read paths publish no mark

launchConfirmationPrompt: true is added in exactly one place in the runner: the non-action return of handleAlert (RunnerTests+Alert.swift:140-149). Every other alert-shaped payload was left untouched — blockingSystemModalPayload (RunnerTests+SystemModal.swift:96-103), the system-modal probe payloads (RunnerTests+Models.swift:394/404/414) and the accept/dismiss verification payload (RunnerTests+AlertObservation.swift:81) publish no launchConfirmationPrompt at all. On the host side, createLaunchConfirmationPort uses awaitAlert for the first read that decides whether the prompt is recognized and readAlert again in verifyFailedAcceptance; those legs are what decide accepted vs alert-unrecognized. If the alert legs for the launch-confirmation probe are served by the system-modal probe/wait path rather than by the handleAlert read branch, the mark never crosses the wire, isLaunchConfirmation is always false, and the whole open --launch-url answer keeps failing with alert-unrecognized — while the newly documented alert get output would still look right, so the live check in the PR description would not catch it. I could not finish verifying which runner command serves the awaitAlert leg inside my read budget, so this is reported at low confidence as the invariant the change silently rests on: every host-visible alert read that the confirmation answer performs must go through the one branch that computes the mark.

Suggested change

Verify the runner command behind the interactor's awaitAlert/readAlert legs is the handleAlert read branch that now sets launchConfirmationPrompt; if any of those legs resolves through the blocking-system-modal probe payload, mark it there too (or move the mark into the shared payload builder) so open sees the same flag alert get prints.

Details

persona: javascript

Reply @apex-sentinel-staging note ... to add context, or @apex-sentinel-staging pivot ... if this is wrong — I will re-check the cited code.

Useful? Reply @apex-sentinel-staging like, or @apex-sentinel-staging dislike <why> if it is not.

(path: "/System/Library/Frameworks/CoreLocation.framework", table: "locationd")
]

/// SpringBoard's launch confirmation. It is read apart from `promptTables`, so a runtime without

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆕 🔵 Nit · /// The only keys … comment sits under the promptTables doc block on launchConfirmationLabelKeys

RunnerSystemPromptStrings.swift:18-21 puts two unrelated documents on one declaration: the first sentence describes launchConfirmationTable (read apart from promptTables), which is declared 6 lines later, and the second describes launchConfirmationLabelKeys, the declaration it is attached to. RunnerLaunchConfirmationPrompt.fromSystemStrings uses the full unfiltered table, and RunnerAlertLabelVocabulary.composed is the only consumer of launchConfirmationLabelKeys, so the misplaced sentence points a reader at a restriction that the other consumer does not apply. Split the two sentences onto their own declarations.

Suggested change

Keep the "read apart from promptTables" sentence with launchConfirmationTable and leave only the key-restriction sentence on launchConfirmationLabelKeys.

Details

Also raised here

Also raised at this location by swift-ios: Doc comment for launchConfirmationLabelKeys mixes two instructions into one block — The comment on launchConfirmationLabelKeys (lines 18-22) explains two unrelated things: why SchemeApproval is read apart from promptTables (which belongs to launchConfirmationTable, declared five lines below with no comment) and why only two keys are taken. AGENTS.md asks for one instruction per sentence and comments attached to what they describe; splitting these makes the key restriction, which is the security-relevant constraint, easy to miss.

persona: javascript, maintainability, swift-ios

Reply @apex-sentinel-staging note ... to add context, or @apex-sentinel-staging pivot ... if this is wrong — I will re-check the cited code.

Useful? Reply @apex-sentinel-staging like, or @apex-sentinel-staging dislike <why> if it is not.

path: "/System/Library/Frameworks/CoreServices.framework",
table: "SchemeApproval"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆕 🔵 Nit · read takes a table list but throws away every table that did read on the first failure

RunnerSystemPromptStrings.read accumulates into read and returns .failure from inside the loop, so a caller that passes more than one path gets no partial result — the tables that read are discarded when a later one does not. promptTables relies on exactly that all-or-none rule, but launchConfirmationTable is passed in its own call only because a shared multi-table call would lose the tables that read. Either state that all-or-none contract in the doc comment above read (it currently only says "A table reads in every preferred language or not at all") or drop the array parameter so the shape cannot invite the wrong call.

Suggested change

Document that read fails as a whole when any path fails, or take a single (path, table) so the partial-read trap cannot be reached.

Details

persona: maintainability

Reply @apex-sentinel-staging note ... to add context, or @apex-sentinel-staging pivot ... if this is wrong — I will re-check the cited code.

Useful? Reply @apex-sentinel-staging like, or @apex-sentinel-staging dislike <why> if it is not.

}
}

let title = preferredAlertTitle(alert.root, buttons: alert.buttons)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆕 🔵 Nit · The launch-confirmation matcher is initialized lazily on the alert-read path and can be built twice

RunnerLaunchConfirmationPrompt.system is a lazy static let that parses SchemeApproval.strings for the OS root in English plus every preferred language (RunnerSystemPromptStrings.read), and it is now consulted from marksLaunchConfirmation on every alert get (RunnerTests+Alert.swift:147, 154-158). The only warm-up is the DispatchQueue.global(qos: .utility).async block in setUp, which builds the vocabulary first and this matcher second, so it serializes two table walks. alert get and alert wait have no activation gate before that lazy read (the hittable probe in probeAlertButtonHittable is accept/dismiss only), so on a host that has not finished the warm-up — a stalled utility queue on a loaded machine, or any alert get racing the prefetch — the first alert read pays the whole file read synchronously inside its own deadline (default 10 s, and LAUNCH_CONFIRMATION_PRESENTATION_TIMEOUT_MS is only 3 s on the launch path) and can report a timeout for a prompt that is plainly on screen. The prefetch comment claims the deadline is protected; it is protected only if the utility block wins the race. Also note RunnerAlertLabelVocabulary.fromSystemStrings reads the same SchemeApproval table a second time, so the warm-up cost is doubled.

Suggested change

Warm both statics concurrently, or share one read of the SchemeApproval table between the vocabulary and the prompt matcher, so no alert read can be the first reader.

Details

persona: senior-developer

Reply @apex-sentinel-staging note ... to add context, or @apex-sentinel-staging pivot ... if this is wrong — I will re-check the cited code.

Useful? Reply @apex-sentinel-staging like, or @apex-sentinel-staging dislike <why> if it is not.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

1 participant