When a connection fails after pressing a button but before its reply arrives, pressing again is tempting. The browser and service may already have processed it. I separated connection errors from work failure and required inspection of the existing outcome before another action.

The error establishes only that the reply was not received

A closed socket or timeout establishes that the caller did not receive a complete reply. It cannot alone determine whether input was dispatched, the service processed it or only the reply was late. Collapsing those possibilities into failure makes recovery a source of duplication.

Intermediary and client errors therefore disable automatic replay explicitly. A field does not eliminate every duplicate, but it clarifies the next decision: inspect the existing task, run or page outcome before considering another submission.

Do not confuse the two request-number layers

The stdio client's JSON-RPC number differs from the pipe's UUID. bridgeCall creates a new UUID by default. Sending the same tool and arguments again, or using a similar JSON-RPC number, does not automatically reuse an earlier pipe receipt.

Process-lifetime receipt protection applies when the same pipe ID carries the same content. An ordinary new tools/call is not inherently a safe reread. Recovery documentation needs this distinction to avoid exaggerating what deduplication actually protects.

Provide a route for reading existing work

Browser resume reads current context and requires the requested task ID to be running. It does not attach to another task. A matching task with a pending outcome starts blocked, preserving uncertainty across reconnection.

Plugins offer status reading by run ID with scope checks. Status is different from a new run request. Finished work or state changed by restart needs handling appropriate to that state. The name resume cannot mean unconditional continuation of every historical job. The caller should retain task and run identifiers from the start reply so recovery can compare them with the current execution instead of guessing which work a reconnected session belongs to.

Verify the original expected outcome

verifyOutcome reads the result of the uncertain input; it does not create a success screen by clicking again. A confirmed result can allow progress, while another timeout retains blocking. A user stop must remain a stop.

The convenience API blocks another fill after uncertainty while allowing reads. Replacing the expectation with an easier success text merely because the result was hard to observe would invalidate verification. Comparing the original expectation with current observation distinguishes a late success from unresolved work.

Count dispatches as well as checking error text

The fixture test rejects another mutation and completion after an uncertain Enter. It checks that only one mutation occurred while reads remained possible. A late-result check must likewise leave the dispatch count unchanged.

This account reads the current client, page API and actual test code. I did not interrupt a live reservation or upload to create duplicates. Fixture control-flow evidence differs from storage guarantees at an external service, where durable journals and service-specific inspection can still be needed.

Recovery guidance is an interface for the next action

A message saying only connection error, retry encourages another submission. The caller needs a way to inspect what was requested and what outcome now exists. Recovering communication and deciding to start work again are different operations.

Other work tools benefit from read-only outcome checks and an uncertain state for actions that leave effects. Evidence of non-dispatch differs from unknown delivery. An agent-friendly interface should expose that distinction rather than hiding it behind automatic retries.