docs: rebuild the documentation site as a product surface - #515
Conversation
Replace the top tab bar with a left sidebar, and group the pages into Getting started / Configuring / Reference / About so the whole documentation set is visible at a glance instead of one tab at a time. On a rule page the sidebar also nests that page's own table of contents, putting every rule one click away. Rewrite the rules reference along the lines of a linter's rule documentation: an index table per category giving each rule's code, name, message, the CLI flag that runs it, and whether it is on by default, followed by a section per rule answering what it does, why it matters, and how to fix it, with a before/after example and the options that control it. Correct several defaults in the configuration reference that had drifted from the source: subject_capitalized and subject_imperative are off by default (documented as on), allow_empty_commits and allow_wip_commits are on (documented as off), and allow_commit_types was missing perf, build, and ci. The "Default Behavior" tip repeated the same mistake. Guard all of it with tests, so the documentation cannot drift again: documented boolean and list defaults are compared against the values in commit_check/__init__.py, and every rule must have a section heading that answers what it does, why it is bad, and which options apply. Also fix four reStructuredText title underlines that were shorter than their titles, letting the docs build cleanly under -W.
✅ Deploy Preview for commit-check ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Review limit reached
Next review available in: 34 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe project migrated its documentation from Sphinx and reStructuredText to MkDocs Material and Markdown. It added site content, build hooks, deployment settings, legacy redirects, and documentation consistency tests. ChangesMkDocs documentation migration
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #515 +/- ##
==========================================
+ Coverage 97.34% 97.43% +0.08%
==========================================
Files 12 12
Lines 1207 1207
==========================================
+ Hits 1175 1176 +1
+ Misses 32 31 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
docs/_static/extra_css.css (1)
67-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winScope the
white-spacerule to rule index tables.
.md-typeset table td codeapplies to every table, although the comment says it targets rule index tables. A long code literal in a configuration or migration table can then force horizontal scrolling. Add a table-specific class and scope this selector to that class.Proposed scope
-.md-typeset table td code { +.rules-index-table td code { white-space: nowrap; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/_static/extra_css.css` around lines 67 - 69, Update the `.md-typeset table td code` selector in the stylesheet to target only tables marked with the rule index table class, and add or reuse that class on the relevant rule index table markup. Keep the `white-space: nowrap` behavior unchanged for rule index tables while preventing it from applying to other tables.tests/rules_catalog_test.py (1)
131-143: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winScope the heading assertion to each rule section.
test_every_rule_has_a_section_headingsearches the entire page. A heading can remain elsewhere while its own rule section loses the heading, and the test still passes. Reuse the anchor-bounded section logic fromtest_every_rule_explains_itselfand check the heading inside that section.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/rules_catalog_test.py` around lines 131 - 143, Update test_every_rule_has_a_section_heading to reuse the anchor-bounded section extraction logic from test_every_rule_explains_itself, then assert each rule’s “name (rule_id)” heading appears within its corresponding section rather than anywhere in the full document.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/configuration.rst`:
- Around line 27-30: Align the documentation with the runtime subject-length
defaults: in docs/configuration.rst lines 27-30, state that subject length is
constrained by minimum 5 and maximum 80 characters; in docs/rules.rst lines
114-123, mark CC004 and CC005 as enabled by default; document subject_max_length
as 80 at lines 385-386 and subject_min_length as 5 at lines 417-418.
- Line 430: Update the author_email_pattern entry in the configuration
documentation to match the runtime default ^.+@.+$ defined by the configuration
merger, unless the implementation is intentionally changed to use an empty
sentinel; keep the documentation and runtime behavior consistent.
In `@docs/rules.rst`:
- Around line 783-790: Update the Options entry in the documentation to
reference branch.conventional_branch instead of commit.conventional_branch,
matching the configuration key used by config_merger.py. Keep the existing
disable-rule behavior and surrounding branch.allow_branch_types guidance
unchanged.
- Around line 719-739: Update the email-pattern rule documentation example so it
does not claim root@localhost violates the built-in ^.+@.+$ pattern; use an
address that fails that pattern, or explicitly state that rejecting local or
placeholder addresses requires a stricter author_email_pattern.
In `@tests/rules_catalog_test.py`:
- Around line 159-182: The test_boolean_defaults_match_configuration_docs method
must also validate the conventional-check defaults. Extend expected with
conventional_commits=True and conventional_branch=True, or derive those values
from get_default_config(), while preserving the existing DEFAULT_BOOLEAN_RULES
and DEFAULT_PUSH_RULES checks.
---
Nitpick comments:
In `@docs/_static/extra_css.css`:
- Around line 67-69: Update the `.md-typeset table td code` selector in the
stylesheet to target only tables marked with the rule index table class, and add
or reuse that class on the relevant rule index table markup. Keep the
`white-space: nowrap` behavior unchanged for rule index tables while preventing
it from applying to other tables.
In `@tests/rules_catalog_test.py`:
- Around line 131-143: Update test_every_rule_has_a_section_heading to reuse the
anchor-bounded section extraction logic from test_every_rule_explains_itself,
then assert each rule’s “name (rule_id)” heading appears within its
corresponding section rather than anywhere in the full document.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 1e74e61a-27a4-4f7d-bd9d-1355c7c15eb7
📒 Files selected for processing (8)
docs/_static/extra_css.cssdocs/changelog.rstdocs/conf.pydocs/configuration.rstdocs/index.mddocs/migration.rstdocs/rules.rsttests/rules_catalog_test.py
… runtime The subject-length rules are on by default, not off. `get_default_config()` sets subject_max_length to 80 and subject_min_length to 5, and `ConfigMerger.from_all_sources()` starts from it, so with no config file at all a subject over 80 characters fails CC004. Both the rules reference and the configuration reference claimed there was no limit. The same review turned up four more inaccuracies: - author_email_pattern defaults to `^.+@.+$`, not an empty string. - require_rebase_target defaults to `""`, not None. - CC201's option is branch.conventional_branch; it was documented under the commit section, where configuration merging would ignore it. - required_signoff_name and required_signoff_email were documented in the example config and in CC012's options, but no such options exist anywhere in the code. Two rule examples also demonstrated values that pass the very check they illustrate: `root` satisfies the built-in author name pattern, and `root@localhost` satisfies `^.+@.+$`. Both now use values that actually fail, with a note explaining how permissive the built-in patterns are and when to replace them. Rework the drift guard so this class of error is caught mechanically. Rather than comparing against a couple of constants, the options table is now parsed and every row checked against `get_default_config()` — the same dict the CLI builds its configuration from. Two further tests assert the table and the runtime describe the same set of options, in both directions, which is what catches an invented option like required_signoff_name or a newly added one that nobody documented. Also scope the rule-index table styling to those tables so long regexes in the configuration table stay wrappable, and check each rule's heading inside its own section instead of anywhere on the page.
|
Verified all seven comments against the source. All seven were correct, and the first one was worse than reported — fixed in 0f4c3ca. Subject-length defaults (major). Confirmed end-to-end, not just by reading: $ git commit --allow-empty -m "fix: this is a deliberately very long commit subject line that goes well past the eighty character limit"
$ commit-check --message --compact # no config file anywhere
[FAIL] CC004 subject_max_length: fix: this is a deliberately very long ...
exit=1
While fixing these I also found that Drift test. Took the suggestion further rather than adding two literals. The test now parses the options table and checks every row against Confirmed the guards fail on the pre-fix content rather than passing vacuously: All 24 runtime options parse and match. Both nitpicks applied. The index tables carry a Docs still build clean under Generated by Claude Code |
The regex match may be None, so reading .group() from it before the None check failed mypy and took the lint session down with it.
Merging this PR will improve performance by ×3.6
Performance Changes
Tip Curious why this is faster? Comment Comparing Footnotes
|
CodSpeed reported test_every_rule_is_documented as a 27% regression. It is not one: that test reads docs/rules.rst and scans it for anchors, and this branch grows that file from 7.4 KB to 22.2 KB. A 2.99x larger file taking 1.37x longer to read is the expected, sub-linear result, and no runtime code changed on this branch at all. The marker is documented as meaning "performance-related tests", which these are not. Left in place, the performance gate would report a regression every time somebody expands the rules reference — penalising the act of writing documentation. The catalog and rule-builder tests in this file keep their marker; those do exercise the package.
The deploy preview failed to build:
ERROR - Config value 'site_url': The URL isn't valid, it should
include the http:// (scheme)
Values in a [context.*.environment] block are literals — Netlify does not
interpolate them — so SITE_URL reached MkDocs as the unexpanded string
"${DEPLOY_PRIME_URL}", which is indeed not a URL.
Set it in the context's build command instead, which runs in a shell where
the variable expands. The redirect hook now also tolerates a site_url without
a trailing slash, since that is the form DEPLOY_PRIME_URL takes.
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/assets/extra.css`:
- Around line 20-22: Update the default light-theme rule for
--md-typeset-a-color to use a darker color with at least 4.5:1 contrast against
the white background, rather than reusing --cc-brand-dark; keep the dark-theme
styling unchanged.
In `@docs/changelog.md`:
- Around line 11-14: Update the AI attribution governance entry in the changelog
to document the implemented [commit] option as ai_attribution, state that its
default is "ignore" and its rejecting mode is "forbid", and remove the incorrect
forbid_ai_attribution boolean configuration description.
In `@docs/configuration.md`:
- Line 257: Correct the allow_force_push configuration mapping in the
documentation table: map allow_force_push = true to CCHK_ALLOW_FORCE_PUSH=true,
and document false as the value that blocks force pushes while preserving the
existing CLI flag context.
In `@docs/example.md`:
- Around line 94-95: Convert the remaining reStructuredText constructs to MkDocs
Markdown: in docs/example.md lines 94-95, replace the `.. tip::` block with a
`!!! tip` admonition; in docs/changelog.md lines 148-149, replace `..
Attention::` with the appropriate MkDocs admonition; and in docs/what-is-new.md
lines 58-61, convert the RST external-link syntax to standard Markdown link
syntax.
In `@docs/getting-started/quickstart.md`:
- Around line 20-21: Update the quickstart scratch repository setup around the
git init and git commit commands to configure local user.name and user.email
values before creating the empty commit, ensuring commit-check is reachable on
clean Git installations.
In `@docs/guides/github-actions.md`:
- Around line 39-58: Update the `pr-comments` documentation in the GitHub
Actions guide to state that fork-originated `pull_request` events may receive a
read-only `GITHUB_TOKEN`, so `pull-requests: write` alone may not enable
comments. Either document that comments may fail for fork PRs or describe a
trusted `pull_request_target` workflow using base-branch checkout without
executing fork code.
In `@docs/guides/organization.md`:
- Around line 26-30: Update the repository configuration description near the
inherit_from example to say each repository needs one line, matching the
single-line configuration shown; do not add omitted configuration.
In `@docs/index.md`:
- Line 139: Update the documentation statement near “Build provenance with
artifact attestation verified at install time” to accurately state that
artifacts carry SLSA Level 3 provenance verifiable before installation, unless
an actual install-time verification mechanism is documented; do not claim
install-time verification based solely on the manual gh attestation verify step.
In `@docs/rules.md`:
- Around line 448-450: Update the Developer Certificate of Origin reference in
the surrounding documentation text to use Markdown link syntax with the existing
link text and URL, replacing the reStructuredText inline-link notation while
preserving the sentence content.
In `@docs/troubleshoot.md`:
- Around line 22-40: Correct the “Bypass Specific Hook” and “Bypass All Hooks”
headings in the troubleshooting documentation: the section using --no-verify
should describe bypassing all commit-time hooks, while the section using
SKIP=check-author-name should describe bypassing only the named hook. Leave the
command examples unchanged.
In `@scripts/mkdocs_hooks.py`:
- Around line 30-38: Update the REDIRECT HTML template to add a client-side
redirect that appends location.hash to the target URL, preserving fragments such
as `#cc003`; retain the existing meta refresh unchanged as the no-JavaScript
fallback.
- Around line 84-89: Normalize the `site_url` base in the redirect-generation
flow before iterating over `LEGACY_URLS`, ensuring it has exactly one trailing
slash after applying the existing root fallback. Use this normalized base when
concatenating each target in `REDIRECT.format` so root redirects retain the
separator.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4a12824c-16cf-41da-b216-ad03c9f9424a
⛔ Files ignored due to path filters (3)
docs/_static/logo.jpgis excluded by!**/*.jpgdocs/assets/favicon.svgis excluded by!**/*.svgdocs/assets/logo.svgis excluded by!**/*.svg
📒 Files selected for processing (37)
.github/workflows/main.yml.gitignore.pre-commit-config.yamlcommit_check/rules_catalog.pydocs/README.rstdocs/_static/extra_css.cssdocs/assets/extra.cssdocs/changelog.mddocs/changelog.rstdocs/conf.pydocs/configuration.mddocs/configuration.rstdocs/example.mddocs/example.rstdocs/getting-started/installation.mddocs/getting-started/quickstart.mddocs/getting-started/why.mddocs/guides/ai-attribution.mddocs/guides/github-actions.mddocs/guides/organization.mddocs/guides/pre-commit.mddocs/guides/signoff.mddocs/index.mddocs/migration.mddocs/migration.rstdocs/rules.mddocs/rules.rstdocs/troubleshoot.mddocs/troubleshoot.rstdocs/what-is-new.mddocs/what-is-new.rstmkdocs.ymlnetlify.tomlnoxfile.pypyproject.tomlscripts/mkdocs_hooks.pytests/rules_catalog_test.py
💤 Files with no reviewable changes (10)
- docs/example.rst
- docs/troubleshoot.rst
- docs/README.rst
- docs/changelog.rst
- docs/configuration.rst
- docs/_static/extra_css.css
- docs/migration.rst
- docs/rules.rst
- docs/conf.py
- docs/what-is-new.rst
| $ git init demo && cd demo | ||
| $ git commit --allow-empty -m "updated the parser" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make the scratch repository commit deterministic.
A clean Git installation without user.name and user.email fails here with Author identity unknown. The reader cannot reach commit-check. Configure a local identity before creating the commit.
Example fix
$ git init demo && cd demo
+$ git config user.name "Demo User"
+$ git config user.email "demo@example.com"
$ git commit --allow-empty -m "updated the parser"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $ git init demo && cd demo | |
| $ git commit --allow-empty -m "updated the parser" | |
| $ git init demo && cd demo | |
| $ git config user.name "Demo User" | |
| $ git config user.email "demo@example.com" | |
| $ git commit --allow-empty -m "updated the parser" |
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)
[warning] 20-20: Dollar signs used before commands without showing output
(MD014, commands-show-output)
[warning] 21-21: Dollar signs used before commands without showing output
(MD014, commands-show-output)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/getting-started/quickstart.md` around lines 20 - 21, Update the
quickstart scratch repository setup around the git init and git commit commands
to configure local user.name and user.email values before creating the empty
commit, ensuring commit-check is reachable on clean Git installations.
The deploy preview could not open /rules/. The build emits a redirect stub at rules.html for the old Sphinx URL, and Netlify normalises "/rules" and "/rules/" to the same resource, so that stub was served in place of the page it points at and redirected to itself forever. Turn the normalisation off and declare the legacy URLs as Netlify redirects, which resolve before file lookup and so cannot collide with the page they target. The emitted stubs stay for GitHub Pages, and now refuse to redirect a page to itself, so the same collision cannot reappear on another host. The stubs also carry the fragment across. The links most worth keeping alive are the per-rule ones — rules.html#cc003 — and a bare redirect dropped the anchor, landing the reader at the top of a 700-line page. From review, all verified against the source before fixing: - The RST converter missed four constructs: `.. Attention::` (it only matched lowercase), `.. tip ::` (a space before the colons), and two links whose text wrapped across a line. They were rendering as literal text. - The changelog documented `forbid_ai_attribution`, which does not exist; the option is `ai_attribution`, defaulting to "ignore". - The options table mapped `allow_force_push = true` to `CCHK_ALLOW_FORCE_PUSH=false`, describing opposite behaviour for equivalent settings. - Troubleshooting had its two bypass headings the wrong way round: --no-verify skips every hook, SKIP= skips one. - Link colour was #1e85a8 on white, 4.2:1, under the 4.5:1 needed for body text. Now #176b89 at 6.0:1. - The landing page claimed attestation "verified at install time"; only a manual verification step exists, so it now says what is true. - The organization guide said "three lines" above a one-line example. - pr-comments cannot post on fork pull requests, because a fork's `pull_request` run gets a read-only token that `pull-requests: write` does not override. Documented, along with why `pull_request_target` is not a casual substitute.
Fix: stop emitting redirect stubs on Netlify (
|
The previous logo.svg was a new line-art icon that did not match the
project's actual logo. Vectorize docs/_static/logo.jpg (a 900x504 PNG in
the old Sphinx site) with potrace instead, so the SVG is pixel-identical
to the original: the 'commit' wordmark, the check mark and the branch
shape in the brand color #2C9CCD.
The old logo.jpg could not be used as-is on the new site: Sphinx's
conf.py had it commented out ('can not display well in blue background'),
it carried 10 KB of transparent padding around a 300x293 mark, and the
new header renders the logo via <img>, where currentColor would resolve
to black. The traced SVG keeps the exact shapes with a hardcoded fill,
so it renders identically in the light and dark palettes.
2fbd4c0 to
f1b4631
Compare
Logo: restored as a vectorized copy of the original (
|
The header background is the brand color #2c9ccd (--md-primary-fg-color),
the same blue the logo is filled with, so the logo was invisible. This is
the same reason the old Sphinx site had html_logo commented out ('can not
display well in blue background').
Keep the original blue logo unchanged and give it a white rounded tile.
On the blue header the tile makes the logo visible; in the drawer, which
sits on a light or dark gray background, the blue logo shows directly.
|
Logo visibility fix (
|
| Where | Background | What shows |
|---|---|---|
| Header (1.2rem) | brand blue #2c9ccd |
white tile stands out, blue logo on it |
| Mobile drawer (2.4rem) | light/dark gray | blue logo directly visible (tile blends in) |
Verified on the rebuilt preview: the served /assets/logo.svg matches the build exactly, and a render check confirms 71k white-tile pixels vs 17k blue-logo pixels — a clear contrast silhouette on the blue header.



Rebuilds the documentation site: new information architecture, a real landing page, MkDocs Material in place of Sphinx, and nine corrections where the docs did not describe the software. Includes #516.
The problem
The site read as a repository, not a product.
docs/index.mdwas a one-lineincludeof../README.md, so the front door ofdocs.commit-check.comwas eight CI badges above a hand-written## Table of Contents. Badges are a trust signal for GitHub visitors and a ToC is a workaround for GitHub's lack of navigation — neither belongs on a documentation site.Behind it, everything was reference material. There was no installation page, no tutorial, and no task-oriented guides. Navigation was a top tab bar, so only one section's pages were reachable at a time.
Framework
MkDocs Material, replacing Sphinx + sphinx-immaterial:
pyproject.toml, CI stays a singlepip install, and contributors need no Node — which matters while we are recruiting them through good-first-issues.sphinx-immaterialwas a partial port of it, so palette, admonitions and feature flags carried over almost unchanged. Docs extras drop from five packages to one.Navigation moves to a left sidebar grouped into sections, and on the rules page the sidebar nests that page's own table of contents, putting every rule one click away.
Content
A landing page with a value proposition, the same policy shown running four ways (CLI / pre-commit / GitHub Actions / MCP) in linked tabs, and cards routing each rule family to its reference.
The pages the site never had:
The rules reference is rewritten along the lines of a linter's rule documentation: an index table per category giving each rule's code, name, message, the CLI flag that runs it and whether it is on by default, then a section per rule answering What it does / Why is this bad? / Example + Use instead / Options.
The Check column closes a real gap — nothing previously told a reader that
commit-check --messagenever evaluates a branch rule.Brand: the 10 KB JPEG logo becomes a 483-byte SVG, and there is a favicon for the first time; the Sphinx config had it commented out.
Corrections
Cross-checking every rule against the source turned up nine places where the documentation did not describe the software.
subject_max_length80subject_min_length5subject_capitalizedtruefalsesubject_imperativetruefalseallow_empty_commitsfalsetrueallow_wip_commitsfalsetrueallow_commit_typesperf,build,ci)author_email_pattern""^.+@.+$require_rebase_targetNone""The subject-length pair matters most.
ConfigMerger.from_all_sources()starts fromget_default_config(), which sets both, so CC004 and CC005 are enforced out of the box. Verified end to end rather than by reading:Also fixed:
branch.conventional_branch, documented undercommit.— where configuration merging would silently ignore it.required_signoff_nameandrequired_signoff_emailappeared in the example config but are implemented nowhere. Removed; if they are wanted, that is a feature request.rootsatisfies the built-in author name pattern androot@localhostsatisfies^.+@.+$, so neither demonstrated a failure. Both now use values that actually fail, with a note on how permissive the built-in patterns are.Things that could have broken the live site
Rule URLs. MkDocs serves directory URLs, so anchors move from
/rules.html#cc003to/rules/#cc003, andRULES_DOCS_URLfollows. Safe to change only because the rule-ID feature has not shipped to PyPI yet — no released version emits the old form.Published links. A build hook emits a redirect stub for every URL the Sphinx site served, since links to
configuration.htmland friends exist in the README, on PyPI and elsewhere.The custom domain.
gh-pagescarries aCNAMEofdocs.commit-check.comand the publish step force-replaces that branch, socname:is now pinned explicitly on the action rather than relying on the file surviving.Deploy previews. Netlify's build settings lived in its web UI and still pointed at Sphinx's
_build/html, so nothing in the repository could show the mismatch in review. The build moves intonetlify.toml, and previews setSITE_URLto their own address — otherwise canonical links and redirect stubs would send a reviewer from the preview back to production.Tests
The anti-drift guards are rebuilt around
get_default_config(), the dict the CLI actually builds its configuration from, and follow the content into Markdown:test_documented_defaults_match_the_runtime— every documented default acrossbool,int,str,list[str]test_every_runtime_option_is_documented— a new option cannot ship undocumentedtest_no_invented_options_are_documented— the table cannot describe options that do not existtest_every_rule_has_a_section_heading/test_every_rule_explains_itself— each rule needs a real section, not just an anchorConfirmed they fail on the pre-fix content rather than passing vacuously:
All 24 runtime options parse and match. The documentation-consistency tests also lost their
benchmarkmarker: they read files rather than exercising the package, so benchmarking them reported a regression every time the documentation grew — penalising the act of writing it.The one failing test,
test_load_config_file_permission_error, reproduces onmainand is unrelated: it usesos.chmod(0o000), which does not restrict root.Not in this PR
example.mdandwhat-is-new.mdare carried over converted but not rewritten — they overlap the new guides and the changelog, and folding them in is a content decision worth making separately. Social cards are not enabled; the plugin needs cairo in CI.Summary by CodeRabbit
Documentation
Deployment
Tests