Repository navigation
v1.18.5
1.18.5 — 2026-10-30
Third audit of the stacked PRs (#1–#4): 7 P0 / 14 P1 / 22 P2 / 8 P3, every P0 reproduced against real git, real hook processes and a real stdio server before counting. This release fixes all 7 P0 and all 14 P1, plus the selected P2/P3 items below.
- [P0] Repository-controlled code execution via the
ext::transport.protocol.ext.allowwas in the server's own-chardening list but not in the claude child'sGIT_CONFIG_*environment, so a repo could setremote.origin.url = ext::<command>plusprotocol.ext.allow = alwaysand the allowlisted (and prompt-suggested)git remote show originexecuted it. The child environment now neutralisesprotocol.ext.allow=neverandprotocol.file.allow=never, and the scanner refuses transport/URL keys (protocol.*.allow,url.*.insteadOf,remote.*.vcs). - [P0]
.git/config.worktreewas never scanned in the main worktree. A repo withextensions.worktreeConfig=truecould keep a livediff.<name>.textconvthere andgit log -pexecuted it. The main worktree now readsconfig.worktreetoo (linked worktrees already did). - [P0]
node_modules/was pruned from the.gitattributeswalk. Git applies attributes from every directory level, so a committednode_modules/.gitattributesactivated a repo-supplied driver while the scanner saw nothing. The scanner now enumerates every tracked/untracked.gitattributesviagit ls-files -z, coveringnode_modules/as well. - [P0] Unambiguous long-option abbreviations bypassed the deny tables.
git blame --cont(--contents),sort/wc --files0(--files0-from),git blame --ignore-revs-file/--mailmap-fileall read host files while the exact spellings were denied. Deny matching now accepts unambiguous prefixes, and the missing file-reading options are denied. - [P0]
gh pr comment --body-file/-F <host path>read a host file and POSTed it to GitHub (postToPR grants the command). The file argument is now scoped to the repository,--reposhape-checked. - Read boundaries: the PreToolUse matcher is catch-all and the hook now confines
Grep/Globpathto the repo (and applies the secret-file list), and a Bash command that references.env/id_rsa/.ssh//credentials/.npmrc/.git-credentialsetc. is refused — previously only theReadtool was protected. - fix-mode persistence:
.husky/**,.github/actions/**,.gitlab-ci.yml,Jenkinsfile,Makefile,.pre-commit-config.yaml,.devcontainer/**,.cargo/config(.toml),.circleci/**,.npmrcare refused (package.json only when the written content carriesscripts/postinstall/preinstall). find -- <path>andecho "prefix"*/echo ~"/".ssh/*(quoted-partial globs) no longer escape the in-repo path/glob checks;echoquoting is judged per character, so literal forms (echo '*',echo 'price: $5') still work.- Repo config enumeration hardening: an
[include]target that exists but is unreadable is now a refusal (was silent), more than 200 include files is refused (1200 includes used to freeze the event loop for 13 s), and the scanner rejectsprotocol.ext/file.allow,url.*.insteadOf,remote.*.vcs. - [P1]
baseRefis honoured inscope=auto(the tool default) instead of being silently dropped: a named ref now selects that branch range in both the prompt and the native command. - [P1] Synchronous failures no longer report
status:"running": the sync path settles the job before stamping it, so a cancelled/timed-out/failedwaitForResult=truecall (and every later poll) reportsfailed. - [P1]
postToPRnow requirespr(preflight refuses otherwise), andscope=prkeeps the caller's full selector (owner/repo#N, URL) instead of letting the reviewer fall back to a bare number resolved against the reviewed repo's remote. - [P1]
scripts/init.mjsships in the npm tarball again (it was excluded by the narrowedfileswhilenpm run initstill pointed at it), and it now includes gateway credentials that live only in~/.claude/settings.json. - Gate honesty: the policy fingerprint covers the hook's
PROTECTED_WRITE/SECRET_READtables (a hook-only policy change now trips the stale-policy check), the smoke test fails on aMISCONFIGUREDverdict instead of printing PASS, and the worktree fixture that used to be a vacuouscheck(..., true, true)is an explicit SKIP. - Prompt/playbook single sources:
REPORT_FORMATis extracted from the bundled SKILL.md (one contract, no second copy), fleet numbers come fromFLEET_NUMBERS(tool schema, prompt and README all render from it; SKILL.md no longer repeats numbers), andscope=autoordering is PR > baseRef > working-dir > last commit everywhere. - Suites: shell-guard 272, audit-fixes 305, p0-regression 163, validation 30, pack 43, cross-cases 154/154 (new C27: auto+baseRef, postToPR without pr, sync-failure job status), smoke PASS —
npm testgreen (7 suites). - Upgrade notes:
postToPRwithoutpris now rejected;focus/outputLanguageare stricter (from 1.18.4); the policy tables changed, so restart the MCP host;claude_review_envis no longer advertised as read-only (it can install/uninstall the skill).