Skip to content

docs: one page for a coding assistant, and a copy-page control on every page - #19

Merged
AlexeyShalaev merged 3 commits into
masterfrom
docs/copy-page-and-agents
Sep 6, 2026
Merged

docs: one page for a coding assistant, and a copy-page control on every page#19
AlexeyShalaev merged 3 commits into
masterfrom
docs/copy-page-and-agents

Conversation

@AlexeyShalaev

Copy link
Copy Markdown
Member

Three things ship together, and each is useless without the others.

1. A "Copy page" control above every docs page. It copies the page's Markdown, or
opens it in ChatGPT / Claude / Perplexity. It works because scripts/emit_markdown.py
runs after the build and writes every docs/<path>.md next to the HTML it built, so each
page has a plain-text twin one URL away: /guide/retries/ and /guide/retries.md. The
Docs workflow gained that one step.

2. docs/agents.md — the whole library on one page, written for a coding assistant:
the public API with its real defaults, where the boundary between the core engine and an
adapter actually runs, the retry/timeout composition, the rules that break code when they
are broken, the mistakes a model makes with this API, and a map of which of the 33 pages
to fetch for the rest. It is in the nav as "For AI agents" and reachable at
/agents/ (with /agents.md for a machine).

3. The rule that keeps it true. CONTRIBUTING.md and the pull request template now
say the page is part of the public API and goes stale in the same pull request that
changes the surface. 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. Locally,

uv sync --no-dev --group docs --frozen
cp CHANGELOG.md docs/changelog.md
uv run --no-sync zensical build --clean
uv run --no-sync python scripts/emit_markdown.py   # wrote 35 Markdown pages into site/

zensical build reports no issues, make check passes (ruff, mypy, import-linter) and
uv.lock is untouched. Every name the page tells a caller to import was checked against
the installed package; the repository's own tests/unit/test_docs_snippets.py also now
covers the page's snippets, so a renamed export fails CI rather than the reader.

docs/assets/stylesheets/copy-page.css, docs/assets/javascripts/copy-page.js,
overrides/main.html and scripts/emit_markdown.py are byte-identical across the
organisation, so all of them can be updated in one sweep.

One deviation worth knowing: the installer could not patch .github/workflows/docs.yml
because it looks for a bare uv run zensical build --clean and this repository
deliberately runs uv run --no-dev --group docs …. The emit step was added by hand in the
same style, right after the build.

While reading the source for the page I found three things that are not this PR's job to
fix but should not stay unwritten:

  • docs/guide/per-call-options.md says idempotent=False "forbids retrying a normally-
    idempotent method". It does not: the gate is method not in retry.methods and not info.idempotent, so a GET with idempotent=False is still retried. Either the doc or
    the gate should move.
  • docs/guide/native-options.md and docs/guide/capabilities.md both promise
    handle.report.native_overrides lists the accepted passthrough per slot. No adapter
    passes native_overrides into compile_plan, so it is always {}.
  • AsyncNormalizer.conn_metrics / SyncNormalizer.conn_metrics are implemented by every
    adapter (aiohttp does real work for it via TraceConfig) but nothing in the engine or
    the telemetry emitter ever calls them; Attempt.conn is always None even though
    aiohttp declares CONN_METRICS: native.

@AlexeyShalaev
AlexeyShalaev merged commit da70e20 into master Sep 6, 2026
8 checks passed
@AlexeyShalaev
AlexeyShalaev deleted the docs/copy-page-and-agents branch September 6, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant