Skip to content

docs: overhaul the documentation and gate it in CI - #377

Merged
mvandeberg merged 1 commit into
cppalliance:developfrom
mvandeberg:pr/doc-improvement
Aug 19, 2026
Merged

docs: overhaul the documentation and gate it in CI#377
mvandeberg merged 1 commit into
cppalliance:developfrom
mvandeberg:pr/doc-improvement

Conversation

@mvandeberg

Copy link
Copy Markdown
Contributor

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)

  • Correct factual defects across every chapter: phantom ReadSource/WriteSink and Source/Sink/BufferSource hierarchies, the "one virtual call per I/O operation" and unconditional heap-frame claims, Corosio's backend count, the stream-concept count, the compiler floor and stale -fcoroutines advice, strand::dispatch's inline-resume condition, fuse's run loop, and seven build recipes that linked a nonexistent target.
  • Link first-mention API references through the cpp: macro instead of retyping signatures, and delete the reproduced contracts and interface sketches those links replace.
  • Declare a Diátaxis :page-mode: per page genre, drop the chapter skeletons, and rebuild each landing page.
  • Apply a Simplified Technical English wording pass to every page and heading.
  • Add 8q.gui-integration with a compiled example under example/gui-integration; move the Corosio echo-server example out to Corosio.

Reference docstrings (include/boost/capy)

  • Rewrite identity-shaped briefs to describe behavior.
  • Specify await-effects contracts for when_all, when_any, task and quitter, and document the awaiter and lock_guard members of async_event, async_mutex, async_waker, immediate, quitter and task.
  • Complete @PARAM, @return, @pre, thread-safety and memory-resource lifetime coverage across full overload sets.
  • Fix docstring examples that did not compile, and correct claims about strand's on_work_started/finished, thread_pool's lazy start, default-constructed UB, after-error behavior, release() postconditions, and MutableBufferSequence conversion.
  • Add the boost/capy/test.hpp umbrella header; exclude internal test helpers from the reference via mrdocs.yml.
  • Apply the same Simplified Technical English pass to header prose.

Doc-quality tooling (doc/lint, doc/.vale, .github/workflows/docs.yml)

  • Vale configuration plus Capy styles: NoFluff, PartHeadings, SentenceLength, SimpleTense, Terminology and an accept vocabulary.
  • Node checkers under doc/lint: doc-lint, sentence-length, mrdocs-warnings, run-a11y, docstring extraction, baseline authoring and comparison, and a selftest with fixtures.
  • baseline.json grandfathers existing violations so the gate fails only on new ones. Docstrings are extracted from /// comments so the gates see headers, not just .adoc.
  • CI runs a blocking doc-quality gate on A1/A6/A7/B2/D2, MrDocs warnings and C2/C4/C9/C10; every check fails closed when it collapses to zero or its corpus was not regenerated. Accessibility (pa11y) and the remaining rules report without blocking. A workflow_dispatch job reseeds the baseline.

Doc tests (test/doc)

  • Extend the compiled snippets and programs, build them warnings-as-errors, and drop the snippets whose page sketches were deleted.

Process artifacts

  • DOC_IMPROVEMENT_PLAN.md, DOC_STYLE_GUIDE.md, DOC_AUDIT_REFERENCE.md, DOC_REVIEW_FEEDBACK.md, DOC_AUDIT_PHASE4_EXIT.md, doc-worklist.md, doc-xref-gaps.md, doc-rationale-classification.md and doc-prompts/ record the plan, the style rules, the audit method and the remaining backlog.

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.

@cppalliance-bot

cppalliance-bot commented Aug 14, 2026

Copy link
Copy Markdown

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

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.09%. Comparing base (aed1c30) to head (446006b).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop     #377   +/-   ##
========================================
  Coverage    98.09%   98.09%           
========================================
  Files          130      130           
  Lines         6291     6291           
========================================
  Hits          6171     6171           
  Misses         120      120           
Flag Coverage Δ
linux 98.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
include/boost/capy/buffers.hpp 100.00% <ø> (ø)
include/boost/capy/buffers/buffer_param.hpp 100.00% <ø> (ø)
include/boost/capy/buffers/buffer_slice.hpp 100.00% <ø> (ø)
include/boost/capy/buffers/consuming_buffers.hpp 100.00% <ø> (ø)
include/boost/capy/buffers/make_buffer.hpp 100.00% <ø> (ø)
include/boost/capy/concept/decomposes_to.hpp 100.00% <ø> (ø)
include/boost/capy/cond.hpp 100.00% <ø> (ø)
include/boost/capy/detail/slice_of.hpp 100.00% <ø> (ø)
include/boost/capy/error.hpp 100.00% <ø> (ø)
include/boost/capy/ex/any_executor.hpp 100.00% <100.00%> (ø)
... and 34 more

... and 41 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update aed1c30...446006b. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cppalliance-bot

cppalliance-bot commented Aug 14, 2026

Copy link
Copy Markdown

GCOVR code coverage report https://377.capy.prtest3.cppalliance.org/gcovr/index.html
LCOV code coverage report https://377.capy.prtest3.cppalliance.org/genhtml/index.html
Coverage Diff Report https://377.capy.prtest3.cppalliance.org/diff-report/index.html

Build time: 2026-08-19 15:22:10 UTC

@mvandeberg
mvandeberg force-pushed the pr/doc-improvement branch 4 times, most recently from 5d4a747 to 02ec655 Compare August 18, 2026 22:09
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.
@mvandeberg
mvandeberg merged commit 59296c7 into cppalliance:develop Aug 19, 2026
39 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Beast2 Aug 19, 2026
@mvandeberg
mvandeberg deleted the pr/doc-improvement branch August 19, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants