Repository navigation
fix(guardrails): sharpen delete and lease hints, block jq credential reads - #6654
Conversation
…reads block-root-delete-target names the allowed roots and the scratchpad before the user hand-off and says not to retry with another tool. block-dangerous-git hints git -C <repo> for an unreadable hash format. block-credential-read blocks jq and cat of .credentials.json and .docker/config.json and jq env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VxGrZW26Qs1qeo3RFgmbvp
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 4m 56s —— View job Security review in progress
|
|
Claude finished @kyle-sexton's task in 4m 55s —— View job Code review in progress
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d07db1c0e
ℹ️ 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-security-review has reviewed this pull request through b2fb143; a later push is reviewed from there. |
|
claude-review has reviewed this pull request through b2fb143; a later push is reviewed from there. |
…ential guard Strip --arg/--argjson operands and tell jq's case-sensitive $ENV builtin from a $env variable before the jq shapes match, with stay-quiet tests for both. Reorder the pre-filter so the prerequisite gate no longer reads `docker ]]` as a docker run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VxGrZW26Qs1qeo3RFgmbvp
|
Claude finished @kyle-sexton's task in 5m 4s —— View job Code review complete
|
|
Claude finished @kyle-sexton's task in 4m 52s —— View job Security review completeIncremental lane — scope was only the three files that changed since
No security issues found. This increment is the fix for Codex's prior P2 finding ( I traced it adversarially for a bypass (a command that genuinely reads one of the two credential files or dumps
Checked this against the instruction-exception register's secret-handling class: this narrows a hook's match precision, not the mechanism itself — the guard still blocks every genuine credential-file read and Changelog fragment text matches the behavior change. |

No related issue: items B3m, B13, A13 and the B3c test from an approved guardrails performance-audit change set.
Summary
block-root-delete-target: theoutside-treeblock names the allowed roots (block_root_delete_target_allowed_roots) and the session scratchpad first, says "do not retry the delete with another tool (find -delete, rmtree, git clean)", and keeps the user hand-off ("only the user can") as the last resort.<H>/worktrees/.tmp-*,<H>/.work.<H>/worktrees/.tmp-xand<H>/.work/xare allowed.<H>/worktrees,<H>/worktrees/other,<H>/.workand<H>are refused. The test only; the guard already handled this (name-prefix entries shipped in feat(guardrails): allow name-prefix entries in block_root_delete_target_allowed_roots #6624).block-dangerous-git: the lease-width hint (unreadable hash format) is nowgit -C <repo> push --force-with-lease=<ref>:<full-sha>instead of "Run the push from inside the repository". The guard refuses thatcd <repo> && git pushform from a session root that is not a repository. The header comment that called it "the very form the block messages above prescribe" now namesgit -Cinstead. No parser change.block-credential-read: blockscat/Get-Content/gc/typeof.credentials.jsonand.docker/config.json,jqof either file, andjq env/jq '$ENV'. The pre-filter at the old line 128 now admitsenv(which covers the old\.env) anddocker, so these shapes reach the matcher. README row updated.Fix
Approved text where the plan corrected it:
jqreads only the two JSON credential files, not every credential file. Matchingjqagainst the whole list would blockjq '.env' package.json, because a.envjq filter looks like a.envpath. A stay-quiet test covers this.jq envfamily: it goes under the existingenv-echoallow-list token. A new token would need aplugin.jsonuserConfig change, which is outside this PR's scope.Test edits in
.shfiles went in throughgit apply. The edit-time shfmt hook re-indented everycasearm inblock-root-delete-target.sh(about 1,900 lines) to match.editorconfigswitch_case_indent, and that churn was dropped. The diff holds only the intended lines.Verification
block-credential-read.test.shPASS=336 FAIL=0;block-dangerous-git.test.shPASS=835 FAIL=0;block-root-delete-target.test.shPASS=2213 FAIL=0.scripts/affected-tests.sh --run: 29 shell suites passed. Its 2 node suites (lib/exec-bash.gates.test.mjs,lib/exec-bash.resolver.test.mjs) passed undernode..shfiles: clean.check-hook-slow-shapes.sh: no slow shapes.check-purged-em-dashes.sh: none.check-changelog-fragments.sh --checkand--check-required origin/main,check-changelog-parity.sh --check-bump origin/main,validate-plugins.sh: pass.Related
.changes/guardrails/fix-guardrails-g1-hints-credential-read-4ea448bd.md(bump: patch).block_root_delete_target_allowed_rootsvalues live in dotfiles, not here.block-hook-bypass) is a separate PR that does not touch these files.🤖 Generated with Claude Code
https://claude.ai/code/session_01VxGrZW26Qs1qeo3RFgmbvp