Skip to content

[P1][Review] Stop automatic replay of non-idempotent writes and honor explicit retry configuration #104

Description

@karlwaldman

Review-only / approval gate

No implementation, PR merge, package publication or production mutation until the owner approves the full sprint plan.

Evidence

Reviewed main 31b8d80686495c5d6dcac0846d6e5a2c8d4bce8b.

Both client.py and async_client.py retry timeout/transport/5xx failures without considering HTTP method or an idempotency contract. Subscription/webhook creates use these helpers. Server completion followed by a lost response can cause repeated writes. Separately, mocked constructor max_retries=0,retry_on=[] becomes 3 attempts and default statuses due to or defaults. Current main DOES already pass quota headers into RetryStrategy; do not re-file that fixed bug.

Preferred smallest change

Default ambiguous non-idempotent writes to one attempt unless a supported server idempotency contract is present. Use explicit None defaults; define/document whether max_retries counts attempts or retries without silently changing existing callers. Preserve caller intent for retry_on=[]. Keep the current durable-quota suppression.

Acceptance / negative-path tests

Simulate commit-then-timeout for POST creates: one send and clear ambiguous-outcome error; GET transient recovery still works. Sync/async/header-return paths agree; empty retry_on preserved; invalid counts fail clearly; explicit zero behavior documented/tested.

Risk and PR gate

High-risk write replay semantics; Saturday.
One focused issue PR; independent adversarial review must challenge deletion safety, public compatibility, failure recovery and whether a smaller deletion suffices. Include red/green test evidence and packed/installable artifact proof for any published SDK/MCP change. Merge only in the approved priority order after reviewer objections are resolved. Do not publish a breaking change as a patch. If already fixed at execution time, record evidence and skip without a cosmetic PR.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions