fix: require GIT_CONFIG for fixture-isolation credit and join shell continuations - #3086
Conversation
…ontinuations Closes #2889 Closes #2893 The fixture-isolation CREDIT signal now requires GIT_CONFIG alongside GIT_DIR and GIT_WORK_TREE. GIT_CONFIG is a second leak path: git-config ENVIRONMENT uses it as --file, so an identity write follows it past -C and a cleared GIT_DIR. Suites and harnesses that already isolated the discovery pair now unset GIT_CONFIG too. The 33-entry grandfathered baseline is untouched (#2872). The shell arm joins physical lines while the previous line ends in an unescaped backslash, so a continued `git … \` / `unset … \` is visible. Two correct clear idioms the gate rejected are now credited: a module-level Python constant iterated into os.environ.pop, and `env -u` / `--unset` naming every required variable. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
|
Claude finished @kyle-sexton's task in 1m 10s —— View job Security review —
|
|
Last security-reviewed head: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7074abf6a8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude finished @kyle-sexton's task in 9m 15s —— View job Code review complete
This is the CI code-review lane ( No blocking findings. I traced the actual risk this change carries — tightening the CREDIT signal from 2 required vars (
Not independently verified (this lane's sandbox doesn't allow executing arbitrary scripts, only a fixed allowlist of read-only commands): I could not run One non-blocking observation, not raised as a finding since it isn't a live regression and isn't touched by this diff: |
Address review on #3086. `env -u` applies only while env runs COMMAND, so a wrap on one fixture line no longer isolates a later unwrapped write. A constant rebound to a non-literal drops its earlier binding instead of keeping the names a previous tuple left behind. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
|
Claude has reviewed this PR 3 times. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
|
Claude finished @cursor[bot]'s task in 6m 6s —— View job /review:code-review — PR #3086
SummaryReviewed the full diff ( Both One finding survived, posted inline (scripts/check-fixture-git-isolation.sh:330-340): The No other correctness or maintainability issues found in the rest of the diff (the |
env -u on one side of `;`/`&&`/`||` must not credit a later unwrapped fixture write on the same physical line. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
Main already shipped work-items 0.39.10. Keep that heading and record the GIT_CONFIG harness clear under 0.39.11. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
|
Claude finished @cursor[bot]'s task in 2m 20s —— View job /review:code-review — PR #3086
SummaryThis is review pass #3 on this PR (
Not independently executed: this lane's sandbox does not have Bash approval for running No new blocking findings. The remaining scope of the PR (GIT_CONFIG credit widening, Python module-level constant/rebind handling, harness |
Closes #2889
Closes #2893
Summary
scripts/check-fixture-git-isolation.shnow requiresGIT_CONFIGin the CREDIT signal, next toGIT_DIRandGIT_WORK_TREE. Officialgit-configENVIRONMENT docs: if no--fileis given,GIT_CONFIGis used as--file. That is a second leak path, not another spelling of discovery —git -C <fixture> config user.email Xstill writes through an inheritedGIT_CONFIGafterGIT_DIRis cleared. Scenario D inscripts/test-git-helpers.test.shalready proves the mechanism.The shell arm now joins physical lines while the previous line ends in an unescaped backslash, so a continued
git … \/unset … \is one unit (the same recall #2876 gave the Python arm for formatter-wrapped argv). Two correct clear idioms the gate rejected are now credited: a module-level Python constant iterated intoos.environ.pop, andenv -u/--unsetnaming every required variable.Isolating harnesses and self-clears that already unset the discovery pair now also unset
GIT_CONFIG, with plugin patch bumps only where those files live under a plugin. The grandfathered baseline is not drained (#2872) — 33 entries remain, none stale.Fix
In
scripts/check-fixture-git-isolation.sh:NREQis 3 (GIT_DIR,GIT_WORK_TREE,GIT_CONFIG) in both language arms.unsetandenv -u/--unsetagainst that logical line.for _v in NAME: os.environ.pop(_v)— the loop-variable tie still applies, so a mention-only constant or a rebound constant does not credit.Isolating helpers that already unset the discovery pair now also unset
GIT_CONFIG(lib/hook-utils.test.sh, plugin test helpers, four claude-memory suites, two skill-quality suites). Plugin patch bumps: claude-memory 0.11.2, repo-hygiene 0.10.8, skill-quality 0.17.4, source-control 0.54.15, work-items 0.39.11. No grandfathered baseline entry was added or deleted.Test plan
bash scripts/check-fixture-git-isolation.test.sh— ALL PASS, including new cases:GIT_CONFIGis a violation (shell and Python)git … initis still a fixtureunsetof all three passesenv -uof all three passes; withoutGIT_CONFIGit does notenv -uwrapping one fixture command does not credit an unwrapped identity write (separate lines or one;-joined line)scripts/check-fixture-git-isolation.sh --check—OK (54 isolated, 33 baselined)bash scripts/test-git-helpers.test.sh— 9 passed, including scenario D (GIT_CONFIG)scripts/check-changelog-parity.sh --check/--check-order/--check-bump origin/main/--check-preserved origin/main— passVerification
Same evidence as the test plan, run from
/tmp/wt-2889against this branch before push. The live-corpus case inside the self-test is the canary that the 33-entry baseline is still exact (no stale line, no new violation).Related
GIT_CONFIG)env -uand a module-level constant)git -Cdoes not survive an exported GIT_DIR #2840 (the gate) and fix: isolate test fixtures from the inherited git environment (#2840) #2876 (Python logical-line join)GIT_CONFIGis used as--file)