Repository navigation
fix(timeouts): prove the longpress request envelope with a worst-case ledger - #3937
Conversation
…ecks The blocking-dialog and foreground observations ran `adb shell dumpsys` with no timeout before and after every Android interaction, so a hung read waited for the client envelope and reset the daemon. Each dump read now carries a 10 s bound. A timed-out read counts as unanswered, the same `unknown` a read that printed nothing produces, so a slow probe still never refuses the command; the reader then skips its remaining variants, so one observation costs at most one bound. This unblocks the longpress envelope ledger in callstack#3326, which cannot prove an envelope while these reads are unbounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… ledger The longpress envelope (210 s) rested on a hand sum that nothing checked. A provider-integration ledger test now drives the Android cold-helper route at the maximum hold through the daemon with a fake adb provider that charges each call its own timeout on a virtual clock. The slowest branch (checksum mismatch, an install refused as INSTALL_FAILED_UPDATE_INCOMPATIBLE, uninstall, reinstall, one-shot hold) costs 279,990 ms; with the 30 s daemon-result margin the envelope must be at least 309,990 ms, so it rises to 310 s and its comment points at the test. The 120 s hold cap becomes LONG_PRESS_DURATION_MAX_MS, read by both the validator and the test. Closes callstack#3326 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR is ready at 3f9b9cf, and I found nothing that needs to change before merge. All 10 checks pass, and there are no conflicts. I did not run the ledger test or its negative control. The 279,990 ms figure and the dumpsys count come from the PR body and my own recomputation of the sum. Not blocking, and you can take or leave these: (1) The fake exec in android-longpress-ledger.test.ts answers the first dump variant of every observation, so the ledger charges one 10 s read each. The real route can walk more variants when one answers without a focus line, and each extra variant adds up to 10 s. Two blocking-dialog observations could then push the sum to about 330 s, over 310 s. The ledger should charge the maximum reads each observation can make, as the ios-fold ledger does for hinge reads. Alternatively, cap an observation at one bound in |
A per-read bound still let one observation walk every dumpsys variant that answered without a focus line, each spending up to its own 10 s. All reads of one observation now draw on a single 10 s budget, so an observation costs at most one bound however many variants it reads; a spent budget or a timed-out read leaves the question unanswered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ss-envelope-ledger-3326
The ledger's fake answered the first dumpsys variant of every observation, so it charged one read each and never saw the foreground check walk into a second observation. Observation dumps now answer without a focus line, which sends each observation through every variant its shared budget allows. The measured worst case rises to 289,989 ms, so the envelope rises from 310 s to 320 s. Also: name the snapshot-helper hand-off the ledger cannot charge and where it is bounded, say the Android-driven envelope applies to every platform, read timeoutMs once in record(), and rewrap the header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. Taken in
🤖 Addressed by Claude Code |
|
This is ready at e10db99. The earlier note on 3f9b9cf stays resolved, and I found nothing new that needs a change. All 10 checks pass on this commit, and merge order depends on #3936 landing first, then main merged into the branch. Not blocking, take or leave: in https://github.com/callstack/agent-device/blob/e10db99/packages/platform-android/src/observation.ts#L93, |
The budget started when the reader was created, so the helper focus call that readBlockingDialog (and readAppFocus, for a shared reader) makes first spent up to 2 s of the 10 s dump budget. The deadline now starts at the first dump read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ss-envelope-ledger-3326
Matches the other platform-android modules that bound a sequence of steps, instead of computing the deadline and remainder by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ss-envelope-ledger-3326
|
Taken. 🤖 Addressed by Claude Code |
|
Thanks for the update. At c962e7a I found no problems in the change. It builds on the earlier review at e10db99 (#3937 (comment)), and the live-session hand-off stays uncharged in the ledger, as the test header says. All 11 checks pass, including the ledger test that exercises this route. I did not re-run the ledger test or There are no conflicts. The merge order is unchanged: #3936 lands first. |
isExpired() and remainingMs() read the clock separately, so a millisecond rollover between them passed timeoutMs 0, which the exec layer treats as no timeout and runs the dump unbounded. The reader now reads the remaining budget once and uses it for both the check and the timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ss-envelope-ledger-3326
|
The PR is ready at 376fddd. The change since c962e7a (the once-per-read clock fix in the Android dump reader and its unit test) is correct, and the earlier clean review still applies. I did not run |
|
Merged main ( 🤖 Addressed by Claude Code |
|
The red Smoke Tests job at
I can't rerun jobs from a fork. Could you rerun the iOS smoke job? 🤖 Addressed by Claude Code |
Summary
Builds on #3936 (merged as
a9fc9a19f); main is merged in, so the diff is this change alone (5 files).The longpress envelope (210 s) rested on a hand sum.
test/integration/provider-scenarios/android-longpress-ledger.test.tsapplies the #2879 ledger pattern tolongpress 195 320 120000on the Android cold-helper route:AndroidAdbProvidercharges each call its owntimeoutMson aDate.now-spied clock, and fails on any call with no bound.The worst branch costs 289,989 ms: checksum mismatch, an install refused as
INSTALL_FAILED_UPDATE_INCOMPATIBLE, uninstall, reinstall, then a one-shot hold.pm path, pullAdding the 30 s margin, the envelope rises to 320 s on every platform. The hold cap is now
LONG_PRESS_DURATION_MAX_MS, read by the validator and the test.Not charged: stopping a running snapshot-helper session waits on host-side timers (
snapshot-helper-session-lifecycle.ts, ≤ 14 s). The test header documents it. #3814 editscommand-descriptor-timeout-policy.test.tstoo.Closes #3326
Validation
pnpm check:affected --run --head 5e298d5a3(main merged in): passed,exactCommit=true(basec48d27a81).envelopeMs: 319_000fails ("289989ms + 30000ms margin exceeds the 319000ms envelope").🤖 Generated with Claude Code