fix: strip repo-local GIT_* env vars from claude -p subprocess#7
Closed
ktinubu wants to merge 12 commits intodbreunig:mainfrom
Closed
fix: strip repo-local GIT_* env vars from claude -p subprocess#7ktinubu wants to merge 12 commits intodbreunig:mainfrom
ktinubu wants to merge 12 commits intodbreunig:mainfrom
Conversation
_collect_source_summaries was walking every .py file via rglob without consulting .plumbignore. In projects with large .venv directories this caused tens of thousands of irrelevant files to be AST-parsed and sent to the LLM, making plumb coverage extremely slow. Reuse the existing parse_plumbignore/is_ignored helpers so patterns like .venv/ are honoured during coverage analysis.
is_ignored now fnmatches directory patterns (e.g. .venv*/) against the top-level path component, so .venv3.10/, .virtualenv3.10/ etc. are matched by a single .venv*/ rule in .plumbignore.
When ANTHROPIC_API_KEY is not set, plumb now detects the `claude` CLI and routes LLM calls through `claude -p` (non-interactive mode). This lets users with a Claude Code subscription run plumb without a separate API key. - Add ClaudeCodeLM (dspy.BaseLM subclass) that shells out to `claude -p` - Update get_lm() / validate_api_access() / get_program_lm() to fall back to CLI when no API key is set - Update CodeModifier to use _call_claude() when no API key - API key always takes precedence when set (zero regression)
The run_pytest_coverage() subprocess call now passes -m "not slow" so that `plumb coverage` skips slow-marked tests, matching the project convention of running quick tests by default.
- Add test_claude_code_lm_raw_call: smoke test for basic prompt/response - Add test_claude_code_lm_parse_spec_single_file: end-to-end spec parsing through DSPy RequirementParser with a tiny markdown spec - Register slow marker and set addopts to skip slow tests by default - Add stderr logging to ClaudeCodeLM.forward() for debugging
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… and requirement parser Previously only question_synthesizer and decision_deduplicator respected program_models config. Now code_coverage_mapper, test_mapper, and requirement_parser also check for per-program LM overrides via dspy.context(). Also adds model name to ClaudeCodeLM log output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nfig Adds "budget" field to program_models entries so users can control chunking granularity. Lower budgets create more parallel chunks, which can improve latency for CLI-based LLM calls. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ook guard _call_claude() now runs subprocess.run with cwd=tempfile.gettempdir() to prevent Claude Code plugin init from corrupting git worktree indexes. Pre-commit hook script now checks PLUMB_SKIP=1 for an escape hatch. Fixes #1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two integration tests (real git, real claude -p, real worktree, no mocks): - Test A: claude -p called directly from pre-commit hook - Test B: plumb hook called from pre-commit hook (full code path) Both assert the desired behavior: index stays intact and commit succeeds. Currently FAIL because _call_claude() does not strip GIT_INDEX_FILE. Refs #1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: during git commit in a worktree, git sets GIT_INDEX_FILE and GIT_DIR. claude -p inherits these and its plugin init overwrites the worktree's index with plugin cache entries (~130 entries). Strips all repo-local GIT_* env vars from the subprocess env in _call_claude(), keeping only safe transport/config vars (GIT_SSH, GIT_CONFIG_*, etc.). Pattern from pre-commit framework's no_git_env(). Removes ineffective cwd=tempfile.gettempdir(). Three e2e tests (real git, real claude -p, real worktree, no mocks): - Test A: proves raw claude -p corrupts the index (upstream bug) - Test B: proves shell-level env stripping prevents corruption - Test C: proves plumb hook protects the index via _call_claude() fix Fixes #1 Co-Authored-By: Claude Opus 4.6 (1M context) <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.
Summary
git commitin a worktree, git setsGIT_INDEX_FILEandGIT_DIR.claude -pinherits these and its plugin init overwrites the worktree's index with plugin cache entries (~130 entries fromhuggingface-skills). Result:error: Error building treesand a destroyed index. 100% reproduction rate.GIT_*env vars from the subprocess env in_call_claude(), keeping only safe transport/config vars (SSH, SSL, config). Pattern from pre-commit framework'sno_git_env().PLUMB_SKIP=1as an escape hatch.Key evidence
claude -pstandalone in worktreeclaude -pin pre-commit hook duringgit commitclaude -pin hook withcwd=/tmpclaude -pin hook withGIT_INDEX_FILE/GIT_DIRstrippedplumb hookin worktree (with fix)Full findings: ktinubu#1 (comment)
Test plan
test_worktree_index_corruption.py(real git, realclaude -p, no mocks): upstream bug canary, shell-level fix proof, plumb hook fix proofPLUMB_SKIPtest verifies hook script contentFixes #1
🤖 Generated with Claude Code