docs(sdk): §16 preamble errata — five SDKs diverged (1.8.2) - #285
Merged
Conversation
Second correction to the same paragraph. The count has been wrong twice, and
the reason both times was the survey method rather than the writing, so this
records the method too.
1.8 said two (Java, Rust)
1.8.1 said three (+ TypeScript)
1.8.2 says five (+ Go, C#) — verified exhaustively
What went wrong: 1.8's survey grepped only some of each repo, and 1.8.1's
follow-up grepped `$repo/src` across the board, which silently skipped Go
entirely — its sources live at the repo root, not under src/. Neither pass
looked at C# at all. The command that produced this table walks every repo with
the right per-language file extensions and no path assumption:
grep -rlniE "backoff|jitter" $repo --include="*.go" --include="*.cs" ...
The full table now names all five and marks the two failure modes that are not
about parameters:
Java 3, 200 ms, 5 s, full jitter, Retry-After floor
C# 3, 200 ms, 5 s, jitter <- defaults conform
Rust 3, library-default backoff, no jitter
Go 3, 100 ms, NO CAP, NO JITTER
TypeScript 3, 1000 ms, 8 s, partial jitter, Retry-After REPLACING the backoff
— and never wired into check_access at all
Go's `backoff *= 2` with no cap and no jitter is the shape §16 most wants to
eliminate: uncapped, the third wait is bounded by nothing but the attempt
count, and unjittered, every client retries in lockstep.
C# is a different kind of non-conformance and is called out separately: its
defaults match this table exactly, but MaxRetryAttempts, RetryBaseDelay and
RetryMaxDelay are public settable options. §16.1 permits lowering the cap or
disabling retry, never raising either — a caller who can raise them turns one
client into the herd the policy exists to prevent. That is a code fix for the
C# SDK, tracked to its own D5 PR, not something the contract can fix here.
Docs only, one file, plus the version footer.
This was referenced Aug 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second correction to the same paragraph. The count has been wrong twice, and both times the fault was the survey method rather than the writing — so this records the method as well as the answer.
Why it was wrong twice
1.8's survey grepped only parts of each repo. 1.8.1's follow-up grepped
$repo/srcuniformly — which silently skipped Go entirely, because its sources live at the repo root, not undersrc/. Neither pass looked at C# at all. A grep that finds nothing looks exactly like a repo with nothing to find, which is what made the same mistake survive a correction.The command behind this table makes no path assumption and enumerates per-language extensions:
I also confirmed the six negatives rather than inferring them, and checked one false positive by hand: PHP's
for ($attempt = 0; $attempt < 3; $attempt++)inOidcClient.phpis §9 single-flight coordination, not a §16 transport retry.The verified table
Retry-AfterSix had none at all: Python, Kotlin, PHP, Swift, C, C++.
Three cells are called out in the text, because each is a distinct way the clause gets got wrong:
Retry-After—retryAfterMs ?? backoffDelayMs(attempt)lets aRetry-After: 0retry immediately, defeating the backoff. §16.1's "floor, never a ceiling" was written on principle and turned out to describe shipped code.check_accesssurface.backoff *= 2with no cap and no jitter is the shape this section most wants to eliminate. Uncapped, the third wait is bounded by nothing but the attempt count; unjittered, every client retries in lockstep.A non-conformance the contract can't fix
C# exposes
MaxRetryAttempts,RetryBaseDelayandRetryMaxDelayas public settable options. Its defaults match the table exactly — it is the closest of the five — but §16.1 permits only lowering the cap or disabling retry outright. A caller who can raise them turns one client into the herd the policy exists to prevent.That is a code fix, tracked to the C# SDK's own D5 PR. Noted here so the table isn't read as "C# conforms".
Verification
scripts/check-doc-links.sh— 129 relative links resolved across 21 files. Version footer1.8.1 → 1.8.2.Notes
sdks/CONTRACT.mdplus the footer. No code, no OpenAPI, no proto.mainafter docs(sdk): §16 preamble errata — three SDKs diverged, not two (1.8.1) #284 merged, per the merged-PR rule.Generated by Claude Code