Files
prose-contracts/pi-approval-architecture.prose.md
root 253e19f680 prose: review, fix, and consolidate infrastructure contracts
- DELETE infrastructure-monitoring.prose.md (redundant — proxmox-monitor already deployed this)
- FIX infrastructure-control.prose.md: remove /grafana/ nginx route (reverted Jul 2, broke gpu-fleet)
- FIX infrastructure-update.prose.md: wrong CT IDs (122→112 Tanko, 123→114 Mumuni, .19→storepve Zulip)
- FIX infrastructure-update.prose.md: Strix Halo :8080→router health check (firewalled to .116 only)
- FIX proxmox-monitor.prose.md: stale /grafana/ URLs→:3001 (post-revert cleanup)
- ADD disk-gc-threat-response.prose.md: verified run (2026-07-04, reclaimed 35.67GB from kagentz)
- ADD infrastructure-update.prose.md, pi-approval-architecture.prose.md, zulip-approval-fix.prose.md, zulip-self-heal.prose.md
- UPDATE hermes-config, litellm-health/self-heal, pm2-self-heal, zulip-* contracts
- ADD runs/20260704-005804-51f9a9 (disk-gc-threat-response run artifacts)

All contracts verified against live PVE API, nginx config, and firewall state.
2026-07-04 21:47:33 +00:00

108 lines
4.7 KiB
Markdown

---
kind: architecture
name: pi-approval-architecture
description: >
Documents pi's approval model vs Hermes, what commands are available,
and the architectural constraints that prevent mid-turn tool approval in pi.
Updated with /approve and /deny stub commands for cross-agent UX consistency.
agent: abiba
version: 1.0.0
---
# Pi Approval Architecture
## TL;DR
| Feature | Hermes | Pi (Abiba) |
|---------|--------|------------|
| `/approve` command | ✅ Full — unblocks agent | ✅ Stub — acknowledges, no blocking |
| `/deny` command | ✅ Full — blocks agent | ✅ Stub — acknowledges, no blocking |
| Dangerous command detection | ✅ 40+ patterns + Tirith | ❌ None (LLM judgment only) |
| Mid-turn tool approval | ✅ Agent thread blocks on Event | ❌ No hook in agent loop |
| Smart approval (aux LLM) | ✅ `approvals.mode: smart` | ❌ N/A |
| Yolo mode | ✅ `/yolo`, `approvals.mode: off` | ❌ N/A |
| Permanent allowlist | ✅ `command_allowlist` + `shell-hooks` | ❌ N/A |
| Session-scoped approval | ✅ `approve_session()` | ❌ N/A |
| Approval timeout | ✅ 60s default, configurable | ❌ N/A |
## Why Pi Can't Do Mid-Turn Approval
Pi's agent loop is **418 lines** of TypeScript. It's deliberately minimal:
```
LLM decides → calls tool → tool executes immediately → output goes to LLM → repeats
```
There is no middleware between "LLM decides to call bash" and "bash executes."
The extension system (`injectIntoSession`) feeds messages IN but doesn't intercept
tool calls mid-turn.
Hermes has a full approval pipeline:
```
LLM decides → check_all_command_guards() → if dangerous → notify_cb → block thread
→ user responds /approve → resolve_gateway_approval() → Event.set() → unblock
```
This pipeline is deeply integrated into Hermes' gateway, tool executor, and
session management. Replicating it in pi would require rewriting the core agent
loop — violating pi's design constraint of minimal core.
## What Pi HAS: `/approve` and `/deny` Stubs
Added to prevent `/approve` and `/deny` from being forwarded to the LLM as
garbled input. When a user types these commands to Abiba:
- **`/approve`** → "Pi doesn't have pending approvals. Commands execute immediately."
- **`/approve session`** → Same response
- **`/deny`** → Same response + "For Hermes agents (Tanko, Mumuni), these work with their built-in approval system."
This keeps the UX consistent across agents — users can type `/approve` anywhere
without getting confused by LLM responses.
## Pi's Full Command Set (Hermes Parity)
| Command | Handler | Description | Hermes Equivalent |
|---------|---------|-------------|-------------------|
| `/status` | System | PM2 processes, containers, session info | `/status` |
| `/retry` | Session | Re-injects last user message | `/retry` |
| `/continue` | Session | Continues truncated response | `/continue` |
| `/new [topic]` | Session | Clears conversation context | `/new` |
| `/stop` | Control | Interrupts current LLM processing | `/stop` |
| `/model [name]` | Info | Show current model, list available | `/model` |
| `/compact` | Session | Requests context compaction | `/compact` |
| `/yolo` | Stub | Pi has no approval system — accepted for UX | `/yolo` |
| `/verbose` | Stub | Verbosity controlled by prompt, not toggle | `/verbose` |
| `/approve` | Stub | Pi executes immediately — no approvals | `/approve` |
| `/deny` | Stub | Pi executes immediately — no approvals | `/deny` |
| `/help [cmd]` | Info | Shows command help | `/help` |
## What Pi COULD Add (Without Core Changes)
These would work within pi's current architecture:
1. **Pre-message dangerous command scan**: Before forwarding an agent response to
Zulip, scan the text for dangerous bash commands and add a warning banner.
Doesn't prevent execution but alerts user.
2. **User-facing approval prompt injection**: When user asks pi to do something
dangerous (detected via regex on user input), pi could respond with a
confirmation request before proceeding. This works because it's at the
message level, not mid-turn.
3. **Response rate-limiting**: If pi generates many bash commands rapidly,
throttle and ask for confirmation. Works within the extension's send path.
## Files
| File | Purpose |
|------|---------|
| `/root/.pi/agent/extensions/zulip/index.js` | Pi Zulip extension with command system |
| `/root/prose-contracts/zulip-approval-fix.prose.md` | Hermes Zulip approval fix |
| `/root/prose-contracts/pi-approval-architecture.prose.md` | This document |
## Related
- Hermes `tools/approval.py` — Full approval pipeline (dangerous patterns, Tirith, smart mode)
- Hermes `gateway/slash_commands.py:_handle_approve_command` — Slash command handler
- Hermes Zulip adapter fix — HTML stripping for command detection