The boundary
The top level is the owner's; what lies below stays open
The agent works in the owner's own stores, so it cannot be shut out of .git/: its jj workspaces write objects, refs and their own worktree. What it must not touch is what the owner's git executes or obeys. Every .git and .internal.git under the shared roots carries two entries for the agent (ADR-001):
- The first stops the agent creating, replacing or deleting anything at the top level: a rename over
configis refused. - The second reaches the files created directly in the git-dir and nothing deeper, so a
config,HEADorpacked-refsthe owner's git rewrites is born denied. - Below the top level,
objects/,refs/andworktrees/<name>/stay writable for the agent's workspaces, andloose-refskeeps the refs its jj updates out ofpacked-refs.
Why the top level: a config written by the agent can set core.hooksPath or core.fsmonitor, which runs the agent's code as the owner on the owner's next git command. Repairing the ACL afterwards comes after that code has run.
One tree, two actors
The boundary follows what each actor executes
The owner's part
The top level of every git-dir and its hooks, jj's config-id, .claude, the secret files under the shared roots and the vault. The agent is denied write on all of it, and read on the secrets and the vault.
The agent's part
A jj workspace of the owner's store, which iter opens and isolation bounds (ADR-002). The agent has no clone: no code path writes, fetches or pushes as the agent with git.
What guides it
Managed Claude Code settings, root-owned, and the agent's CLAUDE.md are part of the boundary, but they orient the agent; they are not what holds it.
Principles
Refused by the host, never asked of the agent
The host refuses
User, group, ACL and ownership: what the agent's account may not do is refused by the kernel.
Applied by the owner
The owner applies the boundary under sudo. The agent never applies, widens or repairs it.
The kernel prevents; a guard reconciles
The guard re-denies what the owner's own rewrites or new repositories opened. It refuses nothing itself and never passes for prevention.
An intrusion is reported, not repaired
A control file owned by the agent is not drift. The guard reports it, notifies and exits 1, leaving the file for the owner to inspect before running git there.
One write path
The agent writes only through jj in its workspace. Accepting is the owner's act and publishing the integration identity's.
Every step is idempotent
Each step is a row applied only when not ok. A workspace iter opened, or opened by hand, reports ok when isolation runs, and the reverse.
Build a host
Declared once, applied in order
A host is declared by merging schema.ncl, catalog.ncl and hosts/<host>.ncl. nu isolation.nu boundary builds only the agent boundary and then exits 1 unless the witness holds: it is what custody's agent_isolation component runs. bootstrap sets up the whole host, stopping at the first failing step.
Provision
provisioncreates the shared group, makes it the agent's primary group and adds its members; on Linux it also creates an absent agent user, with a locked password.Share
apply-aclputs inheritable group ACLs on the shared roots, so what each user creates there is readable by the other.Deny
deny-secretsputs an explicit deny for the agent on every exposed secret file;deny-controldenies it the files the owner's git, jj and Claude Code execute or obey, and the git-dir top level.Orient
managed-claudeinstalls the managed Claude Code settings, root-owned;agent-claudethe agent's Claude Code configuration, its shared parts linked read-only.Guard
guard installschedules the owner'sguard runeveryhost.guard.intervalseconds and at login: a LaunchAgent on macOS, a systemd user timer on Linux.Open the workspace
agent-workspace <store>calls iter for the agent, applies the deny and loose refs to that store and attemptsjj statusthere as the agent. It refuses when iter is not on PATH.
Proof
It proves itself by exit code
witness
Read-only. Exits 1 unless every check row is ok and every control target denied. Custody cites it as the witness of the AgentBoundary axis.
attempt
Tries, as the agent, what the boundary refuses: write each control target, write the managed settings, read the integration identity's key. Exits 0 only when every attempt was refused.
guard check
Read-only. Exits 1 unless the guard's event pass is loaded and watches the .jj/repo of every jj store under the roots; a store created after guard install is reported as unwatched.
scan
Scans files for secrets with the host's rules and prints file, rule and count, never a value. A project's overlay secret gate calls it before the private overlay commits.
Two platforms. macOS uses chmod +a and launchd; Linux uses POSIX ACLs and a systemd user timer. On Linux, iter's store sharing does not work yet (jj-vcs/jj#8716, store files written 0600), so an isolated agent there has no write surface.
Boundaries
What Isolation is not
Not a sandbox
The agent works in the real trees and the real store, beside the owner. Only the owner's part is refused to it.
Not an instruction
It asks nothing of the agent. What the agent's configuration says it should not do, the host refuses anyway.
Not a secrets store
It keeps secret files out of the agent's reach; it does not store, encrypt or hand out secrets.
ontoref Gov
Seven projects, one domain: how a project governed by ontoref governs itself.
What it is
Gov is ontoref's own domain. It holds the arrangement — what a project's boundary declares, its members, which artefacts a consumer inherits — and the exercise — what work is committed and how an act is delivered. Its name is the root of governance, governability and government, and elects none of them.
Why
A decision, a boundary or a delivery that lives only in someone's memory binds no one. In Gov each one is a declaration a project can be held to, and what holds it is a mechanism, not a good intention.
What for
A project reaches Gov by bond, never by imposition, and takes only the parts it needs. Each of the seven carries one: the contract, the host boundary, the operations of work, the signature, the dossier, the observed session and the opening by name.
Part of the same system
Custody
The contract a safeguarded project is held to: who may touch it, who signed it, where its private half lives, and whether its copy restores.
The contract isolation is held to: it provides the AgentBoundary axis.
custody.ontoref.dev →
iter
The operations of work in a jj store shared by an owner and an agent.
Opens the agent's jj workspace; isolation holds the boundary around it (ADR-002).
iter.ontoref.dev →
Signatio
Custody, verification and authorization around the act of signing.
signatio.dev →
SpecDossier
The dossier of a Statement of Work: drafts by digest, review rounds, receipts, and a one-way mirror.
specdossier.dev →
wuwei
Agent sessions, observed without forced intervention.
wuwei.observer →
openbyname
A link on a web page opens a file on your own machine, by name and safely: the link carries only names, and your machine decides what it may do.
openbyname.dev →
One boundary, refused by the host.
The host boundary between an owner and the agent working beside them, applied by the owner and witnessed by exit code.