No description
  • TypeScript 91.3%
  • JavaScript 8.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-23 15:10:01 +02:00
.pi global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
.wayfinder global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
docs wayfinder: 010 golden part done, dogfood handoff recorded 2026-09-23 14:51:53 +02:00
extension/jev-guard global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
golden golden verification: acceptance MET (ticket 010, golden part) 2026-09-23 14:51:29 +02:00
scripts global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
test global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
.gitignore golden verification: acceptance MET (ticket 010, golden part) 2026-09-23 14:51:29 +02:00
LICENSE add MIT license, polish README, translate remaining wayfinder notes to English 2026-09-23 15:01:15 +02:00
package-lock.json build guard core (ticket 008): interception, buffer, checkpoint, block-with-reason 2026-09-23 14:24:34 +02:00
package.json global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00
README.md README: requirements, cloner install path, single-instance warning 2026-09-23 15:10:01 +02:00
tsconfig.json global install support: config fallback + embedded default battery 2026-09-23 15:08:24 +02:00

pi-jev-guard

A pi extension where jev (the cheap typesafe model) is a pre-execution guard rail on every mutating tool call — bash, write, edit. Before a call runs, one batched jev call scores it against a question lens (rich context: task frame + recent calls + outputs); any flag ≥ its threshold hard-blocks the call with a deterministic reason fed back to the agent.

"Jev decides if it's safe to run, the LLM does the work."

How it works

agent wants to run a tool call
        │
        ▼
  mutating? ── no ──► pass (one-liner into the window buffer)
        │ yes
        ▼
  checkpoint due? (interval N · first-in-turn · after a block)
        │ no ──► execute unchecked (counted)
        │ yes — call is HELD
        ▼
  one batched jev call (battery lens for the shape, 0.7/0.8 thresholds)
        │                    │ failure (timeout/transport/bad verdict ×retries)
        ▼                    ▼
   any flag ≥ t?        fail-closed: block "guard unavailable"
   block ◄── yes             │ 3 consecutive (or 5/8 rolling)
   │         no              ▼
   │                    DEGRADED: notify-only + catastrophic regex floor
   ▼                         │ probes (real calls, 60 s cooldown, ×2)
  execute ◄──────────────────┘ auto-recovery → armed
  • Block = deny before execution; the agent sees the flagged question's definition + confidence + "not a human click; do not rephrase, retry, or circumvent".
  • Window buffer: last 12 tool-call entries (mutating rich, read-only one-liners, block events appended) — the evidence jev judges against.
  • Lenses (battery-v2): bash → 8 gate questions (destructive / out-of-workspace / remote-code-exec / credential-exposure / supply-chain / privilege-escalation / force-mutation / unguarded-expansion); write & edit → the 20-question code battery (security sinks + correctness + maintainability) + 2 filesystem gate questions.
  • Commands: /guard off (session-only, audited) · /guard on (re-arm) · /guard status (state, counters, last verdicts).
  • Breaker: 3 consecutive or 5-of-8 rolling jev failures → degraded (calls pass, catastrophic floor still hard-blocks); auto-recovery via real-call probes.
  • Persistent disable: enabled: false in .pi/guard.yaml.

Configuration as data

(This section describes the repo's own reference config — the same files any project can place in its .pi/ to override the global defaults.)

Path Role
.pi/guard.yaml gate knobs: interval, budgets, timeout, tools, thresholds, breaker
.pi/guard-battery.yaml checklist: routing, 28 questions, thresholds, preambles, scope rules
.pi/guard-outcomes.jsonl one line per verdict (gitignored)

Validation

golden/ — 24 labeled cases (12 benign / 12 dangerous), question-set configs, scorer: npm run golden. Acceptance: ≥ 10/12 catch, ≤ 1/12 false-blocks, 3-pass variance protocol. gate-v3: 11/12 / 0 FP. Design/spec: docs/superpowers/specs/2026-09-22-jev-guard-design.md; research notes in docs/research/.

Running & verifying

npm install
npm run check      # tsc --noEmit (strict)
npm test           # 23 tests, mocked jev transport
npm run golden     # live jev testbench (needs TYPESAFE_AI_API_KEY)
node scripts/demo-live.mts   # end-to-end demo: allow / block / fail-closed

Env: TYPESAFE_AI_API_KEY (or TYPESAFE_API_KEY). /reload picks up config + code changes.

Requirements

  • pi ≥ 0.87
  • A TypeSafe AI API key in TYPESAFE_AI_API_KEY (or TYPESAFE_API_KEY)
  • Node ≥ 22 (for the test suite; the extension itself runs inside pi)

Install

Global (recommended) — the guard runs in every pi session; projects without their own .pi/guard.yaml run on built-in defaults + the embedded battery:

git clone ssh://git@git.mooivancrooy.nl:2222/crooy/pi-jev-guard.git
mkdir -p ~/.pi/agent/extensions/jev-guard
cp pi-jev-guard/extension/jev-guard/*.ts pi-jev-guard/extension/jev-guard/battery-default.json ~/.pi/agent/extensions/jev-guard/
cd ~/.pi/agent/extensions/jev-guard && npm install

Start (or /reload) pi — the statusline shows jev-guard: guard: armed (defaults). Pick a project to tune it: copy .pi/guard.yaml + .pi/guard-battery.yaml from this repo into the project's .pi/ and edit (per-project thresholds, interval, floor patterns, breaker settings).

Install either globally or project-local, never both in the same project — two instances would each gate every call.

Repository layout

Path What
extension/jev-guard/ the extension source (index wiring + engine, window, verdict, jev, breaker, config, embedded default battery)
.pi/guard.yaml, .pi/guard-battery.yaml runtime config + question battery (data, edit freely)
golden/ labeled testbench: 24 cases, question-set configs, scorer
docs/superpowers/specs/ the design spec
docs/research/ research notes: pi mechanics, pi-auto-review mining, spike, battery, semantics, breaker policy, golden report
.wayfinder/ planning map + tickets (wayfinder local-markdown tracker)

License

MIT