# Pi Approve for me

A global Pi extension that sends model-issued tool calls to a separate reviewer model.

## Installation

Install as a Pi package:

```bash
pi install npm:pi-approve-for-me
```

For temporary loading without persistent activation:

```bash
pi -e npm:pi-approve-for-me
```

A plain `npm install pi-approve-for-me` does not activate the package in Pi.

## Configuration

The extension reads, validates, and never writes the global `settings.json` namespace:

```json
"approveForMe": {
  "mode": "approve-for-me",
  "reviewer": {
    "model": "openai-codex/gpt-5.6-sol",
    "reasoning": "low"
  },
  "alwaysAllowTools": [
    "trusted_status_tool"
  ]
}
```

`mode` is global and is either:

- `approve-for-me` — apply the bypass rules below and review every other model-issued tool call.
- `full-access` — this handler returns without reviewing any tool, including `bash`.

`alwaysAllowTools` is an exact, case-sensitive list of Pi tool names. It has no globs, patterns, source qualifiers, or argument rules. A missing list is treated as `[]`. Entries must be unique non-empty strings, and `bash` is rejected. Missing or malformed configuration fails closed.

The model id must be fully qualified. The reasoning level must be supported by that model.

## Behavior

In `approve-for-me` mode:

- Genuine Pi built-ins `read`, `grep`, `find`, and `ls` bypass review only when their current `sourceInfo` is Pi's built-in metadata. A custom replacement with one of those names is reviewed unless separately configured.
- A tool named in `alwaysAllowTools` bypasses review regardless of source metadata. Pi routes one effective implementation per name, so a same-name replacement also receives that exemption. This name-collision behavior is intentional.
- Exact tool name `bash` is always reviewed. Config validation rejects it and the runtime gate independently prevents an injected configuration from bypassing it.
- Every other non-bypassed tool is reviewed from its exact name and model-issued arguments, without package-specific interpretation.

Every Pi session that loads the extension uses the same global configuration and policy. There are no cwd, session-header, or package-specific exceptions.

The reviewer receives a planned-action JSON payload and a compact transcript of actual user, assistant, tool-call, and tool-result evidence. After Pi compaction, the same sliding budget also includes Pi's existing compaction or branch summary plus historical user messages from the active branch. A planned action must fit, without string truncation, within an aggregate approximately 16,000-token cap. Oversized actions fail closed before the reviewer is called and direct the main agent to use a smaller command or split the action into smaller tool calls. Bash actions include a generic note that subprocess effects may not appear as separate Pi tool calls; arbitrary custom tools receive no semantic enrichment. Hidden thinking and synthetic extension context are excluded; Pi's own summaries are retained as labeled summary evidence. Reviewer auth is resolved on every attempt. Calls use an extension-registered provider's `streamSimple` when it targets the selected model's API and otherwise `completeSimple`, with the configured reasoning level, no tools, bounded output, active-turn cancellation, and one 90-second deadline.

Malformed output and provider failures get at most three attempts with 200/400 ms backoff. Everything except a parsed `outcome: "allow"` fails closed. Three consecutive explicit model denials, or ten among the latest fifty reviews in one Pi run, abort that run once. Sanitized review entries contain only coarse metadata; exact arguments, prompts, credentials, raw reviewer output, and rationales are not duplicated into them.

A bypass or reviewer allow returns `undefined`. It never approves on behalf of another extension, and later handlers remain independently authoritative. Pi has no run-last `tool_call` priority: this extension reviews the arguments visible at its load-order position, and a later handler may mutate them before execution.

## Security scope

**This extension is a convenience reviewer, not a sandbox or security boundary.** Pi tools and extensions retain the Pi process's OS permissions. Extensions in the same process can perform side effects outside model-issued `tool_call` handling, and this extension cannot mediate interactive shell commands, RPC Bash execution, or arbitrary extension behavior. Use a container, VM, or real sandbox for untrusted or unattended work.

Bypassed built-in `read`, `grep`, `find`, and `ls` calls can place credential or other sensitive file content into the primary model's context. The tradeoff is that downstream reviewed use or exfiltration of that content remains gated; the initial read itself is not.

Reviewer requests are direct provider calls. They do not enter Pi session usage accounting, recursively invoke tools, or inherit coding-agent request/response extension hooks. Extension-registered custom providers are supported through a matching `streamSimple` implementation; other providers use the compatibility `completeSimple` path.

See [`docs/codex-comparison.md`](docs/codex-comparison.md) for adaptation details and verified differences.

## Development

```bash
npm install
npm run check
```

Tests use injected models and in-memory Pi sessions. They make no network calls.
