Skip to content

feat: docs-check gate (recurring doc-vs-reality CI check)#178

Merged
avrabe merged 5 commits intomainfrom
feat/v041-docs-check-gate
Apr 22, 2026
Merged

feat: docs-check gate (recurring doc-vs-reality CI check)#178
avrabe merged 5 commits intomainfrom
feat/v041-docs-check-gate

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 22, 2026

Summary

Introduces a recurring rivet docs check gate that asserts documentation
claims match reality before every PR merge and every release tag. This
complements the one-time doc-reality audit — we catch future drift the
same way clippy catches lint errors.

  • New core module rivet-core/src/doc_check.rs with 8 invariants
    (SubcommandReferences, EmbedTokenReferences, VersionConsistency,
    ArtifactCounts, SchemaReferences, SoftGateHonesty,
    ConfigExampleFreshness, ArtifactIdValidity). 24 unit tests cover
    flagged/clean paths per invariant plus false-positive heuristics.
  • New CLI subcommand rivet docs check [--fix] [--format json]
    that prints file:line [invariant] claim -- reality for each
    violation and exits non-zero if any fire. --fix auto-corrects
    version numbers in ancillary package.json files.
  • CI gate: docs-check job in .github/workflows/ci.yml with
    NO continue-on-error. Release workflow gates create-release
    on the same job.
  • Make-the-tree-pass commit: fixes the 33 violations that the
    gate finds on main today — vscode-rivet 0.3.0 -> 0.4.0, README.md
    stale command table and artifact count, AGENTS.md/CHANGELOG.md/
    audit-report.md file-level AUDIT markers for historical snapshots.

Before/after counts on main:

  • Before: 33 violations across 14 files
  • After: 0 violations (31 files scanned)

Design-doc opt-out

Roadmap / planning docs can opt out of existence-based invariants
(SubcommandReferences, EmbedTokenReferences, ArtifactIdValidity,
VersionConsistency) with either:

  • An HTML comment at the top: <!-- rivet-docs-check: design-doc-aspirational-ok -->
  • Or by living under docs/plans/ or docs/design/ (auto-detected)

They remain subject to SchemaReferences, SoftGateHonesty, and
ConfigExampleFreshness, which are always true-false regardless of
aspiration.

Release-time gate

# .github/workflows/release.yml
docs-check:
  name: Docs Check
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v6
    - uses: dtolnay/rust-toolchain@stable
    - uses: Swatinem/rust-cache@v2
    - run: cargo run --release -p rivet-cli -- docs check

create-release:
  needs: [build-binaries, build-compliance, build-test-evidence, docs-check]

A release tag that contains stale doc claims cannot ship.

Test plan

  • cargo test -p rivet-core --lib doc_check — 24 tests pass
  • rivet docs check on current main — PASS (31 files, 0 violations)
  • rivet docs check --format json — machine-readable output
  • Each invariant has flagged + clean fixture tests
  • GitHub CI runs the new docs-check job green
  • Release workflow blocks create-release when docs-check fails

Trailer

Refs: REQ-054

avrabe added 5 commits April 22, 2026 08:15
…tion

Introduces rivet-core/src/doc_check.rs: an invariant engine that scans
README.md, CHANGELOG.md, AGENTS.md/CLAUDE.md and every *.md under docs/
to catch doc-code drift.

Ships 8 invariants (MVP):
- SubcommandReferences — "rivet <word>" must be a real subcommand
- EmbedTokenReferences — "{{name:...}}" must be a registered embed
- VersionConsistency — workspace version == vscode/npm package.json
  and > every version string mentioned in prose
- ArtifactCounts — "N <noun>" needs {{stats}} or AUDIT marker
- SchemaReferences — schemas/foo.yaml must exist
- SoftGateHonesty — "enforced"/"wired into CI" claims must not match
  a job carrying continue-on-error: true
- ConfigExampleFreshness — fenced yaml/yml blocks must parse
- ArtifactIdValidity — REQ-NNN style IDs must resolve in the store

Opt-out for roadmap docs:
<!-- rivet-docs-check: design-doc-aspirational-ok -->
Files under docs/plans/ or docs/design/ are auto-detected as design docs.

21 unit tests in-module covering fixture-doc-flagged and fixture-doc-
clean paths for each invariant plus line/code-fence helpers.

Refs: REQ-054
Wires the doc_check engine into the CLI as a `check` subtopic of the
existing `docs` command.  Usage:

  rivet docs check              # text output, exit 1 on failure
  rivet docs check --format json
  rivet docs check --fix        # apply auto-fixes (version numbers)

The handler pulls the known-subcommand list from clap::CommandFactory at
runtime so it stays in sync with the actual CLI.  Known embed kinds are
currently hard-coded to match rivet-core/src/embed.rs.

Loads the project store when available; invariants that need it (like
ArtifactIdValidity) silently skip when the project fails to load so the
check can still run against docs-only repos.

Also reads .github/workflows/ci.yml (when present) to drive the
SoftGateHonesty invariant.

JSON output is machine-readable with `status`, `violation_count`,
`by_invariant`, and a `violations[]` array, ready for CI annotations.

Refs: REQ-054
Adds a new 'docs-check' job in both .github/workflows/ci.yml and
.github/workflows/release.yml that runs 'rivet docs check' and fails
the build if any invariant is violated.

The release workflow gates 'create-release' on this job so a tag
cannot produce a GitHub Release while documentation claims are
stale.

Deliberately uses neither continue-on-error nor an allow-list: doc
drift should fail the build the same way clippy errors do.  Budget
is <1 minute on a warm rust-cache.

Trace: skip
Observations running the gate against the current tree:
- "rivet never touches" / "rivet models itself" matched SubcommandReferences.
  Fix: require the match to be inside inline backticks or after a shell-
  prompt marker ("$ ").
- Document front-matter IDs (AUDIT-001, SRS-001, ROAD-001, …) tripped
  ArtifactIdValidity.  Fix: collect front-matter IDs up front and exclude
  them from body checks.
- Anchor-style hex hashes (YAML-654FF0, STPA-654FF0) tripped the same
  invariant.  Fix: recognize the hex-hash suffix pattern.
- DO-178C / UTF-8 / NOPE-999 were flagged.  Fix: extend non-artifact
  prefix skip-list.
- Design docs under docs/plans/ mention future rivet versions (v0.5.0,
  v1.0.0) as part of roadmaps.  Fix: skip VersionConsistency entirely
  for design docs, plus skip versions inside inline backticks (third-
  party version pins like `kani-version: '0.50.0'`).
- CHANGELOG and audit-report.md are large historical snapshots; tagging
  every count line with AUDIT was noisy.  Fix: add a file-level
  `<!-- AUDIT-FILE: verified YYYY-MM-DD -->` marker that suppresses
  ArtifactCounts for the entire document.

Also recognize `rivet import` unconditionally (it exists behind the
`wasm` feature gate but the CI build doesn't enable it) so that docs
describing the full surface don't break the release gate.

Three new unit tests: subcommand_references_skip_plain_prose,
artifact_id_validity_ignores_frontmatter_ids,
artifact_id_validity_skips_hex_anchor_hashes.  All 24 tests pass.

Refs: REQ-054
Fixes the violations that `rivet docs check` reports against main:

- vscode-rivet/package.json: bumped 0.3.0 -> 0.4.0 to match the
  workspace.  Without this the extension version lags every CLI
  release (this has happened every release so far).
- README.md: the commands table listed `rivet import` for
  "ReqIF, sphinx-needs JSON".  The real command for that path is
  `rivet import-results`; `rivet import` is the WASM adapter
  entry point.  Also updated the dogfood line from the stale
  "447 artifacts" to the actual current count (709) with an
  AUDIT marker pointing future readers at `rivet stats`.
- CHANGELOG.md: added a file-level AUDIT-FILE marker.  Every
  count in the changelog is a release-time snapshot and should
  not be required to track current state.
- AGENTS.md: added an AUDIT marker after the retroactive
  traceability table (a frozen historical record of the v0.0.x
  -> v0.3 commit map).
- docs/audit-report.md: added a file-level AUDIT-FILE marker for
  the same reason as CHANGELOG.

Result: `rivet docs check` passes (31 files, 0 violations).

Refs: REQ-054
@avrabe avrabe force-pushed the feat/v041-docs-check-gate branch from a55228e to 49b22f4 Compare April 22, 2026 06:22
@avrabe avrabe merged commit a86cbe7 into main Apr 22, 2026
@avrabe avrabe deleted the feat/v041-docs-check-gate branch April 22, 2026 06:22
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