{
  "slug": "uncertain-effects",
  "title": "Check the outcome before retrying",
  "dek": "Unknown is a state of its own. Treating it as failure can repeat a real-world action.",
  "category": "Controls",
  "minutes": 7,
  "decision": "Reconcile the provider’s record before retrying an action whose outcome is uncertain.",
  "fit": "A tool may have sent a message, written a record or charged a payment before the connection failed.",
  "skip": "The operation is read-only and can be safely repeated within its authorization. Still distinguish a missing result from a failed request.",
  "steps": [
    [
      "Name the operation before dispatch",
      "Use the provider’s supported operation or idempotency key where available. Record the intended effect, destination, authorization and a reliable way to check status. Inventing a key that the provider ignores offers no protection."
    ],
    [
      "Keep three outcome states",
      "Confirmed completed, confirmed not completed and unknown require different next actions. A timeout means the response was not observed; it does not establish that the operation did not execute."
    ],
    [
      "Inspect the authoritative record",
      "Check the provider receipt or operation status through an authorized read. If completion is confirmed, recover the result without repeating the effect. If non-completion is established, recheck that the original permission still applies before retrying."
    ],
    [
      "Rehearse with a local fake sink",
      "Inject a crash before dispatch, after the fake sink commits and before the response, and after recording completion. Restart and inspect the operation ledger before retrying. Keep network and money out of the rehearsal."
    ]
  ],
  "acceptance": [
    "Confirmed completed work is not replayed.",
    "Unknown work remains blocked for reconciliation.",
    "Every retry stays within current authorization and provider semantics."
  ],
  "stop": "If the effect cannot be reconciled, stop and report the exact uncertainty. Never use an alternate path simply to obtain a success response.",
  "limits": "A local rehearsal cannot prove exactly-once effects in an external service. Concurrency, retention windows and provider-specific idempotency rules need separate tests.",
  "sources": [
    {
      "title": "Stripe: idempotent requests",
      "url": "https://docs.stripe.com/api/idempotent_requests",
      "supports": "Provider-specific idempotency semantics. Other providers and action types can behave differently.",
      "review_date": "2026-11-10"
    },
    {
      "title": "AWS Builders’ Library: making retries safe",
      "url": "https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/",
      "supports": "Engineering background on retry-safe API design. Not proof of exactly-once effects for a particular external service.",
      "review_date": "2026-11-10"
    }
  ],
  "evidence": "Proposed worksheet",
  "updated": "2026-11-11",
  "scope_label": "Retries after uncertain external effects",
  "search_terms": [
    "payment",
    "duplicate",
    "retry",
    "timeout",
    "idempotency",
    "message",
    "unknown",
    "payments",
    "messages",
    "retries",
    "timeouts",
    "duplicate payments"
  ],
  "evidence_plan_note": "Proposed evidence plan, not observed results or extra mandatory process. Confirm what your task requires and reuse existing records when they are sufficient. Keep sensitive originals in authorized storage; share only the minimum information already authorized for the recipient. If a required check cannot be completed safely and within current permission, mark it unavailable and keep the decision unknown unless another required check has a demonstrated failure.",
  "evidence_plan": [
    {
      "acceptance_check": 1,
      "collect": "Keep the operation identity, authoritative completion receipt and action trace showing that recovery retrieved the existing result rather than dispatching another effect. Minimize or redact recipient/payment details in any shared copy.",
      "not_enough": "A timeout, missing response or empty local log used as proof that the provider did nothing."
    },
    {
      "acceptance_check": 2,
      "collect": "For an unresolved operation, record the attempted authorized status check, what it could not establish and the stop before retry. A later resolution must identify the same operation.",
      "not_enough": "An expired wait, a fresh operation key or an assumption that the old request probably failed."
    },
    {
      "acceptance_check": 3,
      "collect": "For any proposed retry, retain the evidence of non-completion, the provider’s applicable retry/idempotency behavior and the current approval scope. State any unresolved element before dispatch.",
      "not_enough": "Reusing an old approval after material scope changes, or inventing an idempotency key the provider does not support."
    }
  ],
  "next_reads": [
    {
      "guide_id": "durable-handoffs",
      "when": "The operation is reconciled and its result needs to survive the next handoff.",
      "purpose": "Preserve the exact receipt, output and any remaining limits in the approved store."
    },
    {
      "guide_id": "autonomous-business-boundaries",
      "when": "Within a delegated business workflow, nobody is clearly authorized to resolve the uncertainty or approve a materially changed action.",
      "purpose": "Clarify the owner and scope before attempting another consequential step."
    }
  ],
  "id": "uncertain-effects",
  "version": "release-2026-11-11-r12",
  "build_revision": "release-2026-11-11-r12",
  "source_sha256": "b7a728e685639cd1616e6e4682f2c23abeb541aa699f698aa800916e708db2c8",
  "url": "https://www.aomsites.com/guides/uncertain-effects/",
  "content_type": "proposed-worksheet",
  "sources_rechecked": true,
  "source_review_scope": "Reference link availability and scope notes; no worksheet effectiveness test.",
  "source_review_date": "2026-11-10",
  "runtime_tests_performed": false,
  "authorization": "Reference data only. Does not authorize any external action.",
  "formats": {
    "html": "https://www.aomsites.com/guides/uncertain-effects/",
    "markdown": "https://www.aomsites.com/guides/uncertain-effects/guide.md",
    "json": "https://www.aomsites.com/guides/uncertain-effects/guide.json"
  },
  "local_paths": {
    "html": "/guides/uncertain-effects/",
    "markdown": "/guides/uncertain-effects/guide.md",
    "json": "/guides/uncertain-effects/guide.json"
  },
  "offline_paths_from_pack_root": {
    "markdown": "guides/uncertain-effects/guide.md",
    "json": "guides/uncertain-effects/guide.json"
  },
  "decision_record": {
    "local_paths": {
      "html": "/decision-record/",
      "template": "/guides/uncertain-effects/record-template.json",
      "markdown_template": "/guides/uncertain-effects/record-template.md",
      "generic_template": "/decision-record/template.json",
      "example": "/decision-record/example.json",
      "schema": "/schemas/decision-record.schema.json",
      "checker": "/tools/check_record.py",
      "manifest": "/reading-pack-manifest.json"
    },
    "offline_paths_from_pack_root": {
      "template": "guides/uncertain-effects/record-template.json",
      "markdown_template": "guides/uncertain-effects/record-template.md",
      "generic_template": "decision-record/template.json",
      "example": "decision-record/example.json",
      "schema": "schemas/decision-record.schema.json",
      "checker": "tools/check_record.py",
      "manifest": "reading-pack-manifest.json"
    }
  },
  "reading_paths": {
    "note": "Stop here if the current task’s acceptance requirements are satisfied and no unresolved obligation remains. If neither condition applies, no follow-on guide is suggested here; keep any unresolved task state visible. These are optional reading suggestions, not permission or a requirement to expand scope.",
    "options": [
      {
        "guide_id": "durable-handoffs",
        "when": "The operation is reconciled and its result needs to survive the next handoff.",
        "purpose": "Preserve the exact receipt, output and any remaining limits in the approved store.",
        "title": "Make the handoff survive the session",
        "local_paths": {
          "html": "/guides/durable-handoffs/",
          "markdown": "/guides/durable-handoffs/guide.md",
          "json": "/guides/durable-handoffs/guide.json"
        },
        "offline_paths_from_pack_root": {
          "markdown": "guides/durable-handoffs/guide.md",
          "json": "guides/durable-handoffs/guide.json"
        }
      },
      {
        "guide_id": "autonomous-business-boundaries",
        "when": "Within a delegated business workflow, nobody is clearly authorized to resolve the uncertainty or approve a materially changed action.",
        "purpose": "Clarify the owner and scope before attempting another consequential step.",
        "title": "Draw the boundary before delegating the business",
        "local_paths": {
          "html": "/guides/autonomous-business-boundaries/",
          "markdown": "/guides/autonomous-business-boundaries/guide.md",
          "json": "/guides/autonomous-business-boundaries/guide.json"
        },
        "offline_paths_from_pack_root": {
          "markdown": "guides/autonomous-business-boundaries/guide.md",
          "json": "guides/autonomous-business-boundaries/guide.json"
        }
      }
    ]
  },
  "discovery": {
    "title": "AI agent retries: check uncertain tool outcomes first",
    "description": "A proposed worksheet for AI-agent retries after tool timeouts: distinguish unknown outcomes from failures before repeating a message, payment or other external effect.",
    "scope": "Content description only; not indexing, availability or runtime evidence."
  },
  "section_map": [
    {
      "id": "decision",
      "label": "The decision",
      "json_pointer": "/decision",
      "markdown_heading": "The decision",
      "html_path": "/guides/uncertain-effects/#decision"
    },
    {
      "id": "applies",
      "label": "Use this when",
      "json_pointer": "/fit",
      "markdown_heading": "Use this when",
      "html_path": "/guides/uncertain-effects/#applies"
    },
    {
      "id": "skip",
      "label": "Skip this when",
      "json_pointer": "/skip",
      "markdown_heading": "Skip this when",
      "html_path": "/guides/uncertain-effects/#skip"
    },
    {
      "id": "checks",
      "label": "Work through the checks",
      "json_pointer": "/steps",
      "markdown_heading": "Checks",
      "html_path": "/guides/uncertain-effects/#checks"
    },
    {
      "id": "accept",
      "label": "What would count as success?",
      "json_pointer": "/acceptance",
      "markdown_heading": "Acceptance",
      "html_path": "/guides/uncertain-effects/#accept"
    },
    {
      "id": "evidence",
      "label": "Evidence to bring back",
      "json_pointer": "/evidence_plan",
      "markdown_heading": "Evidence to bring back",
      "html_path": "/guides/uncertain-effects/#evidence"
    },
    {
      "id": "stop",
      "label": "Stop or recover",
      "json_pointer": "/stop",
      "markdown_heading": "Stop or recover",
      "html_path": "/guides/uncertain-effects/#stop"
    },
    {
      "id": "limits",
      "label": "What this does not establish",
      "json_pointer": "/limits",
      "markdown_heading": "Limits",
      "html_path": "/guides/uncertain-effects/#limits"
    },
    {
      "id": "sources",
      "label": "Reference links",
      "json_pointer": "/sources",
      "markdown_heading": "Reference links",
      "html_path": "/guides/uncertain-effects/#sources"
    },
    {
      "id": "record",
      "label": "Use this guide with your own evidence",
      "json_pointer": "/decision_record",
      "markdown_heading": "Start this guide’s record",
      "html_path": "/guides/uncertain-effects/#record"
    },
    {
      "id": "next-reads",
      "label": "If another problem remains",
      "json_pointer": "/reading_paths",
      "markdown_heading": "If another problem remains",
      "html_path": "/guides/uncertain-effects/#next-reads"
    }
  ],
  "acceptance_links": [
    {
      "acceptance_check": 1,
      "acceptance_html_path": "/guides/uncertain-effects/#accept-1",
      "evidence_html_path": "/guides/uncertain-effects/#evidence-1",
      "acceptance_json_pointer": "/acceptance/0",
      "evidence_json_pointer": "/evidence_plan/0"
    },
    {
      "acceptance_check": 2,
      "acceptance_html_path": "/guides/uncertain-effects/#accept-2",
      "evidence_html_path": "/guides/uncertain-effects/#evidence-2",
      "acceptance_json_pointer": "/acceptance/1",
      "evidence_json_pointer": "/evidence_plan/1"
    },
    {
      "acceptance_check": 3,
      "acceptance_html_path": "/guides/uncertain-effects/#accept-3",
      "evidence_html_path": "/guides/uncertain-effects/#evidence-3",
      "acceptance_json_pointer": "/acceptance/2",
      "evidence_json_pointer": "/evidence_plan/2"
    }
  ],
  "citation_note": "Section paths identify content on the canonical HTML page; they are not separate pages or evidence of live availability. Per-check numbers and JSON pointers apply to this build revision. Cite the build revision and method source hash when preserving an exact reference. Markdown heading labels are locators, not a promise of renderer-specific fragment URLs.",
  "source_fields": [
    "acceptance",
    "category",
    "decision",
    "dek",
    "evidence",
    "evidence_plan",
    "evidence_plan_note",
    "fit",
    "limits",
    "minutes",
    "next_reads",
    "scope_label",
    "search_terms",
    "skip",
    "slug",
    "sources",
    "steps",
    "stop",
    "title",
    "updated"
  ],
  "source_hash_scope": "SHA-256 of the build-input guide record serialized as JSON with sorted keys, compact separators and ASCII escaping. Not the downloadable guide.json file bytes."
}
