Skip to content

Security: srinitude/pi-until-done

Security

SECURITY.md

Security policy

Reporting a vulnerability

If you find a security issue in pi-until-done, please report it privately rather than filing a public issue.

  • Email: kiren@fantasymetals.com
  • Subject prefix: [security] pi-until-done — <short description>
  • Expected response time: within 7 days

Please include:

  1. The version (pi-until-done version + Pi version + Bun + mise).
  2. A reproducible example or proof of concept.
  3. The impact you observed and the impact you believe is possible.
  4. Any logs or session JSONL excerpts that help — but redact secrets.

A coordinated-disclosure release will follow once a fix is ready.

Threat model

/until-done is a continuation-loop extension. Its core trust assumption is that the active model is the judge. The extension itself does not introduce new attack surface beyond what Pi already exposes via its built-in tools (read, bash, edit, write, grep, find, ls).

What the extension does:

  • Persists goal state via pi.appendEntry (Pi session JSONL only).
  • Appends a goal reminder to the system prompt via before_agent_start (never replaces).
  • Auto-prepends mise exec -- to verifyCommand so all shell calls go through mise's pinned tool versions.
  • Spawns mise as a subprocess for CI checks (mise tasks ls --json, mise run <verb>, mise exec -- <cmd>).
  • Optionally writes .until-done/tasks.yaml and .until-done/distilled.md inside the project's cwd.

What the extension does NOT do:

  • No network calls of its own (only what Pi/the model invoke).
  • No credential reads, writes, or transmissions.
  • No telemetry, no analytics, no auto-updates.
  • No system-prompt replacement (composes only).
  • No pi.setActiveTools (would silently disable user tools — Pi-philosophy violation).
  • No daemons, no background processes outside an active Pi session.

Authorization model

  • askBefore[] is the user-defined gate for sensitive commands. The extension's tool_call hook compares each bash invocation against this list and triggers a ctx.ui.confirm dialog (with 30s timeout) before the command runs. On dismiss/timeout, the tool is blocked.
  • Hard ceiling: turn budget capped at 20000 (with a confirm dialog above 500), regardless of what the model requests. The orthogonal gates — spin guard, clean-end nudge, CI-failure → block, user input, /until-done pause, and compaction — are turn-independent.
  • Any tool the user has not enabled in Pi cannot be invoked by the extension.

Untrusted content

When the model reads untrusted input (web pages, third-party files, external APIs), prompt injection is possible against the goal contract. Mitigations baked into the extension:

  • The North Star (goal, doneCriteria, verifyCommand, askBefore) is locked at until_done_set; replans cannot change it.
  • The verifiability discipline (injected every turn) refuses proxy-signal completions and requires quoted verifyCommand output.
  • The spin-guard blocks the loop when a turn produces no progress signals — preventing models from "agreeing" to stop.

Supported versions

Only the latest minor version of pi-until-done is supported. Update via pi update pi-until-done or npm install -g pi-until-done@latest.

There aren’t any published security advisories