Skip to content

Prevent ambiguous retry replay - #2371

Open
xeophon wants to merge 2 commits into
mainfrom
agent/prevent-ambiguous-retry-replay
Open

Prevent ambiguous retry replay#2371
xeophon wants to merge 2 commits into
mainfrom
agent/prevent-ambiguous-retry-replay

Conversation

@xeophon

@xeophon xeophon commented Aug 15, 2026

Copy link
Copy Markdown
Member

Summary

  • count fresh logical requests per request-body digest
  • replay or coalesce a marked retry only while that digest identifies exactly one logical request
  • let ambiguous retries sample independently instead of returning another request's completion

Root cause

The retry cache and in-flight map are keyed only by request-body digest. When two fresh byte-identical requests overlap, the second request replaces the first request's in-flight future. A marked retry of the first request can then coalesce onto the second request and receive its independently sampled response.

Impact

Normal completed and in-flight SDK retries retain the existing replay behavior. Once a body is reused by another logical request, the server no longer guesses which request a retry belongs to.

Verification

  • focused async probe: completed replay, in-flight coalescing, and ambiguous retry isolation passed
  • uv run pytest tests/: 914 passed, 75 skipped
  • Ruff format and check passed
  • Ty check passed
  • touched-file pre-commit and pre-push hooks passed
  • all-files pre-commit remains blocked by 321 pre-existing MD033 errors in verifiers/legacy/envs/experimental/composable/tasksets/swe/README.md

Note

Prevent ambiguous retry replay in InterceptionServer request handler

  • Adds request_generations (a per-body-digest counter) to RolloutSession to track how many distinct fresh requests share a given body digest.
  • Derives unambiguous_retry in InterceptionServer: a retry is unambiguous only when its body digest maps to exactly one fresh request.
  • Replaying a cached last_response and coalescing with an in-flight request now require unambiguous_retry instead of just retried, preventing identical bodies across distinct fresh requests from incorrectly triggering replay or coalescing.
  • Behavioral Change: retries with body digests seen more than once are now treated as fresh attempts rather than replayed or coalesced.

Macroscope summarized 690c2d1.


Note

Medium Risk
Changes graph-atomicity behavior on the model interception path for overlapping identical bodies; normal single-request SDK retries are unchanged, but ambiguous cases now re-sample instead of replaying.

Overview
Fixes incorrect retry replay and in-flight coalescing when the same request-body digest is used by more than one logical model call (e.g. overlapping byte-identical requests or compaction regenerating the same body).

RolloutSession now tracks request_generations: how many fresh (non-retry) requests have been seen per body digest. On each intercept, fresh requests increment that count; marked SDK retries seed generation 1 when the original never reached the handler.

Replay and in-flight coalescing require unambiguous_retry—a marked retry whose digest still maps to exactly one logical request—instead of any retried request. Ambiguous retries sample independently so they cannot attach to another request’s completion or fork the graph.

Reviewed by Cursor Bugbot for commit 690c2d1. Bugbot is set up for automated code reviews on this repo. Configure here.

@xeophon
xeophon marked this pull request as ready for review August 15, 2026 18:33
@xeophon
xeophon requested a review from mikasenghaas August 15, 2026 18:33

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 109e3e0. Configure here.

Comment thread verifiers/v1/interception/server.py
@macroscopeapp

macroscopeapp Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 690c2d1

Straightforward bug fix that adds safety checks to prevent serving cached responses for the wrong logical request when identical request bodies appear. Small, focused change with clear intent and limited scope.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant