Repository navigation
[Trace] Template de-dup: de-duplicate SDK doc boilerplate across docs/SDKs - #174
Merged
Merged
Conversation
…/SDKs 10 deliverable-*/partner-* pages carried a full copy of the generic Error Handling intro + status-code table already documented once on each language's canonical page (javascript.md, python.md, go.md, php.md, java.md). template-detector.mjs flagged the same 5-word phrases across ~17 files, matching the URL Inspection evidence that javascript, python, java, quote-javascript, webhooks-java, deliverable-go, and deliverable-php are crawled/discovered but not indexed. Replaced the duplicated table on each deliverable-*/partner-* page with a short paragraph naming the errors that operation actually raises (verified against /home/nicolas/repos/SDK), followed by a link to the language's own Error Handling reference for the full table. Kept the already-differentiated code samples and product-specific notes (Go's errors.As, PHP's typed exceptions, Java's nested TurboDocxException.* classes, partner's IOException/409-conflict callouts) as-is. Also: - Fixed a real bug found while verifying code samples: index.md's PHP error handling example called $e->getCode(), but PHP's Exception::getCode() is hardcoded to 0 by TurboDocxException's constructor; the real field is $e->errorCode. - Fixed two broken links (go.md, java.md pointed at /docs/TurboSign/API-Signatures instead of the correctly-encoded .../API%20Signatures used elsewhere in the same files) and two broken anchors (partner-php.md, partner-javascript.md linked to #orguserrole-organization-users, truncated; the real heading slugifies to #orguserrole-organization-users-and-org-api-keys). - Shortened 11 frontmatter descriptions over 160 chars (agent-skills + 5 quote-*/5 webhooks-* pages) to <=155 chars, language + product first. Not fixed (noted for the owner): docs/SDKs/ruby.md and deliverable-ruby.md 404 live but still get search impressions. This is intentional (draft: true, set in 40efd12 because the gem isn't on RubyGems yet); Docusaurus excludes draft pages from the production build. If those impressions are worth capturing, that needs a redirect decision, not a content change.
added 7 commits
September 23, 2026 07:52
…s, fix canonical tables
Follow-up to the previous commit after review found three real gaps:
1. The 5 canonical per-language pages (javascript.md, python.md, go.md,
php.md, java.md) still shared the generic "The SDK provides typed
error(s)/exception(s) for different ... scenarios" intro sentence
verbatim, and 3 of them (javascript, python, java) are themselves
evidence pages (crawled/discovered but not indexed). Rewrote each
intro to state the real, verified idiom for that language: Go's
errors.As + embedded struct, PHP's readonly statusCode/errorCode
(and the getCode()-returns-0 gotcha), Java's nested
TurboDocxException.* classes with getCode()'s orDefault fallback,
JS's code passthrough from the API response, Python's DEFAULT_CODE
class attribute and Exception-subclass catch order. Sourced from
packages/{go,php,java,js,py}-sdk directly (errors.ts,
TurboDocxException.java, TurboDocxException.php, http.py).
2. deliverable-go.md and deliverable-php.md linked to go.md/php.md as
the canonical Error Handling reference for classes those pages
didn't actually document: go.md's table was missing ConflictError
(it exists in http.go) and php.md's was missing
AuthorizationException and ConflictException (both exist in
packages/php-sdk/src/Exceptions/). Added the missing rows so the
canonical pages actually contain what the product pages point to.
3. Removed unverified "most commonly" frequency language from the 10
deliverable-*/partner-* pages' Error Handling intros (added in the
previous commit); rephrased as "returns/throws/raises X when Y"
without a frequency claim.
Also swept remaining em-dashes in the 5 base-language pages, now that
they have real body edits (previously only go.md/java.md were fully
swept, for their link fixes).
…andling intro
The previous wording implied errors.As was needed specifically because
TurboDocxError is embedded by value ("so match... rather than a type
switch"), which isn't the right causal link and isn't accurate SDK
guidance (a plain type switch would work fine on the unwrapped return
values; errors.As is just the more defensive/robust choice against any
future wrapping). Reworded to state two independently-true facts: by-
value embedding promotes the fields for direct access, and the SDK's
own example already uses errors.As.
Second review pass found more accuracy issues: - go.md/java.md/python.md's Code-field descriptions said the machine- readable code is "always populated". True only for the 7 named subclasses (each has a default). The bare base error returned for an unmapped HTTP status (e.g. an unexpected 5xx) can have an empty/null code, verified: Go's defaultErrorCode() returns "" in its default case, Java's HttpClient.java falls through to `new TurboDocxException(message, code, ...)` with no fallback, and Python's base TurboDocxError has DEFAULT_CODE = None. Qualified all three. - index.md's Java Error Handling tab imported `com.turbodocx.sdk.*` (wrong package; the SDK's actual package is `com.turbodocx`, no `.sdk`), used a response type SigningResult that doesn't exist, and called `turboSign.sendSignature(...)` on a bare variable instead of `client.turboSign().sendSignature(...)`. All three didn't match java.md's own (correct) examples. Fixed to match. - Five deliverable-*.md pages claimed ValidationError fires when a variable is missing "placeholder or mimeType". Checked RapidDocxBackend's actual generate-deliverable handler (DeliverableGenerationHandlers.ts): the Variable interface has `placeholder: string` (required) but `mimeType?: string` (optional). Dropped the incorrect mimeType half of the claim.
…ied field claim
Third review pass on index.md's Error Handling tabs (the same code
block already touched for the PHP getCode()/Java package fixes):
- Go tab: errors.As(err, &turboErr) targeted *sdk.TurboDocxError only.
Go's errors.As requires the target's concrete type to match; the 6
named error types (ValidationError, AuthenticationError, ...) are
distinct types from TurboDocxError even though they embed it, and
none implement Unwrap/As, so this silently matched nothing except
the generic unmapped-status case. The VALIDATION_ERROR branch shown
was dead code. Fixed to match *sdk.ValidationError directly.
- Python tab: printed e.message, but TurboDocxError.__init__ never
sets self.message and Python 3's Exception doesn't have one either,
so this raises AttributeError at runtime. Fixed to {e} (str(e)),
matching python.md's own examples.
- Java tab: missing the com.turbodocx.models.* import that
SendSignatureResponse needs (follow-up to the package-name fix in
the previous commit).
- The "code is always populated" line above these tabs had the same
gap already qualified on the language pages. Qualified it the same
way.
Also corrected the 5 deliverable-*.md pages' claim that ValidationError
fires on a variable missing "placeholder or mimeType". Checked
RapidDocxBackend's DeliverableGenerationHandlers.ts: the Variable
interface has placeholder required, mimeType optional (the reverse of
what was claimed), and I could not find where a missing placeholder is
actually validated at the HTTP boundary (the handler doesn't appear to
check it before using it). Rather than assert an unverified 400, all 5
now say "missing a required field" without naming one, matching
deliverable-java.md's already-safe phrasing.
…rors broke the build) 11 SDK pages (agent-skills, quote-*, webhooks-*) had unquoted description values like 'TurboQuote Go SDK: ...'; YAML reads the second ': ' as a mapping and Docusaurus fails to build. Quote them.
This branch was successfully deployed
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.
Closes #173
Trace task:
template-detector.mjs,config/anti-ai-rules.json, CONTENT SOP "Crawled - currently not indexed" rule (de-duplicate first).Evidence
URL Inspection shows Google refusing to index substantial SDK pages:
docs/SDKs/javascript(4,186 words, crawled - not indexed),python,quote-javascript,webhooks-java,deliverable-go,deliverable-php(crawled - not indexed),java(discovered - not indexed).template-detector.mjsfound the same 5-word phrases repeated across 15 of the 27 live (non-Ruby) SDK pages (a first pass with the tool's own reporting quirks read this as ~17; see "Template detector" below): a generic "Error Handling" intro sentence plus a 7-row status-code table with identical English wording (Invalid or missing API key,Invalid request parameters,Too many requests,Network connectivity issues) copy-pasted regardless of language or product.queries.jsonshows real developer demand: "python digital signature sdk" (433 impressions, currently ranking on the dotcom guide/guides/sign-documents-with-python, not this docs page), "php digital signature sdk" (378, same pattern), "javascript pdf signature integration" (337, same pattern). Data source:queries.jsoncomes fromqueries.py, which calls the Google Search Console API directly (searchAnalytics.queryvia agcloudADC bearer token), not PostHog's GSC warehouse; re-verified all three figures against the file before citing them.What changed
Two layers of duplication, two fixes.
1. De-dup (10 files:
deliverable-{go,php,java,javascript,python}.md,partner-{go,php,java,javascript,python}.md): each carried a full copy of the generic error-type table already documented once on the language's canonical page. Replaced the generic intro + table with a short paragraph naming an error that operation actually raises (verified against/home/nicolas/repos/SDK), followed by a link to the language's Error Handling reference for the full table. Kept the already-differentiated code samples and product-specific notes (Go'serrors.As, PHP's typed exceptions, Java's nestedTurboDocxException.*, partner'sIOException/409-conflict callouts).quote-*.md/webhooks-*.mdhad no such generic error table to begin with, so not part of this fix. (They have their own, separate cross-language duplication in their product-intro paragraphs, disclosed further down; unrelated to the error-table issue fixed here.)2. Rewrote the 5 canonical pages themselves (
go.md,php.md,java.md,javascript.md,python.md): all five opened## Error Handlingwith the identical sentence "The SDK provides typed error(s)/exception(s) for different ... scenarios." Three of those five (javascript.md,python.md,java.md) are themselves evidence pages Google won't index. Replaced each intro with that language's real, source-verified idiom:go.md: errors embedTurboDocxErrorby value; match witherrors.As, read fields directly. Added theConflictErrorrow/case that existed inpackages/go-sdk/http.gobut wasn't documented.php.md:statusCode/errorCodeare public readonly properties; PHP's inheritedException::getCode()is hardcoded to0by the constructor, a real footgun. Added theAuthorizationException/ConflictExceptionrows and catches that existed inpackages/php-sdk/src/Exceptions/but weren't documented, even thoughpartner-php.md/deliverable-php.mdalready referenced them.java.md: every exception is a nested static class ofTurboDocxException; each of the 7 named subclasses falls back to its ownDEFAULT_CODEvia a sharedorDefaulthelper, sogetCode()is populated for those, though the bareTurboDocxExceptionfor an unmapped status has no such fallback.javascript.md:codeis a plain string the HTTP client passes through from the API response when present, falling back to the class default only when the API doesn't supply one, per the docstring inpackages/js-sdk/src/utils/errors.ts.python.md: every subclass sets its ownDEFAULT_CODEclass attribute; catch the most specific exception first sinceexcept TurboDocxErroralso matches its subclasses.Bug fixes (
index.md), found while verifying the code samples against source:$e->getCode(), which PHP'sException::getCode()hardcodes to0inTurboDocxException's constructor. The real field is the public readonly$e->errorCode(packages/php-sdk/src/Exceptions/TurboDocxException.php). Fixed.com.turbodocx.sdk.*(the SDK's real package iscom.turbodocx, no.sdk), returned aSigningResulttype that doesn't exist, and calledturboSign.sendSignature(...)on a bare variable instead ofclient.turboSign().sendSignature(...). Fixed to matchjava.md's own correct examples; also added thecom.turbodocx.models.*import thatSendSignatureResponseneeds.errors.As(err, &turboErr)against*sdk.TurboDocxErroronly. Go'serrors.Asrequires the target's concrete type to match;*sdk.ValidationError(and the 5 other named error types) is a distinct type from*sdk.TurboDocxErroreven though it embeds it, and neither implementsUnwrap/As, so that check silently failed to match any of the 6 named error types, only the generic unmapped-status case, meaning theVALIDATION_ERRORbranch shown was dead code. Fixed to match*sdk.ValidationErrordirectly.e.message.TurboDocxError.__init__never setsself.message(Python 3'sExceptiondoesn't have one either), so this raisesAttributeErrorat runtime. Fixed to{e}(str(e)), matchingpython.md's own examples.codeis always populated" line above these tabs had the same gap the language-page corrections below describe. Qualified it the same way.Correction (5 deliverable-*.md pages): these claimed
ValidationErrorfires when a variable is missing "placeholderormimeType". CheckedRapidDocxBackend/src/handlers/Deliverable/DeliverableGenerationHandlers.ts: itsVariableinterface hasplaceholder: string(required) butmimeType?: string(optional), the opposite emphasis. Couldn't find the runtime validation for a missingplaceholderspecifically (the handler doesn't appear to check it before using it), so rather than assert an unverified 400, all 5 pages now say "missing a required field" without naming one.Corrections ("always populated" claims in
go.md/java.md/python.md): the Code-field descriptions I originally wrote said the machine-readable code is always populated. True only for the 7 named error subclasses, each with its own default. The bare base error returned for an unmapped HTTP status (an unexpected 5xx, for example) can have an empty/null code: Go'sdefaultErrorCode()returns""in its default case, Java'sHttpClient.javafalls through to the bareTurboDocxExceptionconstructor with no fallback, Python's baseTurboDocxErrorhasDEFAULT_CODE = None. Qualified all three.Broken links (4 files):
go.md/java.mdlinked/docs/TurboSign/API-Signatures(hyphen, 404) instead of the correctly-encoded.../API%20Signaturesused elsewhere in the same files.partner-php.md/partner-javascript.mdlinked#orguserrole-organization-users, truncated; the real heading (### OrgUserRole (Organization Users and Org API Keys)) slugifies to#orguserrole-organization-users-and-org-api-keys.Frontmatter descriptions (11 files):
agent-skills.md+ 5quote-*/5webhooks-*pages had descriptions over 160 chars; shortened to <=155, language + product first.Noted, not fixed:
docs/SDKs/ruby.md/deliverable-ruby.md(and 3 other Ruby product pages) 404 live but still get search impressions. Confirmed the removal was intentional:draft: truesince commit40efd12because theturbodocx-sdkgem isn't on RubyGems yet; Docusaurus excludes draft pages from the production build. Per the task's own criterion, intentional removal that still draws impressions needs a redirect. The owner picks the target and timing:javascript.md/python.mdare the closest topical peers, but both are also on the not-indexed list themselves, so neither is an obviously "safe" redirect target either.Out of scope: the one-line credentials callout (15 files) and
## ResourcesGitHub-repo footer (18 files) are short functional text that already links to a single canonical source rather than repeating it; left as-is. Pre-existing em-dashes inquote-*/webhooks-*/agent-skills.mdbody content (this PR only touched their frontmatterdescription) were left alone to avoid an unrelated full-file diff; all prose this PR actually added or edited is em-dash-free.Template detector: before -> after
The stock
template-detector.mjscaps its 5-gram report at 30 matches and its heading-strip regex fuses a heading straight into the next paragraph, which understated this fix on a first pass. Re-ran with an uncapped copy (also stripping fenced code blocks, forcing a sentence boundary after headings) againstgit archive origin/developvs. the final tree, counting the same 27 non-Ruby files on both sides:provides typed error(s)/provides typed exception(s)(the shared intro sentence): 15 files -> 0 (grep -il "provides typed" docs/SDKs/*.md, excluding the 5 draft Ruby pages, returns nothing)Invalid or missing API...,Invalid request parameters,Too many requests,Network connectivity issues): 15 files -> 5, confirmed by direct grep on the 27 non-Ruby files: only the 5 canonical pages still carry it. The raw uncapped tool reports 7-8 because it scans all 32 files including the 5 draft Ruby pages, which this PR didn't touch and which still have the old table (grep -il "Invalid request parameters" docs/SDKs/*ruby*.mdreturns 3 of them)quote-*.md/webhooks-*.md, which this PR didn't touch (see below).Disclosed, not fixed: remaining duplication in
quote-*.md/webhooks-*.mdRunning the uncapped detector on just the 5
quote-*.mdfiles (excluding Ruby) finds 960 five-grams shared by all 5; on just the 5webhooks-*.mdfiles, 700 shared by all 5. Some is unavoidable component boilerplate (<QuickstartSkillNudge .../>), but part is real:quote-php.md,quote-python.md, and the draftquote-ruby.mdopen with a byte-identical "What is TurboQuote?" paragraph, whilequote-go.md/quote-javascript.mdalready differ.quote-javascript.mdandwebhooks-java.mdare themselves evidence pages and got only a frontmatter fix here, not a body rewrite: this PR fixed the Error Handling duplication its author investigated first, but the quote/webhooks product-intro duplication shown above is real and unaddressed, not something this PR already covers. A follow-up pass rewriting the quote/webhooks per-language intros the way this PR rewrote Error Handling is a legitimate next step; not folded into this PR to keep it reviewable and avoid ballooning an already-large diff further. Owner call below.Owner questions
javascript.mdorpython.mdforruby.md/deliverable-ruby.md(and the other 3 Ruby pages), or leave as-is until the gem ships?quote-*/webhooks-*per-language intro de-dup described above?codeempty/null for an error on an HTTP status outside the 7 mapped ones (an unexpected 5xx, for example), even though the Java javadoc fororDefaultsays code "must still be branchable" and is "kept identical across all six SDKs." Worth a TurboDocx/SDK issue?Config check
Re-read
config/title-engineering.jsonper the owner's "playbook configs win over TurboDocx SOP where they conflict" note. ItsmaxLength: 60/number-first rules target page titles for listicle content and don't set a description-length rule, so they don't apply to (and don't conflict with) the description rewrites in this PR.Merge order
This PR only touches
docs/SDKs/*, which the other open Docs Trace PRs (meta-length, broken-links, API-reference enrichment) explicitly skip. No expected conflicts.SDK repo state
/home/nicolas/repos/SDKwas checked out onfeature/turbosign-embedded-identity(unmerged PR #77) while researching this. Re-verified withgit diff origin/mainthat the 5 source files actually cited above are byte-identical toorigin/main, and confirmed no branch-only symbol (createSigningUrl,getEmbeddedSigningSettings,identityVerification, embedded signing, OTP) appears anywhere in this PR's diff.Test plan
template-detector.mjs(uncapped, before/after); cross-checked with directgrepsince the tool's cap and heading-fusion were misleading on the first passgo-sdk/http.go,go-sdk/deliverable.go,go-sdk/turbowebhooks.go,php-sdk/src/Exceptions/{TurboDocxException,AuthorizationException,ConflictException}.php,java-sdk/.../{TurboDocxException,TurboDocxClient,HttpClient}.java,java-sdk/.../models/SendSignatureResponse.java,js-sdk/src/utils/errors.ts,js-sdk/src/modules/{deliverable,partner}.ts,py-sdk/src/turbodocx_sdk/http.pydeliverable-*.mdclaims about the generate-deliverable request body againstRapidDocxBackend/src/handlers/Deliverable/DeliverableGenerationHandlers.ts(itsVariableinterface:placeholderrequired,mimeTypeoptional, opposite of what an earlier commit here claimed)code-passthrough (JS) andDEFAULT_CODE(Python) claims against the actual published@turbodocx/sdk@0.7.0npm tarball andturbodocx-sdk==0.7.0PyPI wheel, not just sourcegithub-slugger)grep -c "—"returns 0 on every file where this PR added or edited proseorigin/main, not the checked-out feature branchReview vs SDK main
A follow-up diligence pass re-verified every SDK-doc claim in this PR against
origin/mainof the SDK repo, published package artifacts (npm, PyPI, Maven Central), andorigin/masterof RapidDocxBackend. 13 confirmed inaccuracies were fixed (plus one duplicate defect shared bydeliverable-go.md):docs/SDKs/index.md— thesenderEmailnote claimed the API rejects TurboSign/TurboQuote sends missing a sender with400 SenderEmailRequired/SenderNameRequired. Backend commit80df5fff("stop rejecting API sends that omit senderEmail", reverted 2026-07-27) removed that rejection; the API now always falls back to a generic TurboDocx sender. Rewrote the note to describe the JS/TS SDK's own client-sideconfigure()-time check instead, softened the credentials table, and removed theSenderEmailRequired/SenderNameRequiredrows from the error-code table.docs/SDKs/javascript.md— same stale400 SenderEmailRequired/SenderNameRequiredclaim in the TurboSign caution block; rewrote to describe the SDK'sHttpClientconstructor throwingValidationErrorclient-side (verified inpackages/js-sdk/src/http.tson SDKorigin/main), not an API-side rejection.docs/SDKs/quote-javascript.md— same stale claim for TurboQuote (assertQuoteSenderResolvable/resolveSenderIdentityno longer throw, per the backend's own doc comment: "Neither branch rejects"). Rewrote the tip block to describe the fallback-to-generic-sender behavior, and removed theSenderEmailRequiredrow from the send-preconditions table.docs/SDKs/quote-javascript.md— theTurboQuote.updateTemplate({ senderEmail, senderName })sample was missing the requiredidpositional argument (updateTemplate(id: string, request: ...)perpackages/js-sdk/src/modules/quote.tson SDKorigin/main); fixed toTurboQuote.updateTemplate(tmpl.id, { senderEmail, senderName }).docs/SDKs/go.md— theMessagefield's table row claimedError()returns the bare message string. Verified inpackages/go-sdk/http.gothatError()actually composesTurboDocx API error [CODE]: MESSAGE (status N). Corrected the row to describe the real format.docs/SDKs/partner-go.md— the Error Handling example and typed-error list omittedConflictError, even though the sharedmapStatusToErrormaps 409 to*ConflictErroruniformly andAddUserToPartnerPortal()documented earlier in the same file can return 409. Added theConflictErrorcase to the example switch and to the typed-error list.docs/SDKs/partner-php.md— claimed a wrong/mismatchedpartnerIdthrowsAuthenticationException(401). Verified inPartnerPortalAuthMiddleware.tson backendorigin/masterthat apartnerIdroute-mismatch actually returns 404 (NotFoundException); only an invalid/missing key is 401. Split the claim accordingly.docs/SDKs/php.md—statusCode/errorCodewere documented as plainint/string. Verified inpackages/php-sdk/src/Exceptions/TurboDocxException.phpthat both are declared?int/?string. Corrected the property descriptions.docs/SDKs/java.md,deliverable-java.md,partner-java.md,quote-java.md,webhooks-java.md— all five install snippets pinned0.5.0, which was never published to Maven Central (confirmed viamaven-metadata.xml: versions jump0.4.0→0.6.0; latest is0.7.0). Updated all Maven/Gradle snippets to0.7.0.docs/SDKs/java.md— removed the "Metadata Configuration (Conditional Fields)" subsection and themetadata/FieldMetadatafield row entirely. Downloaded the publishedturbodocx-sdk-0.7.0.jarfrom Maven Central and confirmedcom.turbodocx.models.FieldMetadata/FieldConditionaldo not exist in it (onlyField,Field$Builder,Field$Offset,Field$Size,Field$TemplateAnchor) — this is an unreleased feature that must not be documented yet.docs/SDKs/partner-java.md— a caution block claimedConflictException"would never fire" on a partner call and that 409s surface as the baseTurboDocxException. Verified inPartnerHttpClient.handleError()that 409 is mapped toConflictExceptionlike every other status. Replaced the caution with an accurate tip.docs/SDKs/deliverable-python.md(anddeliverable-go.md, sharing the same defect) — describedValidationErroras being raised "when a variable dict is missing a required field" with no specifics. Verified against the backend'svariableSchemaWithStackJoi schema (src/models/Variable/IVariable.ts,origin/master):textis conditionally required (required unless the variable setsvariableStackorisDisabled/IsDisabled: true), andmimeType/MimeTypemust be one of a fixed enum. Rewrote both files to name the actual field and condition instead of the vague original wording.Flagged, not fixed in this PR (out of scope): the "Metadata Configuration (Conditional Fields)" content documenting
FieldMetadata/FieldConditionalalso exists, pre-dating this PR, ingo.md,javascript.md,php.md, andpython.md. A quick check of the published@turbodocx/sdk@0.7.0npm/PyPI packages found no equivalent classes there either, suggesting the same unreleased-feature problem across languages. This content already existed ondevelopbefore this PR branched and wasn't part of the confirmed finding set reviewed here, so it was left untouched; recommend a follow-up pass. Also flagged but left alone:docs/SDKs/index.mdstill pins Java to0.4.0in its quickstart snippet (a real Maven Central version, so it won't break an install, just inconsistent with the0.7.0used elsewhere after this fix).