Skip to content
System One

pi-warden

Guardrails for the Pi agent built on pi-typesafe. Jev judges irreversible and off-task tool calls, detects stuck loops, checks unverified completion claims and flags low-quality output, steering the agent rather than interrupting the user.

Real verdicts from pi-warden: the same command gets a different verdict depending on what the user asked for
Image from github.com

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
33 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. */

View in src/action-guard.ts

Open on GitHub

More like this

Use cases this is tagged with