|
|
4 weeks ago | |
|---|---|---|
| .gitignore | 4 weeks ago | |
| README.md | 4 weeks ago | |
| index.ts | 4 weeks ago | |
| package-lock.json | 4 weeks ago | |
| package.json | 4 weeks ago | |
| policy-gate.example.json | 4 weeks ago | |
README.md
@enne2/pi-policy-gate
A standalone pi extension package that applies a practical policy layer to risky tool calls.
It classifies operations into four outcomes:
- allow — execute immediately
- confirm — require human approval
- deny — block outright
- refine — block and tell the model how to reformulate the command safely
The default policy is opinionated but usable, and it is now baked into the code even if you provide no config file.
Built-in defaults:
sudoandsshare not denied by default- risky commands are generally confirmed
- only objectively dangerous or ambiguous forms are denied/refined
- destructive deletes should use an explicit absolute path
curl/wget/nc/socat/telnetare confirmedenv/printenvare confirmed- bash-based writes to sensitive files such as
AGENTS.md,.env, shell dotfiles, SSH config, and local policy files are confirmed - programmatically generated local alert sounds play on confirmation requests and blocks/refinements by default
What it protects against
Examples of behavior it catches by default:
rm -rf *rm -rf .rm -rf ..rm -rf /find . -deletesudo ...(confirmation)ssh .../scp/rsync/sftp(confirmation)curl ...,wget ...,nc ...,socat ...(confirmation)env,printenv(confirmation)git reset --hard,git clean -fdx,git push(confirmation)sed -i ~/.bashrc ...ortee AGENTS.md(confirmation)- writes outside the workspace (confirmation)
- reads/writes to sensitive paths such as
~/.ssh,AGENTS.md, or.env(confirmation)
Install
Directly in pi from git
Private Gitea/GitHub style install:
pi install 'ssh://git@git.enne2.net:222/enne2/pi-policy-gate.git'
Or with HTTPS:
pi install https://git.enne2.net/enne2/pi-policy-gate.git
With npm from the git repository
npm install git+ssh://git@git.enne2.net:222/enne2/pi-policy-gate.git
Then load it from local node_modules or publish it to your npm registry later.
Sound alerts
The extension generates three small WAV files programmatically on first use:
confirm.wav— soft ascending alert for human confirmationblock.wav— lower, harsher alert for denied actionsrefine.wav— distinct mid-tone alert for “blocked, but reformulate safely” cases
By default it writes them under:
~/.pi/agent/policy-gate-sounds/
It automatically uses the first available local player among:
paplaypw-playaplayffplayplay
You can also test them manually inside pi:
/policy-gate-sound/policy-gate-sound block/policy-gate-sound refine
Config files
The extension looks for config files in this order:
- built-in defaults
~/.pi/agent/policy-gate.json- extra file passed with
--policy-gate-config /path/to/file.json .pi/policy-gate.jsonin the current project
Project config overrides global config.
Example config
Copy and adjust:
cp policy-gate.example.json ~/.pi/agent/policy-gate.json
Example:
{
"workspaceRoots": ["."],
"requireAbsolutePathForRecursiveDelete": true,
"soundEnabled": true,
"soundConfirmEnabled": true,
"soundBlockEnabled": true,
"soundRefineEnabled": true,
"soundPlayer": "auto",
"overrides": [
{
"tool": "bash",
"commandRegex": "^sudo systemctl restart my-safe-service$",
"action": "allow"
}
]
}
Config reference
{
"workspaceRoots": ["."],
"requireAbsolutePathForRecursiveDelete": true,
"requireAbsolutePathForFindDelete": true,
"confirmSensitiveReads": true,
"confirmSensitiveWrites": true,
"confirmWritesOutsideWorkspace": true,
"soundEnabled": true,
"soundConfirmEnabled": true,
"soundBlockEnabled": true,
"soundRefineEnabled": true,
"soundPlayer": "auto",
"soundDirectory": "~/.pi/agent/policy-gate-sounds",
"sensitivePathGlobs": ["~/.ssh/**", "**/.env"],
"overrides": [
{
"id": "optional label",
"tool": "bash",
"commandRegex": "^ssh deploy@staging\\b",
"pathGlob": "~/.ssh/**",
"action": "allow | confirm | deny | refine",
"reason": "Shown to the user / model",
"suggest": "Only used with refine/deny to explain the safer alternative"
}
]
}
Notes
-
soundPlayer: "auto"picks the first available local player. -
Set
soundEnabled: falseto disable all alert sounds. -
soundConfirmEnabled,soundBlockEnabled, andsoundRefineEnabledlet you mute just one class of event. -
soundDirectorycan be absolute,~-based, or relative to the project cwd. -
workspaceRootscan be absolute paths,~paths, or paths relative to the current project cwd. -
commandRegexis evaluated against the raw bash command string. -
pathGlobis matched against both the absolute path and the path relative to the current cwd. -
last matching override wins.
Behavior model
Allow
Low-risk reads and normal project-local writes are allowed.
Confirm
Potentially dangerous but legitimate actions prompt the human.
Examples:
sudo systemctl restart nginxssh deploy@staging 'systemctl status api'rm -rf /full/path/to/some/build-cache
Deny / Refine
Only clearly unsafe or ambiguous forms are blocked.
Examples:
rm -rf *rm -rf .find . -delete
The extension tells the model to switch to a safer form such as using an explicit absolute path.
Useful commands
Inside pi:
/policy-gate— show current policy summary/policy-gate-sound— play the confirmation sound/policy-gate-sound block— play the deny sound/policy-gate-sound refine— play the refine sound
Development
Install deps and verify the package tarball:
npm install
npm run pack:check
Try it without installing globally:
pi -e /absolute/path/to/pi-policy-gate --list-models
Packaging notes
This package is intentionally TypeScript-only and relies on pi's built-in runtime loader. No build step is required.