SIGNAL·NODUS
the gate · free and open source

A door the agent cannot open by itself.

Coding agents have dropped production databases with a flag whose name says it destroys data. The gate stops that command at the shell, shows it to a person, and keeps a record of who let it through.

Read the sourceInstall in two minutes

One file, no dependencies, no network calls, no model. MIT licence.

What it does

It is a Claude Code hook on the Bash tool. Before a command runs, the gate matches it against a fixed list. A match is never run on the agent's own say: Claude Code asks you, with the reason, or refuses outright when you set AGENT_GATE_MODE=deny. Everything else passes untouched to the normal permission flow.

Each match is written to ~/.agent-gate/record.jsonl: the time, the session, the directory, the rule, the command, the decision, and, after the fact, whether it ran. That file answers the question a post-mortem starts with: what was attempted, and who allowed it.

What it gates

RuleStops for a person
prisma-data-lossprisma db push --accept-data-loss, prisma migrate reset
drizzle-forcedrizzle-kit push --force
db-resetsupabase db reset, rails db:drop, dropdb
sql-destroyDROP TABLE, TRUNCATE, a DELETE FROM with no WHERE
terraform-destroyterraform destroy, pulumi destroy
kubectl-deletedeleting a namespace, a volume claim, or --all; helm uninstall
cloud-deleteaws s3 rm --recursive, az group delete, gcloud … delete
docker-prunedocker system prune, docker compose down -v
git-forcegit push --force (--force-with-lease passes)
git-discardgit reset --hard, git clean -f
disk-writedd of=/dev/…, mkfs
rm-outsidea recursive rm that leaves the working directory, takes .git, or names a variable the gate cannot resolve

The three commands behind the public reports that prompted it are in the test suite: a forced drizzle-kit push, a Prisma push with --accept-data-loss, and a terraform destroy.

Install

mkdir -p ~/.agent-gate
curl -fsSL https://raw.githubusercontent.com/hgenix20/signalnodus/main/gate/agent-gate.mjs -o ~/.agent-gate/agent-gate.mjs

Read the file before you trust it; it is about 160 lines. Then add the hook to ~/.claude/settings.json (or a project's .claude/settings.json). Node 18 or later.

{
  "hooks": {
    "PreToolUse":  [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "node ~/.agent-gate/agent-gate.mjs" }] }],
    "PostToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "node ~/.agent-gate/agent-gate.mjs" }] }]
  }
}

What it is not

It is a pattern list over the command text, not a sandbox. An agent that writes the same operation into a script and runs the script is not caught, and neither is a destructive call made through an SDK. Scoped credentials and tested backups remain the real defence. The gate covers the moment an agent reaches for the flag.

Running agents in a team?

We are looking for three teams to shape what comes next: one policy for every developer's agent, the record collected in one place, approvals that reach the right person, and hard spending caps per run and per day. If an agent has cost you data or money, a few lines about what happened is the most useful thing you can send. hgenix@agentmail.to