Skip to content

fix: isolate adversarial stage sub-agents from spine persistence [refs OSWE-239] - #121

Merged
ericlitman merged 1 commit into
mainfrom
oswe-239-subagent-checkpointer-isolation
Aug 4, 2026
Merged

fix: isolate adversarial stage sub-agents from spine persistence [refs OSWE-239]#121
ericlitman merged 1 commit into
mainfrom
oswe-239-subagent-checkpointer-isolation

Conversation

@ericlitman

Copy link
Copy Markdown
Owner

Why

The first production adversarial review (tonal-api#3) published nothing and exited success in 4.6s; tonight's canary (PR #120) reproduced it in 3.1s — with PR #117's instrumentation finally exposing the mechanism. Ten Ignoring unknown node name find in pending sends warnings fired from inside the finder nodes: _run_stage forwards the spine node's runtime config (thread_id, checkpoint_ns, the platform's injected checkpointer) into each bounded sub-agent's ainvoke, so under production persistence every stage sub-agent runs as a checkpoint-sharing subgraph of the spine — it loads the spine's own checkpoint, chokes on the spine's pending Send("find") tasks, returns no structured response, and the spine settles and exits success. Locally there is no checkpointer, so all tests passed. LangSmith corroborates: the failed adversarial roots cost 4.3k/4.8k tokens vs ~600k for a real review.

What changed

_bounded_agent passes checkpointer=False — langgraph's documented opt-out from inherited persistence (pregel/main.py resolves False unconditionally, overriding ambient CONFIG_KEY_CHECKPOINTER). Stage sub-agents now run stateless-fresh under any parent checkpointing. _run_stage is untouched, so tracing/callbacks keep flowing.

Regression test

test_stage_subagent_ignores_spine_checkpointer_and_thread: a real _bounded_agent finder driven through a minimal spine replica (node named find, Send fan-out, closure-over-config) under a real InMemorySaver with thread_id + injected CONFIG_KEY_CHECKPOINTER. Mutation check: deleting the fix line reproduces the exact production warning 4x and fails the test; restoring it passes.

Verification

  • uv run pytest tests/reviewer/test_reviewer_adversarial.py → 36 passed
  • uv run pytest -q tests/ → 2383 passed
  • make lint clean; make typecheck 0 errors

Analysis and live evidence on OSWE-239.

🤖 Generated with Claude Code

…s OSWE-239]

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ericlitman
ericlitman enabled auto-merge August 4, 2026 07:06

@mobilyze-open-swe-studio2 mobilyze-open-swe-studio2 Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Open SWE Review: No issues found

Open SWE reviewed this PR and found no potential bugs to report.

Open in Web

@ericlitman
ericlitman merged commit 4c994a6 into main Aug 4, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant