Skip to content

fix: make the env guard catch dead knobs, not just unreachable ones - #656

Merged
NotYuSheng merged 2 commits into
mainfrom
fix/env-guard-detect-dead-knobs
Aug 12, 2026
Merged

NotYuSheng merged 2 commits into
mainfrom
fix/env-guard-detect-dead-knobs

Conversation

@NotYuSheng

@NotYuSheng NotYuSheng commented Aug 11, 2026

Copy link
Copy Markdown
Owner

The gap

The guard added in #645 checked one direction only — variables the backend reads that no compose file passes. It was blind to the inverse: a variable compose passes that no Spring config reads. That knob looks configurable in .env and silently does nothing.

Which is what I shipped in that same PR. #645 wired GEO_TIMEOUT_SECONDS into both compose files because application.yml referenced it — without checking whether anything consumed it. Nothing did; GeoIpService uses hardcoded timeout constants. The knob was inert from the moment it was added, and CI passed green.

#653 caught it independently and removed both the dead property and the compose lines.

A check written because this failure mode had already bitten twice (#628, #641) should not have been able to introduce a third instance of it.

The fix

Reports both directions separately, each with its own remedy:

FAIL — compose passes these to the backend, but no Spring config file
reads them. They look configurable and do nothing.

  dev            TOTALLY_DEAD_KNOB
  prod           TOTALLY_DEAD_KNOB

One deliberate choice

The allowance for variables consumed outside Spring is an explicit two-entry listAPP_MEMORY_MB (read by the entrypoint to size the heap) and TZ (consumed by the OS) — not prefix matching.

I first wrote it as a regex covering LLM_*, MINIO_*, DATABASE_* and friends. That is less maintenance, and it would hide a genuinely dead knob in any of those families — the precise failure this half of the check exists to find. Enumerating the real set showed it is only two entries, so the maintenance argument was hollow.

Verification

Injected fault Result
Knob in compose that nothing reads ✅ fails, names the stacks
SURICATA_ENABLED removed from compose ✅ fails, names the stacks
Unmodified main ✅ passes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved environment configuration validation by detecting missing backend variables and unused Compose variables.
    • Added separate reporting for unreachable and unused configuration values.
    • Recognized documented exceptions for variables consumed outside the application framework.
  • Documentation

    • Updated configuration-check documentation to explain the expanded validation behavior.

The guard checked one direction — variables the backend reads that no compose
file passes — and was blind to the inverse: a variable compose passes that no
Spring config reads. That one looks configurable in .env and does nothing.

Which is exactly what I shipped. #645 wired GEO_TIMEOUT_SECONDS into both
compose files because application.yml referenced it, without checking whether
anything consumed it. Nothing did — GeoIpService uses hardcoded timeout
constants — so the knob was inert from the moment it was added, and CI passed.
#653 removed the dead property and the compose lines with it.

A check written after this failure mode bit twice should not have been able to
introduce a third instance of it. Now reports both directions separately, with
the fix for each.

The allowance for variables consumed outside Spring is an explicit two-entry
list (APP_MEMORY_MB, TZ) rather than prefix matching. A pattern like LLM_* or
MINIO_* would be less maintenance but would hide a genuinely dead knob in the
same family — the precise thing this half of the check exists to find.

Verified in both directions: injecting a knob nothing reads fails the check, and
removing SURICATA_ENABLED from compose fails it too. Passes clean on main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ae1be232-1e91-4279-b33e-5b07d270b003

📥 Commits

Reviewing files that changed from the base of the PR and between 17a0c48 and dc8db32.

📒 Files selected for processing (1)
  • scripts/check_env_passthrough.py

📝 Walkthrough

Walkthrough

The environment checker now validates Spring-to-Compose and Compose-to-Spring coverage. It adds documented passthrough exceptions for infrastructure-consumed variables and reports each failure type separately.

Changes

Environment passthrough validation

Layer / File(s) Summary
Checker diagnostics and passthrough allowlist
scripts/check_env_passthrough.py
The checker documents both validation directions, defines PASSTHROUGH exceptions, reports unreachable and dead variables separately, and succeeds only when both sets are empty.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • NotYuSheng/TracePcap#584 — This PR also modifies Spring-consumed environment variables and Compose passthrough behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: the environment guard now detects dead variables as well as unreachable variables.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@scripts/check_env_passthrough.py`:
- Around line 110-115: Replace the filtered diagnostic append loops that
populate unreachable and dead in the environment passthrough analysis with
list.extend comprehensions over the same filtered tuples. Preserve the existing
ordering and filtering conditions while eliminating the PERF401 findings.
🪄 Autofix

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: afeb08ff-f96e-49a2-bf0c-54301f353842

📥 Commits

Reviewing files that changed from the base of the PR and between bf5eb02 and 17a0c48.

📒 Files selected for processing (1)
  • scripts/check_env_passthrough.py

Comment thread scripts/check_env_passthrough.py Outdated
PERF401 from review on #656. Both filtered append loops become extend over a
generator, which also gave each branch a one-line comment saying what it detects
— the two halves of this check are easy to confuse when skimming.

Adopted the intent rather than the suggested diff: the proposal rewrote the
second loop as dead.extend([(stack, var)]) still inside the for, which is a
single-element extend per iteration and strictly worse than the append it
replaces.

Note there is no Ruff config or Python lint in CI, so this is a readability
change rather than a gate. Behaviour verified unchanged in both directions —
injected dead knob still fails, removed SURICATA_ENABLED still fails, clean tree
still passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@NotYuSheng
NotYuSheng merged commit 3d811ba into main Aug 12, 2026
2 checks passed
@NotYuSheng
NotYuSheng deleted the fix/env-guard-detect-dead-knobs branch August 12, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant