Repository navigation
Guard wave 7: storage, backup and hosted-platform CLIs, cwd-aware rm; blind held-out-10 and 11 - #1997
Merged
Merged
Conversation
… blind held-out-10
The destructive guard now blocks rclone purge/delete/sync, restic forget/prune, zfs/zpool destroy, lvremove/vgremove/pvremove, firebase/supabase/vercel/netlify/wrangler deletes and `supabase db reset --linked`, a relative `rm -r` after `cd /abs`, variable-held flags inside `bash -c`, ln onto shell startup files and ~/.ssh, rsync/scp to host:/etc, vault operator seal/rekey, reg add under HKCU/HKU Software Classes, wmic call reboot, ClickHouse ALTER DELETE/DROP PARTITION/clickhouse-local, a SQL client fed `< file.sql` that drops, make nuke/uninstall at root, mongosh bulkWrite deletes, and sqlite3 `.shell env sh`. cp of a .bak/.orig/.old onto a system path is no longer exempt. Benign forms now allowed (single-action find only, void after a cd to an absolute, ~, $var or .. target and with -L/-H/-follow): find -delete/-exec rm under a named relative dir or with a sole artifact glob, `echo ./a | xargs -I{} rm -rf {}`, wipefs without -a/-o, shred inside $TMPDIR or /tmp.
Held-out-10 (preregistered before scoring, ledger.jsonl): guard on main and wave 6 blocked 44/60 with 6/60 benign blocked; hooks-mastery 13/60 (FP 9); safety-net 14/60 (FP 4, 1 unported). Wave 7 scores 60/60 with FP 1/60 on it (git reset --hard HEAD, a disputed label: the guard keeps blocking it because it discards uncommitted work); the corpus is now in-sample; the blind rows are pinned in test_security_gates_heldout10_blind.py. Held-out-8 and 9 stay 60/60, FP 0.
Tests: 23/23 security gate scripts, test-destructive-guard 16/16, test_audit_skills 11/11, ci-tests.d all pass (run-ledger, prepush-ci-parity, bench-check skipped), size-ratchet ok, git diff --check clean
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QNFFPWVcPUbeuvwM5fk2Z
This was referenced Oct 25, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wave 7 closes the held-out-10 misses and false positives and the gaps folded forward from #1994. A fifth blind corpus, held-out-11, was written and pushed before it was scored. On held-out-11 this wave blocks as many dangerous commands as main with fewer benign blocks, and it blocks three to six times as many as the ported rivals.
prereg/heldout11, ad0ee43, ledger timestamp 2026-10-25T06:47:25Z). The corpus is not in this PR; it lands with wave 8.git reset --hard HEADagain, on purpose. Held-out-10 and held-out-11 both label it benign, but it discards uncommitted work with no way back, so the guard counts the row as a false positive and keeps blocking it.sgdisk --zap-all;cat /dev/null >;npm owner rm.git clean -fdx ./buildandgit stash drop stash@{0}.test_security_gates_heldout10_blind.py. After this wave it scores 60/60 with 1/60 benign blocked, the disputed reset. Held-out-8 and held-out-9 stay at 60/60 and 0/60. These in-sample numbers are tuned and are not a generalization claim.Rule changes:
Now blocked:
purge,delete,sync,move,moveto,bisyncand--delete-*flags, with the verb found after any flags;forget --pruneandprune;zfs destroyandrollback,zpool destroyandlabelclear, LVM removals including throughlvm <options>;a:b:deleteforms;--commandor-cstring drops data, andpsql -forcat file |feeding a dropping SQL file;f=-rf; rm $f /) andrmafter acdto a system path, including inside a subshell;ln -sfonto shell and SSH files in the home directory,rsyncto a remote/etc,vault operator sealandrekey,reg addon user hives,wmic /node ... reboot, clickhouseALTER ... DELETE,DROP PARTITIONand SQL fed through stdin,make nuke|uninstall DESTDIR=/, mongoshbulkWrite, sqlite3.shell;cponto a system path with a backup-looking suffix (.bak,.orig,.old).Now allowed:
findunder the current tree with a single-deleteor a single-exec rm ... {}action;xargs -I{} rmfed only./paths;wipefswithout-aor-o, which only lists signatures;shred -uof a named file in/tmp.Each allowance is void when the command first changes directory to
/,~, a variable or.., andfindloses it with-L,-Hor-follow.Review: 4 🔴 and 4 🟡. Every 🔴 was confirmed by a probe as a regression against main and is fixed in this PR:
-execaction chained after an allowedfind;cd /;find -Lfollowing symlinks out of the tree;git -C <other repo> reset --hard HEAD.Also fixed from the 🟡 list: the rclone verb behind unknown flags, platform delete verbs, LVM through
lvm,psql -f, and a boundedALTER TABLEscan.Folded into wave 8:
A='rm -rf /'; B=$A; $Bfollowed by a 20 KB comment is allowed. Main allows it too; the fix is to fail closed;key removeandunlock --remove-all;lvresizeshrinking a volume,pvcreate -ff;zfs receive -Fandzpool create -f.The adversarial timing limit in the guard self-test moves from 0.5 s to 1.0 s. A 720 KB input takes 0.3 to 0.5 s, and most of that time is spent tokenizing it.
Local gates:
test_security_gates*.py: 23/23.test-destructive-guard.sh: 16/16.test_audit_skills: 11/11.ci-tests.d: pass.run-ledger,prepush-ci-parityandbench-checkcannot run in the local sandbox.git diff --check: clean.🤖 Generated with Claude Code
https://claude.ai/code/session_014QNFFPWVcPUbeuvwM5fk2Z