Skip to content

fix: derive loadConfig() rootDir from --db path in read-only query functions#2018

Open
carlos-alm wants to merge 1 commit into
fix/issue-1865-reconnectreversedepedges-still-mis-wires-samefrom
fix/issue-1881-loadconfig-resolves-from-process-cwd-instead
Open

fix: derive loadConfig() rootDir from --db path in read-only query functions#2018
carlos-alm wants to merge 1 commit into
fix/issue-1865-reconnectreversedepedges-still-mis-wires-samefrom
fix/issue-1881-loadconfig-resolves-from-process-cwd-instead

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

manifestoData(), hybridSearchData(), moduleBoundariesData(), diffImpactData(), complexityData() (via resolveComplexityQueryOptions()), and auditData() each called loadConfig() bare or with process.cwd() instead of deriving the rootDir from the resolved --db path. This meant --db /other/repo/.codegraph/graph.db invoked from a different working directory read the invoking directory's .codegraphrc.json instead of the target repo's — silently applying the wrong manifesto thresholds, analysis depths, search settings, cohesion thresholds, and db.busyTimeoutMs.

auditData()'s file was internally inconsistent: its own resolveThresholds() helper already derived rootDir correctly from customDbPath, while auditData() itself did not — and even resolveThresholds()'s manual path.dirname(customDbPath) + path.resolve(dbDir, '..') computation had a latent bug of its own, silently producing the wrong root when --db pointed at a directory (e.g. --db /repo or --db /repo/.codegraph) rather than a file, because it skipped findDbPath()'s directory-to-graph.db normalization.

Fix

Generalized the private deriveRootDirFromDbPath() helper (added in #1763) into a new exported resolveConfigForDbPath(customDbPath?: string): CodegraphConfig in src/db/connection.ts (re-exported from src/db/index.ts), and switched all six call sites named in #1881 to use it instead of duplicating the rootDir derivation ad hoc. resolveDbSettings() and resolveBusyTimeoutMs() now delegate to the same helper internally, so there is exactly one place that derives rootDir from a DB path.

This is a pure TypeScript fix — the native Rust engine has no equivalent config-loading concept (loadConfig()/.codegraphrc.json resolution only exists on the JS side), so no mirrored Rust change is needed.

Closes #1881

Out of scope

While grepping for every loadConfig() call site, I found the same bug pattern in several more functions not named in #1881's scope (triageData, sequenceData, communitiesData, briefData, statsData, searchData/multiSearchData, and the shared resolveAnalysisOpts() used by fn-impact/exports/context). Filed as #2017 rather than fixed here, to keep this PR to the six call sites #1881 explicitly scoped.

Test plan

  • npx tsc --noEmit / npm run build — clean
  • npm run lint — clean on all touched files
  • New tests/unit/loadconfig-dbpath-resolution.test.ts — unit tests resolveConfigForDbPath() directly (file-style and directory-style --db paths, no---db fallback, missing-config fallback) plus one regression test per fixed call site, each mocking process.cwd() to an unrelated directory and asserting the configured db.busyTimeoutMs still reaches PRAGMA busy_timeout — proving resolution came from --db, not cwd
  • Updated tests/unit/busy-timeout-query-sites.test.ts (from db.busyTimeoutMs: extend config-driven wiring to read-only query paths and Rust connection.rs #1763): the manifestoData/hybridSearchData tests previously had to mock process.cwd() to make the config visible at all — now they mock cwd to an unrelated dir with no config, proving the bug is fixed
  • npm test — full suite: 3512 passed, 0 new failures. The only failures (22 tests across 18 files, all under tests/integration/) are pre-existing native-engine unavailability (Cannot find module '@optave/codegraph-darwin-arm64') in this worktree — a missing prebuilt native binary unrelated to this change (confirmed no file overlap with this diff, and the module is absent from node_modules repo-wide, not something introduced by this branch)
  • codegraph diff-impact --staged -T confirmed the blast radius matches exactly the 6 targeted functions (plus resolveDbSettings/resolveBusyTimeoutMs, refactored to delegate to the new helper with no behavior change) and their existing callers — no unintended scope creep

…nctions

manifestoData, hybridSearchData, moduleBoundariesData, diffImpactData,
complexityData, and auditData called loadConfig() bare or with
process.cwd(), so `--db /other/repo/.codegraph/graph.db` invoked from a
different directory read the invoking directory's .codegraphrc.json
instead of the target repo's.

Export a new resolveConfigForDbPath() helper from db/connection.ts,
generalizing the private deriveRootDirFromDbPath() added in #1763, and
use it at all six call sites named in #1881. resolveDbSettings() and
resolveBusyTimeoutMs() now delegate to it too, so rootDir derivation
lives in exactly one place. Also fixes a latent bug in audit.ts's
manual rootDir computation, which broke for directory-style --db
inputs (findDbPath's directory normalization was bypassed).
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a cross-repo config resolution bug where six read-only query functions (manifestoData, hybridSearchData, moduleBoundariesData, diffImpactData, complexityData, auditData) used loadConfig() or loadConfig(process.cwd()) instead of deriving the root directory from the --db path — causing the wrong .codegraphrc.json to be loaded when the tool was invoked from a different working directory.

  • New resolveConfigForDbPath(customDbPath?) is extracted from the private deriveRootDirFromDbPath helper, exported from src/db/connection.ts and re-exported from src/db/index.ts, becoming the single canonical entry point for config loading at all six call sites.
  • resolveDbSettings() and resolveBusyTimeoutMs() are refactored to delegate to the same helper, eliminating any future drift between the internal and external resolution paths.
  • New regression tests (loadconfig-dbpath-resolution.test.ts) cover file-style and directory-style --db paths, fallback to process.cwd() when no --db is given, and per-call-site assertions that the configured busyTimeoutMs comes from the target repo, not the invoking directory.

Confidence Score: 4/5

The core bug fix is correct and well-tested; the only issue is a redundant resolveConfigForDbPath call inside auditData that is purely a performance concern and does not change correctness.

The centralised helper is implemented correctly, all six call sites are updated, and the new tests prove config resolution comes from the --db path rather than process.cwd(). The one finding is that auditData passes opts.config (not the already-resolved config) to resolveThresholds, triggering a second loadConfig round-trip per auditData call when no opts.config is supplied — wasteful but not incorrect.

src/features/audit.ts — the resolveThresholds call site should receive the already-resolved config rather than opts.config.

Important Files Changed

Filename Overview
src/db/connection.ts Adds the new exported resolveConfigForDbPath() helper and refactors resolveDbSettings() and resolveBusyTimeoutMs() to delegate to it; clean single-responsibility abstraction.
src/db/index.ts Re-exports resolveConfigForDbPath from the barrel file; trivial one-line addition.
src/features/audit.ts Fixes the main auditData() call to use resolveConfigForDbPath; also simplifies resolveThresholds(). However, auditData passes opts.config (not the already-resolved config) to resolveThresholds, causing a redundant resolveConfigForDbPath call when opts.config is absent.
src/features/manifesto.ts Switches loadConfig(process.cwd()) to resolveConfigForDbPath(customDbPath); straightforward and correct.
src/features/structure-query.ts Switches bare loadConfig() to resolveConfigForDbPath(customDbPath) in moduleBoundariesData; correct fix.
src/features/complexity-query.ts Adds customDbPath parameter to resolveComplexityQueryOptions and switches to resolveConfigForDbPath; correct propagation of the db path.
src/domain/analysis/diff-impact.ts Switches bare loadConfig() fallback to resolveConfigForDbPath(customDbPath); correct fix.
src/domain/search/search/hybrid.ts Switches bare loadConfig() to resolveConfigForDbPath(customDbPath) in hybridSearchData; correct fix.
tests/unit/loadconfig-dbpath-resolution.test.ts New regression test file covering all six call sites; tests file-style, directory-style, and no-db-path scenarios via busyTimeoutMs assertions.
tests/unit/busy-timeout-query-sites.test.ts Updates existing manifestoData and hybridSearchData tests to mock process.cwd() to an unrelated directory, proving config no longer depends on cwd.

Comments Outside Diff (1)

  1. src/features/audit.ts, line 173 (link)

    P2 auditData resolves config at the top of the function, but then passes opts.config (not the resolved config) to resolveThresholds. When opts.config is absent, resolveThresholds hits the config || resolveConfigForDbPath(customDbPath) branch and calls resolveConfigForDbPath a second time — doubling the loadConfig + findDbPath work per invocation. Passing the already-resolved config avoids this.

    Fix in Claude Code

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix: derive loadConfig() rootDir from --..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

11 functions changed128 callers affected across 80 files

  • resolveConfigForDbPath in src/db/connection.ts:434 (89 transitive callers)
  • resolveDbSettings in src/db/connection.ts:448 (24 transitive callers)
  • resolveBusyTimeoutMs in src/db/connection.ts:472 (85 transitive callers)
  • diffImpactData in src/domain/analysis/diff-impact.ts:259 (3 transitive callers)
  • hybridSearchData in src/domain/search/search/hybrid.ts:176 (3 transitive callers)
  • resolveThresholds in src/features/audit.ts:32 (4 transitive callers)
  • auditData in src/features/audit.ts:134 (3 transitive callers)
  • resolveComplexityQueryOptions in src/features/complexity-query.ts:284 (3 transitive callers)
  • complexityData in src/features/complexity-query.ts:330 (2 transitive callers)
  • manifestoData in src/features/manifesto.ts:478 (4 transitive callers)
  • moduleBoundariesData in src/features/structure-query.ts:369 (0 transitive callers)

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