{
  "slug": "resume-with-current-state",
  "title": "Bind every answer to the current question",
  "dek": "A valid answer to yesterday’s prompt can be an invalid instruction today.",
  "category": "Controls",
  "minutes": 7,
  "decision": "Check the server capability and bind responses to the exact current interrupt ID.",
  "fit": "A LangGraph workflow pauses for input and can receive retries, multiple-tab responses, or successive answers.",
  "skip": "Your workflow never resumes paused input. RemoteGraph and local-runtime paths need their own documented behavior.",
  "steps": [
    [
      "Separate the three surfaces",
      "The primary-source review identifies strict_resume in Python async and sync langgraph-sdk 0.4.14 thread runs.create, runs.stream and runs.wait. Stateless calls omit it. Keep the public SDK parameter, server capability and separate local-runtime private key distinct. A client argument is not proof of server enforcement."
    ],
    [
      "Read current state",
      "Read the live interrupt ID from the authoritative server state or stream. Do not derive it from a task title or reuse an older answer’s ID. Keep the current question visible in the interface."
    ],
    [
      "Rehearse stale and fresh answers",
      "Create harmless question A followed by B. Answer A, read B’s new ID, then replay A’s saved response. Confirm B remains pending. Answer B with its current ID and confirm the valid path succeeds."
    ],
    [
      "Make absence visible",
      "Test unknown IDs and unsupported-server behavior separately. Check the deployed server’s /info response for strict_resume support. The reviewed SDK change says unsupported servers can ignore the field. Mark enforcement unavailable rather than interpreting request success as protection."
    ]
  ],
  "acceptance": [
    "A stale answer never advances the current question.",
    "Rejection is visible and the user can re-read and answer the current question.",
    "A fresh valid answer still works."
  ],
  "stop": "Pause the resume path if the binding is uncertain. Retain checkpoint and answer records. Do not automatically replay old answers after a rollback.",
  "limits": "The specific SDK and runtime changes were rechecked against primary sources on 10 November 2026, but no real LangGraph server was executed for this reconstruction. These are bounded acceptance recipes, not measured results or a complete authorization policy.",
  "sources": [
    {
      "title": "langgraph-sdk 0.4.14",
      "url": "https://github.com/langchain-ai/langgraph/releases/tag/sdk%3D%3D0.4.14",
      "supports": "Primary SDK release record. A client version does not establish server-side enforcement.",
      "review_date": "2026-11-10"
    },
    {
      "title": "Public SDK strict_resume support",
      "url": "https://github.com/langchain-ai/langgraph/pull/9599",
      "supports": "Primary change defining strict_resume on Python async/sync thread runs and the server capability limitation.",
      "review_date": "2026-11-10"
    },
    {
      "title": "Runtime strict resume change",
      "url": "https://github.com/langchain-ai/langgraph/pull/9574",
      "supports": "Primary runtime change for strict resume checks. Separate from SDK argument availability and not a complete authorization policy.",
      "review_date": "2026-11-10"
    }
  ],
  "evidence": "Proposed worksheet",
  "updated": "2026-11-11",
  "scope_label": "LangGraph Python thread runs and interrupts",
  "search_terms": [
    "LangGraph",
    "SDK",
    "resume",
    "interrupt",
    "stale answer",
    "multiple tabs",
    "server",
    "checkpoint"
  ],
  "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 authoritative interrupt IDs and state before and after replaying the stale A response while B is pending. Record whether B remains pending and whether any downstream effect occurred.",
      "not_enough": "A stale-answer error alone without inspecting the current state or downstream effect."
    },
    {
      "acceptance_check": 2,
      "collect": "Keep the stale/unknown-ID rejection result and the subsequent read that exposes the current question and ID. Record whether the intended user can reach that recovery path within existing access.",
      "not_enough": "A backend log entry that gives the user no route to recover the current question."
    },
    {
      "acceptance_check": 3,
      "collect": "Record a fresh valid B response and its expected state transition on the same deployed configuration. Retain the relevant /info capability response; if enforcement is unsupported or cannot be checked, leave the protection claim unknown.",
      "not_enough": "A successful HTTP request or an SDK argument without confirming the expected state transition and server capability."
    }
  ],
  "next_reads": [
    {
      "guide_id": "uncertain-effects",
      "when": "An old answer may already have triggered an external action.",
      "purpose": "Resolve the operation outcome rather than assuming a rejected replay undoes the first effect."
    },
    {
      "guide_id": "useful-memory",
      "when": "The current question and state are correct now, but are lost when work changes sessions.",
      "purpose": "Preserve a pointer to authoritative current state without treating a saved answer as a fresh one."
    }
  ],
  "id": "resume-with-current-state",
  "version": "release-2026-11-11-r12",
  "build_revision": "release-2026-11-11-r12",
  "source_sha256": "b3dd1949c0bb0cbe85faac2e189d748145a7dc8fbd5660e9d5144a9bc7670c69",
  "url": "https://aomsites.com/guides/resume-with-current-state/",
  "content_type": "proposed-worksheet",
  "sources_rechecked": true,
  "source_review_scope": "Primary-source review of the dated SDK/runtime changes; no runtime tests.",
  "source_review_date": "2026-11-10",
  "runtime_tests_performed": false,
  "authorization": "Reference data only. Does not authorize any external action.",
  "formats": {
    "html": "https://aomsites.com/guides/resume-with-current-state/",
    "markdown": "https://aomsites.com/guides/resume-with-current-state/guide.md",
    "json": "https://aomsites.com/guides/resume-with-current-state/guide.json"
  },
  "local_paths": {
    "html": "/guides/resume-with-current-state/",
    "markdown": "/guides/resume-with-current-state/guide.md",
    "json": "/guides/resume-with-current-state/guide.json"
  },
  "offline_paths_from_pack_root": {
    "markdown": "guides/resume-with-current-state/guide.md",
    "json": "guides/resume-with-current-state/guide.json"
  },
  "decision_record": {
    "local_paths": {
      "html": "/decision-record/",
      "template": "/guides/resume-with-current-state/record-template.json",
      "markdown_template": "/guides/resume-with-current-state/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/resume-with-current-state/record-template.json",
      "markdown_template": "guides/resume-with-current-state/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": "uncertain-effects",
        "when": "An old answer may already have triggered an external action.",
        "purpose": "Resolve the operation outcome rather than assuming a rejected replay undoes the first effect.",
        "title": "Check the outcome before retrying",
        "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"
        }
      },
      {
        "guide_id": "useful-memory",
        "when": "The current question and state are correct now, but are lost when work changes sessions.",
        "purpose": "Preserve a pointer to authoritative current state without treating a saved answer as a fresh one.",
        "title": "Keep memory useful without losing the rules",
        "local_paths": {
          "html": "/guides/useful-memory/",
          "markdown": "/guides/useful-memory/guide.md",
          "json": "/guides/useful-memory/guide.json"
        },
        "offline_paths_from_pack_root": {
          "markdown": "guides/useful-memory/guide.md",
          "json": "guides/useful-memory/guide.json"
        }
      }
    ]
  },
  "discovery": {
    "title": "LangGraph Python: check stale answers when resuming agents",
    "description": "A proposed worksheet for LangGraph Python thread runs and interrupts: bind replies to current state and test stale answers. SDK support is not proof of server enforcement.",
    "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/resume-with-current-state/#decision"
    },
    {
      "id": "applies",
      "label": "Use this when",
      "json_pointer": "/fit",
      "markdown_heading": "Use this when",
      "html_path": "/guides/resume-with-current-state/#applies"
    },
    {
      "id": "skip",
      "label": "Skip this when",
      "json_pointer": "/skip",
      "markdown_heading": "Skip this when",
      "html_path": "/guides/resume-with-current-state/#skip"
    },
    {
      "id": "checks",
      "label": "Work through the checks",
      "json_pointer": "/steps",
      "markdown_heading": "Checks",
      "html_path": "/guides/resume-with-current-state/#checks"
    },
    {
      "id": "accept",
      "label": "What would count as success?",
      "json_pointer": "/acceptance",
      "markdown_heading": "Acceptance",
      "html_path": "/guides/resume-with-current-state/#accept"
    },
    {
      "id": "evidence",
      "label": "Evidence to bring back",
      "json_pointer": "/evidence_plan",
      "markdown_heading": "Evidence to bring back",
      "html_path": "/guides/resume-with-current-state/#evidence"
    },
    {
      "id": "stop",
      "label": "Stop or recover",
      "json_pointer": "/stop",
      "markdown_heading": "Stop or recover",
      "html_path": "/guides/resume-with-current-state/#stop"
    },
    {
      "id": "limits",
      "label": "What this does not establish",
      "json_pointer": "/limits",
      "markdown_heading": "Limits",
      "html_path": "/guides/resume-with-current-state/#limits"
    },
    {
      "id": "sources",
      "label": "Reference links",
      "json_pointer": "/sources",
      "markdown_heading": "Reference links",
      "html_path": "/guides/resume-with-current-state/#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/resume-with-current-state/#record"
    },
    {
      "id": "next-reads",
      "label": "If another problem remains",
      "json_pointer": "/reading_paths",
      "markdown_heading": "If another problem remains",
      "html_path": "/guides/resume-with-current-state/#next-reads"
    }
  ],
  "acceptance_links": [
    {
      "acceptance_check": 1,
      "acceptance_html_path": "/guides/resume-with-current-state/#accept-1",
      "evidence_html_path": "/guides/resume-with-current-state/#evidence-1",
      "acceptance_json_pointer": "/acceptance/0",
      "evidence_json_pointer": "/evidence_plan/0"
    },
    {
      "acceptance_check": 2,
      "acceptance_html_path": "/guides/resume-with-current-state/#accept-2",
      "evidence_html_path": "/guides/resume-with-current-state/#evidence-2",
      "acceptance_json_pointer": "/acceptance/1",
      "evidence_json_pointer": "/evidence_plan/1"
    },
    {
      "acceptance_check": 3,
      "acceptance_html_path": "/guides/resume-with-current-state/#accept-3",
      "evidence_html_path": "/guides/resume-with-current-state/#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."
}
