docs: one page for a coding assistant, and a copy-page control on every page - #15
Merged
Conversation
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.
Three parts, one of which is real work and two of which are the same files every other
repository in the organisation is getting.
The control. A "Copy page" split button above every docs page: it copies the page's
Markdown, or opens it in ChatGPT / Claude / Perplexity. It works because
scripts/emit_markdown.pyruns after the build and writes everydocs/<path>.mdnext tothe HTML it built, so each page has a plain-text twin one URL away —
/guide/resilience/and/guide/resilience.md. The Docs workflow gained that one step.docs/reference/index.mddeclines the control withcopy_page: false: its Markdown isinstructions to mkdocstrings, not the API, so a twin would hand a model four lines of
directives instead of a reference.
The page.
docs/agents.md, in the nav as "For AI agents": the whole library on onepage for a coding assistant — the facts table, the mental model, the public API in tables,
twenty rules that hold or break the code, seven WRONG/RIGHT pairs, the error hierarchy, and
a map of every page of the site with a read it when. The rules are the point, and they
are the ones that are true here: who owns a channel and who closes it, that the pool never
closes an idle channel because gRPC core parks it, that a timeout is the budget of the
whole call rather than of an attempt, that
DEFAULT_RETRYABLE_CODESis two codes andidempotent_methodsis the only real guard, thatfail_thresholdhas to exceedmax_attempts, that nothing propagates a deadline until the caller callsuse_budget, andthat the chain is part of the pool key so it has to be built once per target. Every name on
it was checked against the installed package: 57 of the 58 top-level names resolve directly,
HealthCheckerresolves to theImportErrornaming[health]exactly as the page says,and the 18 submodule-only names the page routes elsewhere all resolve there.
The rule.
CONTRIBUTING.mdgets a section saying the page is part of the public API andgoes stale in the same pull request that changes it, and the pull request template's
documentation line now names it. A stale agents page is worse than none — it teaches a model
an API that no longer exists.
To see it: the Docs workflow deploys on merge, and the page lands at
https://bedrock-python.github.io/grpc-client-kit/agents/ with the control on every page
above it.
docs/assets/stylesheets/copy-page.css,docs/assets/javascripts/copy-page.js,overrides/main.htmlandscripts/emit_markdown.pyare byte-identical across theorganisation, so they can be updated in one sweep; nothing in them is repository-specific.
Verified locally:
zensical build --cleansays "No issues found",emit_markdown.pywrites14 pages with 1 declined,
make checkis clean (ruff, ruff format, mypy on 25 files), anduv.lockis untouched.Three things worth a separate look, all pre-existing and none touched here:
docs/guide/health.mdsays the factory "does not forwardoptionsorcompression"to the health checker. It does —
factory.pypasses both, with the comment explaining why.docs/guide/health.mdalso says every probe asks for the overall server status, and thatHealthCheckerNotRunningErrorlives ingrpc_client_kit.healthand needs the[health]extra.
HealthCheckerhas taken aserviceargument since 0.1.0 and the factory forwardsit, and the error lives in
grpc_client_kit.errorsprecisely so that catching it needs noextra — its own docstring says so.
docs/guide/resilience.mdanddocs/guide/deadlines.mdboth say there is no settingsblock for the wait-for-ready and deadline-budget layers. There is;
docs/guide/configuration.mddocuments it correctly and the factory reads both withgetattr.