Skip to content

ci: gate NEMOCLAW_* env vars against documentation drift (#3184)#3187

Merged
ericksoa merged 2 commits into
mainfrom
feat/3184-env-var-doc-gate
May 9, 2026
Merged

ci: gate NEMOCLAW_* env vars against documentation drift (#3184)#3187
ericksoa merged 2 commits into
mainfrom
feat/3184-env-var-doc-gate

Conversation

@cjagwani

@cjagwani cjagwani commented May 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a CI gate that fails if any NEMOCLAW_* env var read in src/ or bin/ is missing from docs/reference/commands.md and not explicitly allowlisted with a real reason. Closes the doc-drift class of bug surfaced by #3116, where NEMOCLAW_OLLAMA_PULL_TIMEOUT shipped without a doc entry and was caught externally by NV QA rather than by our own pipeline.

Related Issue

Closes #3184

Changes

  • scripts/check-env-var-docs.ts — TypeScript-AST extractor + auditor (~250 lines). Skips assignments, deletes, and comments. Validates the allowlist for short reasons, invalid name pattern, and simultaneous doc + allowlist.
  • test/check-env-var-docs.test.ts — 26 unit tests covering extractor (property/element access, assignment/delete exclusion, non-NEMOCLAW exclusion, comment exclusion), doc parsing, allowlist parsing, and full audit (undocumented, stale-allowlist, invalid-allowlist, simultaneous-doc-and-allowlist).
  • ci/env-var-doc-allowlist.json — two genuinely internal vars (NEMOCLAW_DISABLE_AUTO_DISPATCH test harness sentinel, NEMOCLAW_TEST_NO_SLEEP Vitest sleep bypass), each with a real reason.
  • docs/reference/commands.md — 24 newly documented vars across three new subsections:
    • Onboarding Configuration — provider, endpoint URL, proxy, build-time model overrides (NEMOCLAW_PROVIDER, NEMOCLAW_ENDPOINT_URL, NEMOCLAW_AGENT_TIMEOUT, NEMOCLAW_CONTEXT_WINDOW, NEMOCLAW_MAX_TOKENS, NEMOCLAW_REASONING, NEMOCLAW_INFERENCE_INPUTS, NEMOCLAW_PROXY_HOST/PORT, NEMOCLAW_OLLAMA_REQUIRE_TOOLS, NEMOCLAW_OPENSHELL_BIN, NEMOCLAW_SANDBOX, NEMOCLAW_INSTALL_REF/TAG, NEMOCLAW_PREFERRED_API).
    • Onboarding Behavior FlagsNEMOCLAW_YES, NEMOCLAW_EXPERIMENTAL, NEMOCLAW_IGNORE_RUNTIME_RESOURCES, NEMOCLAW_DISABLE_OVERLAY_FIX, NEMOCLAW_OVERLAY_SNAPSHOTTER, NEMOCLAW_SKIP_TELEGRAM_REACHABILITY, NEMOCLAW_CONFIG_ACCEPT_NEW_PATH.
    • Probe TimeoutsNEMOCLAW_SANDBOX_EXEC_TIMEOUT_MS, NEMOCLAW_STATUS_PROBE_TIMEOUT_MS.
  • .pre-commit-config.yaml — new env-var-docs hook (priority 10) that runs whenever src/, bin/, the docs file, the allowlist, or the gate script changes.

Triage outcome

Initial naive grep over src/ showed 63 "undocumented" NEMOCLAW_* vars. The AST audit narrowed that to 26 actually read via process.env in src/ + bin/ — the other 37 were string literals, constants, or comment text that the regex matched but the extractor (correctly) ignores. Of those 26: 24 documented, 2 allowlisted.

Type of Change

  • Code change with doc updates

Verification

  • npx prek run --all-files passes (commit went through pre-commit hooks including coverage ratchet, markdownlint, biome, gitleaks).
  • npm test passes — 26 new unit tests in test/check-env-var-docs.test.ts.
  • Tests added or updated for new or changed behavior.
  • No secrets, API keys, or credentials committed.
  • Docs updated for user-facing behavior changes.
  • Doc pages follow the style guide.

Verified the gate fails on each of:

  • new process.env.NEMOCLAW_X read with no doc and no allowlist entry,
  • stale allowlist entries (vars no longer read in src/),
  • allowlist entries with too-short reasons or invalid name patterns,
  • vars that are both documented and allowlisted (must pick one).

Summary by CodeRabbit

  • New Features

    • Expanded environment-variable docs: onboarding configuration, behavior flags, probe timeouts, and a new lifecycle flag (NEMOCLAW_CLEANUP_GATEWAY).
    • Added a doc-audit check that detects undocumented or stale environment variables.
  • Documentation

    • Clarified formats, effects, and defaults for many NEMOCLAW_* variables; updated casing for onboard timeouts.
  • Chores / Tests

    • Added development-time tooling, pre-commit audit, and tests to keep docs in sync with code.

Adds a CI gate that fails if any NEMOCLAW_* env var read in src/ or bin/
is missing from docs/reference/commands.md and not explicitly allowlisted
in ci/env-var-doc-allowlist.json with a real reason. Surfaced from #3116,
where NEMOCLAW_OLLAMA_PULL_TIMEOUT shipped without a doc entry and was
caught externally by NV QA rather than by our own pipeline.

Changes:
- scripts/check-env-var-docs.ts: TypeScript-AST extractor + auditor.
  Skips assignments, deletes, and comments. Validates the allowlist for
  short reasons, invalid name pattern, and simultaneous doc + allowlist.
- test/check-env-var-docs.test.ts: 26 unit tests (extractor, doc
  parsing, allowlist parsing, full audit including stale + invalid
  entry detection).
- ci/env-var-doc-allowlist.json: two genuinely internal vars
  (NEMOCLAW_DISABLE_AUTO_DISPATCH test harness sentinel,
  NEMOCLAW_TEST_NO_SLEEP Vitest sleep bypass), each with a real reason.
- docs/reference/commands.md: 24 newly documented vars across three
  subsections — Onboarding Configuration (provider, endpoint URL,
  proxy, build-time model overrides), Onboarding Behavior Flags
  (NEMOCLAW_YES, NEMOCLAW_EXPERIMENTAL, etc.), and Probe Timeouts
  (sandbox exec + status probe ms overrides).
- .pre-commit-config.yaml: new env-var-docs hook (priority 10) that
  runs whenever src/, bin/, the docs file, the allowlist, or the gate
  script changes.

Verified the gate fails on:
- a new process.env.NEMOCLAW_X read with no doc and no allowlist entry,
- stale allowlist entries (vars no longer read in src/),
- allowlist entries with too-short reasons or invalid name patterns,
- vars that are both documented and allowlisted (must pick one).

Signed-off-by: Charan Jagwani <charjags100@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented May 7, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7d0fe026-7baf-4868-ae44-1e44d2747366

📥 Commits

Reviewing files that changed from the base of the PR and between fad0a93 and b4bf1d7.

📒 Files selected for processing (5)
  • .pre-commit-config.yaml
  • ci/env-var-doc-allowlist.json
  • docs/reference/commands.md
  • scripts/check-env-var-docs.ts
  • test/check-env-var-docs.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • ci/env-var-doc-allowlist.json
  • .pre-commit-config.yaml
  • test/check-env-var-docs.test.ts

📝 Walkthrough

Walkthrough

Adds a static doc-drift gate: a TypeScript auditor extracts NEMOCLAW_* env var reads from source, compares them to commands.md and a CI allowlist, reports undocumented/stale/invalid entries, wires the check into pre-commit, adds the allowlist, and includes tests.

Changes

Environment Variable Documentation Enforcement Gate

Layer / File(s) Summary
Data Contracts & Audit Logic
scripts/check-env-var-docs.ts (range_070249771b8e, range_c67d13b60734)
Defines AllowlistEntry, AuditOptions, and AuditResult; implements core audit functions to parse documented vars, load/validate allowlist JSON, extract NEMOCLAW_* reads from source text, and reconcile results into undocumented, staleAllowlist, and invalidAllowlist lists.
Source Discovery & AST Inspection
scripts/check-env-var-docs.ts (range_632816dfaa75, range_dd79ab9e6ad2)
walkSourceFiles() collects candidate .ts/.tsx/.js/.cjs/.mjs files from src/ and bin/ while excluding node_modules, tests, dot-directories, and .d.ts; AST helpers identify process.env property and bracket accesses (string-literal names) and exclude assignments, deletes, dynamic identifier access, and comment-contained reads.
CLI Orchestration & Error Reporting
scripts/check-env-var-docs.ts (range_aee4c85a4169)
main() resolves repository paths, gathers source files and docs, runs the audit, prints category-specific failure messages, and sets process.exitCode = 1 when failures are detected.
Allowlist Data
ci/env-var-doc-allowlist.json (range_64dd5cbfa0c0)
New JSON allowlist enumerating test/internal NEMOCLAW_* environment variables with short reason strings to exempt them from documentation requirements.
Environment Variable Documentation
docs/reference/commands.md (range_6789a44b5eab, range_349e551c5576, range_583cdffb96c4, range_0c495ef52ea3, range_43cb51bae208, range_7ab1edab0cc0)
Expands and restructures the Environment Variables section with Onboarding Configuration, Onboarding Behavior Flags, Probe Timeouts, a capitalization tweak for Onboard Timeouts, and Lifecycle Behavior Flags (NEMOCLAW_CLEANUP_GATEWAY).
Pre-commit Hook Integration
.pre-commit-config.yaml (range_25945032d65e)
Adds local env-var-docs pre-commit hook at priority 10 to run npx tsx scripts/check-env-var-docs.ts, disables pass_filenames so the script rescans the repo, and triggers on src/, bin/, docs/reference/commands.md, ci/env-var-doc-allowlist.json, and the script file.
Comprehensive Test Suite
test/check-env-var-docs.test.ts (range_4626625a65bb, range_5ecb04532e6a, range_20b0ecf0e3b0, range_63a7ee9ea506, range_17e06c55a0fa)
Adds Vitest tests validating AST-based extraction of NEMOCLAW_* reads (property/bracket/destructuring/coalescing; excludes assignments/deletes/dynamic access/comments), markdown parsing, allowlist JSON validation, walkSourceFiles resilience, and full auditEnvVarDocs scenarios (undocumented, allowlist, staleAllowlist, invalidAllowlist).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop through lines with curious paws,

Counting NEMOCLAW without a pause,
I match them to docs and mark what's missed,
Tests and hooks seal every list,
Now docs and code are snug in laws.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly summarizes the main change: implementing a CI gate to enforce documentation of NEMOCLAW_* environment variables to prevent documentation drift.
Linked Issues check ✅ Passed All primary objectives from #3184 are met: the check-env-var-docs.ts script extracts process.env reads and validates against docs and allowlist, the allowlist file documents internal vars with reasons, the pre-commit hook is wired with priority 10, and all 26 undocumented vars are either documented or allowlisted.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the documentation drift gate for NEMOCLAW_* env vars; no unrelated modifications or future-work items are included.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/3184-env-var-doc-gate

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/reference/commands.md`:
- Line 1002: The sentence "These tune how long internal probes wait before
giving up. Defaults are sized for typical hardware; override only if you see
false-positive timeouts." contains two sentences on one line; split them into
two separate lines so each sentence appears on its own line in
docs/reference/commands.md (preserve both sentences and punctuation exactly,
e.g., first line "These tune how long internal probes wait before giving up."
and second line "Defaults are sized for typical hardware; override only if you
see false-positive timeouts.").
- Line 968: The two sentences in the docs string "These variables let you tune
onboarding without editing the Dockerfile or passing repeated flags. Set them
before running `nemoclaw onboard`." should be split into two separate lines so
each sentence occupies its own line for diff-readability; edit the
docs/reference/commands.md entry to place the first sentence on one line and the
second sentence on the next line, preserving punctuation and the inline code
token `nemoclaw onboard`.
- Around line 988-990: Add a one-line introductory sentence immediately after
the "### Onboarding Behavior Flags" heading and before the table to describe
what the flags control (e.g., "These flags control the onboarding flow and
related feature toggles."). Update the section around the "### Onboarding
Behavior Flags" heading so the table is preceded by that brief explanatory
sentence, matching the pattern used by the sibling sections "Onboarding
Configuration" and "Probe Timeouts".

In `@scripts/check-env-var-docs.ts`:
- Around line 144-166: The walk function uses statSync without error handling
which can throw on broken symlinks or race conditions; wrap the statSync(full)
call in a try/catch (similar to readdirSync) and on error simply continue/skip
that entry (optionally log/debug the error) so the script doesn't crash; update
references in the walk function around the statSync usage and keep the existing
behavior of recursing for directories and pushing files into out when stat
succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5886e8a7-820a-4634-9da4-549548e853a1

📥 Commits

Reviewing files that changed from the base of the PR and between 2c3a392 and fad0a93.

📒 Files selected for processing (5)
  • .pre-commit-config.yaml
  • ci/env-var-doc-allowlist.json
  • docs/reference/commands.md
  • scripts/check-env-var-docs.ts
  • test/check-env-var-docs.test.ts

Comment thread docs/reference/commands.md Outdated
Comment thread docs/reference/commands.md
Comment thread docs/reference/commands.md Outdated
Comment thread scripts/check-env-var-docs.ts

@ericksoa ericksoa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head b4bf1d7 after merging current main. CodeRabbit threads resolved; local and GitHub checks are green.

@ericksoa ericksoa enabled auto-merge (squash) May 9, 2026 04:14
@ericksoa ericksoa merged commit ceb1dc9 into main May 9, 2026
17 checks passed
@ericksoa ericksoa deleted the feat/3184-env-var-doc-gate branch May 9, 2026 04:14
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions bug-fix PR fixes a bug or regression chore Build, CI, dependency, or tooling maintenance area: docs Documentation, examples, guides, or docs build and removed CI/CD bug-fix PR fixes a bug or regression labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: docs Documentation, examples, guides, or docs build chore Build, CI, dependency, or tooling maintenance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: enforce documentation for all user-facing NEMOCLAW_* env vars

4 participants