docs: overhaul the documentation and gate it in CI - #377
Conversation
|
An automated preview of the documentation is available at https://377.capy.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-08-19 14:53:27 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #377 +/- ##
========================================
Coverage 98.09% 98.09%
========================================
Files 130 130
Lines 6291 6291
========================================
Hits 6171 6171
Misses 120 120
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 41 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
|
GCOVR code coverage report https://377.capy.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-08-19 15:22:10 UTC |
5d4a747 to
02ec655
Compare
Capy's documentation was accurate in places, stale in others, and had no
mechanism to tell the difference. This replaces it with a documentation set
that is single-sourced from the code, checked against a written standard,
and gated in CI so it cannot drift back.
WHAT A READER GETS
Sixty Antora pages under doc/modules/ROOT/pages, organized by the Diátaxis
modes -- tutorial, how-to, reference, explanation -- with each page
declaring its mode so mixing can be detected. A tutorial track through C++20
coroutines and concurrency, a how-to chapter per subsystem, seventeen worked
examples, and a design section that argues the rationale, including why Capy
does not build on Cobalt, TMC or std::execution.
"Why Capy?" is the entry point and now argues the case rather than listing
features. It leads with the guarantee that makes the coroutine-only choice
pay -- a coroutine always resumes on the executor it was started with, so
state touched between two suspension points needs no mutex, and an awaitable
that could resume anywhere is rejected at compile time -- and shows it in
compiled code. It then says plainly what Capy is not, because Asio ships
sockets and Capy does not, and a comparison that omits this is not honest.
It covers deterministic testing, the bridges to P2300 and Asio, and what
adopting Capy costs: a second library for networking, a C++20 floor, no
callback interop without a bridge, and Asio's two decades of field reports
against Capy's none.
The prose does not restate the reference. Symbols are reached through the
cpp: macro -- 555 uses across 93 targets -- so a signature cannot go stale in
prose, because prose no longer carries signatures.
EVERY CODE BLOCK COMPILES
The pages contain no pasted code. All 355 include:: directives pull tagged
regions out of 41 snippet and 25 program translation units under test/doc,
which the boost_capy_doc_tests target builds with -Wall -Wextra -Werror. A
block that stops compiling fails the build rather than misleading a reader.
Blocks that deliberately do not compile -- other-library comparisons, design
sketches -- carry role=external or role=pseudocode so the gate knows to skip
them, and bare listings holding program output or figures carry role=output
or role=figure so they are not mistaken for uncompiled code.
Because those sources build with warnings as errors while the fragments
deliberately leave results unused, each file carries a block of diagnostic
suppressions. The tagged regions begin below it, so a fragment renders the
code it is about and nothing else. Rather than explain that suppression list
to readers, the Code Convention note on the landing page states the
consequence: the examples leave some results and bindings unused so the
prose can explain them, and should not be built with -Wall or -Werror.
A WRITTEN STANDARD, AND TOOLING THAT ENFORCES IT
doc/STYLE_GUIDE.md states the rules along five axes -- Structure, Accuracy,
Wording, Completeness, Presentation -- each phrased so that a human or an
agent can apply it, and each mapped to a CI gate, a CI warning, or PR
review. doc/prompts/ holds the four agent workflows that operate on the
documentation: audit, fix, sync and write.
doc/lint/ implements the checkable subset in nine Node scripts with no
dependencies: structural AsciiDoc and nav rules, the sentence-length
authority for the 25-word limit, docstring extraction so header comments can
be linted as prose, a MrDocs reference-surface warning parser, an a11y scan,
and the baseline machinery. Five Capy Vale styles cover filler, terminology,
tense and heading shape. selftest.mjs asserts the checks still detect what
they claim, so a gate cannot silently start passing everything.
The Documentation workflow runs all of it. baseline.json grandfathers the
existing backlog; check-no-new-violations.mjs fails the build on anything
new. The blocking gate reports zero new findings on every gated check.
WHAT CHANGED IN THE PROSE
The pages were audited against the Boost review feedback and corrected, then
put through a simplification pass: openers that restate the page title,
paragraphs narrating a code block the reader can already see, ceremonial
transitions, and facts stated twice on one page were removed. That pass
alone took the corpus from 49,280 to 44,848 words, and it stands at 45,536
after the four sections added to "Why Capy?". Reference-dense pages gave up
little, which is correct for them.
Two claims a reviewer would have pressed on are settled. The type-erasure
cost was unverified and a guide summary contradicted it; counted against
any_read_stream.hpp:255-267, the page's figure of five was right, and it now
names the five calls so the claim can be checked rather than trusted. "For
twenty-five years, Boost.Asio has stood alone" asserted a precise duration
and an absolute -- Asio dates to 2003 -- and now reads that Asio set the
standard more than two decades ago and holds it still.
Fifty-nine headers gained or corrected docstrings, so the generated
reference carries behavior, preconditions, thread-safety and exceptions
rather than restating declarations.
FOLLOWING develop
io_result became an alias for std::tuple on develop, so the named ec member
no longer exists. Five prose sites that described the old shape are
corrected, and the io_result section now documents what the alias actually
buys the caller -- tie, apply, get, tuple_cat, comparisons and tuple
assignment -- quoting the header's own docstring. One doc snippet still used
the {{}, n} success shorthand that the alias made ambiguous under libstdc++;
it now spells std::error_code() explicitly, as develop's own snippets do.
VERIFICATION
The 66 test/doc translation units compile with -Wall -Wextra -Werror; all
162 tracked units compile with -Wall -Wextra. doc-lint reports 5
grandfathered D2 findings and no new ones; the hard 25-word limit is met on
every page and every docstring; Vale reports 149 warnings, all
grandfathered. The documentation and CI workflows are both green.
02ec655 to
446006b
Compare
Rewrites the narrative and reference documentation against the shipped code, and adds the linting, baseline and CI machinery that keeps them from drifting again.
Narrative pages (doc/modules/ROOT/pages)
Reference docstrings (include/boost/capy)
Doc-quality tooling (doc/lint, doc/.vale, .github/workflows/docs.yml)
Doc tests (test/doc)
Process artifacts
Known state: the doc-quality job fails on purpose. Two accepted sentence-length (C2) findings in when_any.hpp are not in the baseline; the post-merge reseed grandfathers them. See doc/lint/README.md.