# Expected Findings — Bash Evasion Gallery This is the testable contract. `run-evasion-gallery.mjs` exits 0 only when every T-tag produces a BLOCK. ## Per-tag contract | Tag | Hook stderr must contain | |-----|--------------------------| | baseline | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T1 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T2 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T3 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T4 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T5 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T6 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T7 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | | T8 | `BLOCKED: Destructive command detected — T8 — base64-pipe-shell idiom (echo BLOB \| base64 -d \| sh)` | | T9 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` | All cases must exit with code 2. ## Why $HOME instead of / The "Filesystem root destruction" BLOCK_RULE regex requires a word-boundary anchor after the destination path: ``` \brm\s+(?:-[a-zA-Z]*f[a-zA-Z]*\s+|--force\s+)*-[a-zA-Z]*r[a-zA-Z]*\s+(?:\/|~|\$HOME)\b ``` `rm -rf /` ends with `/` followed by end-of-string; both `/` and EOL are non-word, so `\b` does not match. The variants `rm -rf /tmp`, `rm -rf $HOME`, and `rm -rf /etc` all match — the trailing word character provides the boundary. This gallery uses `$HOME` because it is unambiguously destructive and the regex fires deterministically. The literal `rm -rf /` edge case is not part of this contract — it is covered by Claude Code 2.1.98+ harness-level checks. ## Side effects - No file is modified - No real `bash` is invoked — only `node hooks/scripts/...` - Each hook spawn has `tool_input.command` set to the disguised variant — bash never sees these strings - No mutation of `$HOME`, `/`, `/tmp`, or anywhere else ## Notes for forks - If `bash-normalize.mjs` adds new T-tags (T10+), add a new case to `CASES` and a corresponding row above - If a BLOCK_RULE in `pre-bash-destructive.mjs` is renamed, update the stderr-pattern column above (the assertion lives in `expected-findings.md` for documentation; the run script only checks exit code 2, so it continues to pass after a rename) - The base64 blob in T8 (`cm0gLXJmICRIT01F`) decodes to the literal command. If you change the canonical destructive target away from `$HOME`, regenerate the blob with `printf '' | base64`