
DevMortimer/pi-warden on GitHub
- Stars
- 138
- Forks
- 18
- Language
- TypeScript
- License
- MIT
- Last push
- 24 Sep 2026
Read from GitHub on . Counts change daily.
Reported by the author
- Holds per 1000 calls
- 3
3 holds per 1,000 calls.
github.com
pi-warden supervises the Pi coding agent while it works, watching for risky actions, ignored project rules, stuck loops, unverified “done” claims, security issues and runaway output. Rather than interrupting the person at the keyboard for every problem, it usually feeds the issue back to the agent so it can correct itself and continue.
An action guard holds only irreversible bash, write or edit calls before they run, and records off-task findings without stopping the agent for those. A rules guard checks every write and edit against project rules written in Markdown and quotes the specific rule an edit breaks. Other guards catch stub code, restated comments and dead code; repeated tool failures using the same strategy; “done” claims with no test, build or lint run behind them; hardcoded secrets and injection risks; and a reply stream that starts repeating itself. An optional, beta conscience guard can recommend a skill or tool from the project’s own capability index before the agent acts.
The README reports that across 315 recorded sessions and 18,075 guarded calls, the action guard held 48 times, about 3 per 1,000. It works without any API key in an offline mode using pattern lists and local guards, or with a TypeSafe key for the full judgment layer, and needs Pi 0.85 or newer.
How it uses Jev
No direct call turned up in the code, so this is where it loads the SDK.
import { evaluateAction, textApproves } from "./guard.js";
import type { EvaluateOptions, PreviousAction, TaskMessage, Verdict } from "./guard.js";
import type { TaskSpine } from "./shape.js";
import type { Judge } from "pi-typesafe";
/** One tool call as the agent proposed it. `id` is Pi's tool call id, stable across hooks and retries. */
export interface ToolCallRef {
id: string;
tool: string;
input: Record<string, unknown>;
}
/** What the session says about the call: the latest user prompt, recent messages for scope, and the sibling calls of the same assistant message. */

