Skip to content

Story 14 — Runner transport recovery: status-probe before invalidate, never-replay mutating commands #407

Description

@Lykhoyda

When an rn-fast-runner / rn-android-runner HTTP response is lost after a command was sent (timeout, socket reset, runner busy), the client cannot tell "never executed" from "executed, response lost". Today that ambiguity costs either a session teardown (re-paying runner boot, cf. #382) or a blind retry that risks a double-fired mutation — the tap lands twice and the flow silently diverges.

Approach:

  1. Runner keeps a small bounded journal of recent command outcomes keyed by commandId — small scalar results retained, snapshots/screenshots explicitly excluded from retention.
  2. On an ambiguous post-send failure the client issues one short-budget status(commandId) probe before invalidating: completed ⇒ return the recovered result (no teardown, no resend); failed ⇒ surface the runner's error; unknown/timeout ⇒ existing invalidation path unchanged.
  3. Mutating verbs (tap/longpress/fill/swipe/scroll) are never auto-resent after an observed accepted/started; read-only verbs keep existing retry.
  4. Follow-on: skip the per-command readiness preflight when a healthy mutating response for the same app landed ≤5s ago; recency lives on the session object, dies with invalidation, and clears on any transport failure.
  5. Diagnostics record per command whether a preflight/probe was used, skipped, or recovered — so a fast path failing stays debuggable.

Measurement gate: injected lost-response tests recover without session teardown; zero duplicated mutations across the suite; hot interaction loops save one runner round-trip per command once the recency skip lands.

Impact: session stability + no double-fired taps · Effort: M · Depends: #385 (capability flags); sits one layer below #386 (tap-level healing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort:mEffort: ~1-3 dayskano:must-beKano: basic expectation — absence causes strong dissatisfactionpriority:nowPick up now (top of refined backlog)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions