Skip to content

docs(contracts): scope the iOS keyboard class claim to instantiation - #3572

Merged
thymikee merged 1 commit into
mainfrom
docs/3482-ios-keyboard-ownership-sentence
Oct 13, 2026
Merged

thymikee merged 1 commit into
mainfrom
docs/3482-ios-keyboard-ownership-sentence

Conversation

@thymikee

@thymikee thymikee commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #3482's final review note (#3482 (comment), "not blocking").

The IOS_KEYBOARD_* docblock claimed the classes are "private to the keyboard surfaces — an app cannot host one in its own view tree". That overclaims: the fourth bullet below it (IOS_KEYBOARD_CHROME_MARKER_ROLES) describes hosts the app can fill — its custom inputView, its inputAssistantItem bar buttons riding the assistant view. The sentence is now limited to what is true of the classes themselves — an app cannot instantiate them — and the subtree question is left to the per-table bullets, which already answer it correctly (the subtree table says "an app can never fill these"; the marker table says the opposite and claims no subtree).

Two lines of prose in a docblock. No code, no behavior change, so no test or device evidence applies: the classification the bullets describe is pinned by the snapshot-chrome fixtures and the breakdown case added in #3482, neither of which is touched here.

Validation

pnpm check:affected --run --base origin/main at 4d7d0c807: all runnable checks passed (exit 0) — 565 related test files / 4,323 tests, Fallow clean on the 1 changed file — held under the machine-wide lock, started 2026-10-13T11:03:41Z. format, lint, tsc -b, check:layering and build pass.

The IOS_KEYBOARD_* docblock said the classes are "private to the keyboard
surfaces — an app cannot host one in its own view tree", while the marker
bullet below it describes hosts the app CAN fill. Limit the sentence to what
is true of the classes themselves (an app cannot instantiate them) and leave
the subtree question to the per-table bullets, which already answer it.

Follow-up to #3482's final review note; no behavior change.

@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.

No issues found across 1 file

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

@github-actions

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.18 MB 5.18 MB -4.2 kB
Package (unpacked) 5.18 MB 5.18 MB -4.2 kB
Package (download) 1.56 MB 1.56 MB -884 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 21.6 ms 21.8 ms +0.2 ms
CLI --help 59.9 ms 62.3 ms +2.4 ms

@thymikee

Copy link
Copy Markdown
Member Author

This PR is ready at 4d7d0c8. The change only edits a comment in one contracts file, so it cannot change runtime behavior.

Not blocking: the claim "cannot instantiate" at https://github.com/callstack/agent-device/blob/4d7d0c8/packages/contracts/src/android-input-ownership.ts#L157 holds only for public API, so you could say "cannot instantiate them through public API"; take it or leave it. I did not check the iOS SDK to confirm that no public initializer exists for these private classes.

CI is still pending. All 15 non-passing checks are queued, none have failed. Once they run, the PR can merge.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 13, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Smoke Tests (iOS) failed at 4d7d0c8 on attempt 1 and is rerunning. Recording why I am treating it as environmental, since the standing guidance is that a smoke failure is probably related to the diff:

  • The step is Preflight iOS runner through public CLI, which boots the XCUITest runner and dispatches no app command. Typed details: kind: daemon_startup_failed, startupTimeoutMs: 15000, startupAttempts: 1, diagnosticId: mv6n7pet-b35c6cb2. The retired process in cleanupResults (pid 5289, started 12:14:10, error at 12:14:25) is the daemon this preflight started itself — it started, missed the 15 s reachability probe once, and was cleaned up. No leftover state from another job is visible in this log.
  • This PR cannot reach it. The entire diff is two lines of prose in a docblock in packages/contracts/src/android-input-ownership.ts, a file imported only by the settle chrome classifier and the tap-occlusion band. A comment cannot execute, and nothing in prepare ios-runner reads that module.
  • Second occurrence of the identical signature today. The same daemon_startup_failed / startupTimeoutMs: 15000 / same-step failure killed an attempt of the iOS lane on fix(settle): resolve the default quiet window from the capture it settles #3522 (run 38373920347, attempt 2) — different branch, different content, same shared macOS pool, which is also emitting Due to capacity constraints, jobs targeting macOS arm64 runners may experience longer queue times.

One observation for whoever next touches this preflight, stated as an observation, not a fix: with startupTimeoutMs: 15000 and startupAttempts: 1, a single slow daemon boot on a contended arm64 runner is a hard lane failure. Whether 15 s is the right budget on the shared pool — or whether one retry belongs there — is the owner's call, and I have measured neither.

If the rerun comes back with dispatched: "yes" or failing inside a settle/interaction step, I stop assuming and treat it as diff-caused.

@thymikee

Copy link
Copy Markdown
Member Author

Updating this because my previous note set a standard and the rerun met it: I wrote that if the rerun came back dispatched: "yes", I would stop treating the signature as environmental. It did — so "preflight flake" is off the table and this is the real account.

Attempt 2 failed a different, dispatched step. Not preflight: Run fixture-backed iOS simulator E2E smoke, at the live scenario's snapshot-acquisition gate (assertSimulatorSnapshotAcquisition, reached from assertRegularVisibleDepthFrontier):

raw depth-1 visible-depth snapshot reports no backend served this screen
  snapshotQuality: { state: 'sparse', reasonCode: 'sparse-tree' }
  visibleNodeCount: 2   (Application + Window only), truncated: true
  warnings: Simulator AX snapshot unavailable (target-resolution-failed);
            used XCTest for an unverified app generation.

The capture immediately before it — snapshot --raw on the same screen, one step earlier — passed the same assertion. So the app was up and readable, and the next read of the same screen came back empty because the AX bridge could not resolve its target and the XCTest fallback found no semantic content. The run says so about itself: ios snapshots are slow in this run: p95 1921ms over 47 captures. That warning appears once in this run and zero times in main's own run.

What this is not: caused by this diff. main at a95d2d539 ran the same live scenario green (✔ live iOS simulator fixture E2E), and this lane's checkout is that content plus one docblock sentence, which is not reachable by the AX bridge, the runner fallback, or the snapshot quality latch. My own #3570 passed this same iOS smoke lane on the same pool at 12:34–12:41Z, minutes before this job started at 12:51Z, while t3/settings-replay-corpus-3077 — started 12:39Z, overlapping that green run — went red in the same step on a different live assertion, and t3/android-intent-ownership-3077 went red at preflight daemon_startup_failed. Hosts differ per job; the content does not.

What I am not claiming: that the lane is wrong to fail. assertSimulatorSnapshotAcquisition documents exactly this case — sparse means no backend served the screen, and "the lane must not certify a tree whose acquisition it does not classify". It refused a genuinely degraded capture, which is the behaviour it was written for. The open question belongs to the lane, not to this PR: whether that gate should tolerate one retry when the response pairs sparse-tree with the typed target-resolution-failed disclosure on a host that also reports its snapshots are slow. That is a separate module group from this docblock, so I have not folded anything into this diff — and filing it is your call; say the word and I'll open it with the two attempts, the cross-branch pattern and the main control attached.

So I stopped rerunning. Two attempts on a comment-only change is already pool time I would rather spend on #3522 and #3570, and a third would be collecting flake statistics rather than fixing anything. Your options, in the order I'd take them: rerun this lane when the pool is quieter (the content is proven), merge it as-is on the ground that the diff has no executable change to certify, or close it — the sentence is worth having, but not at the cost of the queue. Nothing here is a blocker for #3522, which is green and mergeable, or for #3570.

@thymikee

Copy link
Copy Markdown
Member Author

Reran the failed job as the owner's call accepts — attempt 3 is queued on 4d7d0c8, no push, so the head the review certified stays exact.

Taking the nit's wording as offered but not pushing for it: a push would restart all lanes, including the smoke job now rerunning, for two words in a docblock. If the sentence should read cannot instantiate them through public API, say so and I'll fold it in — the merge that carries it then just waits for one more lane pass.

@thymikee
thymikee merged commit 01f6812 into main Oct 13, 2026
19 of 21 checks passed
@thymikee
thymikee deleted the docs/3482-ios-keyboard-ownership-sentence branch October 13, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant