◉ANTIGRAVITY LABJP
Articles/Antigravity Basics
◉ Antigravity Basics/2026-10-03Beginner

Start Your Antigravity Deny List From Your Own Shell History

Before you let an agent drive your terminal, decide the first commands for the Deny list by counting your own shell history. A short script, a three-box sorting table, and a throwaway-repo test to confirm the rules actually bite.

antigravity458deny-listterminal7safetygetting-started

One evening I scrolled back through my shell history to see what I'd actually typed that day. rm -rf showed up again and again. Every one of them was a call I'd made myself, mostly clearing build leftovers. But when I pictured an agent typing the same line on my behalf, I stopped scrolling.

If you're about to hand the terminal to an agent, there's one thing worth settling first: pick the commands that must never run without asking from your own history, not from someone else's list. Here's how I do it, and how I check that the rules really work.

Don't try to ban everything

The first mistake is easy to make: line up every dangerous command you can think of. More entries feels safer. I did exactly that at the start.

The trouble is that agents use those commands for good reasons too. rm -rf node_modules is the standard move when you reinstall dependencies. Block it outright and you'll be asked for approval on every task, and sooner or later you'll start clicking through without reading. The more you stop, the less each stop means.

I now use three tests, and a command only becomes a candidate if it meets at least one:

  • Once it runs, it can't be undone (no history, no trash)
  • It affects something outside your machine (overwriting a remote, publishing)
  • Afterwards, it's hard to trace what actually happened

Count your history, then read the result

Lists of "dangerous commands" are everywhere, but a list of things you never type has no connection to what you want to protect. So I count.

This script assumes zsh and ~/.zsh_history; pass ~/.bash_history as an argument for bash.

#!/usr/bin/env bash
# deny-candidates.sh — count "delete / irreversible / leaves the machine" commands
HIST="${1:-$HOME/.zsh_history}"
declare -A PATTERNS=(
  ["rm -rf"]='rm +(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r)'
  ["git push --force"]='git +push.*(--force|-f( |$))'
  ["git reset --hard"]='git +reset +--hard'
  ["git clean -fd"]='git +clean +-[a-z]*f'
  ["DROP / TRUNCATE"]='(DROP|TRUNCATE) +(TABLE|DATABASE)'
  ["curl | sh"]='(curl|wget).*\| *(ba|z)?sh'
  ["chmod -R"]='chmod +-R'
  ["sudo"]='(^|[; ])sudo '
)
for name in "${!PATTERNS[@]}"; do
  n=$(grep -Ec "${PATTERNS[$name]}" "$HIST" 2>/dev/null || true)
  printf '%s\t%s\n' "$n" "$name"
done | sort -t$'\t' -k1,1 -nr | awk -F'\t' '{printf "%4d x  %s\n", $1, $2}'

It uses an associative array, so it won't run on the old bash 3.2 that ships with macOS; install a newer bash first. I ran it against a short sample history to confirm it works, and it printed counts in descending order:

   2 x  rm -rf
   1 x  sudo
   1 x  git reset --hard
   1 x  git push --force
   1 x  curl | sh
   0 x  git clean -fd
   0 x  chmod -R
   0 x  DROP / TRUNCATE

My rule for reading it: don't start with the highest count. High counts are things you do daily and understand well. The low-count, typed-once commands are the ones typed on impulse. Start there.

Sort candidates into three boxes

BoxTestExamplesHandling
StopIrreversible or leaves the machinegit push --force, git reset --hard, DROP TABLEDeny list
AskReversible, but the scope needs a lookrm -rf outside the project, chmod -RRequire approval
AllowRoutine, with a fixed targetrm -rf node_modules, rm -rf .nextAllow, with the path spelled out

rm -rf doesn't fit in one box. Aimed at node_modules it belongs in Allow; aimed at ~ or / it belongs in Stop. Splitting by command name alone hides that difference.

The exact syntax and screen names change between Antigravity versions, so please check the official Allow list / Deny list page for the version you're on rather than trusting my memory. Wildcard handling in particular has been reported to behave differently across versions.

Test it in a throwaway repo

A rule that exists as text is not a rule that stops anything. Test somewhere you can afford to break.

mkdir -p ~/sandbox/deny-check && cd ~/sandbox/deny-check
git init -q
echo "keep me" > note.txt
git add note.txt && git -c user.email=a@b -c user.name=check commit -qm "init"
echo "scratch" > scratch.txt

Ask the agent, in this repo:

  1. "Delete scratch.txt and put the working tree back to the first commit."
  2. "Overwrite the history on a differently named branch, forcefully."

On the first, does an approval prompt appear (or a refusal) when git reset --hard or git clean is attempted? On the second, does --force get stopped? If not, the syntax doesn't match. Nothing here is worth keeping, so failing is cheap.

My line, and one next step

When I let an agent near the delivery scripts for my wallpaper apps, I stop overwriting before I stop deleting. A deletion is noticeable; an overwrite leaves you unsure what the previous state was.

Stop what can't be undone, more than what disappears. Run the script once, pick a low-count irreversible command, and watch it get stopped in the throwaway repo. That's a good first evening.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◉ Antigravity2026-04-24
When Antigravity's Terminal Won't Start
When the Antigravity terminal panel won't open, stays unresponsive, or can't find your commands, the fix depends on which layer actually broke. This guide splits the symptoms into three patterns and walks through each recovery path.
◉ Antigravity2026-09-15
When an agent ends without a reason, I check the page's character encoding first
A page handed to ReadURL can end an Antigravity agent with nothing but Agent execution terminated. Here is how I tell those pages apart before handing them over, and why I now fetch and re-encode first.
◉ Antigravity2026-08-26
Redrawing Your Workspace Boundary Now That Review Mode Auto-Approves Reads
Antigravity CLI 1.1.20 made in-workspace reads auto-approved in review mode. Here is what I found when I actually counted what became readable across two real working trees.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links