Loams v0.1.0 is out: run the whole stack yourself with Docker Compose. See the roadmap

Blog/Research

The harness is an object: places, capabilities and a jailer that doesn't trust the model

What Loams took from Endo and Jason Duncan's essay "The Harness Is an Object", how forty years of object-capability security turn its algebra into rules a machine can check, and the proposed Loams Jailer, a deterministic policy layer with an LLM overseer that is reasoning-blind and may only tighten. Both designs are Proposed; nothing here ships yet.

The harness is an object: places, capabilities and a jailer that doesn't trust the model
On this page
  1. Two sources
  2. The algebra is older than it looks
  3. Places: authority you can see before the run
  4. Why not a harness language
  5. The trifecta check on the way in
  6. Why the model cannot be the boundary
  7. The Loams Jailer
  8. Layer 1: a deterministic policy decision point
  9. Layer 2: sensors and actuators
  10. Layer 3: an overseer that may only tighten
  11. Audit
  12. Prior art, and what we take from each
  13. What this costs, and what we are unsure about
  14. Status and what comes next

Status: Proposed. Nothing in this post ships yet. It describes two design notes from the Loams repository: §60, Places and harness composition, and §61, the Loams Jailer. Their decisions are D1087 to D1105 in the decision log. All of them are Proposed except one licensing choice. The work is planned as JL1, which starts after the sandbox plan SB1 (Planned). Treat everything below as research and intent, not as features.

A coding agent's "harness" used to mean the loop that turns a model's output into tool calls. By autumn 2026 the word was doing four jobs, and two pieces of work helped us pull them apart. The short version of what we concluded: treat a harness as an object in the security sense. It holds authority you can name, it gets more only when something that already holds it hands it over, and composing it with anything else can only shrink what it may do. Build on that, and you can also build a supervisor that does not have to trust the model it supervises.

Two sources

Endo. Endo, from longsurf-ai, is MIT-licensed, at version 0.1.x, and was posted to Hacker News in October 2026. It calls itself a Higher Order Harness: "Compose any agent, on the subscription you already have, into any workflow." It drives Codex, Claude Code, Antigravity and Grok through their own command-line tools and accounts, lets you switch agents mid-thread with the history carried over, and runs workflows written as TypeScript (agent(), parallel(), phase()). "Dig In" opens a side conversation from a selected piece of an answer, and any prompt can be scheduled. It is the clearest statement we have seen of the "harness of harnesses" idea. (It is a different project from Agoric's endojs/endo, the hardened-JavaScript runtime, which comes up again below.)

Loams already has the core of Endo's pitch. Studio (Experimental) runs several harnesses on the user's own subscriptions through loams-agentd, and its run groups fan one prompt out to several agents, each in its own worktree. So what we took from Endo is small: switching harness mid-thread with the switch written into the transcript, "Dig In" as a fork from a selection, and scheduled prompts on Loams Durable (D1093). We took the ideas, not the code. Endo is built on Effect, which our console stack does not use.

"The Harness Is an Object." Jason Duncan's essay, The Harness Is an Object: Notes toward composing intelligence, was published as an X article on 2026-10-16. It is the more important of the two sources for us. Its claim is that "harness" is splitting the way "object" once split into class, instance, interface and module. It names four parts:

  • the cognitive harness, meaning how a mind is assembled from models;
  • the suit, meaning what an agent carries everywhere: its identity, memory and values;
  • the place, meaning the environment it works in: context, tools, rules, and the people and agents present. A repository is a place, and so are a support queue and a kitchen;
  • composition, meaning what happens when a suit meets a place.

Inward composition is "engineered intelligence": a small model answers a typed triage question with a confidence, a threshold escalates to a larger one as a priced choice, and arithmetic and lookups go to deterministic code. Outward composition is entering a place: your harness and the place's compose into a temporary one, and leaving takes it apart while what you made stays behind. A person who walks into a kitchen becomes a chef, and walks out holding a sandwich. The essay then proposes an algebra that it claims holds at every scale, from model into harness to agent into place to team into company:

  • tools intersect, so the place sets the limit;
  • context accumulates for the length of the visit;
  • identity stays with the suit, because a place can give you a role but cannot replace who you are.

We think it is a good essay, and its four-part split is the vocabulary §60 uses. We disagreed with it in one place, which we come back to: it proposes a new three-tier harness language, and we decided not to build one.

The algebra is older than it looks

In 1966 Dennis and Van Horn described capabilities: unforgeable tokens that both name a resource and grant the right to use it. In 1988 Norm Hardy wrote up the confused deputy. A compiler with permission to write a billing file was tricked by a user into overwriting it, because the compiler's authority came from who it was (ambient authority) and not from what it had been handed. An LLM agent steered by a prompt injection is exactly this deputy: it holds authority it was not given for the task at hand.

The object-capability (ocap) tradition turned that into a discipline. Mark S. Miller's E language and his thesis Robust Composition (2006) argued that an object should affect the world only through references it holds, that references come only from creation, introduction by a holder, or the object's own state, and that you attenuate a reference by wrapping it in a weaker one before passing it on. Miller and K. Eric Drexler's "agoric open systems" papers named the company Agoric, whose Hardened JavaScript work lives on as endojs/endo. Under this discipline, composing two objects never produces authority neither held. That is the essay's "tools intersect", made precise.

Operating systems carried the idea into kernels. seL4 proves that authority flows only through capabilities. Capsicum gives FreeBSD processes a capability mode where global namespaces vanish. WASI hands a WebAssembly module only the directories and sockets its host chooses. Landlock lets an unprivileged Linux process drop its own rights irreversibly; not strict ocap, but authority that only shrinks.

Our reading is that the essay rediscovered the right algebra from the agent side, and that the ocap literature supplies what it leaves open: why intersection is safe, what a conflict means, and how to make the rule something a machine checks rather than something a model is asked to respect.

Places: authority you can see before the run

§60's first decision (D1087) makes the Place a first-class record. It bundles a data scope (namespace, project, environment, and a branch of Postgres, Loams SQL, Git or a collection), an allow-list of tools (MCP tools, named Data API operations, engine APIs), the roles it offers, an approval policy, and budgets for time, rows, spend and model calls. Places nest: an organisation is a place made of places, and so are a Studio project, a review room and a support queue.

Entering a Place is an explicit act, and it is recorded. It computes the effective capability: the agent's own grants (its suit) intersected with the grants of the Place and of every place that encloses it. Loams would compute this with OpenFGA and the Place record before the run starts, and show it to the person in the composer and the inspector as a short list of what the agent can and cannot do. Nothing the agent does inside the Place can go beyond it.

Design §60, Proposed. The same operator at every scale: model into harness, agent into place, place into place. Composition can only remove authority, never add it.

§60's second decision (D1088) adopts the essay's rules and applies them the same way at every level: model into harness, agent into place, place into place.

  • Tools and authority intersect. The enclosing scope always sets the limit. This is attenuation, and it is why nesting is safe: a review room inside a project can never grant what the project does not hold.
  • Context accumulates for the visit. On entry the agent gets the place's schema, docs and recent activity, and keeps its own memory. On leaving, context that belongs only to the place is dropped.
  • Identity stays with the agent. A place assigns a role, and the audit trail records the triple (agent, role, place). A role never replaces an identity, so "who did this?" always has an answer that is not "the reviewer".
  • Refusal wins. If the agent's own policy refuses something the place allows, the stricter side decides. If a place requires something the agent's policy forbids, the agent cannot enter that place, and it is told why.

The third decision (D1089) is about what the essay calls leaving behind. Every artifact an agent creates in a place carries (agent, role, place, thread, run): commits, rows with their branch and log position, branches, files, events and approvals. Because the agent's writes land on a branch first, what it left behind can be promoted or discarded as a unit. Because Loams is built on a log, the record of a visit already exists; it only needs labelling.

Why not a harness language

The essay proposes three tiers: natural-language intent on top, an exact "harness IR" in the middle that can be checked before anything runs (LLVM is its precedent), and deterministic machinery at the bottom. We like the middle tier's goal, check it before it runs, and that is what computing the effective capability up front does. But D1092 says Loams will not invent a harness language now.

Query languages taught us this: most attempts to replace SQL ended up compiling to it or forgotten. A Place is data, proto and YAML records checked by OpenFGA and a policy check. If DSPy, BAML or a future standard wins, Loams can compile Places to it.

The trifecta check on the way in

Intersection tells you what an agent may do. It does not tell you whether that combination is safe. Simon Willison's lethal trifecta names the combination that is not: access to private data, exposure to untrusted content, and a way to communicate externally. An agent with all three can be talked into sending the first out through the third, and as he puts it, catching 95% of attempts is a failing grade. Meta's Agents Rule of Two turns this into policy: in one session, hold at most two of the three without a person supervising.

Design §61 (D1097) puts this check where Places make it cheap, at the moment of entry. The effective capability is a concrete set of grants, so you can ask three questions of it: does it reach private data, does it read untrusted input, and can it send data out or change state? If all three are true, the run does not start. The person either drops one leg, for example by limiting egress to the model API and Loams itself, or approves with a typed confirmation that names what they are accepting.

The second half of D1097 is one-way taint. A run starts clean. The moment it reads untrusted content (a web page, the text of an issue or pull request, rows the Data API marks untrusted, files written by another agent) it is tainted, and it stays tainted until the session ends. From then on, any new egress host, any write outside its branch and any tool not named in the Place needs a person's approval. Nothing can clear the taint.

Design §61 §4.5, Proposed. Taint is tracked per session, not per value: coarser than CaMeL's data-flow tracking, but it needs no changes to the harnesses it supervises.

This is a deliberately blunt version of what CaMeL (Debenedetti et al., 2025) does well. CaMeL tracks capability-tagged values through a privileged and a quarantined model, makes most AgentDojo tasks provably safe at about 2.8 times the tokens, and needs the agent rewritten around it. Per-session taint gives up that precision and will ask in cases CaMeL would allow. In exchange it works over any harness unchanged, and the guarantee is easy to say: after a run has read something untrusted, it cannot quietly gain a new way out. We think a guarantee you can say in one sentence is worth some lost utility.

Two related rules sit beside it. Egress is a risk class of its own, distinct from reading or writing, because a GET request with data in its URL is an exfiltration, not a read. Hard budgets for spend, CPU, wall time, rows and turns freeze a run when exceeded, instead of logging a warning.

Why the model cannot be the boundary

The obvious alternative to all of this is to put a second model in front of the first: an LLM that reads each action and decides whether it is safe. Every shipping harness now has something like that, and they are useful. But the research and the vendors themselves agree that it is not a boundary.

  • AI control. In Greenblatt et al.'s AI Control (2023), trusted monitoring alone reached 62% safety, and trusted editing 92% safety at 94% usefulness. Monitors help a lot and leave gaps.
  • Adaptive attacks. Terekhov et al. (2025) showed frontier models "consistently evade diverse monitors" by planting text aimed at the monitor, an attack that "works universally against current protocols that rely on a monitor". Resampling and keeping the least suspicious sample becomes a best-of-n attack.
  • The vendors. Claude Code's auto mode uses a two-stage, reasoning-blind classifier that never sees the assistant's prose or tool outputs, reports 0.4% false positives on real traffic, and hands over to a person after 3 consecutive or 20 total denials, all on top of an OS sandbox and an allow-list proxy. Codex calls its reviewer "not a deterministic security guarantee", and Cursor calls its own "not a security boundary".

The defences with guarantees are deterministic and outside the model. Default-deny tool proxies such as Progent drive attack success to zero within the permissions they enforce, and say nothing about attacks inside them. Deterministic policy gives you a hard edge; a model can make the space inside it pleasanter to work in. Neither substitutes for the other.

The Loams Jailer

The owner's direction for §61 was a "jailer agent that oversees the sandbox", using "KVM and syscall interception, eBPF, all tools for a hypervisor agent". The name comes from Firecracker's jailer, the process that sets up namespaces, cgroups and a chroot for each microVM, drops privileges and then runs the VMM. The design (D1094) keeps the spirit and spreads it across three layers.

Design §61, Proposed (plan JL1, after the sandbox plan SB1). The sandbox and the deterministic layer are the boundary; the overseer is a filter that saves people clicks.

Layer 1: a deterministic policy decision point

The jailer process is the parent of the sandbox and the policy decision point (PDP). Every enforcement point asks it before acting: the agentd approval hook, the MCP and LLM gateways, the egress proxy, Data API writes and Git pushes. It answers from the Place's effective capability first, then from the rules above: trifecta, taint, egress class, budgets, and a circuit breaker that pauses and asks a person after 3 consecutive or 20 total denials, which follows Claude Code's practice. The targets are under 5 ms per decision, a decision that can be reproduced, and no model in the loop.

It has more verbs than allow and deny. It can require approval as a durable promise a person answers tomorrow; rewrite, but only to narrow (point a push at the agent's branch, add --dry-run); defer the turn to another harness or model, picking the most suspicious sample when it resamples; pause, throttle or cut egress while the run keeps its state; quarantine (freeze, snapshot, revoke tokens, mark the output unpromotable); kill; and roll back in one operation (D1103) across Git, Postgres and collection branches plus the checkpoint or snapshot.

Layer 2: sensors and actuators

Here "KVM, syscalls and eBPF" becomes per-platform choices. The sensor order in D1101 runs from cheap and unprivileged to powerful and privileged:

  1. Proxy audit and cgroup events. Egress goes through a proxy; cgroup v2 reports memory events, pressure and CPU. Actuators: cgroup.freeze, cgroup.kill, cpu.max, and a live allow-list change.
  2. Landlock audit. Since Linux 6.15, Landlock can log denials, so the jailer sees what the sandbox refused.
  3. gVisor runtime monitoring. seccheck streams syscall-level trace points to an external sink, with no host eBPF.
  4. A guest agent over vsock. In Firecracker microVMs a guest agent reports over vsock, and the VMM offers pause, snapshots and rate limiters on network and disk.
  5. eBPF, optional, privileged, servers only. An Aya-based sensor for exec, open and connect per cgroup, with cgroup BPF egress pinning as a second check.

The "don'ts" matter as much as the list:

  • seccomp user notification is never the boundary. Its man page says it "can not be used to implement a security policy" (time-of-check to time-of-use races). Audit and ask, never enforce.
  • No reliance on BPF-LSM denials on desktops. It is often built in but not enabled (Ubuntu is an example), and eBPF needs CAP_BPF and CAP_PERFMON, which an unprivileged desktop daemon should not hold.
  • No VM introspection. LibVMI, DRAKVUF and similar tools need out-of-tree kernels, target Xen first and are GPL or LGPL.

The one approved decision here (D1102) is licensing: eBPF kernel programs, if we write them, live in their own crate under GPL-2.0-only OR MIT, the split Cilium and Tetragon use, while userspace stays Apache-2.0.

None of this replaces the sandbox. The Loams sandbox design (§56, plan SB1, Planned) remains the boundary: namespaces, cgroups, Landlock and seccomp on Linux, gVisor or Firecracker where tenants share hosts, Seatbelt on macOS, AppContainer on Windows. D1096 adds pause, resume, set_net_policy, set_limits and an event stream to its interface as SB1 is built, so the jailer can steer a running sandbox.

Layer 3: an overseer that may only tighten

The LLM overseer is never inside the sandbox and has no tools. It is a stateless call the jailer makes, and its only output is a verdict. It sees only the cases the PDP marks ambiguous, and it sees them through a paraphrased, reasoning-blind view (D1100): the user's intent, the Place, the action, the diff and a summary of the taint. It never sees raw text written by the agent or by a tool, because that text is the channel the adaptive attacks above use.

It runs in two stages. The first is a small local model answering typed questions with a confidence (is this exfiltration? destructive? off task?), and it leans towards flagging. The second is a larger model reached through the Loams LLM gateway, ideally from a different model family than the harness to reduce the chance of collusion, and it runs only on what the first stage flagged. The target is a second-stage call on at most 5% of actions.

What makes the design safe is the monotone rule. The overseer may move a verdict up the ladder, from allow to ask or from ask to deny, as often as it likes. It may move one step down in exactly one case: an action the PDP marked "ask" that already sits inside the effective capability may be auto-allowed. That is the whole of its utility, and it is a real one, because fewer clicks for people means fewer people giving up and granting full access. It can never allow something the policy denies. Destructive Git operations and typed confirmations always go to a person. So the worst a fooled overseer can do is save a click it should not have saved, inside a boundary the deterministic layer already approved.

The overseer also has to earn even that. It ships in shadow mode, logging verdicts without acting on them, until its false-positive rate on real Studio traffic is under 1% and adaptive red-team attacks do not raise attack success above the deterministic-only baseline.

Audit

Every verdict becomes a CloudEvent on the thread's stream (D1104): agent, role, Place and run, a digest of the input, which layer decided and how, the model and confidence, and the actuator used. Verdicts link to what the agent left behind, a local copy goes into a hash-chained log, and "why was this blocked?" has a record to point to.

Prior art, and what we take from each

WorkWhat it doesWhat Loams takes
E, Robust Composition, AgoricNo ambient authority; authority by reference; attenuationEffective capability as an intersection; composition only removes authority
seL4Proven capability-based kernelAuthority you can enumerate before the run
CapsicumCapability mode for Unix processesEntering a Place as a one-way narrowing
WASIHost hands a module only what it may useTools as an allow-list per Place, not a global registry
LandlockUnprivileged, irreversible self-restriction, with auditA desktop sandbox without root, and a denial log
gVisorUser-space kernel; runtime monitoringSyscall-level sensors without host eBPF
FirecrackermicroVMs; jailer; snapshots; rate limitersThe name, and pause, snapshot and throttle as actuators
eBPF and BPF-LSMIn-kernel observation and enforcementAn optional, privileged server sensor; never a desktop dependency
CaMeL, ProgentData-flow tracking; default-deny tool proxyOne-way taint per session; deny by default at every enforcement point
Claude Code auto mode, Codex auto-reviewReasoning-blind reviewer over an OS sandboxThe overseer's view, its circuit breaker, and its place: above the boundary

What this costs, and what we are unsure about

  • Clicks. The trifecta check and taint rule add approvals. That is why the overseer exists, and why we measure before trusting it.
  • Coarseness. Session-level rules will refuse some safe things. We chose rules we can state over rules that are clever.
  • Sabotage. Benchmarks such as SHADE-Arena suggest monitors miss most subtle sabotage. The mitigation is structural: branches, tests, and a person promoting what the agent left behind.
  • Open questions (Q936 to Q948): where the Place record lives, whether places learn from visitors (default: only through a proposal a person approves), whether an agent may rewrite its own Place (only inside the enclosing limits, as a proposal), and how much a cloud second stage may see.

Status and what comes next

Both designs are Proposed. The order in D1105: the sandbox plan SB1 first (approved, not built), then JL1a, the deterministic jailer in agentd; JL1b, the overseer in shadow mode; JL1c, enforcement in the LLM, MCP and Data API gateways; JL1d, gVisor and microVM sensors; and JL1e, eBPF, last. Places land with the next part of the console redesign, where the composer's scope chips select a Place and the inspector shows its effective capability and what the agent left behind.

Thanks to the Endo authors for showing how far a harness of harnesses gets you, to Jason Duncan for giving the problem a vocabulary, and to the object-capability community, which worked out the algebra decades before agents needed it. We will write again when JL1 has numbers.

More from the blog