The two PRs beneath this one fix ~25 false documentation claims. This one stops them coming back.
[!NOTE] Stacked on #1400. Review order: #1399 → #1400 → this.
Why the drift was invisible
The Docs workflow is path-filtered on docs/:
on:
push:
paths:
- 'docs/**'
- 'bunpress.config.ts'So a change under src/ that renamed a flag, retired a command or dropped a config key never re-checked the page describing it. Combined with bin/cli.ts (3,401 lines, ~30 commands) being imported by zero tests, nothing in the repo could notice. That is why so much of the drift was flag-shaped.
What this adds
bun run check:docs derives the truth from source at run time, so it cannot go stale the way a hand-maintained list would:
- CLI surface — every
buddy <command> [--flags]written in the docs must resolve to a command registered inbin/cli.ts, with flags that command actually declares. - Config keys — every key in a Buddy config example must exist in
BuddyConfig(src/types.ts) orPackageRule(src/rules/engine.ts).
It lives in CI rather than the Docs workflow precisely because CI has no path filter, and publish-commit now depends on it so drift cannot reach the registry.
Keeping it honest rather than merely loud
Two refinements, both of which were real false positives during development:
- Keys under a
Record<string, …>are user data, not schema — a package name inpinis not reported. - A fence that declares types is describing a shape rather than using one.
That second rule is also the blind spot: an invented interface in an API reference page still passes. Checking a documented type against a real one is a different problem, and the script header says so rather than implying coverage it does not have.
Proof it works
Injecting three regressions into docs/usage.md:
docs/usage.md
724: unknown command: buddy frobnicate
725: buddy scan: unknown flag --totally-fake-flag
732: unknown config key: imaginarySection
✗ 31 claim(s) in 3 file(s) do not match the source.Exit 1. On the current tree:
✓ 75 pages agree with 30 commands and 221 config keysVerification
- 1885 pass / 0 fail, lint clean, typecheck clean
check:docspasses on this branch
Part 3 of 3.
🤖 Generated with Claude Code