ariel

A single-user Discord agent whose only action surface is a Python program run in a gVisor sandbox.

ariel is a personal AI agent runtime, Discord-primary and single-user: a FastAPI backend, a Discord bot, Postgres persistence, and one agent loop that serves both my messages and its own proactive wakes. Its capabilities are Gmail, Calendar, Drive, Maps, weather, web search, and web extraction, with approval gates on side effects. The doctrine is written down: AI owns judgment; deterministic code owns the service rails, and never performs product judgment by heuristic.

The first decision is the action surface. The model does not emit JSON tool calls; it writes a Python program, and the runtime executes it in a gVisor sandbox — one persistent rootless runsc container, a fresh guest process per program, capabilities exposed as typed syscalls over line-delimited JSON, hard caps at 64 syscalls, 64KB of source, 5 seconds of CPU, 256MB of memory, 30 seconds wall clock. The commit that landed it deleted the flat JSON tool-call list, and a terminal subsystem had already been cut before that. Two predecessor designs, both deleted.

The second decision was subtraction: sessions were abolished. The repo had built chat-style sessions with auto-rotation, thresholds, and reason codes; the forward-only migration deletes all of it, and turns and events become globally scoped. The commit message argues that sessions were a judgment, not just data — and judgments belong to the model.

The third was forced by a bill. The cutover spec quantifies four days of uncached Claude calls from the production events table: $17.28 across 5.67M input tokens in 76 calls, zero cached. The same spec ships four coupled changes at once: MAIN to Kimi K2.6, OpenRouter prompt caching on, the recent-events budget cut from 100K to 20K tokens, and a bounded grounding-retry loop. Model identity is a code constant, not deployment config.

Side effects run a fail-closed taint policy: the model's own taint assertions are advisory; runtime provenance decides; a tainted irreversible write or external send is denied outright, and the ambiguous cases escalate to approval.

Numbers: 286 commits, 2026-02-27 to 2026-05-27; 71 migrations in twelve weeks; 969 test functions in 78 files, test lines outweighing source 45,481 to 39,724 by wc -l; 143 commits carry Claude co-author trailers.

What is wrong with it. The README still documents the /v1/sessions endpoints that were removed the day before the last commit. A three-bug stack silently dropped every proactive Gmail wake from the day Google was connected until 2026-05-26 — the push pipeline shipped without a liveness check. The migration ledger is a record of churn: proactive tables built and dropped. The gVisor tests skip wherever runsc is not installed, and that is the one layer that must not go untested.

It serves one user, one guild, one box on a tailnet. The user is satisfied and biased.