All checks were successful
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m3s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m42s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 46s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 33s
standards workspaces build + test / map-rs (pull_request) Successful in 29s
standards workspaces build + test / mesh-rs (pull_request) Successful in 34s
standards workspaces build + test / openpay (pull_request) Successful in 1m23s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 1m1s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 5s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 6s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 6s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m14s
standards workspaces build + test / eoc-rs (pull_request) Successful in 2m0s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m39s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m11s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m12s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m18s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m13s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m20s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 5s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 4m2s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 4m38s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m8s
After the branch graded these figures by how they were obtained, the
docs still called them measured: jouledesk's channel example printed
"the teammate's measured contribution", Joule::energy_summary's doc and
SPEC §6 said the contribution "is *measured*", the room example sealed
an Estimator figure and closed "at its measured energy" (each turn
"metered {est} µJ" for a scripted estimate), and joulehook INSTALL.md
promised the Mesh proxy as "the only *measured* + *capped* option" that
"returns the measured energy".
Each now says the figure carries the grade of the meter that produced it
(a hardware reading only where a live counter read the work, else an
estimate graded as one), that a rollup is no better than the weakest
figure it sums, and the room example calls its figures estimates.
Text only; jouledesk and jouledesk-github tests pass unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
244 lines
13 KiB
Markdown
244 lines
13 KiB
Markdown
# Joule Desk — The Open, Energy-Accounted Agent Teammate
|
|
|
|
**Version:** 0.1.0-draft.1 · **Status:** Draft · **Profile:** `jouledesk/1`
|
|
**Specification text:** CC-BY-4.0 · **Reference code (`jouledesk-rs/`):** Apache-2.0
|
|
|
|
Joule Desk is the open standard for a **persistent agent teammate you delegate to in a
|
|
shared channel** — the shape a proprietary "tag @the-assistant in Slack" product made
|
|
familiar — built with the properties that shape needs and a closed product cannot
|
|
give you: authority that is a **signed, enforced grant** rather than an admin setting,
|
|
work that is **energy-metered and attested**, and a **shared, signed ledger the
|
|
whole channel can verify** rather than merely watch.
|
|
|
|
You add `@joule` to a channel. An administrator issues it a **grant chain** — the
|
|
tools and data it may touch, and a **joule budget**. Any member tags `@joule` to
|
|
delegate a task; it decides every action against those grants **outside the model**,
|
|
runs the work in an **attested sandbox**, **meters the energy**, and seals every
|
|
decision and every completed unit to the channel's ledger. Everyone in the channel
|
|
can not only see what it did — they can **verify** it: which principal, under which
|
|
capability, at what energy cost, with a signature that holds up.
|
|
|
|
Joule Desk is the **collaboration/teammate binding of [Joule Table](../jouletable)**
|
|
(`jt.transaction.science`) — the umbrella standard for a metered, gated, attested agent
|
|
at *every* surface; its sibling binding [Joule Hook](../joulehook) covers coding editors,
|
|
and Joule Desk's own `editor` class *is* Joule Hook. Joule Desk is one of the
|
|
[Transaction Science open standards](../README.md). It does not reinvent; it **composes**
|
|
the siblings — **JCP** (identity, grants, the shared channel, orchestration),
|
|
**`jcp-efficiency`** (the energy receipt), **Sandbox** (attested execution), and, where
|
|
the teammate works in an editor, **Joule Hook**.
|
|
|
|
---
|
|
|
|
## §1 Why Joule Desk exists
|
|
|
|
The agent-teammate shape is right: a persistent principal, tagged in a shared space,
|
|
that plans and executes delegated work under scoped access. But in its proprietary
|
|
form three things are weaker than the shape deserves:
|
|
|
|
- **Authority is configured, not enforced.** "These tools, this data, in this
|
|
channel" is an admin setting a relying party has to *trust*. Nothing outside the
|
|
model *decides* each action against a capability, and nothing *proves* afterward
|
|
what the agent was allowed to do.
|
|
- **The work is unmeasured.** When a teammate produces the majority of a team's
|
|
output, "did it work" is the wrong question; "what did it cost **per completed
|
|
unit**, and where is the waste" is the right one — and there is no energy figure.
|
|
- **The audit is visibility, not verifiability.** Everyone can *watch* the agent
|
|
work; no one can *verify*, later and independently, that a given action happened
|
|
under a given authority at a given cost.
|
|
|
|
Joule Desk closes all three: the authority is a JCP grant decided outside the model
|
|
and sealed; the work carries an `efficiency/1` receipt; the channel keeps a
|
|
signed ledger anyone holding the steward key can verify.
|
|
|
|
---
|
|
|
|
## §2 The teammate
|
|
|
|
`@joule` is a **persistent principal** — a stable `did:key` identity, not a session —
|
|
advertised by an **agent card** (§`jcp-a2a`) listing the skills it offers. The same
|
|
identity persists across tasks and across restarts, so its ledger is one continuous,
|
|
attributable chain. A deployment MAY run several teammates in a channel; each is a
|
|
distinct principal with its own card, grants, and ledger head.
|
|
|
|
---
|
|
|
|
## §3 The channel and its grants
|
|
|
|
A **channel** binds the teammate and its human **members** over a shared JCP channel
|
|
(§`jcp-channel`). It has:
|
|
|
|
- an **administrator** who issues the teammate a **grant chain** — a set of
|
|
[`SignedGrant`]s, each content-addressed to a `(surface, tool/skill)` audience and
|
|
carrying a **joule budget**;
|
|
- a set of **members** authorized to delegate;
|
|
- a **steward** who seals the ledger (§5) and whose public key verifies it.
|
|
|
|
The grant chain is the whole access model, and it is enforceable and portable: a tool
|
|
or datum the chain does not name is denied, whoever asks and however the request was
|
|
phrased. Reducing a teammate's authority is re-issuing (or revoking) grants, not
|
|
editing a console — and the change is itself a sealed, dated event.
|
|
|
|
---
|
|
|
|
## §4 The tag → the delegation loop
|
|
|
|
Tagging `@joule` with an intent submits a **task** (§`jcp-orchestrate`). For each task
|
|
the teammate, **in order**:
|
|
|
|
1. **Authorises** each action against its channel grants, in the runtime, never in
|
|
the model (JCP): the action's content-addressed resource MUST be permitted by a
|
|
held capability, and the grant's joule budget MUST cover the action's estimated
|
|
cost. A failure denies before any side effect.
|
|
2. **Executes** the admitted work in an **attested sandbox** (Sandbox S-tier), so
|
|
what ran is verifiable, not merely reported.
|
|
3. **Meters** the energy the work consumed (honest provenance).
|
|
4. **Seals** every dispatched decision — the allow, and any grant-level deny — and
|
|
every completed unit to the ledger (§5), debiting the budget on allow. (A tag the
|
|
teammate holds no skill or budget for is refused at routing; see §5.)
|
|
|
|
Retries are bounded and every attempt is charged (§`jcp-orchestrate`): a task that
|
|
never completes is spend the ledger attributes to no result, not silent loss.
|
|
|
|
---
|
|
|
|
## §5 The shared ledger
|
|
|
|
Every **dispatched** decision seals to the channel's ledger as an independently-signed
|
|
**JCR-1 receipt** — the allow that ran, and any grant-level deny. Alongside them the
|
|
ledger carries the **`efficiency/1`** receipt per completed unit (§6) and the **grant
|
|
events** (issuance, revocation) that change the teammate's authority. A tag for a skill
|
|
the teammate does not hold, or one with no remaining budget, is refused at **routing**
|
|
— enforced and recorded as a denied outcome before any dispatch; sealing that refusal
|
|
as a receipt too is a conformant extension.
|
|
|
|
The ledger is the multiplayer surface. Any member — and any third party holding the
|
|
steward's public key — can **verify** it receipt by receipt: that each is signed by the
|
|
steward, and therefore *which principal did what, under which capability, at what
|
|
energy cost, and in what order*. That is the difference from a product where the work
|
|
is merely visible: here it is **non-repudiable and independently checkable**. A
|
|
deployment MAY seal the ledger in the **chained** form (tamper-evident ordering) where
|
|
it wants the order itself — not only each entry — to be provable.
|
|
|
|
---
|
|
|
|
## §6 Energy accounting
|
|
|
|
Each task that runs seals an `efficiency/1` receipt (§`jcp-efficiency`) carrying its
|
|
energy at honest provenance and its outcome anchor (`completed`). Rolled up
|
|
(`aggregate`), a channel's ledger yields the figure a teammate's ROI actually turns
|
|
on — **joules per completed, verified unit** — which *charges the wasted energy of the
|
|
tasks that ran but never completed against the results actually delivered*. That is
|
|
the number a "tasks handled" count hides. Where a skill's work is itself token-based
|
|
(an LLM skill), the receipt also carries the per-token figures (µJ per accepted token,
|
|
tokens per completed unit, waste fraction); for a general task, joules-per-completed-
|
|
unit is the honest headline. The teammate's contribution is *metered*, not asserted:
|
|
each task's figure carries the grade of the meter that produced it — a hardware
|
|
reading only where a live counter read the task, otherwise an estimate, graded as
|
|
one — and a rollup is no better than the weakest figure it sums.
|
|
|
|
---
|
|
|
|
## §7 Settlement
|
|
|
|
The teammate's spend rides a **settle-able channel** (§`jcp-channel`): members and the
|
|
administrator exchange signed statements and settle, so the shared budget is
|
|
reconciled — who authorised what, what was spent, what remains — with an overdraft
|
|
that is bounded and enforced, not discovered on an invoice. A joule budget here is a
|
|
debited, settle-able quantity, the same object as the capability that spends it (JCP).
|
|
|
|
---
|
|
|
|
## §8 Host bindings (the collaboration surface)
|
|
|
|
Joule Desk is surface-agnostic. A **binding** maps a collaboration surface's primitives
|
|
onto the loop: "a member mentions `@joule`" → a task (§4), and the ledger (§5) → a
|
|
view the members can read and verify. Conformance profiles per surface:
|
|
|
|
| Profile | Surface | Tag | Ledger view |
|
|
|---|---|---|---|
|
|
| `chat` | a team chat (channels + mentions) | `@joule <intent>` | pinned/threaded receipts |
|
|
| `forge` | a git forge (issues/PRs) | `@joule` on an issue/PR | a checks/receipts view |
|
|
| `editor` | a coding editor via **JouleHook** | the editor's agent surface | JouleHook's receipt surface |
|
|
| `api` | a service | a task submission | the receipt log / MCP |
|
|
|
|
A binding MUST NOT weaken the loop: it maps the surface, it does not move the decision
|
|
into the model or drop the sealing.
|
|
|
|
The reference `jouledesk-bind` implements the `chat` profile for **Slack**, **Discord**,
|
|
and **Matrix**, and the `forge` profile for **GitHub** and **GitLab** (plus a neutral
|
|
`{who,text}` shape any other service maps onto), each as a thin event-parse +
|
|
reply-render pair; the `editor` profile is **JouleHook**. Parsing the event and
|
|
rendering the reply are pure and testable offline; *delivering* the reply is the
|
|
operator's token/webhook wiring.
|
|
|
|
### §8.1 The real-time (media) binding class
|
|
|
|
The bindings above are **discrete-message**: a mention becomes a task, and the reply
|
|
is a message. A `@joule` that joins a **live voice/video room** — Zoom, Google Meet,
|
|
Microsoft Teams, or a LiveKit/WebRTC room — is a different loop, because the work is a
|
|
continuous *session*, not one task per mention. A **real-time binding** is four seams:
|
|
|
|
1. **Join** the room under a signed grant (the JOIN seam). The room's own admission
|
|
credential — a LiveKit access token / `RoomAgentDispatch`, a Zoom RTMS handshake, a
|
|
Teams calling permission — is where the capability already lives; a conformant
|
|
binding *fuses it with the grant's joule ceiling* so nothing joins without authority
|
|
**and** budget.
|
|
2. **Gate each turn** outside the model (the TURN seam): a turn whose capability the
|
|
grant does not hold, or that would exceed the budget, is refused *before the model
|
|
generates* (in LiveKit, `on_user_turn_completed` → `StopResponse`), and the decision
|
|
seals.
|
|
3. **Meter each model call** at the model-call boundary (the METER seam): a `base_url`
|
|
proxy for a cascaded STT→LLM→TTS pipeline, a WebSocket relay for a native
|
|
speech-to-speech model, or the framework's own `gen_ai.usage.*` telemetry. Energy is
|
|
*derived* from token/audio counts at honest provenance — never claimed as a physical
|
|
measurement. (Media that flows peer-to-peer over WebRTC/SIP bypasses the meter; there
|
|
the binding gates at the token mint and reconciles from the provider's usage after.)
|
|
4. **Seal one `efficiency/1` receipt per session** (the RECEIPT seam), anchored to the
|
|
room/meeting id — the verifiable, energy-accounted record of what `@joule` did in the
|
|
call. A signed such receipt is a **superset of the compliance recording** these
|
|
platforms already sanction.
|
|
|
|
| Profile | Surface | Join seam | Meter seam |
|
|
|---|---|---|---|
|
|
| `room` (reference: **LiveKit**) | LiveKit / WebRTC room | access token + dispatch | `llm_node` override / OTel `gen_ai.usage` |
|
|
| `room` (**Zoom**) | Zoom RTMS + Meeting SDK | RTMS HMAC handshake + OAuth scope | RTMS socket / AI Studio tokens |
|
|
| `room` (**Teams**) | Graph Cloud Comms media bot | `Calls.AccessMedia` + RSC | per media-frame + STT/LLM |
|
|
|
|
The reference `RealtimeSession` (`jouledesk-rs`) models the four seams; its METER seam
|
|
reuses the *same* model-call proxy that meters a text session, so a joule ceiling is
|
|
enforced identically whether `@joule` is typing or talking.
|
|
|
|
---
|
|
|
|
## §9 What Joule Desk adds over a closed teammate
|
|
|
|
| Property | Closed teammate | Joule Desk |
|
|
|---|---|---|
|
|
| Authority | admin configuration, trusted | a **signed grant**, decided outside the model, enforced |
|
|
| Access change | a console edit | a **sealed, dated grant event** |
|
|
| Work integrity | reported | **attested** (Sandbox) |
|
|
| Energy | none | **`efficiency/1`** — µJ + cost per completed unit + waste |
|
|
| Audit | visible | **verifiable** — a signed ledger anyone can check |
|
|
| Budget | a quota | a **debited, settle-able** joule budget (§7) |
|
|
| Portability | one product | **any surface**, one standard (§8) |
|
|
| Openness | proprietary | **forkable** — the wire and the right to fork are public |
|
|
|
|
---
|
|
|
|
## §10 Relationship to the sibling standards
|
|
|
|
Joule Desk is a **profile that composes**, not a re-implementation:
|
|
|
|
- **JCP** supplies identity (`Did`), the grant model, the shared **channel**
|
|
(`jcp-channel`), and **orchestration** (`jcp-orchestrate`); Joule Desk binds them to
|
|
the teammate-in-a-channel shape and the tag→delegate loop.
|
|
- **`jcp-a2a`** supplies the teammate's advertised **agent card** and budget mandate.
|
|
- **`jcp-efficiency`** is the energy receipt the ledger carries per completed unit.
|
|
- **Sandbox** is where admitted work runs, attested.
|
|
- **JouleHook** is the `editor` binding — when the teammate works in a coding editor,
|
|
its tool calls ride JouleHook's gate + meter + receipt seams.
|
|
|
|
The contribution of Joule Desk is the **normative teammate-in-a-channel profile** — the
|
|
persistent principal, the channel grant chain, the tag→delegate→attest→meter→seal
|
|
loop, and the shared verifiable ledger — that turns a pile of primitives into an
|
|
accountable, energy-native teammate anyone can run and verify.
|