Background
#3116 surfaced a class of bug: a code-side env var (NEMOCLAW_OLLAMA_PULL_TIMEOUT from #3037) was added without a matching update to docs/reference/commands.md. NV QA caught it externally via test T5882289, which then got auto-synced as a GitHub issue.
The QA test only checks one var at a time, after the fact. We have no internal gate that prevents the next undocumented var from landing the same way.
Current gap
Quick survey of main:
- 85 unique
NEMOCLAW_* env vars are read in src/.
- 22 are documented in
docs/reference/commands.md.
- ~63 are undocumented today. Some are user-facing (
NEMOCLAW_PROVIDER, NEMOCLAW_ENDPOINT_URL, NEMOCLAW_GPU, NEMOCLAW_GATEWAY_START_TIMEOUT, ...). Others are genuinely internal/test sentinels (NEMOCLAW_TEST_*, NEMOCLAW_BACK_TO_SELECTION__, NEMOCLAW_INSTALLING, ...) and shouldn't be documented.
Proposal
Add a small CI gate, modeled after scripts/check-direct-credential-env.ts and scripts/find-source-shape-tests.ts:
scripts/check-env-var-docs.ts — extracts every process.env.NEMOCLAW_* read in src/, diffs against docs/reference/commands.md and an allowlist file.
ci/env-var-doc-allowlist.json — explicit list of internal/test/legacy vars that are intentionally undocumented. Each entry needs a one-line reason so the allowlist doesn't become a dumping ground.
- Wire it up in
.pre-commit-config.yaml (priority 10) and CI so a new undocumented var fails the build at PR time.
Required first-pass triage
The gate can't be turned on cold. Before enabling, someone needs to walk the ~63 undocumented vars and decide for each: document or allowlist with reason. That's the bulk of the work; the script itself is ~50 lines.
Out of scope
- Generating docs from a typed env-var registry (bigger refactor; consider later).
- Documenting non-
NEMOCLAW_* env vars (e.g., BRAVE_API_KEY, TELEGRAM_*) — same idea but the var name pattern is different. Can extend after the core gate lands.
Definition of done
- Adding
process.env.NEMOCLAW_FOO in src/ without either documenting it in commands.md or adding it to the allowlist with a reason fails the prek pre-commit hook and CI.
- All ~63 currently-undocumented vars are either in
commands.md or in the allowlist.
Surfaced from #3116.
Background
#3116 surfaced a class of bug: a code-side env var (
NEMOCLAW_OLLAMA_PULL_TIMEOUTfrom #3037) was added without a matching update todocs/reference/commands.md. NV QA caught it externally via test T5882289, which then got auto-synced as a GitHub issue.The QA test only checks one var at a time, after the fact. We have no internal gate that prevents the next undocumented var from landing the same way.
Current gap
Quick survey of
main:NEMOCLAW_*env vars are read insrc/.docs/reference/commands.md.NEMOCLAW_PROVIDER,NEMOCLAW_ENDPOINT_URL,NEMOCLAW_GPU,NEMOCLAW_GATEWAY_START_TIMEOUT, ...). Others are genuinely internal/test sentinels (NEMOCLAW_TEST_*,NEMOCLAW_BACK_TO_SELECTION__,NEMOCLAW_INSTALLING, ...) and shouldn't be documented.Proposal
Add a small CI gate, modeled after
scripts/check-direct-credential-env.tsandscripts/find-source-shape-tests.ts:scripts/check-env-var-docs.ts— extracts everyprocess.env.NEMOCLAW_*read insrc/, diffs againstdocs/reference/commands.mdand an allowlist file.ci/env-var-doc-allowlist.json— explicit list of internal/test/legacy vars that are intentionally undocumented. Each entry needs a one-line reason so the allowlist doesn't become a dumping ground..pre-commit-config.yaml(priority 10) and CI so a new undocumented var fails the build at PR time.Required first-pass triage
The gate can't be turned on cold. Before enabling, someone needs to walk the ~63 undocumented vars and decide for each: document or allowlist with reason. That's the bulk of the work; the script itself is ~50 lines.
Out of scope
NEMOCLAW_*env vars (e.g.,BRAVE_API_KEY,TELEGRAM_*) — same idea but the var name pattern is different. Can extend after the core gate lands.Definition of done
process.env.NEMOCLAW_FOOinsrc/without either documenting it incommands.mdor adding it to the allowlist with a reason fails the prekpre-commithook and CI.commands.mdor in the allowlist.Surfaced from #3116.