Skip to content

fix(jrag): honor JAVA_CODEBASE_RAG_SOURCE_ROOT over a stray ancestor marker#387

Merged
HumanBean17 merged 1 commit into
masterfrom
fix/jrag-source-root-env
Jul 6, 2026
Merged

fix(jrag): honor JAVA_CODEBASE_RAG_SOURCE_ROOT over a stray ancestor marker#387
HumanBean17 merged 1 commit into
masterfrom
fix/jrag-source-root-env

Conversation

@HumanBean17

Copy link
Copy Markdown
Owner

Summary

Fixes the 3 test_jrag_traversal_compose.py failures (test_outline_lists_file_symbols, test_imports_resolves_graph_nodes, test_imports_text_mode_marks_unresolved) by making jrag honor JAVA_CODEBASE_RAG_SOURCE_ROOT over a stray ancestor .java-codebase-rag marker — matching resolve_operator_config's intended precedence (env var > YAML > discovery) and the java-codebase-rag CLI.

Root cause

jrag._resolve_cfg passed source_root=discover_project_root(Path.cwd()) into resolve_operator_config. That function only honors JAVA_CODEBASE_RAG_SOURCE_ROOT when source_root is None (config.py: the env-var branch is the else of if source_root is not None). So whenever any ancestor of cwd had a .java-codebase-rag/ marker, the discovered root was passed explicitly and the env var was silently ignored — even though pipeline.subprocess_env sets exactly that env var for the cocoindex child and the operator/test contract relies on it.

Symptom: jrag imports <rel-file> resolved <file> against the wrong source root and returned file not found ... (looked at <source_root>/...), exit 2.

This is the same class of hijack issue #357 addressed for $HOME, generalized: any ancestor marker beats an explicit env var. CI stayed green only because a clean checkout has no stray marker; the failures reproduced anywhere a .java-codebase-rag/ index existed up-tree from the run dir.

Fix (java_codebase_rag/jrag.py)

_resolve_cfg now passes source_root=None, mirroring cli._resolved_from_ns (which passes None unless --source-root is given). resolve_operator_config then resolves: env var → YAML source_rootdiscover_project_root(cwd). Interactive use (no env var) is unchanged — discovery still runs as the fallback. The config_source pointer behavior from #383 is preserved (it's part of resolve_operator_config's index-dir path, which still runs).

Test (tests/test_jrag_status.py)

test_resolve_cfg_honors_source_root_env_over_stray_marker — creates a non-empty .java-codebase-rag/ marker in an ancestor of cwd, sets JAVA_CODEBASE_RAG_SOURCE_ROOT to a different dir, and asserts _resolve_cfg resolves to the env-var root. Verified to fail on the pre-fix code and pass with the fix, so CI catches future regressions (the traversal tests only caught it when a marker happened to exist locally).

Verification

  • All 3 previously-failing tests now pass (with a stray marker present — the hijack condition).
  • Full jrag suite green.
  • Regression test fails without the fix, passes with it.

🤖 Generated with Claude Code

…marker

jrag._resolve_cfg passed source_root=discover_project_root(cwd) into
resolve_operator_config, which only honors JAVA_CODEBASE_RAG_SOURCE_ROOT when
source_root is None. So any ancestor .java-codebase-rag marker silently
overrode the env var that pipeline.subprocess_env sets for the cocoindex child
(and that operators/tests rely on), making `jrag imports/outline <rel-file>`
resolve against the wrong root → "file not found", exit 2.

Pass source_root=None instead, mirroring cli._resolved_from_ns: resolution is
now env var → YAML source_root → discover_project_root(cwd). Interactive use
(discovery fallback) is unchanged; the #383 config_source pointer is preserved.

Regression test creates a non-empty ancestor marker + sets the env var and
asserts the env var wins (fails on pre-fix code, passes with the fix).

Co-Authored-By: Claude <noreply@anthropic.com>
@HumanBean17 HumanBean17 merged commit dd60906 into master Jul 6, 2026
3 checks passed
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