Agent skill

Guarding Destructive Operations

by kajisho5 in kajisho5/ffmpeg-skill

Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of…

MITAuto-check passedTesting & QA

Install Guarding Destructive Operations

skills CLI
$ npx skills add kajisho5/ffmpeg-skill --skill guarding-destructive-operations -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install kajisho5/ffmpeg-skill guarding-destructive-operations --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/kajisho5/ffmpeg-skill.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/destructive-operations .claude/skills/guarding-destructive-operations && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
guarding-destructive-operations
GitHub stars
1.9k
Token cost
~2.6k tokens
SKILL.md length
1,205 words
Files
1
Skills in repo
14
Repo updated
First seen
Licence
MIT

At a glance

Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of…

  • Reviewing a --rebuild/--reset/--purge command
  • SKILL.md covers Refuse; don't warn, and don't…, Put the guard ahead of the…, Classify structurally, not by… and Name validation and resolved…, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • A history rewrite

What it does

Guarding Destructive Operations is an agent skill from kajisho5/ffmpeg-skill. Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of the first mutation, structural classification rather than string-prefix matching, name validation plus resolved-path containment as two independent checks, why a guard on the destructive path is invisible to the dry-run, and mutation-testing each half separately. Use when writing or reviewing a --rebuild/--reset/--purge…

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Test coverage. The licence is MIT.

When your agent uses it

  • Reviewing a --rebuild/--reset/--purge command
  • A history rewrite
  • An rm -rf-shaped step
  • Any code that turns an argument into a file path

Example prompts

  • “/guarding-destructive-operations”

Requirements

  • Python 3

What it can do on your machine

Read from SKILL.md and the folder at commit 1f7e7e3. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are go and python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Guarding Destructive Operations loads about 2.6k tokens when it runs. Until then it costs about 169 tokens; SKILL.md has 1,205 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~169
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from kajisho5/ffmpeg-skill at commit 1f7e7e3, republished under its MIT licence (© kajisho5). 1,205 words, ~2,628 tokens.

Download SKILL.mdSave it as .claude/skills/guarding-destructive-operations/SKILL.md (or your agent's skills folder).
name
guarding-destructive-operations
description
Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of the first mutation, structural classification rather than string-prefix matching, name validation plus resolved-path containment as two independent checks, why a guard on the destructive path is invisible to the dry-run, and mutation-testing each half separately. Use when writing or reviewing a `--rebuild`/`--reset`/`--purge` command, a bulk delete, a history rewrite, an `rm -rf`-shaped step, or any code that turns an argument into a file path.

Guarding Destructive Operations

Some operations have no undo: an orphan-branch rewrite, a recursive delete of every tracked file, an overwrite of a stored artifact, a DROP/purge path. The implementation is usually short and usually correct for the setup its author had in mind. The bug is never the deletion itself — it is that nothing checked whether the target was the thing the author imagined.

Two shapes recur, and they take the same fix:

  • Blast radius. The operation is correct only in a dedicated, single-purpose target and is catastrophic in a mixed one.
  • Boundary escape. A caller-supplied name is joined onto a base directory and lands outside it.

Refuse; don't warn, and don't add an override

A destructive operation that discovers its precondition is violated should return an error and change nothing. A warning is read by nobody, and a --force escape hatch turns the guard into documentation.

go
// A rebuild that recreates history does `checkout --orphan` then
// `rm -rf --ignore-unmatch .`, keeping only the state files it rewrites.
// That is correct in a dedicated mirror repository whose ONLY tracked content
// is `.state/`. Run it where source code also lives and the new branch loses
// the source code.
func (e *Engine) rebuild() error {
    if err := e.ensureDedicatedRepo(); err != nil {
        return err   // nothing mutated yet
    }
    ...
}

The honest justification for having no override flag: there is no situation where the operator wants this command to delete unrelated tracked files. If a real one appears later, that is a separate, differently-named command — not a boolean on this one.

Put the guard ahead of the first mutation

"Refuses" is only true if the refusal happens before anything has changed. Walk the function and find the first statement with an effect — it is often not the obvious deletion. In-memory state clearing, a branch checkout, and a read-then-rewrite of the very files you are preserving all count.

go
// Order that makes the refusal safe:
//   1. reject detached HEAD / ambiguous state
//   2. ensureDedicatedRepo()          <-- the new guard, nothing mutated yet
//   3. read the state files to preserve
//   4. CheckoutOrphan()
//   5. RemoveAllTrackedFiles()
//   6. ClearAllProgressCounts()

Steps 3-6 are all mutations of something (3 is not, but it is where the "what to preserve" snapshot is taken, and a guard after it has already committed you to a shape). Land the guard at 2 and a rejected run leaves the working tree byte-identical.

Also refuse ambiguous state before rewriting it. A history rewrite that assumes a named branch should reject detached HEAD up front rather than silently recreating the wrong ref.

Classify structurally, not by string prefix

The guard needs to answer "is every tracked path inside the directory this command owns?". A HasPrefix/startswith on the bare directory name is the wrong answer and looks right in every test you would think to write.

go
// Bad — admits `.state-backup/notes.md` and `.stateful.txt`, so a repository
// full of unrelated content passes the guard and gets deleted.
func owned(path string) bool {
    return strings.HasPrefix(path, ".state")
}

// Good — the directory itself, or something genuinely under it.
func owned(path string) bool {
    return path == ".state" || strings.HasPrefix(path, ".state/")
}

The same distinction in Python is Path(p) == base or base in Path(p).parents, not p.startswith(str(base)). Any time a check compares paths as strings, ask what a sibling with a longer name does to it.

Name validation and resolved containment are two checks, not one

When a public argument selects a file — a baseline name, a template id, a report slug — do both, in this order:

python
NAME_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]*$")

def _validate_name(name: str) -> str:
    if ".." in name or not NAME_RE.match(name):
        raise ValueError(f"invalid name: {name!r}")
    return name

def _resolve(name: str, base: Path) -> Path:
    candidate = (base / f"{_validate_name(name)}.json").resolve()
    if not candidate.is_relative_to(base.resolve()):
        raise ValueError(f"name escapes {base}: {name!r}")
    return candidate

The containment half is not redundant with the regex. The regex stops .. segments and absolute paths; only the resolve() + containment check stops a symlink placed inside the directory that points out of it — a name matching ^[A-Za-z0-9] all the way through can still resolve anywhere. Route every entry point through both: the loader, the saver, and any path-building helper a public method still calls directly. A single unrouted helper reinstates the whole hole.

Without this, an implicit suffix (name + ".json") plus an absolute-path argument reads any file on disk whose name happens to end in that suffix.

A guard on the destructive path is invisible to the preview

If the real run reaches the guard but --dry-run short-circuits earlier, the preview cheerfully describes an operation the real run will refuse. That is a defensible design — the destructive path is the one that must be safe — but be explicit about it:

  • The preview will show a full rebuild in a repository where the rebuild is forbidden. Only the real invocation errors.
  • Anything meant to warn the operator earlier has to live in the preview stage or the CLI argument-validation layer, duplicated deliberately, not moved.

Say which one you chose in the PR description; a reviewer cannot tell from the diff whether the dry-run gap is intentional.

Know what the caller does with your refusal

Tightening validation only helps if the new error reaches somebody. A broad except Exception two frames up will turn a hard refusal into an ordinary result shape:

python
try:
    features = self._load(baseline)
except Exception as e:                       # already there, catches your ValueError
    return {"error": f"Analysis failed: {e}", "features": {}, "flags": {...}}

This is often fine — an API boundary that never raises is a real contract, and the refusal surfaces as a normal error-shaped response rather than a protocol error. But check it deliberately: if that shape is what your caller sees, the integration test asserts on result["error"], not on pytest.raises.

Show full SKILL.md (480 more words)Show less

Testing

  • Mutate each half separately. Neuter only the regex and confirm a .. fixture fails; neuter only the containment check and confirm a symlink fixture fails. One combined test passes with either half deleted and proves neither.
  • Write the sibling-name fixture explicitly. A test whose repository tracks .state/data.json passes against HasPrefix(path, ".state") too. The test that separates the implementations tracks .state-backup/old.json and asserts the operation is refused.
  • Assert nothing was mutated on refusal, not just that an error came back: the branch is unchanged, the tracked file list is unchanged, the in-memory progress counters are unchanged. That is the actual claim.
  • Existing fixtures become the rejected shape. Older tests for the destructive path were often built loosely — a repository tracking app.txt alongside the state directory, because nothing cared. After the guard, such a test no longer reaches the code it was written to cover; it now exercises the refusal. Tighten those fixtures to the allowed shape and add the refusal case as a new test, or you silently lose coverage of the destructive path.
  • Reproduce the failure with the narrowest hook. When you need one specific operation to fail in order to test the recovery path, target it precisely — a blanket hook that rejects every operation of that kind aborts the run earlier than the path you were trying to reach, and the test proves something else.

Checklist

  • Every irreversible operation states its precondition in code, not in a doc
  • Violation returns an error; no --force, no warn-and-continue
  • The guard runs before the first statement with an effect
  • Ambiguous state (detached HEAD, missing target, multiple candidates) rejected up front
  • Path/ownership classification is structural, never a bare string prefix
  • Caller-supplied names are validated and resolved-path contained
  • Every entry point routes through both checks, including internal helpers
  • The dry-run/preview gap is intentional and stated
  • Tests mutate each half of the guard independently
  • A sibling-name (x-backup/) and a symlink fixture both exist
  • Refusal tests assert the target is unchanged, not just that an error was raised

Note for this repository (ffmpeg-skill)

This repo's actual exposure is much narrower than the examples above — there is no --rebuild/--purge-shaped command, no history rewriting, and "Keep originals" is already a stated design principle (README.md design principle #9: no tool overwrites its input; a test hashes every input after every run, see tests/test_all.py/tests/test_contract.py's input-hash checks). The closest analogue is -o/output-path handling: every tool takes a caller-supplied output path and ffmpeg_base() always passes -y (overwrite without prompting) — there is no confirmation step before an existing file at that path is silently replaced. Since this is a local CLI a human or agent invokes directly (not a server resolving untrusted network input against a base directory), the "boundary escape" half of this skill is low-stakes here; the "refuse before the first mutation" and "existing input-hash tests still prove nothing was touched" halves are the parts that actually apply.

Source: wdm0006/python-skills (MIT).

© kajisho5, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/destructive-operations of kajisho5/ffmpeg-skill.

Open the folder on GitHubat commit 1f7e7e3

Compare with similar skills

Guarding Destructive Operations next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Guarding Destructive Operations compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Guarding Destructive Operations this skillkajisho5/ffmpeg-skill1.9k—~2.6kAutomated safety check: PassMIT
Requirementsrizsotto/Bear6.5k—~2kAutomated safety check: PassGPL-3.0
Crap Analysisardalis/RiverBooks1352 repos~3.4kAutomated safety check: PassNone
Bmad Testarch Automatechenjackle45/SayIt1152 repos~867Automated safety check: PassMIT
Code Coverages3s-project/s3s311—~789Automated safety check: PassApache-2.0
Project Statusbactopia/bactopia522—~787Automated safety check: PassMIT

Similar skills

  • Requirements

    rizsotto/Bear

    Write, modify, or review a requirement file under docs/requirements -- pick the single owning file, keep the text contract-only, name IDs so they need no explanation, and verify cross-references and…

    6.5k GitHub stars~2k tokensUpdated 2 days ago
    Testing & QAAuto-check passed
  • Crap Analysis

    ardalis/RiverBooks

    Analyze code coverage and CRAP (Change Risk Anti-Patterns) scores to identify high-risk code.

    135 GitHub starsUsed in 2 repos~3.4k tokens
    Testing & QAAuto-check passed
  • Bmad Testarch Automate

    chenjackle45/SayIt

    Expand test automation coverage for codebase. An agent skill from chenjackle45/SayIt.

    115 GitHub starsUsed in 2 repos~867 tokens
    Testing & QAAuto-check passed
  • Code Coverage

    s3s-project/s3s

    Measure and grow the line coverage of the s3s crate. An agent skill from s3s-project/s3s.

    311 GitHub stars~789 tokensUpdated 2 days ago
    Testing & QAAuto-check passed
  • Project Status

    bactopia/bactopia

    Show a live snapshot of the Bactopia project state — component counts, GroovyDoc coverage, nf-test coverage, and structural issues.

    522 GitHub stars~787 tokensUpdated 2 mo ago
    Testing & QAAuto-check passed
  • Check Coverage

    ldayton/Dippy

    Ensure comprehensive test coverage for a CLI handler. An agent skill from ldayton/Dippy.

    243 GitHub stars~403 tokensUpdated 4 mo ago
    Testing & QAAuto-check passed

More from kajisho5/ffmpeg-skill

All 14 skills in this repo
  • Ffmpeg Skill

    kajisho5/ffmpeg-skill

    Edit video and audio with local FFmpeg from natural-language requests: cut, trim, join, resize/reframe (9:16, 1:1), speed change, captions and subtitles (SRT/ASS, animated, karaoke), logos and text…

    1.9k GitHub stars~7.4k tokensUpdated today
    Auto-check passed
  • CI Pipeline Synthesizer

    kajisho5/ffmpeg-skill

    Generate GitHub Actions CI/CD pipeline configurations for automated building and testing of library and package projects.

    1.9k GitHub starsUsed in 1 repo~1.1k tokens
    Auto-check passed
  • Reviewing Ffmpeg Skill Changes

    kajisho5/ffmpeg-skill

    Review a change to the ffmpeg-skill repository for the failures its own contract makes possible — a claim in a result document that is true at one layer and false at the layer a caller reads, a new…

    1.9k GitHub stars~2.3k tokensUpdated today
    Auto-check passed
  • Building Python MCP Servers

    kajisho5/ffmpeg-skill

    Builds robust Python MCP (Model Context Protocol) servers with FastMCP — tool design, error contracts, event-loop-safe blocking work, subprocess/CLI wrapping, single-file vs packaged distribution…

    1.9k GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • Concurrent Branches

    kajisho5/ffmpeg-skill

    Resolve conflicts and merges when several branches are open against one repo at the same time — the hotspot files every change must touch (registry manifests, a single version field, shared tool…

    1.9k GitHub stars~2.8k tokensUpdated today
    Auto-check passed
  • Keeping Git Repos Clean

    kajisho5/ffmpeg-skill

    Prevents, detects, and remediates files that should never be committed — secrets (.env, API tokens, hardcoded credentials) and dev artifacts (build output, scratch databases, editor/OS files).

    1.9k GitHub stars~2.1k tokensUpdated today
    Auto-check: notes

Categories

Questions about Guarding Destructive Operations

What does Guarding Destructive Operations do?

Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of…. Guarding Destructive Operations is an agent skill from kajisho5/ffmpeg-skill. Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of the first mutation, structural classification rather than string-prefix matching, name validation plus resolved-path containment as two independent checks, why a guard on the destructive path is invisible to the dry-run, and mutation-testing each half separately.

When should I use Guarding Destructive Operations?

Guarding Destructive Operations fits situations like: reviewing a --rebuild/--reset/--purge command; A history rewrite; an rm -rf-shaped step; any code that turns an argument into a file path.

How do I install Guarding Destructive Operations in Claude Code?

Run `npx skills add kajisho5/ffmpeg-skill --skill guarding-destructive-operations -a claude-code`. Or copy the skill folder (.claude/skills/destructive-operations in kajisho5/ffmpeg-skill) into .claude/skills/guarding-destructive-operations in your project. Claude Code loads it when a task matches its description.

How do I install Guarding Destructive Operations in Codex?

Run `npx skills add kajisho5/ffmpeg-skill --skill guarding-destructive-operations -a codex`. Or copy the skill folder (.claude/skills/destructive-operations in kajisho5/ffmpeg-skill) into .agents/skills/guarding-destructive-operations in your project. Codex loads it when a task matches its description.

Can I use Guarding Destructive Operations in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kajisho5/ffmpeg-skill --skill guarding-destructive-operations -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/guarding-destructive-operations, .gemini/skills/guarding-destructive-operations, .github/skills/guarding-destructive-operations and .opencode/skills/guarding-destructive-operations in your project.

What does Guarding Destructive Operations need to run?

SKILL.md names no scripts, command-line tools or credentials: Guarding Destructive Operations is instructions for the agent only. Our summary lists: Python 3.

Does Guarding Destructive Operations access the network?

SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.

Is Guarding Destructive Operations safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Guarding Destructive Operations use?

Guarding Destructive Operations is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Guarding Destructive Operations use?

About 2.6k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Guarding Destructive Operations?

Skills that share tags, products or a category with Guarding Destructive Operations: Requirements (rizsotto/Bear, 6.5k stars), Crap Analysis (ardalis/RiverBooks, 135 stars), Bmad Testarch Automate (chenjackle45/SayIt, 115 stars) and Code Coverage (s3s-project/s3s, 311 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Guarding Destructive Operations?

kajisho5 (a GitHub user) maintains it in kajisho5/ffmpeg-skill, which has 1,909 GitHub stars. The repository holds 14 skills in this directory. The repository was last updated on October 10, 2026.

Source: kajisho5/ffmpeg-skill on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.