OXYGENHUB
◆ main oxygen / docs / ai_native_agent_workflows.md
11.8 KiB · Markdown · last changed Who did the work: via AGENT in log and show, delegates by name 1 month ago renderedsource blame history raw
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. In practice
49
  (implemented 2026-10-04): the agent's keys live in its own `$OXY_HOME`,
50
  and its user config (or `$OXY_SIGNER`) sets `author.signer` to its
51
  KeyId; the checkout's `author.key` stays the human's, so `oxy commit`
52
  run by the agent carries the human as author and the agent's
53
  signature, and `oxy log -r 'delegated()'` lists what the agent did.
54
55
**Scoped delegation (§14.2, implemented 2026-10-04).** Before it, a
56
delegate moved references as far as its delegator may (§14.5). That is
57
right for a hub signing browser edits, and wrong for an agent. `delegates`
58
is a list of entries:
59
60
```
61
delegates [8]: [{ key [0]: KeyId, scope [1]: ["changes" | "refs" | "seal"], expires [2]: u64? }]
62
```
63
64
- An agent is added with `--scope changes`. Its signature authenticates
65
  changes, but a reference or tag attestation, or a seal, signed by it is
66
  refused. **An agent can never land on a protected bookmark**, even
67
  when its owner could.
68
- A per-delegate `expires` limits an agent to a session or a day
69
  (`--expires 8h`), without rotating the human's own expiry.
70
- Hosts that sign for users keep the current behaviour with
71
  `--scope changes,refs`.
72
- A bare KeyId in an older identity means every scope.
73
74
**Revocation by the delegator (implemented 2026-10-04).** Before it,
75
only the revoked key itself or a policy root key could sign `revoke`. An agent's key may be lost on a
76
compromised machine, and the policy root is often someone else, so the
77
identity that delegated a key may also revoke it. Removing a delegate in
78
a successor identity stops future use. Revoking it also marks the changes
79
the agent already signed as *valid but revoked* in `oxy verify` and on
80
the hub, so they get a second look.
81
82
## 3. Isolation: one workspace and bookmark per session
83
84
**Exists:** `oxy workspace add` creates an extra checkout that shares the
85
repository, each with its own current bookmark.
86
87
**New:** `oxy agent start NAME` does three things:
88
1. creates a workspace under `.oxy/agents/NAME/`;
89
2. creates the bookmark `agents/NAME/<session>` from the human's current
90
   heads;
91
3. records a session operation carrying the agent's KeyId.
92
93
The agent works only there. This replaces a session marker in the
94
human's operation log:
95
96
- **The human's working copy is never touched.** Changes commute, so the
97
  human keeps working on the same files at the same time, and merging
98
  the agent's bookmark later is an ordinary `oxy merge`.
99
- **Discarding a session** is `oxy agent drop NAME`: delete the
100
  bookmark and the workspace. Nothing the human did is undone, unlike an
101
  undo in a shared workspace would.
102
- **Undo within a session** is the agent's own operation log (§12),
103
  scoped to its workspace. The new `oxy undo --to OP` returns to any
104
  earlier operation of that workspace.
105
106
## 4. Micro-changes: keep them, show them folded
107
108
Agents produce many small changes. Oxygen keeps them, because each is
109
signed, cheap, and commutes with everything that does not touch the same
110
lines. The noise is a display problem first.
111
112
- **New, display folding:** `oxy log` shows a run of consecutive changes
113
  signed by the same agent key as one line: "aider: 37 changes, 4
114
  files". `--expand` shows them all. The hub does the same.
115
- **New, adoption:** when the human wants one change in history,
116
  `oxy fold -r REVSET` folds the selected changes into one new change.
117
  It uses the revset language, for example
118
  `oxy fold -r 'signed_by(aider) & main..agents/aider/s1'`. The folded
119
  change is authored and signed by the human's own key. It records the
120
  folded changes' hashes in its description footer, so the trail to the
121
  agent's work stays verifiable while those changes remain stored.
122
  The existing `oxy squash` folds one change into a dependency and stays
123
  as it is.
124
- **Folding is optional.** Unfolded agent changes stay valid history.
125
  Folding is for when a team's convention wants one reviewed change.
126
127
## 5. Conflicts as data, for agents
128
129
**Exists:** conflicts are recorded in states, not raised as errors (§9).
130
A conflicted state can be committed and built on, and `oxy resolve`
131
reports which conflicts the current files resolve.
132
133
- **Reading conflicts:** `oxy status --json` lists each conflict: path,
134
  node, kind (order, name or tree), and the contributing ChangeIds.
135
  `oxy cat PATH --at CHANGE` gives each side's text for the agent's
136
  context.
137
- **Resolving:** the agent writes the resolved files and runs
138
  `oxy commit`. **Oxy computes the resolution's dependencies**: a
139
  resolution must depend on every change that contributed an atom to
140
  the conflict. An agent never writes `deps` by hand. Correctness of the
141
  graph is Oxygen's job, not the model's.
142
- **A valid resolution is not necessarily a right one.** The graph will
143
  be well-formed; the code may still be wrong. A policy rule for
144
  protected bookmarks can require that a resolution signed by an agent
145
  has a passing Flow receipt and a human approval before it lands.
146
147
## 6. Review and policy on the hub
148
149
- **Badges (implemented 2026-10-04):** a change signed by a delegate
150
  shows its author and, beside it, `via NAME` with an `agent` badge: in
151
  history rows on the hub, as a `via` row under the author on the change
152
  page (`↳ Antigravity <…> · delegate for changes, until … · key …`),
153
  under the author in Contributors ("via Antigravity 3"), as `via` in
154
  the API's change summaries, and the same in `oxy log` (`via NAME`) and
155
  `oxy show` (the `via` row). The author stays the human; the agent is
156
  the instrument, and a revoked or withdrawn delegation turns the badge
157
  red. The hub also links a rotated identity to its owner's account by
158
  itself when a push brings it, so delegating never breaks attribution.
159
- **Approvals:** approvals count only signatures by keys that are not
160
  agent-scoped delegates, so an agent cannot approve its own work or
161
  anyone else's.
162
- **Policy:** a policy rule may name agent rules, for example "agents may
163
  push `agents/**` bookmarks only" or "an agent-signed change needs a
164
  passing receipt to land".
165
- **Audit:** the trust page and `oxy verify` list agent-signed changes
166
  separately, with the delegation that authorized each.
167
168
## 6a. Optional: a human always lands AI work
169
170
Whether a human must land every AI-authored change is a **per-project
171
choice**. A regulated codebase may insist on it; a personal project or a
172
team that trusts its agents and tests may not. Oxygen's job is to make
173
the gate easy to turn on and impossible to bypass when it is on. It must
174
never impose the gate on everyone.
175
176
**With scoped delegation (this draft).** The agent is your delegate
177
with `--scope changes`, so its changes carry your authorship and its
178
signature. The policy decides whether it can land:
179
180
```
181
rules: [
182
  { pattern: "main",      keys: [andy, sam], threshold: 1, require: "signed" },
183
  { pattern: "release/*", keys: [andy, sam], threshold: 2, require: "signed" },
184
  { pattern: "agents/**",  keys: [andy, sam], threshold: 1 },
185
]
186
```
187
188
- **Gate on:** an agent-scoped delegate can never sign a reference
189
  attestation, so only Andy or Sam can move `main`. Approvals count only
190
  keys that are not agent-scoped, so a human approved and a human landed.
191
  The agent's changes keep their own signatures, so the landed history
192
  still shows which agent wrote what.
193
- **Gate off:** delegate the agent with `--scope changes,refs` instead.
194
  It then moves references as far as its owner may, and can land on its
195
  own where the policy allows. The project chooses this per agent, and
196
  the trust page and `oxy verify` still show every agent-signed change and
197
  every agent-signed bookmark move.
198
- **Per bookmark:** the usual setup gates `main` and `release/*` and
199
  leaves `agents/**` open, so agents push and move their own bookmarks
200
  freely while a human lands everything else. That needs refs scope
201
  that reaches only the open rules: a policy rule field naming agents
202
  explicitly, which is part of the §14.5 change.
203
204
**With today's spec (no scoped delegation).** A delegate moves
205
references as far as its owner, so the gate needs a different setup:
206
1. Give the agent its **own identity**, not a delegate.
207
2. List only human keys in the `main` rule, and the agent's key in an
208
   `agents/**` rule.
209
3. Policy checks each change a bookmark move adds, so the agent's changes
210
   cannot reach `main` directly at all. A human adopts the work by folding
211
   or re-committing it under their own key.
212
213
This gate is strict and works now. The cost is that the landed history
214
records the human as signer, not the agent.
215
216
**On the hub: agent-scoped tokens.** Policy governs keys, but landing on
217
the hub is done with an account's token. An agent using a human's token
218
lands *as that human*, and no policy can tell. The hub therefore needs
219
**agent tokens**:
220
- tied to an agent key and its human owner;
221
- allowed to push `agents/**`, open and update proposals, and comment;
222
- refused for landing, approving, changing settings or policy, and
223
  creating tokens, whatever the owner may do.
224
225
Hub actions taken with an agent token are recorded as "AGENT on behalf of
226
HUMAN" in the audit log and on the proposal. A project with the gate off
227
may still let agent tokens land, as a repository setting that mirrors the
228
policy, never by default.
229
230
## 7. Summary of new work
231
232
| Item | Spec section to change |
233
|---|---|
234
| Scoped, expiring delegates (done 2026-10-04) | §14.2 identity object, §14.4, §14.5 policy |
235
| Revocation by the delegator (done 2026-10-04) | §14.2 |
236
| `oxy agent start` / `drop`, session operation | §12, CLI |
237
| `oxy undo --to OP` | §12, CLI |
238
| Display folding, `oxy fold -r` | CLI, hub |
239
| Agent-aware approvals and policy rules, optional human gate (§6a) | §14.5, hub spec |
240
| Agent-scoped hub tokens | hub spec (API tokens) |
241
| `oxy status --json` conflict listing (check what exists) | §9, CLI |