Read .env from the working directory, as grapharc.toml already is - #85
Merged
Conversation
`find_env_file` walked up parent directories to `/`, while the config layer next door refuses exactly that on principle — so the file that *spends money* was discovered more eagerly than the one that *constrains* a run. A run started in a scratch subdirectory picked up an `OPENROUTER_API_KEY` from any ancestor: a `.env` in `$HOME` billed every user's experiment on a shared box to that key, and since `redact()` is the only thing that ever prints a key, nothing said which file paid. The start directory (default: cwd) is now the only directory consulted. The signature and the None-when-absent contract are unchanged, so `get_secret` and the four backend accessors needed no edit, and neither escape hatch moved: a real environment variable still beats any file, and `env_file=` still names a file anywhere. No search boundary replaces the walk — stopping at a git root would still be an upward search. Behaviour change: a parent-directory `.env` stops being read. It is called out in the README's limits list and the changelog, and the docstrings and cookbook sentences that described the walk now describe the rule that replaced it. Fixes #20 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
.envin a parent directory is no longer read. If you relied on one (a key in$HOME, or above a checkout), do one of:.envinto the directory you run from,exportthe variable in your shell, orenv_file=naming the file explicitly.A real environment variable still beats any file, and an explicit
env_file=still reads a file anywhere on disk. Called out in the README's Status and limits list and inCHANGELOG.mdunder## Unreleased.The fix
gateway/config.find_env_filewalked(here, *here.parents)— up to/— whilecli/config.pyrefuses exactly that on principle forgrapharc.toml. So the thing that spends money was discovered more eagerly than the thing that constrains a run: a run started in a scratch subdirectory silently billed against a key the operator never put in scope (a.envin$HOMEon a shared box; a demo checked out under a client project), and sinceredact()is the only thing that ever prints a key, nothing in normal operation revealed which file paid.It now reads the start directory (default: cwd) and no ancestor of it:
The signature and the
None-when-absent contract are unchanged, soget_secretand the four backend accessors (openrouter_api_key,openai_api_key,ollama_api_key, the base-URL lookups) needed no edit. Env-var precedence is untouched —get_secretstill checksos.environfirst.Deliberately not done, per the issue: no new "search boundary" (stopping at a git root is still an upward search), no change to
grapharc.tomldiscovery, no new key spellings.Before / after
Same repro as the issue — a
.envthree directories above the working directory:Prose updated
grapharc/gateway/config.pymodule docstring — states the one-directory rule and why it binds harder here than on the config layer.README.mdlimits list — the "inconsistency" bullet becomes ".envandgrapharc.tomlfollow the same discovery rule", plus the migration note.grapharc/slack/config.pydocstring anddocs/cookbook/07-slack.md— both described the upward search as the reason the bot won't use this loader; the reason is restated (the bot's workdir is somewhere other things write), the stale claim is gone.docs/cookbook/02-models.md— "the nearest .env" was the walk by another name.docs/architecture-review.md§4.7 is left alone on purpose: it is a dated audit snapshot ("Version audited: 0.1.1"), not live documentation.Tests
Three new tests in
tests/test_gateway_openrouter.py:.envis not found while one in the start directory is;env_file=in an unrelated directory still resolves;.envin cwd.Reverting the one loop turns the first one red (
assert find_env_file(deep) is None→ the parent's.env), verified; the other two stay green either way, which is what makes them a precedence check rather than a restatement of the fix.Verification:
pytest→ 1,847 passed, 12 deselected (the live ones);ruff check grapharc testsclean. The README byte-comparison tests (test_readme.py,test_cookbook_*.py) are green.Fixes #20
🤖 Generated with Claude Code