opbox

The agent is the interface. A reasoning loop calls the same verbs a human would, over the kernel’s MCP door — so the agent gains no special powers; it is bounded by exactly the verb surface its bearer can reach.

The owned agent loop

scripts/opbox_agent.py is the owned agent loop. Given a message, it:

  1. Lists the verbs the kernel’s MCP tools/list exposes for its bearer — no client-side filtering. The kernel governs which calls actually succeed.
  2. Runs a tool-calling loop: the model picks a verb, the loop calls it over /mcp, feeds the result back, and repeats until the model answers.

It serves two shapes: a synchronous POST / and a streaming POST /chat/stream that emits AG-UI events (RUN_STARTED, TOOL_CALL_*, TEXT_MESSAGE_*, RUN_FINISHED) — one loop, two projections.

The cage

The agent is untrusted. Its only path to firm or matter data is the kernel’s verb surface; native shell, python, and web access are stripped, and egress is locked. The kernel — not any agent hook — enforces authz, audit, and budget.

The caged Hermes engine is now exercised, not just planned. An unmodified upstream Nous Hermes agent (NousResearch/hermes-agent) runs caged: its only tools are the always-on Core kernel verbs over MCP (~68 verbs) plus an in-memory todo tool. It has no terminal, browser, web, file, or code-exec access. This was verified end to end: the caged agent made a real kernel tool-call and returned the live result. The owned opbox_agent.py loop coexists as a driver and a fallback; the cage is what makes consuming an upstream engine safe, so the substrate stays owned while the reasoning engine is commodity.

The model is provider-configurable and engine-agnostic. The active default is cloud GLM-4.6 via z.ai’s coding endpoint; a local Ollama model is the no-egress fallback; any OpenAI-compatible provider works by config. Model inference egresses to the chosen provider, but that is independent of the tool cage: the agent’s tool surface is the kernel verbs no matter which model reasons over them.

MCP is the agent door

INV-3 denies a HUMAN identity over the MCP door — MCP is the agent door, HTTP is the human door. This is load-bearing for the chat design: a browser user’s SESSION bearer authenticates them at the HTTP door, but the agent cannot be that human over MCP.

The bounded chat-agent

Because the agent executes over MCP under its own identity, that identity must be bounded. The public chat runs under a dedicated chat-agent provisioned as org.agent.create role=WORKER with autonomy 1 and a MEMBER tier — never the OWNER Chief-of-Staff key. Autonomy 1 is the real bound: it permits reads and writes but denies every sensitive or owner operation, regardless of verb scope.

The human SESSION bearer is the access gate (who may chat); the bounded WORKER is the execution identity (what the chat may do). This split, and the rule that the standing OWNER key never backs a public chat, is a fixed design rule of the agent-chat surface.

Provisioning

The genesis ceremony mints the Chief-of-Staff agent (the org root, OWNER over MCP) and, acting as the CoS, creates the bounded WORKER chat-agent. See Genesis.