Roles
Isolate the authority, not the work
Copying the work into separate clones forced every change through several git crossings. What has to be kept apart is who signs as whom and who publishes. iter separates who works, who decides, who accepts and who publishes:
Work
The session, the agent's or the owner's: its own workspace of the store, and no publishing key.
Decide
Governance: ontoref's gov and the repository's declaration hold the rules, and nothing able to carry them out.
Accept
The owner, when the class of the change requires it, with their own signing key. A change of a free level is accepted without calling the owner.
Publish
The integration identity, whose push is limited by the forge. It has no judgement of its own: it carries out what was accepted.
The declaration
What holds for every user of the store travels with it
jj keeps its per-repository config in each user's directory, not in the repository. So the policy is declared in the repository, in iter.ncl and allowed_signers, held to schema/declaration.ncl, and each user applies it with iter setup:
- Read from the published trunk. setup reads
main@origin, never a working copy or the local bookmark: anyone who writes in a shared store could move either, and the agent could add itself as a trusted signer. The remote's URL is pinned on first use and the commit is checked against the forge. - sign_on_push is always false. A shared store always mixes authors, and signing on push would rewrite another author's commits. Each author signs their own change when describing it; publishing refuses what is unsigned.
- workspace_root is where users' workspaces open:
<root>/.iter-ws/<store>/<name>, declared once, here.
A change, end to end
Nobody runs a synchronisation step
Open
iter workspace <name> <store> --root <dir>colocates a plain git repository first if needed, opens the user's workspace and links its.claudeand.coderto the project's.Work and finish
jj snapshots the folder; there is no staging, no commit and no push. Finishing is
jj describeandjj new: the change, signed by its author, stops being the working copy.See
iter statuscomputes, from the store, each unpublished change's workspace, author, state, signature, collisions with other sessions and the next act. Nobody reports it, so it cannot fall behind.Accept
iter accept <change>brings the change into the trunk only when every commit is signed by its author, the contracts covering what it touches are paid on its own tree, and every crossing is under a verified verdict. It puts an accept commit by the caller on top and moves the bookmark: the agent's commit is never rewritten, so its signature survives.Publish
iter publish, run by the integration identity, judges everything between the published trunk and the local bookmark as accept does, requires the bookmark to descend from what was published, and pays the contracts due at publish time: a red one leaves the forge's trunk where it was.
The owner's signature appears only at accept, and only when the class of the change requires it.
Commands
The operations of work, each idempotent or judged
status
Unpublished changes of one store, or of every store under --root. A store it cannot read is reported as a row; it does not hide the others.
declare
Writes a repository's iter.ncl from iter's template and its signers into allowed_signers; committing and publishing them stays the owner's act.
setup · forge-commit
Applies the published trunk's declaration to your own jj config. A user without forge access receives the trunk commit another user read from the forge.
workspace · link
Opens a user's workspace of a store and links .claude and .coder to the store root's, excluded from the store before the link is created.
accept · publish
Judge, then act. With --check they judge and change nothing; with --repay they run every due contract again, even one already paid over the same bytes.
once · batch
once records a command's pass under the content of the tree it ran over, so the same bytes are not run again, from a hook, a recipe or a contract inside accept. batch carries the crossings of several stores under one signature per signer.
Principles
What holds in a shared store
Each author signs their own
Rewriting a commit destroys its signature. A change is signed by whoever made it, and nothing published carries a commit not signed by its author.
Accepting never rewrites
Accepting is putting your own signed commit on top, never rebasing someone else's.
State is computed, not told
What is ready, signed, accepted or colliding is read from the store every time.
A member opens inside its spine
A store nested in another repository opens inside that repository's workspace of the same name, which must exist first (ADR-001). iter knows nothing of ontoref: the rule is about nesting.
Boundaries
What iter is not
Not the policy
It does not decide what a class of change requires; gov does, and the repository declares it. iter carries it out.
Not the boundary
It opens the agent's workspace; isolation holds the boundary around it. Each runs without the other.
Not a forge or a CI
The forge keeps the published trunk and limits who may push. iter judges and moves a bookmark; it hosts nothing.
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.
iter provides its SignedHistory axis, which a store shared by workspaces relies on.
custody.ontoref.dev →
Isolation
The host boundary between an owner and the agent working beside them.
Holds the host boundary around the workspace iter opens.
isolation.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 →
Two workspaces, one rule, one trunk.
Nothing is published that accept has not judged, and nothing judged loses the signature of the one who wrote it.