test(env): resolve two static process.env bracket shapes in the docs guard - #649
Conversation
…guard The libredb#566 drift guard extracted env vars by matching literal `process.env.NAME`, which is the minority shape here, so it saw 40 of the 57 statically resolvable names and its header comment framed the gap as an edge case. Extend the extractor to the two same-file bracket shapes that make up the gap: 1. `const X = "NAME"` (exported or not) read as `process.env[X]` -- the per-name aliases in `src/lib/agent/config.ts`; 2. an object field whose value is a bare uppercase string literal, read as `process.env[<expr>.field]` -- the rate-limit bucket table in `src/lib/api/rate-limit.ts` (`process.env[spec.maxVar]`). This recovers the six agent aliases and the ten `RATE_LIMIT_*` names the issue lists, plus `VERCEL_DEPLOYMENT_ID` (a seventh alias, platform-injected) which is added to the allowlist with its reason. Names reaching `process.env[...]` as a function argument stay out of scope -- `getEnvVar("LLM_PROVIDER")` and `process.env[envVar]` need a call graph -- and the header comment now states that boundary and the six names it leaves undiscovered instead of naming dynamic reads as an aside. New tests pin each shape by naming specific variables rather than asserting a count, and one pins the out-of-scope boundary so a future widening is a deliberate edit rather than a silent gain. Closes libredb#609 Claude-Session: https://claude.ai/code/session_01TfCvCagTXgpe6bHmtQZ1ry
|
Good first PR here: you measured before you wrote, you pinned names instead of a count, and you wrote down what the guard still cannot see. That last part is the one most people skip. |
|
Merged.
|
…ary test a control (#652) Two follow-ups from #649 review, both from probing the guard rather than a defect in it. - The header and inline comments described shape 2 as `process.env[<expr>.field]`, but `fieldReadPattern` accepts only a single bare identifier before `.field`: `process.env[a.b.field]` and `process.env[arr[0].field]` are not matched. The comment is the guard's contract, so it now says what the regex accepts and names the shapes it skips. Nothing in `src/` is in the deeper shape today, so this is wording only. - `#609 boundary: ...` asserts only absences, so it passed on an empty `readNames()`. The file as a whole is not vacuous -- the first test guards that -- but the negative test now carries its own control: `expect(names.has("JWT_SECRET")).toBe(true)` before the absence checks, in the file's own idiom. One test file, comments and one assertion, no product code.
Extend the #566 env-documentation drift guard (
tests/unit/env-documentation.test.ts) to resolve two staticprocess.env[...]bracket shapes it was blind to, taking the extractor from 40 to 57 of the statically-resolvable names. Its header comment framed that gap as an edge case when it was most of the gap.Type of Change
Related Issue
Closes #609
Changes Made
readNames()to resolve two same-file bracket shapes, in addition to literalprocess.env.NAME:const X = "NAME"(exported or not), thenprocess.env[X]— the per-name aliases insrc/lib/agent/config.ts.process.env[<expr>.field]— the rate-limit bucket table insrc/lib/api/rate-limit.ts(process.env[spec.maxVar]).Both resolve within a single file only; an alias defined elsewhere would need a module graph the guard does not have.
LIBREDB_AGENT_ENABLED,LIBREDB_AGENT_THREAD_CONTEXT,AGENT_MODEL_TUNING_PATH,AGENT_MODEL_TURN_TIMEOUT_MS,WORKFLOW_LOCAL_DATA_DIR,WORKFLOW_TARGET_WORLD) and the 10RATE_LIMIT_*names the issue lists.VERCEL_DEPLOYMENT_ID(a seventh alias, platform-injected, not operator-facing) toALLOWLISTwith its reason; the guard's own "still read / still carries a reason" and "not also documented" tests keep that entry honest.process.env[...]as a function argument stay out of scope —getEnvVar("LLM_PROVIDER")insrc/lib/llm/utils/config.tsandprocess.env[envVar]insrc/lib/seed/credential-resolver.tsneed a call graph — leavingHOSTNAME,MY_DB_PASSWORDand the fourLLM_*names undiscovered.LLM_*/MY_DB_PASSWORDare not found) so a future widening of the extractor is a deliberate edit rather than a silent gain.Testing
bun test tests/unitare pre-existing and environmental (nohelmon PATH, native addons built for a different Node ABI, missinglibstdc++); they are identical with and without this change, and this PR adds +3 passing tests.Ran locally:
bun run format,bun run lint(0 errors),bun run typecheck,bun run knip— all clean.bun test tests/unit/env-documentation.test.ts— 8 pass / 0 fail.Could not run in full:
bun run testandbun run build— the chart tests needhelm(see #570) and several native-addon tests need a rebuild for this machine's Node ABI. This change touches one test file and nosrc/lines, so the 100% line-coverage gate is unaffected; a maintainer approving the workflow run gets the full gate.Test Environment
main@ db40452Screenshots (if applicable)
n/a
Checklist
docs/change)