$ shellfirm
How It Works

Blast Radius

Runtime impact analysis that shows concrete damage before you confirm

Severity tells you how dangerous a command is. Blast radius tells you how wide the damage spreads. shellfirm computes real metrics at runtime so you see concrete impact numbers before confirming a risky command.

What blast radius computes

Depending on the check group, shellfirm runs quick system queries to measure the actual impact:

GroupWhat is measuredExample output
fsFile count + total size"Deletes ~347 files (12.4 MB) in ./src"
fs-strictFile count + total size"Deletes directory with ~89 files (2.1 MB)"
gitModified files, tracked files, commit count"Resets 5 modified files" or "Force-pushes 12 commits to origin/main"
git-strictStaged/unstaged file count"Stages 23 files"
dockerContainer, image, and volume counts"Prunes up to 12 images, 3 containers, 2 volumes"
kubernetesResource count in namespace"Deletes namespace 'staging' with 47 resources"

Blast scopes

Each blast radius computation is assigned a scope that indicates the breadth of potential damage:

ScopeMeaningExamples
ResourceSingle file, branch, or containergit branch -D feature-x, chmod 644 file.txt
ProjectRepository, database, or applicationgit reset --hard, git push --force, rm -rf ./src
NamespaceKubernetes namespace or resource groupkubectl delete ns staging
MachineEntire local hostrm -rf /, docker system prune -a

Scopes are ordered: Resource < Project < Namespace < Machine. When multiple checks match, the highest scope is reported.

How it looks in practice

When you type a command with blast radius support, the challenge prompt includes an extra line:

Filesystem Blast Radius
$ rm -rf ./node_modules
============ RISKY COMMAND DETECTED ============
Severity: CRITICAL
You are going to delete everything in the path.
Blast radius: Deletes ~5,629 files (247 MB) in ./node_modules
Alternative: trash <path>
(Renames instead of deleting, allowing easy recovery.)
? Solve the challenge:: 3 + 8 = ? Esc to cancel ›

For git operations:

Git Blast Radius
$ git push --force origin main
============ RISKY COMMAND DETECTED ============
Severity: HIGH
This command will force push and overwrite remote history.
Blast radius: Force-pushes 7 commits to origin/main
Alternative: git push --force-with-lease
(Only overwrites if no one else has pushed, preventing accidental data loss.)
? Type Enter to continue Esc to cancel ›

For Docker:

Docker Blast Radius
$ docker system prune -a
============ RISKY COMMAND DETECTED ============
Severity: HIGH
This will remove all unused Docker data.
Blast radius: Prunes up to 15 images, 4 containers, 3 volumes
Alternative: docker system prune
(Prunes without the -a flag, keeping images that are tagged.)
? Solve the challenge:: 6 + 2 = ? Esc to cancel ›

Supported checks

Blast radius is computed for these specific check IDs:

Filesystem:

  • fs:recursively_delete -- counts files and total size at the target path
  • fs:move_to_dev_null -- reports the size of the file being destroyed
  • fs:flush_file_content -- reports the size of the file being flushed
  • fs:recursively_chmod -- counts files affected by recursive permission change
  • fs:delete_find_files -- counts files under the find search path
  • fs-strict:any_deletion -- counts files/size for the deletion target
  • fs-strict:folder_deletion -- counts files/size for the directory
  • fs-strict:change_permissions -- counts files in the target directory

Git:

  • git:reset -- counts unstaged + staged modified files
  • git:delete_all -- counts tracked files
  • git:clean_force -- counts untracked files/directories
  • git:force_push -- counts commits ahead of remote
  • git:force_delete_branch -- names the branch being deleted
  • git:force_checkout -- counts files with uncommitted changes
  • git:filter_branch -- counts total commits being rewritten
  • git-strict:add_all -- counts files to be staged
  • git-strict:commit_all -- counts files to be committed

Docker:

  • docker:system_prune_all -- counts images, containers, and volumes
  • docker:force_remove_all_containers -- counts running containers
  • docker:volume_prune -- counts unused volumes
  • docker:stop_all_containers -- counts running containers

Kubernetes:

  • kubernetes:delete_namespace -- counts resources in the namespace

3-second timeout with graceful degradation

Each blast radius computation runs with a 3-second timeout. This is deliberate:

  • The user is already stopped at an interactive challenge prompt, so a brief pause is acceptable
  • Operations like find on large directories (e.g., node_modules) need a moment
  • Most computations (git, du, docker) complete in under 100ms

If any computation times out, fails, or produces unexpected output, blast radius is silently skipped. The challenge prompt is shown without the extra line. Blast radius never interferes with the core safety flow.

Configuration

Enable or disable blast radius globally in ~/.config/shellfirm/settings.yaml:

blast_radius: true    # enabled by default

Or open the interactive config editor:

shellfirm config edit

Or in ~/.config/shellfirm/settings.yaml:

blast_radius: true    # default

Blast radius in audit logs

When blast radius is computed, the scope and description are included in the audit log entry:

{
  "event_id": "abc123",
  "command": "rm -rf ./src",
  "matched_ids": ["fs:recursively_delete"],
  "severity": "Critical",
  "outcome": "Denied",
  "blast_radius_scope": "PROJECT",
  "blast_radius_detail": "Deletes ~347 files (12.4 MB) in ./src"
}

This makes audit logs more useful for incident investigation -- you can see not just what was attempted, but what the actual impact would have been.

Blast radius in MCP responses

When AI agents query shellfirm via MCP, blast radius data is included in the risk assessment:

{
  "matched_rules": [
    {
      "id": "fs:recursively_delete",
      "severity": "Critical",
      "blast_radius_scope": "PROJECT",
      "blast_radius_detail": "Deletes ~347 files (12.4 MB) in ./src"
    }
  ],
  "blast_radius_scope": "PROJECT",
  "blast_radius_detail": "Deletes ~347 files (12.4 MB) in ./src"
}

This gives agents concrete data to include in their decision-making and user-facing explanations.