Scenario

An agent starts a partner catalogue sync with an idempotency key. The first call returns no usable result before the client timeout. A status tool can check the operation by key, and the server may expose Retry-After when it is temporarily unavailable.

Product problem

A timeout does not prove that nothing happened. Retrying a state-changing call without checking its state first can do the work twice and makes the recovery harder to trust.

AX systems touched

  • Orientation and discovery
  • Tools and interfaces
  • Workflows and state
  • Delegated action and trust
  • Evaluation and improvement

State flow

  1. Start call submittedEvidence: The agent generated an idempotency key and called catalog.start_partner_sync.Next: Wait for a structured result or timeout.
  2. Local timeout creates uncertaintyEvidence: The client has no accepted/failed result after 15 seconds.Next: Record uncertainty instead of retrying the side effect.
  3. Status lookup resolves duplicate riskEvidence: catalog.get_sync_status returns accepted for the same idempotency key.Next: Observe operation sync_7b2 rather than submitting again.
  4. Handoff is verifiableEvidence: Run record contains idempotency key, operation id, status, and next check.Next: Report progress only with the observed state.

Regression case

This input and output come from the decision function the site’s tests run.

{
  "input": {
    "firstAttemptTimedOut": true,
    "idempotencyKey": "sync-key-2026-09-11-a",
    "status": "accepted",
    "operationId": "sync_7b2",
    "retryAfterSeconds": 30
  },
  "output": {
    "state": "in_progress",
    "repeatStartCall": false,
    "next": "poll existing operation after 30 seconds",
    "handoff": "First submit timed out locally; status lookup found accepted operation sync_7b2. I am not resubmitting."
  }
}

Deterministic fixture

User request: “Sync the approved catalogue with the partner account and tell me when it is done.”

Starting state

  • catalog.start_partner_sync requires catalog_id, partner_account_id, and idempotency_key; its result should include operation_id when accepted.
  • catalog.get_sync_status accepts either operation_id or idempotency_key and returns unknown, accepted, running, complete, or failed.
  • The first start call times out locally after 15 seconds and returns no structured result to the agent.
  • A later status check for the same idempotency key returns accepted with operation_id: sync_7b2.

Agent should do

  • Record the first attempt as uncertain, not failed or complete.
  • Check status using the idempotency key before repeating the start call.
  • If status is accepted/running/complete, do not call start again; observe or report the existing operation instead.
  • If the service returns temporary unavailability with Retry-After, wait or schedule the follow-up according to that value before polling again.
  • Return a handoff with the idempotency key, observed status, operation id, and next check.

Agent should not do

  • Do not retry the side-effecting start call merely because the client timed out.
  • Do not erase the timed-out attempt from the run history.
  • Do not report success until a status or result proves the terminal state.

Expected decision: Verify by idempotency key first; because the status is accepted with operation sync_7b2, continue observing that operation instead of submitting a second start call.

Exercise

  1. Classify the timeout state before recovery begins: success, failure, or uncertain.
  2. Choose the next tool call and name the input that prevents duplicate work.
  3. Write the final user-facing handoff if the status check returns running.

Answer key

  1. The timeout state is uncertain because the client lacks proof that the server did or did not accept the operation.
  2. Call catalog.get_sync_status with the original idempotency key; do not repeat catalog.start_partner_sync first.
  3. Handoff: “The first submit timed out locally, but status lookup found operation sync_7b2 running for the same idempotency key. I am not resubmitting. Next check should poll sync_7b2 after the advised delay or until a complete/failed status appears.”

Limits

  • The fixture assumes a trusted service checked the status against the original operation. Accepting whatever status string comes back would not count as verification.
  • It describes one recovery decision. Each API still needs its own retry policy.
  • It assumes the product offers an idempotency key or a status lookup. Without either, handing the decision to a person may be the safer result.
  • It is a teaching case and says nothing about real-world reliability.

Public source basis