source: GitHub releases
Release
Every blocked-pattern change, parser hardening, and CLI integration shipped to the guardrail.
Latest release
GitHub release$ gh release view v2.4.4
tag: v2.4.4
published: Sep 20, 2026
channel: stable
v2.4.4
- Fix
What's Changed
- fix(analyzer): track a literal cd so a relative rm -rf inside a temp root is a temp delete by @kenryu42 in https://github.com/kenryu42/cc-safety-net/pull/124
- fix(analyzer): allow git discards in a temp-root repository reached through a tracked cd by @kenryu42 in https://github.com/kenryu42/cc-safety-net/pull/125
- fix(analyzer): relax a forced worktree removal whose operand is an existing temp-root directory by @kenryu42 in https://github.com/kenryu42/cc-safety-net/pull/126
Full Changelog: https://github.com/kenryu42/cc-safety-net/compare/v2.4.3...v2.4.4
Signal index
Find changes by signal
Jump straight to the releases that changed safety behavior, migrations, integrations, fixes, or docs.
Security
Latest matching releases
Sep 17, 2026
Sep 17, 2026
Sep 14, 2026
Sep 4, 2026
Sep 3, 2026
Showing latest 5 of 14. The full chronological ledger stays below.
Breaking
Latest matching releases
Sep 17, 2026
Sep 17, 2026
Sep 14, 2026
Sep 1, 2026
Aug 31, 2026
Showing latest 5 of 10. The full chronological ledger stays below.
Migration
Latest matching releases
Sep 17, 2026
Aug 31, 2026
Aug 20, 2026
Aug 19, 2026
Aug 10, 2026
Showing latest 5 of 7. The full chronological ledger stays below.
Integration
Latest matching releases
Sep 17, 2026
Sep 14, 2026
Sep 14, 2026
Sep 4, 2026
Sep 3, 2026
Showing latest 5 of 17. The full chronological ledger stays below.
Fix
Latest matching releases
Sep 20, 2026
Sep 17, 2026
Sep 17, 2026
Sep 14, 2026
Sep 14, 2026
Showing latest 5 of 25. The full chronological ledger stays below.
Docs
Latest matching releases
Sep 17, 2026
Aug 10, 2026
Jun 14, 2026

Previous releases
v2.4.3
v2.4.3
- Security
- Breaking
- Migration
- Integration
- Fix
- Docs
This release adds OpenCode 2.0.6+ support alongside the existing OpenCode v1 integration. It also raises the minimum supported OpenCode v1 version to 1.18.29.
Highlights
- Added OpenCode 2.0.6+ support, using the same policy, analyzer, and audit behavior as the v1 integration. (#123)
Added
- Added protection on OpenCode v2 through its tool hook, covering
shellcommands and read, edit, write, patch, grep, glob, and unknown-tool inputs, with typed tool denials. Code Mode child tool calls pass through the same hook. (#122) - Added v2 installation and updates to
npx -y cc-safety-net@latest install --opencode, which detects the host version and usesopencode plugin addandopencode plugin update, then confirms the plugin is registered inopencode plugin list. - Added a
shellplugin option for OpenCode v2 that sets the expected dialect (posixorpowershell). The plugin defaults to POSIX on Unix and PowerShell on Windows, verifies the actual executable before a shell starts, and rejects a mismatched or unsupported shell rather than analyzing it with the wrong parser. Seedocs/opencode-compatibility.md. - Added the
/cc-safety-netcommand on OpenCode v2. A command of that name already present when the plugin loads is preserved. - Added the
cc-safety-net/opencode/v2entry point for TypeScript consumers using the OpenCode v2 SDK. v1 consumers continue to useCCSafetyNetPluginfromcc-safety-net.
Changed
- Changed
install --opencodeto stop with a migration message when an OpenCode v2 config already listscc-safety-netunder a spec other thancc-safety-net@latest, instead of creating a duplicate plugin ID. Change that entry's package spec, keeping its options and comments, then retry.
Fixed
- Fixed OpenCode config discovery to honor the
OPENCODE_CONFIG_DIRoverride, which affects both integration detection and uninstall. - Fixed
uninstallto removecc-safety-netentries from every detected OpenCode config file instead of stopping at the first one, and to report accurately whether an entry was removed. - Fixed OpenCode detection and uninstall to recognize both the
pluginandpluginsarrays and object-form plugin entries, and to match only thecc-safety-netpackage spec instead of any entry whose name contains it. - Improved OpenCode config editing so removing a plugin entry preserves neighboring comments in JSONC configs.
Breaking Changes
- Raised the minimum supported OpenCode v1 version to 1.18.29, up from 1.18.3.
install --opencodenow stops with a version error on older releases. - Migration: Upgrade OpenCode to 1.18.29+ or 2.0.6+ before updating CC Safety Net.
Sep 17, 2026
GitHub releasev2.4.2
v2.4.2
- Security
- Breaking
- Fix
This release closes three command-analysis gaps where a destructive command could be hidden from the gate, and removes a false positive that denied plain
gitnetwork commands for anyone whose shell exports an SSH override.Highlights
- Fixed heredoc handling so a carriage-return-suffixed delimiter line can no longer end a heredoc early and let the rest of its body run unanalyzed. (#115)
- Stopped denying
git fetch,git pull, andgit pushwithgit.ssh-envwhenGIT_SSH_COMMAND,GIT_SSH, orGIT_SSH_VARIANTis inherited from the user's shell profile. Inline assignments such asGIT_SSH_COMMAND=./evil git fetchand-c core.sshCommand=...overrides still deny. (#119)
Changed
- GNU Parallel forms the analyzer cannot follow now deny as
parallel.command-stream-dynamic: multiple:::groups, negative{-n}placeholders, and--workdir/--wd. The child command is still expanded and re-rooted, so a catastrophic root or home deletion is still caught when the stream rule is off. (#121) - A placeholder that lands in a position owned by a configured rule's command is now treated as dynamic input and denies with the existing
xargs.shell-dynamicandparallel.shell-dynamicids. (#121) - Improved GNU Parallel job expansion to charge the shared analysis budget as it builds, so a wide
:::product fails closed promptly instead of constructing a very large job matrix before the denial. (#121) - Changed
--workdirtilde handling so only a leading~expands and a tilde inside a path component is literal, as the shell treats it. This also fixes workdir re-rooting on Windows paths containing 8.3 short names such asC:\Users\RUNNER~1\.... (#121) - An override with an unknown rule id and a value other than
onoroffnow reports one diagnostic instead of two. (#120) rule init --examplenow writes the project-scope description and author into the example rulebook instead of the user-scope wording. (#121)
Fixed
- Fixed policy-target comparison on macOS, where a hard link to a policy file could make two lookups of the same path disagree and flip a verdict. Targets are now canonicalized through their parent directory; hard links remain distinct targets. (#117)
Removed
- Removed
shadowedRulesfromdoctor --json; its only value was an empty array. (#121) - Removed
isOverriddenToNonTempfrom thetmpdir-checkstep ofexplain --json; it was the negation of theallowTmpdirVarvalue next to it. (#120) - Removed the accepted-but-ignored
rule --checkflag;cc-safety-net rule --checknow reports an unknown option. (#121)
Security
- A heredoc body now ends only at a byte-exact delimiter line, matching bash. A heredoc written with CRLF no longer closes at a bare delimiter line, so a payload such as
$(rm -rf /)placed after one is analyzed instead of allowed; at strict safety an unterminated heredoc fails closed. (#115) - Brace expansion at command position now uses the quote-aware scanner, so
{"rm",ls} -rf /,{'rm',ls} -rf /, and{r\m,ls} -rf /denyrm.recursive-force-root-or-homeinstead of parsing a literal command head. (#120) - The secret walk of
bash -cnow resolves the command operand through the shell's own option grammar, sobash -c -- "cat .env"and the-xand-svariants are checked for secret access, and an option value such asbash -O .env -c ...is no longer re-read as the command. (#120)
Sep 17, 2026
GitHub releasev2.4.1
v2.4.1
- Integration
- Fix
A patch release that repairs plugin installation for Amp and OpenClaw when running the published package.
Fixed
- Fixed
cc-safety-net install --ampandcc-safety-net install --openclawfailing with a "Packaged ... artifact not found" error when run from the published package (for example vianpx -y cc-safety-net). The packaged plugin artifacts are now also looked for beside the bundled CLI, where they actually ship.
Sep 14, 2026
GitHub releasev2.4.0
v2.4.0
- Security
- Breaking
- Integration
- Fix
v2.4.0 rebuilds the runtime from the ground up. The hook, CLI, API, GUI and all thirteen host integrations keep their behavior, verified command by command against v2.3.4 before the old code was removed. What changes is what you feel: every hook call is less than half as long, the package has no runtime dependencies, and secret protection now follows
cd.Highlights
- Hook calls are 2.2× faster. A tool call on Claude Code went from 195 ms to 85 ms on the verification machine, and the p90 tail from 229 ms to 89 ms. Peak memory per call dropped from 76 MB to 56 MB and CPU time from 220 ms to 94 ms.
- Zero runtime dependencies.
zodis gone, the published manifest declares no dependencies, and package verification fails if one reappears. The Amp and OpenClaw plugin bundles shrank from 428 KB to 314 KB each. - Secret protection follows `cd`.
cd ~ && cat .ssh/configand its pipe, redirection and variable forms are now denied at every level, with the operand reported as the evidence. No policy change is needed. - Fewer false positives.
jqfilters ending in.key(#112),<<inside interpreter code understrict(#111), a POSIX heredoc feeding a Python script, and string literals inside inline Python, JavaScript, Ruby, Perl and PHP code (#114) are no longer denied.
Performance
Hook invocation, measured as
hooks/hooks.jsonruns it: a fresh Node process per tool call, isolatedHOME, fresh git repository as the working directory. Median of 40 interleaved rounds, Node 22 on a 4-core Linux container, barenode -e ""≈ 40 ms. Decisions were identical on every scenario.| Scenario | v2.3.4 | v2.4.0 | Δ | |---|---:|---:|---:| | allow
ls -la| 195 ms | 85 ms | −57% | | denyrm -rf /| 183 ms | 80 ms | −56% | |git status && bun test \| grep x| 206 ms | 98 ms | −53% | | p90, allow path | 229 ms | 89 ms | −61% | | peak RSS | 75.5 MB | 55.9 MB | −26% | | CPU, user + system | 220 ms | 94 ms | −57% |Time spent above bare Node, the part cc-safety-net controls, went from ~155 ms to ~45 ms.
In-process callers see the same gain. Through the public
checkCommandAPI, a decision costs ~1.5 ms instead of ~3 ms, so the OpenCode, Pi, Amp and OpenClaw integrations handle ~670 decisions per second where they handled ~330.Where the time went:
- The hook loads only what a decision needs. The bin resolves the
hookverb before one dynamic import of the CLI, so the hook path loads about 350 KB of JavaScript instead of about 808 KB.explain,status,doctorand the rest sit behind that import and pay for it only when invoked. - `node:crypto` left the hook's static closure. Audit ids and temp-file suffixes need uniqueness, not unpredictability, and now come from a
Math.randomhelper with the same sixteen-hex shape. A test fails if the hook's import closure grows past 400 KB (measured 344 KB). - The hook ships as a CommonJS bundle behind a compile-cache loader. Skipping the ES module loader is worth 13 to 15 ms per call.
dist/bin/cc-safety-net.jsis now a tiny loader that enables Node's compile cache and requiresdist/bin/hook.js, so the bundle's bytecode is cached after the first run under~/.cc-safety-net/compile-cache. The first run per home pays 15 to 30 ms once; a Node without the API runs uncached. - Secret protection stops re-deriving constant paths. Coding-CLI roots are memoized per decision, and
win32.parseis skipped on paths without a backslash. This is most of the in-process throughput gain.
Measured and rejected: a V8 startup snapshot (7 MB per Node version, only 3 ms better than the shipped bin) and running the bin under Bun. A persistent daemon is the only way below the current floor and stays out of scope.
Two costs worth knowing: the npm tarball grew from 521 kB to 532 kB because the CommonJS hook bundle carries its own copy of the gate beside the ESM chunk the other entries share, and one ~220 KB compile-cache file per Node version accumulates under
~/.cc-safety-net/compile-cache.Changed
- Changed secret-protection path resolution to follow the shell's directory scope:
cd -returns to the previous directory, acdinside a subshell,$( ), backticks or a process substitution ends with that shell, and a brace group or function body keeps itscd. Ash -cbody is walked as shell, so acdinside it counts.pushd/popdstay untracked. Commands that read a protected file after acdare denied where they were previously allowed. No policy, rule or level change is required. - Changed standard mode to keep an interpreter string literal as a path candidate only when the surrounding code holds a filesystem, command-execution or
evalmarker. Strict mode still keeps every literal and scans inside literal text. - Improved the
Config warning:line a denial carries whenpolicy.jsonholds something the loader will not accept: it now names the dropped section or field, for examplesafety.level: not one of standard, strict, paranoid, instead of repeating schema wording.cc-safety-net doctorandcc-safety-net policy checkkeep their existing wording.
Fixed
- Fixed inline
jq,gojqandjaqfilters ending in.keybeing denied as sensitive filenames (#112). - Fixed
<<inside interpreter code, such as a JavaScript template literal, blocking understrictwith an unsupported-heredoc error (#111). - Fixed a POSIX heredoc being auto-detected as PowerShell, which denied a command whose heredoc body merely mentioned a PowerShell command.
- Fixed interpreter code being scanned as shell text: a heredoc, pipe or
-cbody handed to a non-shell interpreter is now read as code, so its string literals no longer become bare path operands. A literal passed to a shell-exec call such asos.system,subprocess.*orexecSyncis still walked as shell and still denies (#114). - Fixed a
sh -cbody being matched by the inline-code scanner rather than walked as shell, which denied a display-onlyprintf '%s' .envinsidesh -cwhile allowing the same command at the top level; a body that reads a protected file, such assh -c 'cd ~ && cat .ssh/config', now denies. - Fixed
printfformat operands without conversions being forwarded as path candidates in pipe analysis. - Fixed a
find -execbody inside an unknown wrapper command skipping the full analysis, which allowed shapes such ascustom-tool -x find . -exec dd of=/dev/sda \;. - Fixed non-BMP characters, including emoji, being corrupted when decoding quoted filenames in Git patch headers.
- Fixed a
git configprobe inside a linked worktree timing out after 2 seconds on a cold process, which withheld a relaxation and could deny a command that should have been allowed; the cap is now 5 seconds. - Fixed the policy GUI answering from the repository shape it saw at startup, so a
.gitmarker created or removed while the GUI is open now changes the command tester's answer immediately.
Removed
- Removed the
zodruntime dependency. The published package declares no dependencies and no longer shipsTHIRD_PARTY_LICENSES.txt.
Security
- Improved diagnostic redaction: an assignment whose quote is never closed now has its entire remaining value redacted, instead of leaving the tail of the value in diagnostic output.
Sep 14, 2026
GitHub releasev2.3.4
v2.3.4
- Fix
Fixes a secret-protection false positive where an allowlisted file was still blocked when it was passed as an assignment value.
Fixed
- Fixed allowlisted paths being blocked when supplied through an
exportassignment or Git's global-coption, such asexport GIT_SSL_CAINFO=/path/to/ca.pemorgit -c http.sslCAInfo=/path/to/ca.pem ls-remote origin. ExplicitdenyPathsentries and coding-CLI configuration protection still take precedence, and ordinary filenames containing=are still inspected as paths. (#109)
Sep 8, 2026
GitHub releasev2.3.3
v2.3.3
- Security
- Integration
- Fix
A Windows-focused fix release: native paths are no longer lost when guards inspect command-style input from unregistered tools, the Hermes Agent plugin now works on Windows, and audit-log project filtering handles Windows paths.
Fixed
- Fixed guards losing native Windows paths in command-style input from tools outside the adapter registry. Such input is now parsed with PowerShell rules on Windows, so policy and secret protection recognize targets such as
C:\Users\<user>\.cc-safety-net\policy.json. Metadata-onlylsandstaton these inputs stay allowed in Standard mode and are blocked in Strict and Paranoid. (#101, #102) - Fixed the Hermes Agent plugin erroring on Windows. The generated pre-tool-call hook no longer requests a POSIX-only process session that Windows rejects, and an analyzer timeout now terminates the analyzer process tree with
taskkilland still returns an explicit block. (#104) - Fixed
cc-safety-net logs --projectnot matching directories nested under the given project on Windows, where the filter assumed/path separators. (#106)
Sep 4, 2026
GitHub releasev2.3.2
v2.3.2
- Security
- Integration
CC Safety Net now ships a native Codex plugin, so Codex runs the same destructive-command and secret-access checks before a tool call as the other supported agents.
Added
- Added a native Codex plugin: the package now ships a Codex plugin manifest and a
PreToolUsehook definition that runs CC Safety Net before Codex executes a tool. (#100) - Added the
hook --codex(-cx) flag so the CLI can be wired into Codex as aPreToolUsehook directly. (#100)
Changed
- Codex hook decisions are now recorded with
codexas the agent in the audit log instead of relying on transcript-path detection, socc-safety-net logs --agent codexreliably shows them. (#100)
Sep 3, 2026
GitHub releasev2.3.1
v2.3.1
- Breaking
- Fix
Closes five detection gaps in command analysis:
curluploads of secret files, downloads piped to a shell inside unscanned bodies, live substitutions in unquoted heredocs,functionkeyword definitions, and PowerShell home-path spellings.Fixed
- Fixed
curluploads that read sensitive files being allowed.-d @.env,-F file=@.env,--data-ascii,--data-binary,--data-urlencode, and<fileform parts are now blocked, including the attached (-d@.env),=-joined (--data=@.env), and clustered (-sF file=@.env) spellings.--data-raw,--form-string, and@-still pass, because they never open a file. - Fixed downloads piped to a shell going undetected inside command bodies the parser does not descend into, such as a heredoc fed to
bash.curl ... | shand itswget,nc, andaria2cvariants are now blocked, includingsudo,env,command, andbuiltinwrappers and line continuations, while benign pipes such ascurl ... | jq .stay allowed. - Fixed unquoted heredoc bodies hiding live code.
$(...)and backtick substitutions in such a body are now parsed and matched against the full rule set, socat <<EOFwith$(find . -delete)reports thefind.deleterule instead of a generic text match. Quoted (<<'EOF') bodies and escaped\$(...)remain inert data. - Fixed bash
function name { ... }andfunction name() { ... }definitions not being parsed. Commands inside such a function are now analyzed when it is called, including mutations of the protected policy file. - Fixed PowerShell secret checks missing native path spellings. A
$HOME\,$env:USERPROFILE\,$env:HOME\, or~\prefix now resolves forGet-Content,Set-Content,Add-Content,Copy-Item,Move-Item,Remove-Item, and the aliasesgc,cat,type,cp,mv,rm, anddel, and a backtick escape inside the path no longer hides it. A path assembled any other way, such as concatenation, a subexpression, orJoin-Path, stays out of scope.
Sep 1, 2026
GitHub releasev2.3.0
v2.3.0
- Security
- Breaking
- Migration
- Fix
This release adds team-shareable project policies with a human-confirmed
policy apply, curated official rulebooks for infrastructure CLIs, and replaces the rulebook lock-and-cache with live vendored files. Installs that added GitHub rulebooks on 2.2 or earlier need a one-timerule syncper scope after upgrading.Highlights
- Added a project policy scope: a team lead commits
.cc-safety-net/policy.jsonand every clone picks it up with no member action, layered over each member's own user policy. (#97) - Added official rulebooks for Terraform, AWS, gcloud, and Azure, installable with
cc-safety-net rule add --only terraform aws --global. (#96) - Changed rulebooks to live files: the runtime reads each
rulebook.jsonon every tool call, so an edit applies to the next command with no sync step. (#97)
Added
- Added
cc-safety-net policy check <file>to validate a policy proposal and print its diff, andcc-safety-net policy apply <file>to write it after an interactive terminal confirmation. Add--globalto target the user policy instead of the project one. - Added project-scope policy merging: the project file supplies safety level, per-feature toggles, per-rule overrides, and path lists, while any field it leaves out keeps inheriting from the user policy. Per-rule overrides merge by rule id, path lists are the union of both scopes, and
auditstays user scope only. - Added project-policy reporting across every surface:
statusshows the project policy path and a line-by-line list of what it relaxed,doctorprints the same deltas under Effective Safety,explainnames the scope that supplied the safety preset, and the status line shows a🔻marker. - Added a "Draft project policy" mode to
cc-safety-net gui: pick a project directory, mark only the fields to write, review the merged diff and relaxation warnings, and save.cc-safety-net/policy.json. (#98) - Added repository-wide rulebook installs:
rule add owner/repoadds every rulebook on the default branch,--only <rulebook...>selects specific ones, and--ref <ref>picks a branch, tag, or commit. Runningrule add --only <rulebook...>with no source selects from the officialcc-safety-net/rulebooksrepository. The command now prints the scope it wrote to and the rulebooks and commits it vendored. - Added
rulebook_version2, which replacessubcommandandblock_argswith an exact-tokenmatchobject (command_path,any_args,exclude_args). Value-taking global options foraws,gcloud, andazare recognized when locating the command path, so options such as--profile proddo not defeat a rule. Version 1 rulebooks keep their fields and behavior. - Added fixture evaluation for version 2 rulebooks: their
testsentries are checked against the rulebook's own rules byrule add,rule update, andrule verify, and a failing fixture rejects the source before it is written. Fixture commands are analyzed, never executed. - Added support for GitHub refs containing
/, such asowner/repo#feature/rulebook-v2.
Changed
- Changed remote rulebook handling:
rule addvalidates and vendors the rulebook files into your own configuration, and nothing updates in the background. Runrule update [source]to re-fetch and rewrite the vendored copies; a source with an ordinary update failure keeps its existing copy while the others still update. - Changed
rule listto describe version 2 rules by their command path andany_args/exclude_argsinstead of printing an emptyBlock argsrow. - Changed the
/cc-safety-netskill into a full operator: it explains why a command was blocked, triages false positives, authors rules and policy proposals, manages agent CLI integrations, and diagnoses protection. It is manual-only and never triggers on its own. - Changed
doctorto report leftover rulebook lock and cache files from an earlier version, with the command that migrates them.
Breaking Changes
- Replaced the
rule syncsynchronization step: rulebooks no longer have a lock or cache, and the command now only migrates leftovers from an earlier install. - Migration: If you installed rulebooks from GitHub on 2.2 or earlier, run
npx -y cc-safety-net rule synconce per scope after upgrading, adding--globalfor user-scope sources. Until then, those GitHub-sourced rules are inactive andstatusanddoctorreport the degraded sources. - Removed the
--checkoption from everyrulesubcommand; passing it is now an error. - Migration: Use
cc-safety-net rule verifyfor offline validation of config and rulebooks.
Security
- Blocked agents from applying policy proposals:
cc-safety-net policy applyis denied when an agent runs it, including through package runners such asnpx,pnpm dlx, andnpm exec, and it refuses to run without an interactive terminal.cc-safety-net policy checkstays available so an agent can show what a proposal would change. - Extended policy-file protection to the project
.cc-safety-net/policy.json, so an agent can no longer create or modify the project policy that the guards enforce.
Aug 31, 2026
GitHub releasev2.2.2
v2.2.2
- Fix
A maintenance release that makes Amp block messages explain why a command's working directory was rejected and how to recover from it.
Fixed
- Fixed Amp shell commands whose working directory cannot be resolved being reported as an unexpected internal failure. The command is still blocked before analysis, but the message now states that the requested directory is missing, inaccessible, not a directory, or in an unsupported path form, echoes the command and directory, and tells the agent to retry from an existing accessible directory. (#94)
Aug 25, 2026
GitHub releasev2.2.1
v2.2.1
- Integration
- Fix
A patch release that fixes a Windows-only path comparison bug which caused safe deletions inside the system temporary directory to be blocked.
Fixed
- Fixed
rm -rfon a path inside the Windows temporary directory being blocked when the path's letter case differed from the resolved temp root, so an MSYS-style target such as/c/Users/<user>/AppData/Local/Temp/claude/...is now treated the same as itsC:/Users/...equivalent. (#91)
Aug 25, 2026
GitHub releasev2.2.0
v2.2.0
- Security
- Breaking
- Integration
- Fix
Adds Grok Build as a supported coding agent CLI, and fixes Windows protection for Git Bash style
/c/...paths that previously slipped past checks theirC:/...spelling would have blocked.Added
- Added Grok Build support: install the PreToolUse hook with
cc-safety-net install --grok-build(remove it withuninstall --grok-build), or run the adapter directly withcc-safety-net hook --grok-build/-gb. The hook config is written to~/.grok/hooks/cc-safety-net.json, honorsGROK_HOME, and install and uninstall preserve any other hook entries in that file. Note that Grok Build hooks are fail-open by design, so only an explicit deny blocks a tool call; seeSECURITY.mdfor the limits. (#92) - Added Grok Build to
cc-safety-net doctor, which reports the hook as configured and warns when the managed entry has drifted, such as a coverage-narrowingmatcher, a handlertypeother thancommand, or a changed timeout. (#92) - Added secret protection for Grok Build credentials and config files:
~/.grok/auth.json,~/.grok/mcp_credentials.json,~/.grok/config.toml,~/.grok/managed_config.toml,~/.grok/requirements.toml,<project>/.grok/config.toml,/etc/grok/managed_config.toml, and/etc/grok/requirements.toml. (#92)
Fixed
- Fixed Windows handling of MSYS and Git Bash path spellings such as
/c/Users/..., which were previously read as paths on the current drive. Recursivermclassification, protected policy path checks, secret-file protection, andHOMEandCC_SAFETY_NET_HOMEresolution now normalize these to the nativeC:/...form first, so a destructive command written in the/c/form is treated the same as itsC:/form. (#91)
Aug 25, 2026
GitHub releasev2.1.1
v2.1.1
cc-safety-net updatenow refreshes thebunxcache alongside thenpxcache, so a laterbunx cc-safety-netrun picks up the new release instead of the stale cached one. Persistent installs that are behind the latest published version also get a one-line update nudge.Added
- Added
bunxcache clearing tocc-safety-net update. Each run removes the current user'sbunx-<uid>-cc-safety-net@*entries from the OS temp directory, including when no integrations are installed. Entries are matched by name, so another tool that merely depends oncc-safety-netkeeps its own cache, and the entry the running process was launched from is preserved. (#90) - Added an update nudge to
cc-safety-net update. When a persistent install (for examplenpm i -g cc-safety-net) is behind the latest published version, the command prints the current and latest versions plus an upgrade hint. Ephemeralnpxandbunxruns skip the registry check entirely, and a failed or offline check stays silent and does not change the exit code. (#90)
Changed
- Changed
cc-safety-net updateto report abunxcache-clearing failure and exit with a non-zero status, instead of silently succeeding. (#90)
Aug 24, 2026
GitHub release- Added
v2.1.0
v2.1.0
- Security
- Breaking
- Fix
Adds a
cc-safety-net/apilibrary entry so Node.js hosts can check a command in-process without installing an agent integration, and hardens--delete-sourceso it can no longer remove files a concurrent process added.Added
- Added the
cc-safety-net/apipackage entry exportingcheckCommand({ command, cwd }), which returns anallowordenydecision for a single shell command without executing it, writing audit data, changing configuration, or making network requests. Denials include a displayreasonand an optionalruleId. (#89) - Added an absolute-path
cwdrequirement tocheckCommand, which anchors relative command targets and selects the project policy so the check never falls back to hidden process state. An unusable directory fails closed with a deny. (#89) - Added TypeScript declarations for the new entry, so
checkCommandandCheckCommandResulttype-check fromcc-safety-net/apialone without any optional agent-integration packages installed. The entry requires Node.js 18 or later and ESM; there is no CommonJS build. (#89)
Fixed
- Fixed
--delete-sourcerecursively deleting files that a concurrent process added to a rulebook source directory after the pre-sync safeguard ran but before the delete. The safeguard now re-runs at delete time, an unexpected file refuses the delete with the existing "delete manually" error and a clean configuration rollback, and only the validatedrulebook.jsonplus the then-empty directory are removed. (#88) - Fixed
--delete-sourcereporting a failure when the source directory was already removed during the sync, which is the requested end state. (#88)
Aug 24, 2026
GitHub releasev2.0.11
v2.0.11
- Security
- Integration
- Fix
This release removes two false blocks — literal heredoc bodies and Amp shell commands that run outside the workspace root — and hardens the doctor, GUI, and integration paths against malformed input.
Changed
- Changed the local GUI server to reject a request body larger than 1 MiB with HTTP 413 instead of buffering it in memory.
Fixed
- Fixed the analyzer blocking an unquoted heredoc whose body contains no
$, backtick, or backslash. Such a body reaches the command byte-for-byte, so it is now analyzed as literal data, while a body with expansion or escape characters keeps the raw-text scan. (#87, #86) - Fixed Amp shell calls failing closed when
dirpoints outside the workspace root. The directory is now canonicalized, with symlinks resolved, and the command is analyzed there; a directory that cannot be canonicalized still fails closed. (#85) - Fixed Git metadata protection covering only the execution directory's repository. It is now anchored to both the execution and configuration directories, so a workspace repository's
.gitstays protected when a command runs elsewhere. (#85) - Fixed
cc-safety-net doctorexiting0while reporting an error-level finding, such as an unsafe policy, config, or audit directory. - Fixed the GUI policy editor failing to render a draft saved by an older build or damaged in storage. Drafts are now validated against the policy shape and discarded when they do not match.
- Fixed the GUI folder picker offering a dialog program that cannot start. A
PATHentry now counts only when it is an executable file. - Fixed GitHub Copilot CLI detection accepting a hook config with an unexpected shape. An invalid
hooks.preToolUseis now reported as a configuration error. - Fixed Antigravity CLI installation failing on a hand-edited hooks config that holds unexpected JSON shapes. Unrecognized entries are now left untouched.
- Fixed doctor and audit summaries trusting malformed audit log records. A record that does not match the expected shape is now counted as skipped.
- Fixed hook agent detection failing when a payload supplies a non-string transcript path. It now falls back to an unknown agent so analysis still runs.
- Fixed rulebook discovery from GitHub accepting unexpected API responses. It now stops with a clear inspection error.
Aug 23, 2026
GitHub releasev2.0.10
v2.0.10
- Fix
Fixes a false-positive denial where a command carrying many path-like tokens in a single argument was blocked with a command-analysis-limit error instead of being analyzed.
Fixed
- Fixed legitimate commands being denied with a command-analysis-limit error when one argument contained a large number of path-like tokens, such as a quoted
python3heredoc listing hundreds of file paths. A path whose nearest existing ancestor is past the missing-component limit now resolves to its lexical form instead of aborting the analysis, and the remaining canonicalization budgets still fail closed. (#83)
Aug 21, 2026
GitHub releasev2.0.9
v2.0.9
- Security
- Fix
This release closes an
env -Sbypass in the policy-file and Git-metadata guards and stops commands full of path-like tokens from being denied as an internal failure.env -Sand GNUparallel --envare no longer emulated, so a few commands that previously passed analysis are now refused.Highlights
- Blocked policy-file and Git-metadata mutations hidden inside an
env -Ssplit string, such asenv -S 'rm <policy-path>' true(#82). - Fixed commands containing many path-like tokens being denied as an unexpected CC Safety Net failure; policy-path checks now do far less filesystem work (#82).
Changed
- Changed
env -Shandling: the split string is no longer expanded. Its value is scanned for destructive text, and an inert value is spliced ahead of the remaining operands and analyzed as the real command line. Under thestrictandparanoidsafety levels anenv -Scommand is now refused as an unverifiable execution source. - Changed GNU
parallel --envhandling: because the selected values are supplied at run time, the command is now refused as unverifiable construction instead of being emulated. - Improved analysis-limit denials: they now say the command exceeds safe analysis limits and suggest simplifying or splitting it, instead of reporting an internal CC Safety Net fault.
- Changed audit logging so fail-closed failure entries keep the whole command instead of a truncated one.
- Changed the
git.alias-configrule to follow the resolved destructive-command rule state, so turning off destructive-command protection now suppresses it too.
Fixed
- Fixed
xargsreplacement input not being treated as dynamic for themerge,rebase,reflog,rm,stash, andworktreeGit subcommands. - Fixed worktree-mode Git environment tracking: an assignment that only prefixes a command no longer persists into later segments, a
NAME=valuetoken after the command word is no longer treated as an environment override, a prefixedunsetis now tracked, andcommand -v/-Vis treated as a query rather than an invocation. - Fixed the policy GUI showing default settings for a partially invalid policy file while the engine enforced the salvaged values; it now shows the policy that is in force.
- Fixed the policy GUI refresh buttons staying disabled and spinning when a reload failed.
Security
- Fixed policy-file and Git-metadata protection missing mutations hidden in an
env -Ssplit string; the split words are now scanned against the protected paths. - Fixed destructive text in a GNU
parallelenvironment value being allowed when the coarseparallelrules or destructive-command protection were turned off; such values now stay blocked in every configuration.
Aug 21, 2026
GitHub releasev2.0.8
v2.0.8
- Breaking
- Migration
- Integration
- Fix
Fixes Amp plugin installation, which could leave the plugin unable to load, by shipping it as a directory plugin and migrating existing installs automatically.
Fixed
- Fixed the Amp plugin failing to load: it is now installed as a directory (
cc-safety-net/index.ts) in your Amp personal plugins repository instead of the root filecc-safety-net.ts, which Amp base64-encodes into a single process environment entry that exceeds Linux's per-entry limit. (#79) - Fixed migration from earlier releases:
install --ampnow removes the legacycc-safety-net.tsfile in the same commit, so no manual cleanup is needed. (#79) - Fixed
uninstall --ampscope: it now removes only the managed entry file and leaves any other files you keep in the plugin directory untouched. (#79) - Fixed
install --ampreporting the plugin as already up to date when the plugin path is ignored by your personal plugins repository; staging the file now fails with an error instead. (#79) - Fixed cleanup of a masking local copy: install and uninstall now also remove a
~/.config/amp/plugins/cc-safety-net/directory when it holds nothing but the managed entry, and refuse rather than delete anything else. (#79) - Fixed retry instructions in Amp error messages, which told you to rerun
install --ampeven when the failure happened duringuninstall --amp. (#79)
Aug 20, 2026
GitHub releasev2.0.7
v2.0.7
- Security
- Breaking
- Migration
- Integration
- Fix
This release blocks forced
git rmworking-tree removal, closes several audit-found analyzer bypasses, and removes common false denials such asls -la ~/.sshandeval "$(ssh-agent -s)"at the standard level. Note two breaking--jsonoutput changes indoctorandexplain.Highlights
- Added a
git.rm-forcerule that blocks forcedgit rmworking-tree removal (e.g.git rm -rf .) at every safety level, motivated by a real-world incident that destroyed a project (anthropics/claude-code#70687). - Closed analyzer fail-opens found in a security audit:
rm -rf *at a home working directory is now blocked at all levels, and strict mode now catches variable-provenance command heads and substitution-derivedrmflags. - Reduced standard-level false denials: metadata-only
ls/statdiscovery and verifiable local generator sources likeeval "$(ssh-agent -s)"andsource <(kubectl completion bash)are now allowed.
Added
- Added the default-enabled
git.rm-forcerule:git rmwith an effective--force/-fis blocked unless--cachedor--dry-run/-nis present; non-forcedgit rmandgit rm -r --cached .stay allowed. The standard preset now enables 45 rules.
Changed
- Allowed
eval "$(CMD)"andsource <(CMD)at the standard level whenCMDis a single fully literal local command; remote fetchers (curl,wget, ...), shells, command wrappers, and env-assignment-prefixed bodies stay denied, and strict/paranoid still deny every dynamic shell source. Note that the generator's emitted shell itself runs unverified (seeSECURITY.md). - Allowed metadata-only discovery with
lsandstatheads (e.g.ls -la ~/.ssh,stat .env) at the standard level; content access such ascat ~/.ssh/id_rsastays blocked, and strict/paranoid still block both. - Changed the Kimi Code plugin manifest to intercept all tools instead of only
Bash, so the native plugin install protectsRead/Write/Editlike the global-hook install already did.
Fixed
- Fixed
rm -rf *with the working directory at home being allowed at standard: a bare*now classifies as a root-or-home target and is blocked at all levels, while a quoted literalrm -rf '*'(a single file named*) is classified by its actual target. - Fixed strict-mode fail-opens where
c=rm; "$c" -rf dir,$CMD --version, andrm $(printf -- '-rf') dirwere allowed at every level; strict and paranoid now block them while standard verdicts are unchanged. - Fixed statement-level env assignments with space-containing values (e.g.
TMPDIR="/tmp/safe /Users"; rm -rf $TMPDIR/x) escaping shell-state tracking; strict and paranoid now block the word-splittingrmtarget. - Fixed Kimi Code ignoring the per-call
Bashtool_input.cwd: it is now contained against the session directory and used as the execution directory, failing closed on invalid or escaping values. - Fixed Pi tool calls being analyzed under the raw context
cwdinstead of the validated, canonicalized one, and routed the built-infindtool as a read-only glob so searches under protected directories are no longer falsely denied. - Fixed OpenClaw Code Mode JavaScript
execevents being parsed as shell commands and falsely denied, and expanded a leading tilde inOPENCLAW_STATE_DIRandOPENCLAW_CONFIG_PATH. - Fixed OpenCode integration gaps: slash-rooted Windows workdirs pass through instead of failing closed, config and cache roots follow
XDG_CONFIG_HOME/XDG_CACHE_HOME, install now verifies the plugin actually loads, and an unconfigured shell resolves to PowerShell on Windows and to$SHELLelsewhere instead of the auto heuristic. - Fixed
doctormisreporting a never-installed Codex plugin as disabled, missing Copilot CLI hooks defined in~/.copilot/settings.jsonand the repository's.claude/settings.json/settings.local.json, and probingcodex plugin listwith a shorter timeout thaninstall, which could report Codex as not installed whereinstallsaw it. - Fixed the Copilot CLI
powershellruntime tool being analyzed with the wrong shell dialect, and the Hermes Agent plugin now resolves the working directory in the host's own order. - Fixed a successful GUI install rendering an empty status box instead of the success report.
- Fixed
explaincrashing with a stack trace and empty stdout on analysis-limit inputs (e.g. a recursion bomb); it now prints a bounded JSON error under--jsonor a plain message on stderr and exits 1. Pipedexplainoutput is also no longer truncated at the pipe buffer size. - Fixed
explaintrace steps naming functions that do not exist and theenv -Sdenial reason claiming an unreachable condition; the reason now names the real 16,384-token expansion-limit trigger.
Breaking Changes
- Changed
doctor --jsonto report integration versions under a singleversionsmap keyed by integration id instead of twelve flat fields such asclaudeCodeVersion. - Migration: Read
versions.<integration-id>instead of the per-integration*Versionkeys. - Changed
explain --jsontrace output:rule-checksteps emit onerulestring in place ofruleModule/ruleFunction, andenv-strip.envVarsis an array of variable names instead of an object. - Migration: Read
rulefor the rule identity and treatenvVarsas a string array.
Removed
- Removed the Pi
Shelltool adapter; the tool no longer exists on the Pi host, and the built-inbashroute is unchanged.
Aug 19, 2026
GitHub releasev2.0.6
v2.0.6
- Breaking
- Fix
This release adds configurable allow paths to secret protection and fixes several cases where the secret path scanner misread commands, including a detection gap for symlinked credential directories.
Added
- Added a
secret_protection.allow_pathspolicy setting with a matching "Allow paths" list in the policy GUI. Literal file or directory entries are exempt from the secret pattern rules; explicit deny paths and the coding-CLI protections still apply. Entries that cover the home directory or the guard's own configuration are rejected, and glob patterns are not supported. (#77)
Fixed
- Fixed the home credential rules (
~/.ssh,~/.aws, ...) so they still block access when the credential directory is a symlink, as commonly created by dotfile and password managers. (#77) - Fixed false blocks on text that does not name a local file: regex operands such as
git grep "process\.env", prose that begins with a sensitive prefix such as.env.example), and remotehttp(s)URLs. Files that exist on disk with such names,file:URLs, and shell-escaped operands stay blocked. (#77) - Fixed the
explainexemption to cover every documented invocation form, includingbunx cc-safety-net explain,npx -y cc-safety-net explain, andbun run <entrypoint> explain. Other runners and packages keep full argument inspection. (#77) - Fixed the policy GUI so an unsaved draft created before this release restores without breaking the editor. (#77)
Aug 17, 2026
GitHub releasev2.0.5
v2.0.5
- Integration
This release makes
cc-safety-net updatefaster and gives it clearer progress feedback.Changed
- Improved
cc-safety-net updatespeed: all detected integrations now update concurrently, and integration detection starts while the install banner plays. (#75) - Improved
updateprogress feedback: the command shows a spinner while it checks and updates integrations, then prints one result line per integration. (#75) - Improved Codex updates: the update reuses the
codex plugin listoutput from detection instead of querying the Codex marketplace a second time. (#75) - Changed the stale
npxcache cleanup during updates: the cache is cleared once before the targets run, and a cleanup failure now fails only the targets that depend on that cache while the other integrations still update. (#75)
Aug 14, 2026
GitHub releasev2.0.4
v2.0.4
- Integration
- Fix
Fixes a silent failure where custom rules never enforced in plugin installs that copy a repository checkout instead of running a package manager.
Fixed
- Fixed custom rules never loading in repository-checkout plugin installs, such as the Claude Code marketplace, Codex, Copilot CLI, and Kimi Code. These installs have no
node_modules, so the schema loader's lazyrequire('zod')failed and every custom rule stayed inactive while built-in protections kept working. The CLI bundle now resolves its schema dependency from a vendoreddist/vendor/zod.cjscopy that ships with the package. (#72, #74) - Fixed rulebook and policy configuration errors being reported as
Invalid JSONon files that are valid JSON. These loaders now reportInvalid JSONonly for a real parse failure, and show the underlying filesystem or dependency message otherwise. (#72)
Aug 14, 2026
GitHub releasev2.0.3
v2.0.3
- Integration
- Fix
Highlights
- Amp personal-scope install.
install --ampnow publishes the plugin to your Amp Personal Plugins repository, so the safety net follows your account to every machine — including remote Orb threads — instead of living in one local config. - Native Kimi Code plugin. The release now shipskimi.plugin.json, so you can install via/plugins installand let Kimi Code manage enable, disable, update, and removal. The installer offers a choice between the global hook and the native plugin when you select Kimi Code.Features
-
install --ampembeds a snapshot of your user policy in the published plugin. A remote Orb with an empty home directory now enforces your policy instead of only the built-in defaults. - Flagged installs (e.g.install --codex) show a loading spinner while the host CLI runs, so slow network installs no longer look hung.Fixes
- Windows: npm-installed CLIs ship as
.cmdshims, which Node'sspawncannot start directly. All native install probes and commands now route throughCOMSPEC, soinstall --codexand the interactive picker work on Windows (#69). - Amp: if an unmanaged file or symlink at~/.config/amp/plugins/cc-safety-net.tswould mask the newly published personal plugin, the install now fails with an actionable error instead of reporting success while the hook may never run. - Amp: the machine-generated commit in the throwaway checkout now carries an explicit git identity, so the install works on machines with no globaluser.name/user.emailconfigured. - A stalled host CLI is now killed after 120 seconds and reported as a failure, so an install can no longer hang forever. - The Amp install now stops immediately when its staged-status probe fails instead of attempting the commit anyway.Internal
- The release pipeline validates
kimi.plugin.jsonalongside the other manifests, preserves manifest formatting when bumping versions, and lints the prepared files before tagging — the failure class that blocked v2.0.2 can no longer reach a tag.Aug 12, 2026
GitHub releasev2.0.1
v2.0.1
- Migration
- Integration
- Fix
Fixes
- `update` migrates pre-rename plugins — updating from the old
safety-netplugin name now works across hosts: - Detects the pre-rename Copilot CLI plugin and removes it after migrating.
- Refreshes an already-registered marketplace before installing on Claude Code, Codex, and Copilot CLI, so updates no longer fail against a stale catalog.
- Legacy-plugin cleanup is best-effort: a failure warns instead of failing the target, since the host CLI may have already dropped the record.
codex plugin listnow runs with a 30 s timeout, so a cold run no longer silently drops Codex from detection.- One failed target no longer stops the remaining update targets; the command still exits non-zero at the end.
Release pipeline
- The prepare-release workflow now takes a
patch/minor/majorbump choice and computes the next version automatically; an explicit version input remains as an override. - The publisher looks up GitHub releases with a draft-aware query, fixing a failure on the first publish of a tag.
Upgrade
bash npx -y cc-safety-net@latest updateFull changelog: https://github.com/kenryu42/cc-safety-net/compare/v2.0.0...v2.0.1
Aug 10, 2026
GitHub releasev2.0.0
v2.0.0
- Security
- Migration
- Integration
- Docs
V2 is a ground-up rebuild: one installer for twelve coding CLIs, secret protection, a policy GUI, and a rebuilt evaluation engine with decision tracing.
Upgrading from v1? One command upgrades every installed integration:
npx -y cc-safety-net@latest update. If you defined custom rules under v1, see Upgrading from an older version.Renamed: `safety-net` → `cc-safety-net`
The plugin, npm package, and CLI are now uniformly named cc-safety-net. Claude Code marketplace installs migrate automatically; no action is needed.
Highlights
- Universal installer — interactive
install/uninstall/updateacross all twelve supported agent CLIs (Claude Code, Codex, Cursor, Gemini CLI, Copilot CLI, OpenCode, Amp, Pi, and more). - Secret protection — built-in rules block access to SSH keys,
.envfiles, cloud credentials, and coding-CLI credential stores, across shell commands and file tools. - Rebuilt evaluation engine — canonical command IR, immutable policy snapshots, and an ordered guard pipeline with decision tracing via
explain. - Always-on catastrophic protections — recursive deletion of root or home, Git metadata mutation, and policy-file tampering are blocked in every mode.
- Safety presets —
standard/strict/paranoidwith per-rule overrides, trusted delete allow-paths, and env vars that can only raise protection. - Policy GUI —
cc-safety-net guiserves a local, token-authenticated policy editor with live preset preview. - Audit trail — allowed and blocked decisions logged to local per-project JSONL with secret redaction; browse with
cc-safety-net logs. - Documented threat model — the SECURITY.md mode contract, explicit resource limits, and a residual-risk registry.
Get started
bash npx -y cc-safety-net@latest installFull documentation: https://ccsafetynet.com/docs
Full changelog: https://github.com/kenryu42/cc-safety-net/compare/v1.0.6...v2.0.0
Aug 10, 2026
GitHub releasev1.0.6
v1.0.6
- Fix
Changes
- fix: avoid duplicate home rule scope (#62) — When the user config path and the project config path resolve to the same file (e.g. running inside
$HOME), the rules config was loaded twice, producing duplicate rule entries. The policy loader now detects this viaresolve()andrealpathSync()and skips the redundant read.
Tests
- test: isolate home scope regression — Added dedicated tests to verify that rules are not duplicated when the home and project scopes overlap.
Thanks to @sQVe for reporting the issue in #61 .
Jun 15, 2026
GitHub releasev1.0.5
v1.0.5
- Migration
- Integration
- Docs
Changes
- kimi-code: resolve config from correct directory — Config path now resolves from
KIMI_CODE_HOME/.kimi-codeinstead of the legacyKIMI_SHARE_DIR/.kimi. - kimi-code: match PreToolUse hook to `Bash` tool — The hook matcher was targeting
Shellbut Kimi Code exposes the tool asBash. Updated to match the correct tool name.
Docs
- readme: note optional cc-safety-net skill for Kimi Code — Added a note about the
/cc-safety-netskill for configuring custom rules.
Jun 14, 2026
GitHub releasev1.0.4
v1.0.4
- Security
- Integration
- Fix
Bug Fixes
- opencode: write audit logs for blocked commands — When a command is blocked and a
sessionIDis present, the plugin now correctly writes an audit log entry. Previously, blocked commands in OpenCode sessions were not being logged. - opencode: inject audit log home directory — The plugin now accepts and forwards a
homeDirparameter to the audit logger, ensuring logs are written to the correct location.
Thanks to @johnatas-henrique for reporting the issue in #58 .
Jun 14, 2026
GitHub releasev1.0.3
v1.0.3
- Security
- Fix
Security Fix
- Bumped `shell-quote` to v1.8.4 — addresses a parsing vulnerability in the upstream dependency (#56)
Thanks to @joerawr for reporting the shell-quote vulnerability in #55.
Jun 13, 2026
GitHub release