Skip to content

Ring

A Ring is one of three in-process enforcement positions.

Rings sit inside the agent's process. Each ring's enforcement depends on what the surrounding sandbox supports. Filled by per-target Providers selected into a Runtime.

Three rings, period. Targets multiply within each ring; rings stay stable. Per ADR 0001 — Rings, not layers.

What it isA category of in-process enforcement (3 of them; not 5)
SitsInside the agent's process
Filled byOne Provider per ring, selected into a Runtime
Configured fromThe relevant aspect(s) of the Compiled Policy
Distinguished fromThe two cross-cutting layers (LLM Gateway, MCP Broker) which sit between processes
RingTypeGovernsFailure mode caught
Ring 1 — HarnessSemantic, cooperativeWhat tool calls an agent attemptsAgent "helpfully" runs rm -rf in the wrong directory; agent chains an allowed tool with a dangerous parameter
Ring 2 — KernelCompulsory, coarseWhat the agent process can do (FS, network, syscalls, credentials)Compromised agent binary; exfiltration over DNS/WebSocket; credential theft via env-var dump
Ring 3 — InterpreterNarrow, hardWhat code the agent writes can do (codemode)LLM writes Python that tries to shell out; unbounded memory/CPU as DoS; reading env vars from generated code

Per ADR 0001:

  • Rings sit inside the agent's process; their enforcement depends on the agent's runtime cooperating (cooperative for harness; compulsory for kernel; narrow for interpreter).
  • Cross-cutting layers sit between processes and are always compulsory regardless of agent runtime.

The earlier "5 flat layers" framing hid this structural distinction. Calling them all the same thing obscured the fact that one cooperates with the agent's process while the others are structurally above it.

These three are commonly confused; clarification:

  • A Ring is a category of enforcement (one of three: harness, kernel, interpreter).
  • A Target is a specific implementation that fills out a ring on a particular platform (e.g., within the kernel ring: nono, OpenShell, gVisor, Firecracker, sandbox-exec, K8s NetworkPolicy + Gatekeeper).
  • A Provider is the per-target translator (pure function provider(compiled_policy, capabilities) → target_config) that renders the Compiled Policy as native config for one target.

Rings are the stable taxonomy. Targets are the long tail. Providers are how each target is filled.

Compiled Policy aspects each ring consumes

Section titled “Compiled Policy aspects each ring consumes”

The Compiled Policy is organized by aspect (network / filesystem / tools / interpreter / budget / compliance) per ADR 0003. Each ring's Provider consumes the aspects it can act on:

RingAspects typically consumed
Harnesstools.allow / tools.deny + compliance_tags (rendered into settings.json allow/deny lists, hooks)
Kernelnetwork.* + filesystem.* + identity (rendered into Landlock rules, L7 egress, credential hiding)
Interpreterinterpreter.* (host functions, memory/CPU caps) + network.allow_domains (for executor network)

The same aspect can be enforced at multiple positions — defense in depth — without duplication in the Compiled Policy.

RingWhen the Compiled Policy changes, the Provider…
HarnessRewrites the settings file; agent reloads on next prompt
KernelHot-reload-network where supported (OpenShell L7 proxy <100 ms); restart for FS/exec changes
InterpreterRe-imported on next interpreter boot

The host runtime supervisor handles the per-target update semantics so the user-visible promise — "policy updates apply within seconds" — holds across all rings.

  • filled byProvider (per target)
  • composed intoRuntime (recipe with one provider per ring + cross-cutting)
  • applied toSandbox (one running agent)
  • paired with → cross-cutting layers (LLM Gateway, MCP Broker) — same enforcement plane, different position class
TopicFile
Strategic frameStrategy Memo v3 §06 — Pillar 1: Enforcement Plane
Long-form visiongoverned-agents.md §9 — bypass matrix
Detailed taxonomyenforcement-layers.md — rings + cross-cutting taxonomy
Component cardsq09-rings-and-cross-cutting/
DecisionADR 0001 — Rings, not layers
  • Ring ≠ Layer. Rings are in-process. The "5 layers" framing conflated them with cross-cutting layers (LLM Gateway, MCP Broker), which are between processes.
  • Ring ≠ Target. A ring is a category; targets fill it. Within the kernel ring there are many targets (nono, OpenShell, gVisor, …) — they don't compete; they cover different platforms.
  • Ring numbering is taxonomic, not sequential. Ring 1 (Harness) is not "applied first" — at sandbox start the kernel-ring Provider applies first (you need a sandbox before you can launch the harness inside it). Numbering reflects what each ring governs (most semantic → most compulsory → most narrow), not application order.