perf(ios): fuse scroll frame resolution and drag into one runner command#760
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
|
Note for whichever of this and #763 merges second: #763 adds a readiness-preflight skip allowlist in runner-session.ts keyed on runner command names. The fused |
Code reviewVerdict: looks good — minor issues only. The Swift port of Findings
OverallA careful, well-tested fusion. The only substantive pre-merge ask is tightening the parity vector mirror (finding 1), since the whole two-language invariant rests on it. Generated by Claude Code |
Non-tvOS scroll now sends a single mutating 'scroll' runner command. The Swift runner resolves the interaction frame and executes the same non-synthesized drag path, eliminating the separate read-only interactionFrame request per scroll. The command is lifecycle-journaled with retained response JSON so lost-response recovery returns the result without replaying the gesture. Closes #668
#763 landed the healthy-mutation preflight skip with a note that the fused scroll command should join the allowlist once it exists. Add 'scroll' to PREFLIGHT_SKIP_ELIGIBLE_RUNNER_COMMANDS, drop the now-resolved code note, extend the per-family skip tests, and update the allowlist enumeration in ADR 0005 and the protocol-optimizations doc. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
6205b7e to
9f46b57
Compare
Address review on the cross-language parity vectors: - mirror the Swift pixels-plan vector (down, 120px @ 300x600) in the vitest suite so every vector exists in both languages - add amount > 1 clamp and tiny-frame (2x2) vectors to both suites; the tiny frame engages every max(1, ...) floor and the .5 rounding cases where JS half-up and Swift half-away-from-zero must agree https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
|
Follow-up on the review above, as of 01a0279:
Also note: the branch was rebased onto main and Generated by Claude Code |
|
Rebased onto main with #763 (healthy-mutation preflight skip) and #760 (fused scroll). Per the merge-order note, add 'sequence' to PREFLIGHT_SKIP_ELIGIBLE_RUNNER_COMMANDS so a successful sequence earns the next hot-command skip instead of always taking the conservative_command path. Extend the per-family skip tests and the allowlist enumeration in ADR 0005 and the protocol-optimizations doc. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
…eries (#764) * perf(ios): add lifecycle-safe runner sequence command for hot press series Adds a narrow 'sequence' runner command that batches an explicit allowlist of coordinate steps (tap, longPress, drag) into one lifecycle-tracked request with stop-on-first-failure and small bounded per-step results. iOS press series with hold/jitter now issue one sequence request per ~20-step chunk (also budgeted to stay under the runner's 30s main-thread watchdog) instead of one request per press. Sequence responses are journaled and retained, so lost-response recovery returns observed results without replaying the gesture sequence. Closes #669 * fix: perform every press in direct press series runDirectPressSeries guarded the awaited interaction itself with ??=, so presses 2..N were silently skipped once the first result was kept (affects Android series and doubleTap series; introduced in #512). The kept-first-result shape is preserved. * chore: unexport internal sequence chunk budget constant * perf(ios): make sequence eligible for readiness preflight skip Rebased onto main with #763 (healthy-mutation preflight skip) and #760 (fused scroll). Per the merge-order note, add 'sequence' to PREFLIGHT_SKIP_ELIGIBLE_RUNNER_COMMANDS so a successful sequence earns the next hot-command skip instead of always taking the conservative_command path. Extend the per-family skip tests and the allowlist enumeration in ADR 0005 and the protocol-optimizations doc. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo --------- Co-authored-by: Claude <noreply@anthropic.com>
Closes #668
What
Non-tvOS iOS scroll now executes as one runner lifecycle command instead of a read-only
interactionFramerequest followed by a mutatingdragrequest.scrollcarries the pre-frame inputs (direction,amount?,pixels?).resolvedTouchReferenceFrame, computes drag endpoints with a line-for-line Swift port ofbuildScrollGesturePlan(parity test vectors mirrored in both languages), and executes the same non-synthesized drag path scroll used before.normalizeIosScrollResultunchanged — result shape and gesture recording metadata are byte-compatible.interactionFramestays runner-supported for wire compat with older daemons (annotated as no longer sent).Lifecycle safety
scrollis intentionally omitted fromisReadOnlyRunnerCommand, so it gets command-id tracking, single-send (no transport retry), readiness preflight, and journal-based lost-response recovery. The journal retains its small response JSON (~200 bytes), so a lost response is recovered without replaying the gesture.Validation (iPhone 17 Pro Max simulator, iOS 26.2)
Per-request diagnostics (
--debug) for a 6-scroll hot loop in Settings:interactionFrame+drag)scroll){direction, x1, y1, x2, y2, referenceWidth, referenceHeight, pixels, message}.swipe/gesture pansmoke-tested after the Swift drag-body extraction.pnpm typecheck, focused unit suites (285 tests), andpnpm build:xcuitest(iOS + macOS) all pass.