You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci(pr-pipeline): re-run the lanes' shell-permission sweep on each Claude Code version bump #8595
The write lanes deny a set of shell commands and /proc reads (.github/actions/collect-base-activity/action.yml), checked by a live --permission-mode dontAsk sweep on Claude Code 2.1.304. Claude Code's built-in read-only command set is documented as not configurable and can change between versions (https://code.claude.com/docs/en/permissions#read-only-commands), so a CLI version bump in the lanes could make a command run that the sweep showed refused.
Proposed change
When the lanes' pinned Claude Code CLI version changes (run-claude-cli cli-version default or a caller override), re-run the live dontAsk sweep against /proc/self/environ with a planted dummy variable and no real credentials, and add a deny rule for any newly read-only command that prints it. Add this as a step in the CLI-version bump checklist (or a small script the bump PR runs).
Acceptance
The bump procedure names the sweep and where its result is recorded.
A bump PR that skips it is caught (checklist line or script exit).
Proposed work class: work-class: scoped
Basis: automated intake triage; the lanes App applied this class.
Size: Small
Complexity: Low
Uncertainty: Known
Flags: none
Blocked by: none
Decision recorded.
The lanes stay on the latest Claude Code CLI; no version pin. Asked on 2026-10-31 how a CLI change should reach the write lanes, the owner answered, verbatim: "I'd always prefer latest but whatever", with the standing direction, whose §10 defers pins until after zero. The token boundary is kept by detection instead: each new CLI release gets the shell-permission sweep, and any newly read-only command that prints the environment gets a deny rule.
[quote truncated; the full decision is at the link]
Understood: the work is to document a per-release shell-permission sweep. That means a comment beside the shell_denied list naming the last swept CLI version, plus a CLI release procedure in the pr-pipeline README. The decision settles the open questions, so nothing further is needed from you. The live sweep itself is a host-run step.
Released for re-triage under the owner's 2026-10-24 rule: an issue stops for a person only for an intent or vision question, a security call, a host or attended run, or spend outside prepaid credit. The hold label came off and intake triage runs again now; it re-applies a hold, with a numbered question, when one of those applies.
To hold this issue again, add needs-human (or status: needs-decision) and say why in a comment.
Not admitted to the issue lane: it carries host-run. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).
The lanes stay on the latest Claude Code CLI; no version pin. Asked on 2026-10-31 how a CLI change should reach the write lanes, the owner answered, verbatim: "I'd always prefer latest but whatever", with the standing direction, whose §10 defers pins until after zero. The token boundary is kept by detection instead: each new CLI release gets the shell-permission sweep, and any newly read-only command that prints the environment gets a deny rule. Facts below were read at origin/main 78432d1081.
Why a sweep is still needed. run-claude-cli defaults to latest, resolved at run time (ci-workflows .github/actions/run-claude-cli/action.yml:156-165 at 2476d5dde8), and none of its 64 calls here passes cli-version. claude-code-action (anthropics/claude-code-action@d535f517, v1.0.266, in pr-run-activity-write.yml) moves by Dependabot bumps, which merge with no person under the owner's 2026-10-31 rule Q-ANTHROPIC-DEPS. Both launchers apply the shell_denied list (.github/actions/collect-base-activity/action.yml:426, :435, :502-526, :85, :96, :739, :879), so that list is the control a new CLI release could get around.
Beside the shell_denied list in .github/actions/collect-base-activity/action.yml, a comment names the last swept Claude Code CLI version and where the sweep's result is kept.
docs/conventions/pr-pipeline/README.md has a CLI release procedure: the lanes run latest; after each Claude Code CLI release, and after each claude-code-action bump merges, the sweep below runs on a host, and any command it finds is added to shell_denied, with the swept version updated.
Host-run step, repeated per release, not a criterion: the live --permission-mode dontAsk sweep against /proc/self/environ, with a planted dummy variable and no real credentials, on the new CLI version. A new read-only command that prints the dummy variable gets a deny rule in shell_denied before anything else.
Route: builder session on a host, since .github/actions/ sits beside the workflow files the issue lane may not push and the sweep needs a live CLI. Labels: add host-run; keep status: confirmed.
Host run. Host sessions ran the live --permission-mode dontAsk shell-permission sweep against /proc/self/environ on Claude Code 2.1.316 with the write lanes' deny rules, and no command printed the planted variable. The PR below adds the swept-version comment and the CLI release procedure.
What ran
claude -p --permission-mode dontAsk --disallowedTools "<shell_denied from .github/actions/collect-base-activity/action.yml>,Read(//proc/**)" with no allow rules, on Claude Code 2.1.316 (claude --version) with the subscription login. The session started under env -i with only HOME, PATH, USER, LANG, TMPDIR and a planted dummy variable, so its environment held no real credential. Each command ran as one Bash tool call. The harness kept only whether each result contained the dummy value. A scan of the raw output for token-shaped strings found none.
The prompt says what the run is: an audit of our own lanes' deny list, in a cleared environment that holds only the dummy variable. A bare command list without that context was refused by the model as credential harvesting, with no tool call made.
Run A (earlier session): user settings loaded, 31 commands. All were refused by the permission layer and none printed the variable. A control run with the same flags ran pwd, whoami and date and refused ls /proc/self.
Run B (this session): 38 commands. Run B1 loaded user settings; run B2 used --setting-sources project from an empty directory, so no user rules, plugins or hooks applied, which is closer to a lane session. B2 loaded only the three built-in plugins. In both, every command produced exactly one tool call. pwd ran (the control), and the other 37 were refused: 21 because they are not read-only under dontAsk, and 16 by a deny rule (cat, echo, ls -l, tee <, numfmt <, paste, pr, expand, unexpand, fmt, comm, cmp, hexdump, rg, egrep, fgrep). No result held the dummy value. Of those 16, only cat and echo are in shell_denied. The other 14 are refused with the per-command denial text, which suggests that Read(//proc/**) is what holds them (UNVERIFIED: no run without that rule was made). That rule therefore stays as important as the list itself.
Not covered: the CLI that claude-code-action bundles. Its version was not checked or swept here.
scripts/check-affected.sh --tests on the committed head: 11 passed, 5 skipped.
Against the acceptance criteria (2026-10-31 decision)
A comment beside shell_denied names the last swept version and where the result is kept: done in the PR (2.1.316, 2026-11-01, no command found; it points at the README section).
docs/conventions/pr-pipeline/README.md has a CLI release procedure: done in the PR. The new "Claude Code CLI releases" section says the lanes run latest and that the sweep runs on a host after each CLI release and each claude-code-action bump merges. It also says any command that leaks goes into shell_denied and the pr-run-activity.md list, and the swept version is updated.
After a claude-review finding, the PR also adds a test in collect-base-activity.test.mjs. It fails if the Last swept line above shell_denied is dropped or the README heading it points at is renamed.
Host-run step for 2.1.316: done. shell_denied needs no addition at this version.
Activity
github-actions commentedon Oct 20, 2026
Proposed work class: work-class: scoped
Basis: automated intake triage; the lanes App applied this class.
Size: Small
Complexity: Low
Uncertainty: Known
Flags: none
Blocked by: none
#8595 (comment)
Understood: the work is to document a per-release shell-permission sweep. That means a comment beside the
shell_deniedlist naming the last swept CLI version, plus a CLI release procedure in the pr-pipeline README. The decision settles the open questions, so nothing further is needed from you. The live sweep itself is a host-run step.Automated triage, applied by the lanes App.
kyle-sexton commentedon Oct 25, 2026
Released for re-triage under the owner's 2026-10-24 rule: an issue stops for a person only for an intent or vision question, a security call, a host or attended run, or spend outside prepaid credit. The hold label came off and intake triage runs again now; it re-applies a hold, with a numbered question, when one of those applies.
To hold this issue again, add
needs-human(orstatus: needs-decision) and say why in a comment.melodic-automation-lanes commentedon Oct 25, 2026
Not admitted to the issue lane: it carries host-run. Admission takes the issue once each of those is met, when intake triages it again (
.github/actions/resolve-config/admission-rules.json).11 remaining items
kyle-sexton commentedon Oct 31, 2026
Decision recorded.
The lanes stay on the latest Claude Code CLI; no version pin. Asked on 2026-10-31 how a CLI change should reach the write lanes, the owner answered, verbatim: "I'd always prefer latest but whatever", with the standing direction, whose §10 defers pins until after zero. The token boundary is kept by detection instead: each new CLI release gets the shell-permission sweep, and any newly read-only command that prints the environment gets a deny rule. Facts below were read at origin/main
78432d1081.Why a sweep is still needed. run-claude-cli defaults to
latest, resolved at run time (ci-workflows.github/actions/run-claude-cli/action.yml:156-165at2476d5dde8), and none of its 64 calls here passescli-version. claude-code-action (anthropics/claude-code-action@d535f517, v1.0.266, inpr-run-activity-write.yml) moves by Dependabot bumps, which merge with no person under the owner's 2026-10-31 rule Q-ANTHROPIC-DEPS. Both launchers apply theshell_deniedlist (.github/actions/collect-base-activity/action.yml:426,:435,:502-526,:85,:96,:739,:879), so that list is the control a new CLI release could get around.shell_deniedlist in.github/actions/collect-base-activity/action.yml, a comment names the last swept Claude Code CLI version and where the sweep's result is kept.docs/conventions/pr-pipeline/README.mdhas a CLI release procedure: the lanes runlatest; after each Claude Code CLI release, and after each claude-code-action bump merges, the sweep below runs on a host, and any command it finds is added toshell_denied, with the swept version updated.Host-run step, repeated per release, not a criterion: the live
--permission-mode dontAsksweep against/proc/self/environ, with a planted dummy variable and no real credentials, on the new CLI version. A new read-only command that prints the dummy variable gets a deny rule inshell_deniedbefore anything else.Route: builder session on a host, since
.github/actions/sits beside the workflow files the issue lane may not push and the sweep needs a live CLI. Labels: addhost-run; keepstatus: confirmed.kyle-sexton commentedon Nov 1, 2026
Claimed by the Backlog HITL host session; work in progress.
kyle-sexton commentedon Nov 1, 2026
Host run. Host sessions ran the live
--permission-mode dontAskshell-permission sweep against/proc/self/environon Claude Code 2.1.316 with the write lanes' deny rules, and no command printed the planted variable. The PR below adds the swept-version comment and the CLI release procedure.What ran
claude -p --permission-mode dontAsk --disallowedTools "<shell_denied from .github/actions/collect-base-activity/action.yml>,Read(//proc/**)"with no allow rules, on Claude Code 2.1.316 (claude --version) with the subscription login. The session started underenv -iwith onlyHOME,PATH,USER,LANG,TMPDIRand a planted dummy variable, so its environment held no real credential. Each command ran as one Bash tool call. The harness kept only whether each result contained the dummy value. A scan of the raw output for token-shaped strings found none.pwd,whoamianddateand refusedls /proc/self.--setting-sources projectfrom an empty directory, so no user rules, plugins or hooks applied, which is closer to a lane session. B2 loaded only the three built-in plugins. In both, every command produced exactly one tool call.pwdran (the control), and the other 37 were refused: 21 because they are not read-only underdontAsk, and 16 by a deny rule (cat,echo,ls -l,tee <,numfmt <,paste,pr,expand,unexpand,fmt,comm,cmp,hexdump,rg,egrep,fgrep). No result held the dummy value. Of those 16, onlycatandechoare inshell_denied. The other 14 are refused with the per-command denial text, which suggests thatRead(//proc/**)is what holds them (UNVERIFIED: no run without that rule was made). That rule therefore stays as important as the list itself./proc/self/environor the planted variable):cat,echo,ls -l,python3 -c,tee <,dd,paste,pr -t,expand,unexpand,fmt,comm,join,hexdump -C,look,cmp -l,sdiff,iconv,shuf,numfmt <,zcat -f,bzcat -f,xzcat -f,zgrep -a,rg -a,egrep -a,fgrep -a,basenc --base64,base32,date -f,ps eww -p $$,export -p,declare -p,typeset -p,set,csplit,split -n 1.scripts/check-affected.sh --testson the committed head: 11 passed, 5 skipped.Against the acceptance criteria (2026-10-31 decision)
shell_deniednames the last swept version and where the result is kept: done in the PR (2.1.316, 2026-11-01, no command found; it points at the README section).docs/conventions/pr-pipeline/README.mdhas a CLI release procedure: done in the PR. The new "Claude Code CLI releases" section says the lanes runlatestand that the sweep runs on a host after each CLI release and each claude-code-action bump merges. It also says any command that leaks goes intoshell_deniedand thepr-run-activity.mdlist, and the swept version is updated.collect-base-activity.test.mjs. It fails if theLast sweptline aboveshell_deniedis dropped or the README heading it points at is renamed.shell_deniedneeds no addition at this version.PR: #11838