Skip to content

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

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

AlexeyShalaev merged 2 commits into
masterfrom
docs/copy-page-and-agents

Conversation

@AlexeyShalaev

Copy link
Copy Markdown
Member

Three things, all documentation.

A "Copy page" control above every page. A split button: copy the page as Markdown, view it as plain text, or open 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 — /user_guide.md beside /user_guide/. A page can opt out with copy_page: false in its front matter, and the emit step honours the same key.

docs/agents.md — the whole library on one page. The public surface with real signatures and defaults, what is and is not exported from the root, the rules a caller has to obey, # WRONG / # RIGHT pairs for the mistakes a model actually makes with this API, the exception table, and a map of every page of the site with a reason to fetch it. It is written from the source, not from the other pages; the rules section is the point of it. The ones that carry the most weight here: the key is the whole identity and the request body is not part of it, two concurrent callers both run the business logic (the check is a GET, the write is SET NX, and the loser replays the winner's record), the decorator reads the key from keyword arguments only and silently does nothing when it or the coordinator is missing, coordinate() swallows every storage and decode failure, and a TTL in seconds is truncated to whole minutes with a floor of one.

The rule that keeps it true. CONTRIBUTING.md gains a section saying that page is part of the public API and changes in the same pull request the API does, 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.

How to see it. The Docs workflow deploys on merge, with the emit step added after the build; the page lands at https://bedrock-python.github.io/idempotency-kit/agents/ and the control appears at the top of every page. Locally: make docs-build && uv run python scripts/emit_markdown.py, then serve site/zensical serve rebuilds into the same directory without the twins, so the control answers 404 under it.

Verified on this branch: zensical build --clean says "No issues found", the emit step writes 8 Markdown pages, make check passes (ruff, ruff format, mypy over 31 files), uv.lock is untouched, and every public name the page tells a caller to import was checked against the installed package — nothing missing, and nothing in idempotency_kit.__all__ that the page leaves out.

A few things I noticed while reading the source, none of them touched here:

  • RedisAsyncIdempotencyRepository raises ImportError: ... pip install idempotency-kit[redis-aio], and docs/architecture.md says [redis-aio] too. The extra is redis.
  • docs/api_reference.md describes the repository's redis argument as an "instance of redis-client-kit client". It is any redis.asyncio.Redis; the instrumented client is one option, not the type.
  • The repository and the coordinator both record hit, miss and latency. With one collector shared between them — which is exactly what IdempotencyProvider wires — every coordinator-driven get is counted twice.
  • BaseIdempotencySettings.enabled is read by nothing. No shipped provider consults it.
  • BaseIdempotencySettings defaults (60 min, floor 1 s, ceiling 30 days) are a different set from IdempotencyDomainService's own (30 min, floor 60 s, ceiling 24 h), so the effective bounds depend on which way the service was built.
  • PydanticResultAdapter.encode returns None for a falsy value and decode raises on a falsy payload, so an action that may return None stores null and then fails to decode it for the life of the record — a permanent miss that re-runs the action on every replay. The page says to use VoidResultAdapter or JsonResultAdapter instead, but the adapter could refuse the shape up front.
  • IdempotencyDomainService.validate_record and IdempotencyRecordExpiredError are unused by the library itself.

The four shared 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 in one sweep.

@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@AlexeyShalaev
AlexeyShalaev merged commit 6aa5831 into master Sep 6, 2026
7 checks passed
@AlexeyShalaev
AlexeyShalaev deleted the docs/copy-page-and-agents branch September 6, 2026 17:29
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