Overview
Polpo follows a supervisor architecture: it manages agent lifecycles, task assignment, assessment, and error recovery. Agents are isolated processes that know nothing about each other — Polpo handles all coordination.
Under the hood, Polpo is composed of four layers:
- Interface layer — CLI, TUI, Web UI, OpenAI-compatible chat endpoint (
/v1/chat/completions), and REST API provide different ways to talk to Polpo
- Core — the supervisor loop, task registry, mission executor, system context (
.polpo/system-context.md), project memory, and all the managers (assessment, approvals, escalation, scheduling, etc.)
- Runner layer — detached subprocesses that host individual agents, communicating with Polpo via the file-based RunStore
- Agent layer — the actual AI agents (Claude, GPT, Gemini, etc.) running on the built-in engine
Built-in Engine
All agents run on Polpo’s built-in engine — a multi-provider LLM runtime powered by pi-agent-core. The engine handles agent spawning, tool execution, and activity tracking.
Each agent run produces an AgentHandle that Polpo uses to monitor the agent:
interface AgentHandle {
agentName: string;
taskId: string;
pid: number; // real process ID
sessionId?: string; // optional session ID for transcript access
activity: AgentActivity; // live activity data (tools, files, progress)
done: Promise<TaskResult>; // resolves when agent finishes
isAlive(): boolean;
kill(): void;
}
Supervisor Loop
Polpo runs a 5-second tick loop that:
- Collects results from terminated runners (via RunStore)
- Assesses completed tasks using the configured expectations
- Retries failed tasks (with fix phase for targeted corrections)
- Spawns new agents for pending tasks whose dependencies are met
- Enforces health checks — kills stale or timed-out agents
- Detects deadlocks — tasks blocked on failed dependencies (Deadlock Resolution)
- Recovers orphans — reconnects to live processes after a crash
- Checks SLA deadlines — emits warnings or violations when deadlines approach
- Evaluates quality gates — blocks mission progression until thresholds are met
- Processes approval gates — transitions tasks through
awaiting_approval when required
Detached Runners
Each agent runs as a detached subprocess (runner.ts), completely independent of Polpo’s main process:
This architecture means:
- Crash resilience: If Polpo crashes, runners keep working
- Process isolation: One agent crashing doesn’t affect others
- Orphan recovery: On restart, Polpo reconnects to live runners
Event System
Polpo uses a typed event emitter with 55+ event types organized by category:
| Category | Events | Description |
|---|
task:* | created, transition, updated, removed, retry, fix, maxRetries, timeout, recovered, question, answered | Task lifecycle |
agent:* | spawned, finished, activity, stale | Agent lifecycle |
assessment:* | started, progress, complete, corrected | Task assessment |
orchestrator:* | started, tick, deadlock, shutdown | System events |
deadlock:* | detected, resolving, resolved, unresolvable | Deadlock resolution |
mission:* | saved, executed, completed, resumed, deleted | Mission lifecycle |
session:* | created, message:added | Chat sessions |
approval:* | requested, resolved, timeout | Approval gates |
sla:* | warning, violated, met | SLA monitoring |
quality:* | gate:passed, gate:failed, threshold:failed | Quality gates |
schedule:* | triggered, created, completed | Mission scheduling |
escalation:* | triggered, resolved, human | Escalation chain |
notification:* | sent, failed | Notification delivery |
log | — | General log messages |
Events are consumed by the TUI, HTTP/SSE server, and notifications. See Events Reference for full payload details.
Persistence
| Component | Storage | Purpose |
|---|
| Task Registry | File-based store (default) | Task state with atomic writes |
| RunStore | File-based store (default) | Runner process tracking |
| Log Store | File-based store (default) | Persistent event log |
| Mission Store | File-based store (default) | Mission definitions and status |
| Memory | File (.polpo/memory.md) | Project context for agents |
| System Context | File (.polpo/system-context.md) | Standing instructions for Polpo (injected into every conversation) |
| Runner configs | JSON (.polpo/tmp/) | Temporary config for detached runners |
File-based stores are the default. SQLite and PostgreSQL are available as alternatives via configuration (powered by Drizzle ORM in @polpo-ai/drizzle).
File-based stores use atomic write operations to handle concurrent access from Polpo and multiple runner processes.