# Regex deny patterns for command-guard.py Layer 1.5.
#
# Format: one Python regex per line. Blank lines and lines starting with # ignored.
# Patterns are applied via re.search() so they match anywhere in the command.
# Commands matching shared.allow_commands.txt prefix list (Layer 0.5) bypass
# this layer entirely — that is the wide-rm + prefix-whitelist tradeoff
# discussed in proposals/harden_destructive_command_guard.md sec.2.2 / sec.8 Q1.
#
# Bad regex in this file = fail-closed (block all commands, surface error).

# rm -rf with any path argument that is not whitelisted
# (catches absolute Windows paths, $HOME, ../, ./*, etc.)
^\s*rm\s+(-[rRfF]+\s+)+[^|;&]*[\w./~$]
^\s*sudo\s+rm\s+-

# Force push variants (force-with-lease included; --force=anything)
\bgit\s+push\b.*--force(-with-lease)?\b
\bgit\s+push\b.*\s-f\b
\bgit\s+push\b.*\s:\S+
\bgit\s+push\b.*--delete\b

# Branch / tag / remote destruction
\bgit\s+branch\s+-D\b
\bgit\s+tag\s+-d\b
\bgit\s+remote\s+(rm|remove)\b

# History rewriting that may not match exact literal forms
\bgit\s+gc\b.*--prune=now
\bgit\s+update-ref\s+-d\b

# GitHub CLI destructive remote operations (irreversible; NOT caught by the
# git-focused patterns above). `gh repo delete <repo> --yes` deletes the whole
# repository with no confirmation. gh issue delete is intentionally NOT denied
# here -- relatively safe and used for candidate-sweep cleanup. (P-0097, gc #85)
\bgh\s+repo\s+delete\b
\bgh\s+repo\s+archive\b
\bgh\s+release\s+delete\b
\bgh\s+secret\s+(delete|remove)\b

# Repo deletion via raw API / GraphQL / curl / transfer / scope-grant.
# Precision-tuned to the repo ROOT path /repos/{owner}/{repo} + terminal boundary
# so sub-resource DELETEs (labels, comments, refs, runs) stay allowed. Validated
# probe: 13 block / 12 allow, 0 false-neg, 0 false-pos. (P-0097, gc #85)
(?i)\bgh\s+api\b.*(?:-X|--method)\s+delete\b.*\brepos/[^/\s'"]+/[^/\s'"]+/?(?:["'\s?]|$)
(?i)\bgh\s+api\b.*\brepos/[^/\s'"]+/[^/\s'"]+/?["'\s].*(?:-X|--method)\s+delete\b
(?i)\bgh\s+api\b.*deleteRepository\b
(?i)\bgh\s+api\b.*\brepos/[^/\s'"]+/[^/\s'"]+/transfer\b
(?i)\bcurl\b.*\bdelete\b.*api\.github\.com/repos/[^/\s'"]+/[^/\s'"]+/?(?:["'\s?]|$)
(?i)\b(?:Invoke-RestMethod|Invoke-WebRequest|irm|iwr)\b.*\bdelete\b.*api\.github\.com/repos/[^/\s'"]+/[^/\s'"]+/?(?:["'\s?]|$)
(?i)\bgh\s+auth\s+refresh\b.*\bdelete_repo\b

# Case-insensitive SQL destruction (covers lowercase + title-case)
(?i)\b(drop|truncate)\s+(table|database|schema)\b
(?i)\bdelete\s+from\s+\w+\s*(;|--|$)

# SQL TRUNCATE without explicit "table" keyword (some dialects accept
# TRUNCATE <name>;). Distinguishes from unix `truncate -s SIZE FILE`
# by requiring no `-` arg (unix truncate needs -s flag).
(?i)\btruncate\s+\w+\s*(;|$)

# find . -delete in any path-arg permutation (catches -type f -delete etc.)
\bfind\b.*\s-delete\b

# PowerShell Remove-Item with -Force or -Recurse, any order/casing.
# Covers both PS5.1 (powershell.exe) and PS7 (pwsh) since the cmdlet name
# is identical.
(?i)\bRemove-Item\b.*(-Recurse|-Force)
(?i)\bRemove-Item\b.*-r\w*\s.*-f\w*

# Windows del with destructive flag combinations
(?i)\bdel\b.*(/s|/q|/f).*(/s|/q|/f)

# Redirect-truncate of sensitive files (.env, .git/, *.db, *.sqlite, config/)
^\s*(:|cat\s+/dev/null|true|echo\s*)\s*>\s*\S+
^\s*>\s*\S*(\.env|\.git/|\.db|\.sqlite|config/)

# rm targeting .git directory anywhere (path-variant of literal above)
\brm\s+(-[rRfF]+\s+)*\S*\.git(/|\b)

# Disk-level destruction (defense in depth, low likelihood)
\bdd\s+if=.*of=/dev/
\bmkfs\.\w+\b
