Review: The agent layer (darc → Reagent)
Review of the agent layer as described, under the
sovereignty litmus. Verdicts cite xenon-runtime main @b0cfc90, the xenon-cap
/ xenon-grant crates, and the xe-darc design docs. The gap IDs here (G-1
resident agent, G-2 delegation) are this beat’s agent-side register and feed
Part IV. The device-side gaps (G-3…G-7) are held
in the device review.
The headline
The agent layer is the mission and the least-built layer. The whole system — peer serving, the device fabric, the capability substrate — exists so that a resident agent can act for you, under your inspection, bounded by capabilities you can fork and revoke. That agent, as a bounded resident process, does not exist yet. What exists is a real capability-and-consent substrate, and a real research-preview browser (darc) whose only live boundary is a human approving each tool call.
This is not a criticism to soften; it is the program’s central honest fact, and the site should state it plainly rather than let the vocabulary imply that a bounded resident agent ships today. Concretely:
- Real:
xenon-capcapabilities,xenon-grantauthority-signed grant bundles,ConsentAttestation/ConsentStatement(used by the companion), the hash-chained audit ledger. - Real but unbounded: darc — a working Controlled-Frame browser-as-IWA with an agent sidebar; the only gate is human-approves-each-tool-call.
- Paper: Reagent (the productized, bounded resident agent); the
injection-boundary enforcement; the
capabilities[] → grantpipeline; every agency-ladder rung.
Everything below is downstream of that one paragraph.
Desired vs current
| Want (mission / decisions) | Have (code @b0cfc90) | Delta |
|---|---|---|
| A resident agent that sees, decides, acts under capability bounds | darc research preview (real, unbounded); daemon/main.js is 0 bytes | The agent has no daemon and no capability boundary; the human is the boundary. (G-1) |
| Agent authority expressed as capabilities (litmus: fork permissions) | xenon-cap + xenon-grant shipped and capability-shaped | agent://act is declared + audited only, not enforced; capabilities[] → grant unwired. (G-2) |
| BYO models + keys (sovereignty litmus) | Keys local; darc model IDs hardcoded | Sovereign model choice is unmet — litmus debt the kickoff flagged. (G-1) |
| Agency ladder governs agent actions (d/082, d/091) | Settled vocabulary; injection-boundary enum on paper | Zero rungs enforced in code. |
| Auditable agent actions | Hash-chained ledger discipline exists (companion + injection §3.4) | Ready to carry lease-use records; nothing mints them yet. |
Gap register (agent slice)
G-1 — The resident agent itself (darc → Reagent)
Exists: darc, a real research preview — but the only gate on its actions
is a human approving each tool call (injection §1.3); the agent sidebar and
the untrusted page share one IWA shell with no capability check between them
(§1); the CDP proxy forwards '*' so Runtime.evaluate passes
unconditionally (§1.1); daemon/main.js is 0 bytes. The substrate crates it
would bind to (xenon-cap, xenon-grant) are shipped.
Why this needs design: where the resident agent physically lives (in the
shell now, or in a real daemon/), what it can see and do, how consent and
audit extend to agent actions (not just app grants), and how BYO-model wiring
replaces the hardcoded model IDs. Until D-5 (the lease-signing root) is
answered, a “signed Lease” is aspirational: the shell shares an address space
with the forgeable iwa: IPC channel, so nothing prevents a lease being minted
by the very surface it is meant to bound.
Options / tradeoffs: injection-boundary D-1 (ship the boundary in the shell now vs. stand up the daemon first) — shell-now is faster but keeps the agent and the page co-resident; daemon-now is the honest boundary but is net-new. D-5 (lease-signing root) — a separate signer process vs. the OS keystore vs. deferring signed leases entirely. BYO-model — a model-selection capability vs. a config file vs. status quo hardcoding.
Decides: Luke + Jan — the injection-boundary D-1…D-7 burn-down.
G-2 — Delegation model: per-action consent vs. standing grants
Exists: a genuinely UCAN-adjacent substrate. xenon-cap::Capability =
(resource URI × ability verb × typed constraints) with audience + expiry +
onward-delegation flag, verified by verify_chain / authorize_invocation
(xenon-cap/src/lib.rs:30-84). xenon-grant mints runtime-authority-signed
Delegation bundles per install principal with onward:false
(xenon-grant/src/lib.rs:23-53,233-291). ConsentAttestation /
ConsentStatement are shipped and used by the companion.
Why this needs design: the pipeline capabilities[] → plan table → minted grant is parsed but not wired (capability-model-design §1); the agent
family (agent://act) is declared + audited only, not enforced; there is
no cross-device grant sync (out of scope, §9). Leases (the attenuated
per-action invocations, injection §3.1) are designed but not minted.
Why UCAN maps here exactly: the model is naturally both per-action and
standing — a grant is a long-lived delegation, a lease is a short-lived
attenuated delegation minted under it, and onward:false means no
re-delegation. That is a UCAN delegation, a UCAN invocation, and a no-proof
leaf, respectively. The recommendation this review offers the session: make the
UCAN alignment an explicit product decision, not an implementation detail —
decide whether Reagent’s authority is the xenon-cap/xenon-grant substrate
(it should be), and whether agent://act is enforced in v1 or stays
declared+audited.
Options / tradeoffs: CM-1 (the v1 grantable set — how wide); CM-2
(outbound network: declared-only vs. a block-catalog); grant-vs-lease split as
above (standing vs. per-action). Enforcing agent://act in v1 is the honest
choice but couples the agent milestone to the grant-minting pipeline; keeping
it declared+audited ships sooner but leaves the boundary advisory.
Decides: Luke — CM-1…CM-7. The full outline is a Part V candidate: Grant / Lease delegation model (UCAN-aligned).
The one ledger discipline (a convergence note)
The companion’s Kotlin audit chain
(devices §3.4) and the
agent-layer AuditEntry.prevHash (injection §3.4) are the same idea
implemented twice: a tamper-evident, per-device hash chain, 64-bit truncated,
not externally anchored. If lease-use records are going to be the agent’s audit
trail, the two should converge on one ledger discipline (this is
injection-boundary D-5’s neighbor). Naming it now avoids two subtly different
“audit logs” in one product.
Sovereignty litmus check
| Criterion | Verdict for the agent layer |
|---|---|
| Inspect what it sees | Partial. darc surfaces each tool call for human approval — genuine inspection — but there is no capability-scoped record of what the agent may see; the boundary is a person, not a policy. |
| Fork permissions | Weakest point. The substrate can express attenuable grants/leases, but agent authority is unenforced (agent://act audited-only). You cannot yet fork or revoke the agent’s permissions because it holds none. (G-2) |
| BYO models + keys | Fails for models. Model IDs are hardcoded in darc — the sovereignty debt the kickoff named. Keys are local. (G-1) |
| Movable memory | Not yet. Agent memory is local per device; no cross-device grant or memory sync (capability-model §9). |
| Auditable actions | Ready, unwired. The hash-chain discipline exists and the AuditEntry shape is specified; nothing mints lease-use records because no bounded agent acts. |
| Exit without loss | N/A yet. No resident agent state to carry; becomes real the moment the daemon holds memory. |
Questions for the Luke + Jan session
- G-2 / the UCAN decision — is Reagent’s authority the same
xenon-cap/xenon-grantsubstrate (Grant = long-lived UCAN delegation, Lease = attenuated invocation), and doesagent://actget enforced in v1 or stay declared + audited? This is where UCAN alignment should be a product decision, not an implementation detail. - G-1 / D-1 + D-5 — does the boundary ship in the shell now or wait for a
real daemon, and what is the lease-signing root, given the shell shares an
address space with the forgeable
iwa:IPC channel? - BYO model — a model-selection capability, a config file, or status-quo hardcoding for v1? (Litmus: BYO models + keys.)
- Naming hygiene — the site must not let a reader conflate the product
delegation model (
capability-model-design.md+injection-boundary-design.md) withdocs/delegation-interfaces.md(an unrelated broker). Agreed as a glossary fix?