Skip to content

fix(providers): don't warn about project-local providers.json when it is the global file - #3256

Open
curtisgray wants to merge 1 commit into
Graphify-Labs:v8from
curtisgray:fix/local-providers-samefile
Open

fix(providers): don't warn about project-local providers.json when it is the global file#3256
curtisgray wants to merge 1 commit into
Graphify-Labs:v8from
curtisgray:fix/local-providers-samefile

Conversation

@curtisgray

Copy link
Copy Markdown

Running graphify with the working directory at $HOME makes the relative project-local path ./.graphify/providers.json resolve to ~/.graphify/providers.json itself. _load_custom_providers() then warns it is ignoring the user's own trusted global file — which it immediately loads via the global path anyway. The warning is a false positive with an unfortunate failure mode: the remedy it suggests, GRAPHIFY_ALLOW_LOCAL_PROVIDERS=1, is exactly the thing a user (or an agent tidying up warnings) would export globally, permanently disarming the injected-config gate the warning exists to enforce.

Fix: a local path that is the same file as the global one (Path.samefile) is treated as not-local — no warning, no double read. A stat error resolves to "distinct", so the gate never silently relaxes; behavior for a genuinely distinct project-local file is unchanged. One test added mirroring the existing F1 tests.

pytest tests/test_provider_registry.py: all pass including the new test; ruff check clean. Noticed while verifying, unrelated to this diff: test_detect_backend_custom_provider_after_builtins fails on a dev machine that has a real ~/.graphify/providers.json provider whose env key is set (the #1084 dogfood setup) when test_llm_backends.py is collected in the same run — it fails identically on an unmodified checkout and can't affect CI, so I left it alone; happy to file it separately.

https://claude.ai/code/session_0115RXPvhNCHAnc7AFn1ud3H

… when cwd is $HOME

Running graphify from the home directory makes the relative
./.graphify/providers.json resolve to ~/.graphify/providers.json itself,
so the gate warned about 'ignoring' the user's own trusted global file —
which it then loaded via the global path anyway. A false positive here
trains users to export GRAPHIFY_ALLOW_LOCAL_PROVIDERS=1 and disarm the
gate for real. Treat a local path that is the same file as the global one
as not-local: no warning, no double read. Stat errors resolve to
'distinct' so the gate never silently relaxes.

Claude-Session: https://claude.ai/code/session_0115RXPvhNCHAnc7AFn1ud3H

@graphify-labs graphify-labs 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.

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Formal verification. 1 change(s) tested, no difference found (not proven).


Graphify review — findings

Stops _load_custom_providers from warning about and skipping the project-local providers file when it resolves to the same inode as the trusted global ~/.graphify/providers.json (e.g. when run from $HOME), so the user's own config loads without a false-positive warning that pushes people toward the GRAPHIFY_ALLOW_LOCAL_PROVIDERS bypass. Any stat error during the samefile check treats the path as distinct, keeping the gate closed rather than silently relaxing it.

No blocking issues surfaced.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 807 functions depend on the 190 functions this change touches.

Health — this change adds coupling hotspots:

  • new: deduplicate_entities() — 63 callers, 21 callees
  • new: build_merge() — 62 callers, 13 callees
  • new: extract_files_direct() — 17 callers, 20 callees
  • new: extract_corpus_parallel() — 26 callers, 11 callees
  • new: _call_claude_cli() — 31 callers, 9 callees
  • new: dispatch_command() — 2 callers, 123 callees
  • new: _extract_with_adaptive_retry() — 22 callers, 10 callees
  • new: _call_llm() — 11 callers, 18 callees
  • …and 16 more — each is listed as a finding

Verification — 807 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 511 function(s) in the blast radius were not formally verified this run

Formal verification

No difference found (not proven): No behavior difference found in \_load\_custom\_providers (not a proof).

The verifier ran both versions of \_load\_custom\_providers on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.

Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.

Note: An input the sampler did not try could still differ.

· 24 more finding(s) on lines outside this diff (see the check run).

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