Skip to content
Back to skills

Skill Safe Commands

ASecurity

Centralized list of commands safe for auto-execution without user approval. Single source of truth.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 9, 2026
ai-agentspythonrustgoshellnodetestinggit

Works with

  • claude code
  • cursor
  • terminal

Security analysis

A100/100

Scanned October 9, 2026

npx -y skills add MatrixFounder/Agentic-development --skill skill-safe-commands --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Skill Safe Commands?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Skill Safe Commands
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/matrixfounder-skill-safe-commands/badge)](https://www.skillsdirectory.com/skills/matrixfounder-skill-safe-commands)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: skill-safe-commands
description: "Centralized list of commands safe for auto-execution without user approval. Single source of truth."
tier: 0
version: 1.5
---
# Safe Commands Protocol

This skill defines **all commands that are SAFE TO AUTO-RUN** without user approval.

> [!IMPORTANT]
> **This is the single source of truth for Safe Commands.**
> All other skills and prompts should reference this skill instead of duplicating the list.

## Auto-Run Command Categories

| Category | Commands | Reason |
|----------|----------|--------|
| **Read-only** | `ls`, `cat`, `head`, `tail`, `grep`, `rg`, `fd`, `wc`, `echo` | Do not modify state; `rg` and `fd` without the options that run a program |
| **Symlink-aware** | `ls -L`, `rg --follow` / `rg -L`, `fd -L` | Read-only, but follow symlinks into framework dirs (`.agent/`, `.agents/`, `.cursor/skills/`, `System/`, `.agentic-development/`). Plain `find`/`ls`/`rg` do **not** descend into symlinked directories |
| **File info** | `stat`, `du`, `df` | Informational only |
| **Git read** | `git status`; `git log`, `git diff`, `git show` without `--output`; `git branch`, `git remote`, `git tag` with no argument | Read-only git operations |
| **Archiving** | `python3 .agent/tools/archive_move.py` | Moves `docs/TASK.md` and `docs/PLAN.md` into `docs/tasks/` and `docs/plans/`; refuses every other operand (TASK 112) |
| **Directory** | `mkdir -p docs/tasks`, `mkdir -p docs/plans`, `mkdir -p docs/architectures` | Idempotent; three fixed directories |
| **Tool calls** | `generate_task_archive_filename`, `list_directory`, `read_file` | Native tools |
| **Framework scripts** | `python3 .agent/skills/skill-session-state/scripts/update_state.py`, `python3 .agent/tools/task_id_tool.py`, `python3 .agent/tools/rebase_links.py`, `python3 .agent/skills/skill-creator/scripts/validate_skill.py`, `python3 .agent/skills/skill-creator/scripts/init_skill.py`, `python3 .agent/skills/artifact-formalizer/scripts/scan_register.py`, `python3 .agent/skills/artifact-formalizer/scripts/selftest_scan.py`, `python3 .agent/skills/artifact-formalizer/evals/selftest_evals.py`, `python3 .agent/skills/artifact-formalizer/evals/grade_run.py`, `python3 System/scripts/doctor.py` | Framework automation; `rebase_links.py` writes markdown in the working directory by real path, `init_skill.py` by path |
| **Testing** | `python -m pytest`, `python3 -m pytest`, `npm test`, `cargo test`, with no argument | Their options can run a program, delete a directory or overwrite a file (TASK 111 D14) |

> [!IMPORTANT]
> **`artifact-formalizer/evals/run_authoring.py` is deliberately NOT on this list.** The other two
> eval scripts read files and spawn nothing. `run_authoring.py` spawns `claude -p` once per arm per
> case and spends tokens, so it requires approval on every invocation.

## Pattern Matching Rules

Commands are safe if they match these patterns:

- **From the project root only.** The framework-script patterns name paths relative to the project
  root. Run from another directory, the same text names another file, such as a nested checkout's
  script of the same path.
- **In the project's own work tree only.** The test-runner patterns run the code of the directory
  they start in: a nested checkout's `conftest.py` or `package.json` scripts.
- **Enforcement.** No hook enforces these two conditions yet: an allow list cannot see the
  working directory, so the agent runs these commands from the project root. A PreToolUse hook to
  make a relative-path command ask inside a nested checkout is deferred to WI-34.
- **`find` is not on this list.** `-exec`, `-execdir`, `-ok` and `-delete` run a command or
  delete files, and a pattern cannot tell them apart; `find` asks for approval.
- **Options that run a program.** `rg --pre` and `rg --hostname-bin` run a program, and so do
  `fd -x`, `fd -X`, `--exec` and `--exec-batch`. The `rg` and `fd` patterns exclude these options
  wherever they stand. ripgrep 14.1.1 rejects an abbreviated long option; the `fd` pattern excludes
  every long option that starts with `--exe`, and `x` or `X` anywhere in a short-option cluster,
  digits included (`fd -1x`).
- **Archiving runs through a script.** `archive_move.py` accepts `docs/TASK.md` with
  `docs/tasks/task-<ID>-<slug>.md` and `docs/PLAN.md` with `docs/plans/plan-<ID>-<slug>.md`, and
  refuses every other operand, a link and an existing file. The pattern admits any operand
  because the script is the guard (TASK 112 R1).
- **No `file`.** `file` is off this list: `-C`, and its abbreviation `--co`, write a compiled
  magic file (TASK 112 D2).
- **An allow rule names its command whole.** `X *` matches `X` with arguments; `X*` also matches
  every command whose name starts with `X`, such as `git difftool` for `git diff*`. Each pattern
  ends at its command or its script's name for the same reason.
- **Read forms only.** `--output` makes `git log`, `git diff` and `git show` write a file. With an
  argument, `git branch`, `git tag` and `git remote` create or delete a ref or change a remote.
  `tree -o` writes a file, so `tree` is off this list. Claude Code's built-in check approves the
  read forms of `git` with no rule, and the committed settings name only the bare forms of these
  commands (TASK 111 D13).
- **Test runners with no argument.** An option of `pytest`, `npm test`, `jest` or `cargo test` can
  run a program, delete a directory or overwrite a file. The patterns match the bare commands
  only. `npx jest` is off this list: it downloads jest when the project has none (TASK 111 D14).
- **Each simple command, after quote removal.** A pattern applies to each simple command of a
  compound command, after the shell removes its quotes. A simple command with an output
  redirection to a file other than `/dev/null`, a command substitution or a process substitution
  is not safe. Neither is a command with a line continuation, `$'…'` or `$"…"` quoting, a
  parameter or brace expansion, or, for `rg`, `fd` and `git`, an unquoted glob: the shell can turn
  each into an option the patterns never see. Neither is a command the agent cannot reduce that
  way.

```
# Read-only filesystem
^(ls|cat|head|tail|grep|wc|stat|du|df|echo)(?:\s|$)

# Symlink-aware listing — framework dirs (.agent/, .agents/, System/, .agentic-development/) may be symlinks
^ls\s+-[a-zA-Z]*L

# rg and fd, except the options that run a program; -L and --follow follow symlinks
^rg(?![\s\S]*\s--(?:pre|hostname-bin)(?:[=\s]|$))(?:\s|$)
^fd(?![\s\S]*\s(?:-[^-\s]*[xX]|--exe))(?:\s|$)

# Git read operations (the boundary keeps `git difftool -x <program>` out; `--output` writes a file)
^git\s+(status|log|diff|show)(?![\s\S]*\s--output)(\s|$)
^git\s+(branch|remote|tag)$

# Archiving: the script refuses every operand but the two archive pairs
^python3\s+\.agent/tools/archive_move\.py(\s|$)

# Directory creation (three fixed directories)
^mkdir\s+-p\s+docs/(tasks|plans|architectures)$

# Python testing (bare forms only)
^(python|python3)\s+-m\s+pytest$

# Node and Rust testing (bare forms only)
^npm\s+test$
^cargo\s+test$

# Framework scripts (each pattern ends at the script's name)
^python3\s+\.agent/skills/skill-session-state/scripts/update_state\.py(\s|$)
^python3\s+\.agent/tools/task_id_tool\.py(\s|$)
^python3\s+\.agent/tools/rebase_links\.py(\s|$)
^python3\s+\.agent/skills/skill-creator/scripts/(validate_skill|init_skill)\.py(\s|$)
^python3\s+\.agent/skills/artifact-formalizer/scripts/(scan_register|selftest_scan)\.py(\s|$)
^python3\s+\.agent/skills/artifact-formalizer/evals/(selftest_evals|grade_run)\.py(\s|$)
^python3\s+System/scripts/doctor\.py(\s|$)
```

## Implementation Guidelines

### For Agents (Runtime Behavior)
When calling `run_command` in **ANY** environment:
1. Check whether the command matches a pattern above. The table names the same commands; it
   approves no command that no pattern matches.
2. If match found → Set `SafeToAutoRun: true`.
3. If no match → Set `SafeToAutoRun: false` (require approval).

> [!IMPORTANT]
> **Symlink-following is the default for framework paths.** When listing or
> searching `.agent/`, `.agents/`, `.cursor/skills/`, `System/`, or
> `.agentic-development/`, prefer the symlink-aware variants (`ls -L`,
> `rg --follow`, `fd -L`) — a plain `ls`/`rg`/`fd` silently skips symlinked
> directories. If a read-only probe returns **nothing** under a known
> framework directory, retry it **once** with symlink-following enabled before
> treating the path as empty or missing.

### For Users (Configuration)
> **Note for Agents:** Do NOT create configuration files (like `.cursorrules` or `AGENTS.md`) automatically. These are user-managed files.

**Cursor Users:**
- Add the patterns above to your `.cursorrules` or `AGENTS.md` file to enable auto-approval.

**Antigravity Users:**
- Add the command list below to "Allow List Terminal Commands" setting in IDE options:
  `ls,cat,head,tail,grep,wc,stat,du,df,git status,python3 .agent/tools/archive_move.py`
- Antigravity matches an entry as an exact word or token prefix, so `ls` does not admit `lsof`
  (antigravity.google/docs/permissions, read 2026-10-06). A chain or a pipeline of listed
  commands still matches, and so does a simple file redirect, which writes. A command or process
  substitution turns prefix matching off for the whole line.
- An entry cannot exclude an option, so the list names only commands with no option that writes
  or runs a program. `rg`, `fd`, `mkdir` and the test runners ask; from `git`, only `git status`
  is listed. The agent's `SafeToAutoRun` still rejects a redirect (Troubleshooting item 1).
  `python3 .agent/tools/archive_move.py` admits any operand as a prefix entry; the script refuses
  every operand but the two archive pairs. Its path is relative, like every framework-script
  pattern, so the agent runs it from the project root (WI-34).

### Troubleshooting
If the IDE still requests approval for commands listed here:
1. **Agent Behavior**: Ensure the Agent is actually setting `SafeToAutoRun: true` in the tool call. If the Agent sets it to `false`, the IDE *must* ask for approval regardless of the Allow List.
2. **Prefix Matching**: Antigravity matches a word or token prefix. If `git status` runs unasked
   but a longer command asks, check whether the command carries a construct that turns prefix
   matching off, such as a command substitution. Do not shorten an entry to a bare command such
   as `mv` or `git`: it then admits every form of that command.

## Integration

### How Other Skills Should Reference This

Instead of duplicating Safe Commands lists, use:

```markdown
## Safe Commands
See `skill-safe-commands` for the authoritative list of commands safe for auto-execution.
```

### Required by
- `skill-archive-task` — archiving commands
- `artifact-management` — file operations
- `developer-guidelines` — test commands
- All agent prompts — general command execution

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…