Skip to content

Your first guardrail

By the end of this you’ll have a working guardrail that refuses a real agent action, and you’ll have watched it fire — because a rule that loads but never refuses is worse than no rule at all.

You need the plugin — see Install. In short, in Claude Code:

Terminal window
/plugin marketplace add sloprail/sloprail
/plugin install sloprail@sloprail-marketplace

That registers the hooks, and the next session installs the sr* binaries they call. From now on, every tool call and every turn-end runs through sloprail.

A guardrail is a folder. The folder name is the rule name. Create one:

Terminal window
mkdir -p .sloprail/file-guard/no-todo-in-committed-code

Add its declaration — a file-guard, because we’re judging one file’s state:

.sloprail/file-guard/no-todo-in-committed-code/file-guard.yaml
match: path endsWith ".ts"
checks:
- script: ./check.sh

And the check — a script whose exit code is the verdict (0 permits, non-zero refuses):

.sloprail/file-guard/no-todo-in-committed-code/check.sh
#!/usr/bin/env bash
if grep -q "TODO(no-ship)" "$SR_FILE"; then
echo '{"reason": "This file has a TODO(no-ship) marker — resolve it before writing."}'
exit 1
fi

This is the part most people skip, and it’s the whole point. Ask your agent to write a .ts file containing TODO(no-ship). The write is refused, and the reason you wrote is shown back to the agent.

Now ask it to write a .ts file without that marker. The write lands.

If both happened, your guardrail is real. If the bad write went through, your rule loaded but didn’t fire — which is the failure this whole product exists to prevent.

  • A guardrail is a folder under .sloprail/, named for the rule.
  • It has a nature (here, file-guard) that decides when it runs.
  • Its check is a script (exit code = verdict) or a judge.
  • Loading is not firing — always confirm the refusal actually happens.