Implementing Command Guards
Use these recipes to create code-enforced memories with memory_add(...). For how memories are stored and managed over time, see Curating Project Memory. For automated review-loop commit blocking, see Automating Code Reviews.
Note: These recipes document project-specific guards you add yourself. For the full settings reference, see Configuration & Settings.
Block a destructive cleanup command
Use this when you want Pi to reject a specific bash command before it runs.
memory_add(
text="Never prune Docker images or containers from this repo",
category="lesson",
trigger="bash_contains docker system prune",
action="block"
)
This creates a hard block on any bash tool call containing docker system prune. Use bash_contains when the command is easy to match with a plain substring and you do not need regex flexibility.
- Good fits:
terraform destroy,kubectl delete namespace,aws s3 rm --recursive - Keep one rule per dangerous command so the reason stays obvious
Block force-pushes with a regex
Use this when a command has multiple spellings and you need one rule to catch all of them.
memory_add(
text="Never force-push from this repo",
category="lesson",
trigger="bash_regex git\\s+push\\s+--force(?:-with-lease)?\\b",
action="block"
)
This blocks both git push --force and git push --force-with-lease. Use bash_regex when a simple substring is too broad or would miss important variants.
Tip: Keep regexes short and targeted. This matcher is for command guards, not full shell parsing.
Warn when editing secret files
Use this when a file should stay editable, but every edit deserves an extra reminder.
memory_add(
text="Check for secrets before saving .env files",
category="pattern",
trigger="file_modified *.env",
action="warn"
)
This appends a warning when Pi uses write or edit on a matching file path. Use warn for sensitive files that sometimes need changes but should never be edited casually.
file_modified *.pymatches by extensionfile_modified Dockerfilematches by path substring
Require approval before merging a PR
Use this when a command is allowed only after another tool has run in the same turn.
memory_add(
text="Always get explicit approval before merging a pull request",
category="pattern",
verifier="tool_called ask_user before gh pr merge"
)
This adds a semantic verifier instead of a trigger/action pair. If Pi runs gh pr merge without calling ask_user first, the turn is flagged as a violation.
Note: This checks ordering inside a single turn:
ask_usermust happen before the merge command.
Make the repo read-only for direct edits
Use this when you want Pi to inspect and plan, but never modify files directly.
memory_add(
text="Do not write files directly in this repo",
category="preference",
trigger="tool_name write",
action="block"
)
memory_add(
text="Do not edit files directly in this repo",
category="preference",
trigger="tool_name edit",
action="block"
)
These rules block tool calls by exact tool name rather than by shell text. Use tool_name when the risky behavior is the tool itself, not a particular bash command.
- Common targets:
write,edit, or other project-specific tools - For agent-level workflow controls, see Managing Custom Agents
Run one safe follow-up command after a file edit
Use this when you want Pi to perform a tightly controlled check right after a successful change.
# In your shell before starting pi
export PI_ENFORCEMENT_ALLOWED_COMMANDS="git diff -- Dockerfile"
# In pi chat
memory_add(
text="Show the Dockerfile diff after every edit",
category="pattern",
trigger="file_modified Dockerfile",
action="run_after git diff -- Dockerfile"
)
This runs git diff -- Dockerfile immediately after a matching write or edit succeeds, and only because the command is allowlisted exactly. Use this for short, deterministic checks that you want attached to a specific kind of edit.
Warning: Allowlist entries must match exactly, character for character.
-
To allow more than one follow-up command, use a colon-separated list:
export PI_ENFORCEMENT_ALLOWED_COMMANDS="git diff -- Dockerfile:git status --short" -
Keep follow-up commands fast so they do not slow down normal edits