Skip to content

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

Merged
AlexeyShalaev merged 1 commit 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#16
AlexeyShalaev merged 1 commit into
masterfrom
docs/copy-page-and-agents

Conversation

@AlexeyShalaev

Copy link
Copy Markdown
Contributor

Three parts, all documentation.

A "Copy page" control above every page. A split button that copies the page's
Markdown, or opens it in ChatGPT / Claude / Perplexity. It works because
scripts/emit_markdown.py runs after the site 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/health/ and /guide/health.md. The API reference declines the control with
copy_page: false in its front matter: its Markdown is one instruction to a docstring
renderer, not the API, so a twin there would mislead rather than help.

docs/agents.md — the whole kit on one page, written for a coding assistant. The
public surface with real signatures and defaults, and the section that actually earns
its keep: the ordering rules a caller has to get right and gets no error for breaking.
Configure before build(), because interceptors go to grpc.aio.server() at
construction and there is no adding one later. The interceptor list is outermost first,
which is why AsyncSentryInterceptor must sit after the exception handler — put it
first and it captures nothing, ever, silently. grace_period=None aborts in-flight RPCs
immediately rather than waiting forever. context.abort() raises grpc.aio.AbortError,
which except grpc.RpcError does not catch. A GrpcApp is single-use. Then the
mistakes a model makes with this API as WRONG/RIGHT pairs, the errors (all builtins —
the kit defines no exception classes, and a model will happily invent one), and a map
of which page to fetch for the rest.

The rule that keeps it true. CONTRIBUTING.md and the pull request checklist now
say the page is part of the public API and goes stale in the same pull request that
changes 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 builds and deploys on merge, and now runs the emit step
after zensical build. Locally, make docs-build && uv run python scripts/emit_markdown.py
zensical serve rebuilds into the same directory without knowing about the twins, so
a served preview answers 404 to the control.

Checks: zensical build --clean reports no issues, emit_markdown.py writes 9 pages
with 1 declined, make check and make test-unit (400 passed) are green, and uv.lock
is untouched.

The four installed files (docs/assets/stylesheets/copy-page.css,
docs/assets/javascripts/copy-page.js, overrides/main.html,
scripts/emit_markdown.py) are byte-identical across the organisation on purpose, so
they can be updated everywhere in one sweep.

@AlexeyShalaev
AlexeyShalaev merged commit ccbfaa5 into master Sep 6, 2026
5 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