From 072920ff0e9abbdeb13da607a1c0a3e6439e7c19 Mon Sep 17 00:00:00 2001 From: vadimwit Date: Mon, 13 Jul 2026 21:36:02 +0100 Subject: [PATCH] =?UTF-8?q?docs+config:=20never-delete=20policy=20?= =?UTF-8?q?=E2=80=94=20CLAUDE.md=20hard=20rule=20+=20.claude/settings.json?= =?UTF-8?q?=20deny=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude must never execute destructive/irreversible commands (rm, git branch -d/-D, git push --delete, reset --hard, force-push, DROP, etc.) — it proposes them for the user to run. Enforced behaviorally in CLAUDE.md (authoritative) and as permissions.deny rules in .claude/settings.json (defense-in-depth). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/settings.json | 35 +++++++++++++++++++++++++++++++++++ CLAUDE.md | 18 ++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..1482c02 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,35 @@ +{ + "$comment": "Team-shared restricted options. Destructive/irreversible commands are DENIED so Claude proposes them for the user to run instead of executing them. Authoritative policy: see the 'Destructive operations — NEVER delete' section of CLAUDE.md.", + "permissions": { + "deny": [ + "Bash(rm:*)", + "Bash(rmdir:*)", + "Bash(git branch -d:*)", + "Bash(git branch -D:*)", + "Bash(git branch --delete:*)", + "Bash(git push --delete:*)", + "Bash(git push -d:*)", + "Bash(git push origin --delete:*)", + "Bash(git push github --delete:*)", + "Bash(git push origin -d:*)", + "Bash(git push github -d:*)", + "Bash(git tag -d:*)", + "Bash(git tag --delete:*)", + "Bash(git remote remove:*)", + "Bash(git remote rm:*)", + "Bash(git reset --hard:*)", + "Bash(git clean -f:*)", + "Bash(git clean -d:*)", + "Bash(git clean -x:*)", + "Bash(git push --force:*)", + "Bash(git push -f:*)", + "Bash(git push --force-with-lease:*)", + "Bash(git checkout --:*)", + "PowerShell(Remove-Item:*)", + "PowerShell(rm:*)", + "PowerShell(del:*)", + "PowerShell(rmdir:*)", + "PowerShell(Clear-Content:*)" + ] + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 179154b..9310b46 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,24 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +## Destructive operations — NEVER delete (hard rule) + +**Claude must never EXECUTE a destructive or irreversible command. Always ask, and hand the user the exact command(s) to run themselves.** + +This covers (non-exhaustively): +- Deleting files/directories: `rm`, `rm -rf`, `rmdir`, `del`, `Remove-Item`. +- Deleting branches: `git branch -d` / `-D`, `git push --delete`, `git push :branch`. +- Deleting tags/remotes: `git tag -d`, `git remote remove` / `rm`. +- Discarding work: `git reset --hard`, `git checkout -- `, `git clean -f`. +- Force-pushing: `git push -f` / `--force` / `--force-with-lease`. +- Dropping data: `DROP`, `TRUNCATE`, destructive migrations. + +Instead: print the command(s) in a fenced block with a one-line note on what each does and what it affects, and let the **user run them**. Never run them yourself, even when the desired outcome is clear — `rm` and `-d` are **prompted, never executed**. + +Leave regular branches alone (`main`, the active sprint branch) unless the user explicitly names them. Before calling any branch "stale", prove containment (`git branch --merged`, 0 unique commits) and report that evidence — do not act on it. + +These are also enforced as `permissions.deny` rules in `.claude/settings.json` (defense-in-depth), but this behavioral rule is authoritative and covers cases the patterns can't. + ## Commands ```bash -- 2.52.0