diagnose(1874): instrument the synthesized commit wait and add a dispatchable stall loop - #1941
Conversation
Size Report
npm unpacked components
Startup median (7 runs, lower is better):
Top changed chunks: no changes in the largest emitted chunks. Top changed packed files
|
|
P1 — the diagnostic instrumentation writes raw observed field contents to NSLog on the shipped synthesized-text path: observedText.prefix(40). This is not confined to the workflow or unit-test build, so ordinary type commands can persist credentials/PII in runner.log; the diagnostic workflow then uploads those logs on a stall. Please keep the cadence evidence value-free (for example observed length, expected-prefix match length, progress state, and timestamps), or gate any raw fixture-only trace behind a compile-time diagnostic build that cannot ship. Add a regression/source guard that makes reintroducing raw observed text into runner logging fail. |
|
Addressed in 634367f. The per-poll trace now logs only |
|
P1 — The shipped poll path is value-free now, but the new guard does not enforce that invariant. It only reviews literal NSLog formats containing %@, so Swift interpolation of observedText is skipped entirely, and passing observedText to an already-allowlisted %@ format also passes. Please put cadence logging behind a typed value-free boundary that accepts only lengths, timestamps, and enums, then test its emitted output with a sentinel secret instead of partially parsing Swift format strings. Update the PR body too: item 1 still says the trace includes the observed value, which is no longer true. Finally, #1874 and #1844 are both closed while the PR says this temporary instrumentation remains until #1874 is root-caused; reopen the cleanup issue or name an active owner and removal trigger before shipping it. |
|
Addressed in e7524f9.
|
|
Not merge-ready on the current base yet: #1948 landed after this branch and changes the same synthesized-commit wait from Please rebase onto current |
A generic simulator destination leaves the active arch undefined; Xcode 26.6 defaults it to x86_64, running the whole runner under Rosetta on arm64 hosts. Pin ARCHS=arm64 across every lane that builds the iOS runner and bump the derived-data cache suffixes. Measured ~30% faster commits on identical CI hardware; delivery-throttle episodes still occur but start from a lower base.
The per-poll trace logged the observed field's contents (prefix(40)) on the shipped type path; that value is user content and runner.log persists. Log lengths and the expected-prefix walk instead, allowlist every string-interpolating NSLog format in the module behind a source-scan guard, and pin commonPrefixLength in the host-lane policy tests.
…ndary logCommitCadence accepts Int lengths and a timestamp only, so observed field contents are unrepresentable at the poll call site; its emitted line is pinned by a sentinel-secret test in the host-lane policy tests. The source guard becomes structural — boundary present, poll path logs through it, no raw NSLog in the observe closure — instead of parsing Swift format strings. #1874 is reopened as the removal-tracking thread for this temporary instrumentation.
e7524f9 to
956cd37
Compare
|
Rebased onto current Reruns: both Swift gates build locally ( |
|
Re-reviewed at |
|
…equest-bound-migration-803b60 * origin/main: perf(contracts): granularize entry surfaces so hub importers stop evaluating the facade clump (#1969) fix(ios): preserve regular snapshot depth through structural wrappers (#1947) diagnose(1874): instrument the synthesized commit wait and add a dispatchable stall loop (#1941) refactor(tests): replace the test-utils barrel with direct module imports (#1956) fix(ios): enforce regular snapshot clip invariant (#1946) refactor(daemon): lazy-load platform cleanup helpers in session teardown (#1950) perf(typecheck): make the root tsc project incremental (#1957) docs: drop stale apps.ts over-budget warning from AGENTS.md (#1954) refactor: dedupe containsPoint and rectArea into @agent-device/kernel (#1953) # Conflicts: # packages/platform-android/src/runtime.ts # packages/platform-harmonyos/src/runtime.ts # packages/platform-linux/src/runtime.ts # packages/platform-vega/src/runtime.ts # packages/platform-web/src/runtime.ts # packages/provider-limrun/src/app-log-runtime.test.ts # packages/provider-limrun/src/interaction-operations.ts # packages/provider-webdriver/src/platform-runtime.ts # src/core/command-descriptor/registry.ts # src/core/dispatch.ts # src/platforms/apple/plugin.ts
Refs #1874, #1844. Follow-up to #1924 (merged): production now reports
TEXT_INPUT_COMMIT_NOT_OBSERVEDinstead ofok: trueover a partial commit. This PR ships the diagnosis tooling for the remaining question — why synthesized-event delivery occasionally stalls on CI.What we know (evidence from 2026-08-18..21 failures)
32176591415typed"hardware-keyboard", held"ha"at failure time, and the field read"hardware-key"~40s later with nobody typing. The burst drains late.macos-26-arm64image; Xcode 26.6 builds x86_64 from-destination generic/platform=iOS Simulator).32485228371) passed 50/50 but caught one sub-critical episode:type-all2487ms across 5 polls — the same mechanism at recoverable severity. Episodes that outlast the 3s commit window are the rare failures (~4 in days of full-suite runs).Conclusion: transient throttling of the synthesized input pipeline on CI VMs; most episodes recover inside the commit window, the tail does not.
What this PR adds
[DEBUG-1874]instrumentation inawaitSynthesizedFirstResponderCommit: per-poll timestamp, observed length, and expected-prefix length through the real injectedobserveclosure, plus post time of the synthesize call and the final outcome — value-free by construction (typed Int-only boundary, sentinel-tested). Any future red lane now carries a cadence trace instead of a bare value mismatch, and no typed field content reaches runner.log..github/workflows/1874-diagnose.yml—workflow_dispatchmatrix (isolated vs pair-after-predecessor) looping the bare-type test N times on the CI image, with per-iteration verdicts and stall evidence artifacts.Validation
pnpm gate swift-runner-ios—** TEST BUILD SUCCEEDED **; local run prints[DEBUG-1874] poll ... outcome=settled elapsedMs=34.pnpm check:affected --run— all runnable checks passed.32479566150,32485228371); the second completed 50/50 green with evidence artifacts.Intent
Keep the workflow dispatchable until #1874's underlying stall is root-caused; when a lane goes red again, its logs will show whether the prefix walks slowly (delivery throttling) or freezes (queue wedge). Remove both once resolved.
Mitigation shipped in this PR
The 2×2 matrix (runs
32485228371,32497125475) measured native arm64 at ~30% faster commits than Rosetta x86_64 on identical CI hardware (mean type-all ~860ms vs ~1150ms), with slow-delivery episodes occurring on both architectures. Rosetta amplifies episode severity; it is not the fundamental cause. This PR pinsAGENT_DEVICE_XCUITEST_ARCHS=arm64across every lane that builds the iOS runner (ios.yml,xctest-nightly,perf-nightly,conformance-differential,replays-manual) via the new build-script override, and bumps derived-data cache suffixes.TEXT_INPUT_COMMIT_NOT_OBSERVED(#1924) remains the backstop for episodes that outlast the commit window.Cleanup ownership
This instrumentation and the dispatchable workflow are temporary. Removal trigger: #1874 (reopened — the delivery throttle is not root-caused) identifies the mechanism, at which point the
[DEBUG-1874]boundary, its guard tests, and1874-diagnose.ymlare deleted in one commit. Owner: the iOS runner maintainers; the reopened issue is the tracking thread.