open-standards/jouledesk
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 2bfde7fb19
All checks were successful
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m57s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m22s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m10s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 37s
standards workspaces build + test / map-rs (pull_request) Successful in 31s
standards workspaces build + test / mesh-rs (pull_request) Successful in 31s
standards workspaces build + test / openpay (pull_request) Successful in 1m40s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 57s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 7m18s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m8s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 27s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m48s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m55s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m7s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m28s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m8s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m13s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m15s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m13s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m6s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 11m7s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m36s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 6m34s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 17s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 12m58s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 8s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 24s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 46s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m46s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m18s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m6s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
wai-pack / wai-pack · linux (pull_request) Has been skipped
wai-pack / wai-pack · linux-arm64 (pull_request) Has been skipped
wai-pack / wai-pack · macos (pull_request) Has been skipped
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been skipped
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been skipped
wai-pack / wai-pack · dependency licences (pull_request) Has been skipped
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m21s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m51s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 2h2m13s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 23m45s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 2h1m9s
jouledesk: an interrupted tag is not a failed one, and is not sealed as waste
This completes #189 at its only consumer, and closes a hole that PR opened.

`jouledesk` has a path dependency on `jcp-orchestrate` and matches on
`WorkState`. Adding `WorkState::Interrupted` did not break the build — the match
has a catch-all — so an interrupted task fell through it and came out
`TagOutcome::Failed("no terminal state")`. Then the next branch sealed it:

    // a `Failed` is spend that bought no result (waste)
    if matches!(outcome, TagOutcome::Done | TagOutcome::Failed(_)) {

So a task whose work may well have completed, whose joules were debited, and
whose outcome nobody knows, would have been reported to a person as failed and
sealed in an `efficiency/1` receipt as waste. That is exactly what §4.11 — which
#189 writes — forbids: an implementation MUST NOT report such an action as
completed or as failed.

A compiler could not catch it, and nor could CI: the catch-all made it compile,
and the still-pending `jouledesk-rs` job would have passed.

`TagOutcome::Interrupted { harness }` now carries the harness that held the task,
because that is who can settle it. The sealing branch excludes it alongside
`Denied` — a denied tag ran nothing, an interrupted one may have run everything,
and sealing it either way states as fact something unknown. Its joules stay
debited on the grant regardless; the dispatch decision that incurred them is
sealed in the orchestrator's own ledger.

Five consumers updated. Four were exhaustive matches the compiler found,
including `jouledesk-github`'s `seal`, which now reports `interrupted (held by
<harness>)` rather than `failed`. Every surface renders it, so no binding tells a
different story about the same outcome.

**Falsifying it caught my own test being worthless.** The first version
asserted `!matches!(interrupted, Done | Failed(_))` — a property of the *enum*,
not of the code — so changing the sealing branch, or deleting the match arm
entirely, left it green. The same vacuousness I had just caught in #190.

The obstacle was real: `WorkState::Interrupted` could not arise through
`Teammate`'s API, because `tag` submits and runs to a terminal state in one
process. So the fix was to make it reachable rather than to assert around it.
`Teammate` gains the minimum resume surface over #189's journal —
`with_journal`, `replay`, and `outcome_of` — which is the composition that
journal exists for, and jouledesk's whole purpose is composing
`jcp-orchestrate`. The mapping and the sealing rule are now named functions
(`outcome_for`, `seals_efficiency`) used by the real code paths, so a test reads
the rule instead of restating it.

The test is now end to end: tag once with a journal, truncate it after the
dispatch — the crash this models — replay into a fresh teammate, and assert the
tag reports `Interrupted { harness }` and seals nothing. Both earlier
falsifications now fail it: sealing an interrupted tag as waste, and removing the
match arm so it falls back to the catch-all.

jouledesk-rs workspace: 40 passed, clippy clean.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-10-09 02:50:39 -04:00
..
conformance/v1 jouledesk: refresh the published receipt to jcp/2, and hold it byte for byte 2026-09-30 14:16:01 -04:00
jouledesk-rs jouledesk: an interrupted tag is not a failed one, and is not sealed as waste 2026-10-09 02:50:39 -04:00
LICENSE jouledesk: rename Joule Tag → Joule Desk (naming call), part of the Joule Table umbrella 2026-07-05 07:30:53 -04:00
LICENSE-SPEC jouledesk: rename Joule Tag → Joule Desk (naming call), part of the Joule Table umbrella 2026-07-05 07:30:53 -04:00
README.md no-vanity-metrics: clear the three failures blocking the gate on main 2026-07-23 00:17:08 -04:00
SPEC.md jouledesk: frame as the collaboration binding of Joule Table (jt.transaction.science) 2026-07-05 07:35:45 -04:00

Joule Desk — The Open, Energy-Accounted Agent Teammate

The agent-teammate shape — a persistent principal you tag in a shared channel to delegate work under scoped access — is the right shape. Joule Desk is the open standard for it, with the three things that shape needs and a closed product cannot give you:

Authority that is a signed, enforced grant — not an admin setting. Work that is energy-metered and attested — not merely reported. And a shared, signed ledger the whole channel can verify — not just watch.

You add @joule to a channel; an admin issues it a grant chain (the tools and data it may touch, and a joule budget). Any member tags it 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 completed unit to a ledger anyone can verify — which principal did what, under which capability, at what cost.

Joule Desk is the collaboration/teammate binding of Joule Table (jt.transaction.science); its sibling binding Joule Hook covers coding editors — and Joule Desk's own editor class is Joule Hook. It does not reinvent — it composes the sibling standards: JCP (identity, grants, the shared channel, orchestration), jcp-efficiency (the energy receipt), Sandbox (attested execution), and Joule Hook (when the teammate works in a coding editor). It is one of the Transaction Science open standards.

  • Licence: Apache-2.0 for reference code (LICENSE); CC-BY-4.0 for the specification text (LICENSE-SPEC).
  • Status: v0.1.0 draft. Specification published (SPEC.md); reference workspace jouledesk-rs/ ships the teammate loop (Teammate + Skill over jcp-orchestrate + jcp-efficiency): grant a skill → tag it → authorise outside the model → seal to a per-receipt-verifiable ledger, with efficiency/1 energy accounting (energy_summary → joules per completed unit, charging waste).

What Joule Desk adds over a closed teammate

Property Closed teammate Joule Desk
Authority admin config, trusted a signed grant, decided outside the model, enforced
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
Portability one product any surface (chat / forge / editor / api), one standard

Conformance profiles (surfaces)

chat (team chat + mentions) · forge (git issues/PRs) · editor (a coding editor via JouleHook) · api (a service). See SPEC.md §8.

The reference jouledesk-bind binary targets real discrete-message services — Slack, GitHub, GitLab, Discord, Matrix, and a neutral shape — each a thin parse+render pair over one event→tag→reply transform:

echo '{"comment":{"user":{"login":"alice"},"body":"@joule summarize the thread"}}' \
  | jouledesk-bind --surface github
# → {"body":"✅ **@joule** completed it, @alice — decision sealed. _ledger: 1 decisions, all verified…_"}

And a real-time (media) binding class (room, SPEC.md §8.1) for when @joule joins a live voice/video meeting — Zoom, Teams, Meet, or a LiveKit/WebRTC room. The loop is four seams — join under a signed grant, gate each turn outside the model, meter each model call at the model-call boundary, seal one efficiency/1 per session anchored to the room. RealtimeSession (jouledesk-rs) is the reference (target: LiveKit Agents); its meter reuses the same model-call proxy that meters a text session, so the joule ceiling holds whether @joule is typing or talking. examples/room runs a live call — turns gated outside the model, metered at the boundary, and sealed into one verifiable session receipt.

What's here

jouledesk/
├── SPEC.md          — the normative standard (§1–§10)
├── README.md        — this file
├── jouledesk-rs/     — ✅ reference implementation: the teammate loop (Teammate + Skill +
│                      parse_mention/tag_mention for the chat/forge binding, §8) over
│                      jcp-orchestrate. `examples/channel` runs a multiplayer channel;
│                      `examples/vector` regenerates the conformance vector.
└── conformance/v1/  — ✅ a byte-deterministic sealed decision receipt (summarize-allow.hex)
                        + its verified-decode target (receipt.json)

Transaction Science is the steward, not the proprietor: the wire and the right to fork are public.