A docs-lint test, and what it immediately found
Three classes of doc breakage reached main and survived months because nothing checked documentation against the code. All three are cheap to assert offline:
- every code fence closes
- every prose page starts with a heading
- no identifier has
_rewritten as*, and no multiplication has*rewritten as_ - every documented
db./trx./tx.call names a method that exists - every documented
DB_*variable is one the library reads
The method and env-var checks read the live code — methods from a real builder plus a real chain, variables from a scan of src/ — so neither drifts as the API grows.
It earned its keep on the first run: docs/aggregations.md is a seventh page truncated by eaa3b24, the same commit behind the six repaired in #1066. That pass missed it because it worked from a list instead of a check. Restored from eaa3b24^. Also fixed two SELECT _ FROM in README.md that should have been SELECT *.
A correction on the env vars
I filed #1070 on a bad grep and it was wrong. DB_HOST, DB_PORT, DB_USERNAME and DB_PASSWORD are read — createConnectionString does const e = process.env and then reads e.DB_HOST, which a search for process.env.DB_* misses entirely.
The true problem is narrower and more useful: those variables only apply when DB_CONNECTION names the dialect. Setting DB_HOST alone is silently ignored. Verified both directions:
DB_HOST=env-host -> postgres://u:p@config-host:5432/d
DB_CONNECTION=postgres DB_HOST=env-host -> postgres://u:p@env-host:5432/dThat gating was never documented, and it is the likely reason following the docs appeared to do nothing. So this documents reality rather than changing behaviour — deliberately, since making the vars apply ungated would mean a stray DB_HOST in someone's environment silently redirecting their database.
docs/usage.md now lists every variable that is read and says plainly that DB_CONNECTION arms the rest. docs/features/cli.md's security example sets it and uses DB_USERNAME rather than the never-read DB_USER. DB_TIMEOUT, DB_RETRY_ATTEMPTS, DB_HEALTH_CHECK_INTERVAL and DB_WAIT_READY_ATTEMPTS are gone — read nowhere, and the settings they implied are config rather than environment, so the section points at setConfig().
The scanner strips comments before matching, so db.ts's own note about the unread DB_NAME doesn't count as a read.
Repo hygiene
other.db, other.db-shm, other.db-wal were tracked at the repo root and again inside the package — six files of sqlite scratch state from 81e6b40, regenerated by two connection-string tests on every run. .gitignore listed sqlite paths one at a time and only covered packages/benchmark/; it now ignores *.db, *.db-shm, *.db-wal anywhere. Nothing currently tracked matches.
The root qbx was two lines from 2733193 chore: wip pointing at ./bin/cli, which does not exist at the repo root — it only ever produced Cannot find module './bin/cli', and wasn't executable so the shebang never applied. Deleted. The published qbx binaries are unaffected; they're declared as ./dist/bin/cli.js.
Verification
Typecheck 0, lint 0 errors, 1706 pass / 4 skip / 0 fail (+7 from the new checks).
🤖 Generated with Claude Code