OXYGENHUB

Design: AI-native agent workflows (refs #64) b277870b0749

Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-03 20:10 UTC
Signature
✔ signed by Andy McCall
Hash
b277870b074948c7e28655381786d2197c59b152f632e6bb56c595a56f75e40b
Depends on
ff0af1ee299d
Depended on by
5cde7882d767 ff1a64f81c1c 7ba155f20aa0
In bookmarks
agents-in-readme bare-hashes carried-not-removed carry-identical doctor-trust identical-sides keyless-tags main merge-remote-bookmark only-help-103 paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state switch-says
In tags
v0.10.0 v0.11.0 v0.4.0 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
1 atom, 1 tree operation, 1 file

Browse the tree at this change

added docs/ai_native_agent_workflows.md +228 −0
1 +
# Oxygen (`oxy`): AI-Native Agent Workflows Specification
2 +
3 +
| | |
4 +
|---|---|
5 +
| **Status** | Draft 1.1 |
6 +
| **Date** | 2026-10-03 |
7 +
| **Audience** | Implementers and AI tooling developers |
8 +
| **Depends on** | spec.md §6 (changes), §9 (conflicts), §12 (operation log, workspaces), §14 (identity, policy), revsets (`revset_query_language.md`) |
9 +
10 +
## 1. Overview and philosophy
11 +
12 +
Coding agents, such as Aider or Claude Code, or local LLM loops, commit
13 +
at machine speed. A version control system must let them work without
14 +
giving them the keys to the kingdom, and without burying the human's
15 +
history in micro-changes.
16 +
17 +
The guiding principle is **delegated, bounded, reversible autonomy**:
18 +
19 +
- **Delegated:** an agent acts under its human owner's identity, with its
20 +
  own key, so every change it makes is attributable to both.
21 +
- **Bounded:** an agent can record changes but cannot move protected
22 +
  bookmarks, approve, or seal, whatever its owner may do.
23 +
- **Reversible:** an agent works in its own workspace and bookmark, so
24 +
  discarding its session never touches the human's work.
25 +
26 +
None of this weakens what Oxygen already guarantees. The change graph is
27 +
immutable, every change is signed with Ed25519 and ML-DSA-65, policy is
28 +
verified on fetch and push, and the operation log records everything.
29 +
30 +
Each section says what **exists** today and what is **new**.
31 +
32 +
## 2. Agent identity and delegation
33 +
34 +
**Exists (§14.2):** an identity object has `delegates [8]: [KeyId]`.
35 +
These are keys allowed to sign or seal changes whose `author` is that
36 +
identity. Delegation is one level deep and not transitive, and
37 +
`oxy identity delegate add|remove` manages it. Any change to an identity
38 +
is a rotation: a successor object.
39 +
40 +
- **The agent's own key pair.** An agent generates its own Ed25519 and
41 +
  ML-DSA-65 key pair locally. Its identity object's `name` says what it
42 +
  is, for example `"aider 0.x on andy-laptop"`. An agent never holds the
43 +
  human's secret keys.
44 +
- **Authorship.** Changes the agent records set `author` to the human's
45 +
  `KeyId` and are signed with the agent's key. The signature's KeyId
46 +
  identifies the agent. **No marker is stored in the change:** `extra
47 +
  [9]` is reserved and must stay empty, and the signature already proves
48 +
  which agent made the change, which a marker could not.
49 +
50 +
**New: scoped delegation.** Today a delegate moves references as far as
51 +
its delegator may (§14.5). That is right for a hub signing browser edits,
52 +
and wrong for an agent. `delegates` becomes a list of entries:
53 +
54 +
```
55 +
delegates [8]: [{ key [0]: KeyId, scope [1]: ["changes" | "refs" | "seal"], expires [2]: u64? }]
56 +
```
57 +
58 +
- An agent is added with `--scope changes`. Its signature authenticates
59 +
  changes, but a reference or tag attestation, or a seal, signed by it is
60 +
  refused. **An agent can never land on a protected bookmark**, even
61 +
  when its owner could.
62 +
- A per-delegate `expires` limits an agent to a session or a day
63 +
  (`--expires 8h`), without rotating the human's own expiry.
64 +
- Hosts that sign for users keep the current behaviour with
65 +
  `--scope changes,refs`.
66 +
- This is a format change to the identity object. That is acceptable
67 +
  before 1.0.
68 +
69 +
**New: revocation by the delegator.** Today only the revoked key itself
70 +
or a policy root key may sign `revoke`. An agent's key may be lost on a
71 +
compromised machine, and the policy root is often someone else, so the
72 +
identity that delegated a key may also revoke it. Removing a delegate in
73 +
a successor identity stops future use. Revoking it also marks the changes
74 +
the agent already signed as *valid but revoked* in `oxy verify` and on
75 +
the hub, so they get a second look.
76 +
77 +
## 3. Isolation: one workspace and bookmark per session
78 +
79 +
**Exists:** `oxy workspace add` creates an extra checkout that shares the
80 +
repository, each with its own current bookmark.
81 +
82 +
**New:** `oxy agent start NAME` does three things:
83 +
1. creates a workspace under `.oxy/agents/NAME/`;
84 +
2. creates the bookmark `agents/NAME/<session>` from the human's current
85 +
   heads;
86 +
3. records a session operation carrying the agent's KeyId.
87 +
88 +
The agent works only there. This replaces a session marker in the
89 +
human's operation log:
90 +
91 +
- **The human's working copy is never touched.** Changes commute, so the
92 +
  human keeps working on the same files at the same time, and merging
93 +
  the agent's bookmark later is an ordinary `oxy merge`.
94 +
- **Discarding a session** is `oxy agent drop NAME`: delete the
95 +
  bookmark and the workspace. Nothing the human did is undone, unlike an
96 +
  undo in a shared workspace would.
97 +
- **Undo within a session** is the agent's own operation log (§12),
98 +
  scoped to its workspace. The new `oxy undo --to OP` returns to any
99 +
  earlier operation of that workspace.
100 +
101 +
## 4. Micro-changes: keep them, show them folded
102 +
103 +
Agents produce many small changes. Oxygen keeps them, because each is
104 +
signed, cheap, and commutes with everything that does not touch the same
105 +
lines. The noise is a display problem first.
106 +
107 +
- **New, display folding:** `oxy log` shows a run of consecutive changes
108 +
  signed by the same agent key as one line: "aider: 37 changes, 4
109 +
  files". `--expand` shows them all. The hub does the same.
110 +
- **New, adoption:** when the human wants one change in history,
111 +
  `oxy fold -r REVSET` folds the selected changes into one new change.
112 +
  It uses the revset language, for example
113 +
  `oxy fold -r 'signed_by(aider) & main..agents/aider/s1'`. The folded
114 +
  change is authored and signed by the human's own key. It records the
115 +
  folded changes' hashes in its description footer, so the trail to the
116 +
  agent's work stays verifiable while those changes remain stored.
117 +
  The existing `oxy squash` folds one change into a dependency and stays
118 +
  as it is.
119 +
- **Folding is optional.** Unfolded agent changes stay valid history.
120 +
  Folding is for when a team's convention wants one reviewed change.
121 +
122 +
## 5. Conflicts as data, for agents
123 +
124 +
**Exists:** conflicts are recorded in states, not raised as errors (§9).
125 +
A conflicted state can be committed and built on, and `oxy resolve`
126 +
reports which conflicts the current files resolve.
127 +
128 +
- **Reading conflicts:** `oxy status --json` lists each conflict: path,
129 +
  node, kind (order, name or tree), and the contributing ChangeIds.
130 +
  `oxy cat PATH --at CHANGE` gives each side's text for the agent's
131 +
  context.
132 +
- **Resolving:** the agent writes the resolved files and runs
133 +
  `oxy commit`. **Oxy computes the resolution's dependencies**: a
134 +
  resolution must depend on every change that contributed an atom to
135 +
  the conflict. An agent never writes `deps` by hand. Correctness of the
136 +
  graph is Oxygen's job, not the model's.
137 +
- **A valid resolution is not necessarily a right one.** The graph will
138 +
  be well-formed; the code may still be wrong. A policy rule for
139 +
  protected bookmarks can require that a resolution signed by an agent
140 +
  has a passing Flow receipt and a human approval before it lands.
141 +
142 +
## 6. Review and policy on the hub
143 +
144 +
- **Badges:** changes signed by a delegate with `changes` scope show
145 +
  "agent: NAME on behalf of HUMAN" on the hub and in `oxy log`.
146 +
- **Approvals:** approvals count only signatures by keys that are not
147 +
  agent-scoped delegates, so an agent cannot approve its own work or
148 +
  anyone else's.
149 +
- **Policy:** a policy rule may name agent rules, for example "agents may
150 +
  push `agents/**` bookmarks only" or "an agent-signed change needs a
151 +
  passing receipt to land".
152 +
- **Audit:** the trust page and `oxy verify` list agent-signed changes
153 +
  separately, with the delegation that authorized each.
154 +
155 +
## 6a. Optional: a human always lands AI work
156 +
157 +
Whether a human must land every AI-authored change is a **per-project
158 +
choice**. A regulated codebase may insist on it; a personal project or a
159 +
team that trusts its agents and tests may not. Oxygen's job is to make
160 +
the gate easy to turn on and impossible to bypass when it is on. It must
161 +
never impose the gate on everyone.
162 +
163 +
**With scoped delegation (this draft).** The agent is your delegate
164 +
with `--scope changes`, so its changes carry your authorship and its
165 +
signature. The policy decides whether it can land:
166 +
167 +
```
168 +
rules: [
169 +
  { pattern: "main",      keys: [andy, sam], threshold: 1, require: "signed" },
170 +
  { pattern: "release/*", keys: [andy, sam], threshold: 2, require: "signed" },
171 +
  { pattern: "agents/**",  keys: [andy, sam], threshold: 1 },
172 +
]
173 +
```
174 +
175 +
- **Gate on:** an agent-scoped delegate can never sign a reference
176 +
  attestation, so only Andy or Sam can move `main`. Approvals count only
177 +
  keys that are not agent-scoped, so a human approved and a human landed.
178 +
  The agent's changes keep their own signatures, so the landed history
179 +
  still shows which agent wrote what.
180 +
- **Gate off:** delegate the agent with `--scope changes,refs` instead.
181 +
  It then moves references as far as its owner may, and can land on its
182 +
  own where the policy allows. The project chooses this per agent, and
183 +
  the trust page and `oxy verify` still show every agent-signed change and
184 +
  every agent-signed bookmark move.
185 +
- **Per bookmark:** the usual setup gates `main` and `release/*` and
186 +
  leaves `agents/**` open, so agents push and move their own bookmarks
187 +
  freely while a human lands everything else. That needs refs scope
188 +
  that reaches only the open rules: a policy rule field naming agents
189 +
  explicitly, which is part of the §14.5 change.
190 +
191 +
**With today's spec (no scoped delegation).** A delegate moves
192 +
references as far as its owner, so the gate needs a different setup:
193 +
1. Give the agent its **own identity**, not a delegate.
194 +
2. List only human keys in the `main` rule, and the agent's key in an
195 +
   `agents/**` rule.
196 +
3. Policy checks each change a bookmark move adds, so the agent's changes
197 +
   cannot reach `main` directly at all. A human adopts the work by folding
198 +
   or re-committing it under their own key.
199 +
200 +
This gate is strict and works now. The cost is that the landed history
201 +
records the human as signer, not the agent.
202 +
203 +
**On the hub: agent-scoped tokens.** Policy governs keys, but landing on
204 +
the hub is done with an account's token. An agent using a human's token
205 +
lands *as that human*, and no policy can tell. The hub therefore needs
206 +
**agent tokens**:
207 +
- tied to an agent key and its human owner;
208 +
- allowed to push `agents/**`, open and update proposals, and comment;
209 +
- refused for landing, approving, changing settings or policy, and
210 +
  creating tokens, whatever the owner may do.
211 +
212 +
Hub actions taken with an agent token are recorded as "AGENT on behalf of
213 +
HUMAN" in the audit log and on the proposal. A project with the gate off
214 +
may still let agent tokens land, as a repository setting that mirrors the
215 +
policy, never by default.
216 +
217 +
## 7. Summary of new work
218 +
219 +
| Item | Spec section to change |
220 +
|---|---|
221 +
| Scoped, expiring delegates | §14.2 identity object, §14.5 policy |
222 +
| Revocation by the delegator | §14.2 |
223 +
| `oxy agent start` / `drop`, session operation | §12, CLI |
224 +
| `oxy undo --to OP` | §12, CLI |
225 +
| Display folding, `oxy fold -r` | CLI, hub |
226 +
| Agent-aware approvals and policy rules, optional human gate (§6a) | §14.5, hub spec |
227 +
| Agent-scoped hub tokens | hub spec (API tokens) |
228 +
| `oxy status --json` conflict listing (check what exists) | §9, CLI |