| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
standards workspaces build + test / aac-rs (push) Has been cancelled
standards workspaces build + test / arl-rs (push) Has been cancelled
standards workspaces build + test / eoc-rs (push) Has been cancelled
standards workspaces build + test / jcp-rs (push) Has been cancelled
standards workspaces build + test / joule-code-rs (push) Has been cancelled
standards workspaces build + test / joule-ui-rs (push) Has been cancelled
standards workspaces build + test / jouleclaw-rs (push) Has been cancelled
standards workspaces build + test / joulecontract-rs (push) Has been cancelled
standards workspaces build + test / jouledesk-rs (push) Has been cancelled
standards workspaces build + test / joulehook-rs (push) Has been cancelled
standards workspaces build + test / map-rs (push) Has been cancelled
standards workspaces build + test / mesh-rs (push) Has been cancelled
standards workspaces build + test / openpay (push) Has been cancelled
standards workspaces build + test / proof-rs (push) Has been cancelled
standards workspaces build + test / sandbox-rs (push) Has been cancelled
standards workspaces build + test / sense-rs (push) Has been cancelled
standards workspaces build + test / smart-byte-rs (push) Has been cancelled
conformance/v1 was written by gen_vectors and read back by nothing. The in-crate
tests call the fixture functions, so they check the library against itself; a
third party told to reproduce these facts "from the published vectors alone" had
no evidence the reference implementation still did.
tests/pack.rs works from the files on disk. Where the pack carries an input the
input comes from the pack, and where it records an output the whole recorded
output is compared:
- every file matches its MANIFEST content address;
- C1: registry and both surfaces deserialized from the pack, validate()
reproducing the exhaustive error list exactly and in order;
- C2/C3: interactions rebuilt from the pack's surface, action, inputs, meter
step and budget, compared whole; C2's surface_id checked against C1's valid
surface so the two classes agree on one published surface;
- C4: the sealed chain deserialized and verified, excision breaking at index 1,
and tampering with content, a signature bit, or link order each caught at
the right link.
The pack is current -- unlike joulehook's, nothing here was stale.
One sharp edge the test has to cover, because verify_chain does not:
verify_chain checks each link's signature against the key that link CARRIES, and
never compares that key to a trusted one. Re-sealing the same interactions under
an unrelated key produces a chain verify_chain accepts in full. The pack
publishes steward_verifying_key_hex for exactly this reason, so the test binds
every link's signer to it and includes the forged chain as a negative. That is
arguably correct for an integrity primitive -- binding to a trusted key is the
caller's job -- so verify_chain's semantics are left alone; but a verifier that
calls it alone is not checking authenticity, and nothing tested that before.
Falsified by disabling the DisallowedChild rule. The pack test fails on exactly
the C1 case and nowhere else. Stated plainly so coverage is not overclaimed: the
existing conformance lib test (which asserts only invalid.len() >= 3 against a
recorded list of 4) stays green, but joule-ui-core's own unit tests already catch
that rule. The pack test's unique contribution is binding the published bytes and
the steward check, not that rule.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
| .. | ||
| conformance | ||
| joule-ui-rs | ||
| LICENSE | ||
| README.md | ||
| SPEC.md | ||
joule-ui
A typed declarative protocol for agent-emitted user interfaces.
joule-ui is the sibling to JouleClaw for the moment when an
agent's resolution has to become something a human can see and interact
with. The agent emits a widget tree — (name, props, children),
recursively — against a widget registry the host has published. The
host renders. No React in the spec, no HTML over the wire, no agent
holding the renderer.
The shape the field has converged on for this is declarative components against a registry: agents are far more reliable emitting structured data than emitting code, and renderers are far easier to harden when they own their own widgets. joule-ui pins that shape as a protocol; the renderer is product surface, owned by the consumer.
What ships in v1
-
joule-ui-rs/crates/joule-ui-core/— the protocol types (Widget,PropValue,WidgetSchema,Registry) and the recursive validator. Pure Rust, no IO, JSON-serialisable. -
joule-ui-rs/crates/joule-ui-interaction/(v0.2) — the layer no other UI protocol carries: when a human or an agent fires anAction, the invocation is an accountable event. Every fire names the principal that made it — adid:key, the same whether a person or an agent (the protocol draws no distinction; both are traced).run_interactionauthorizes it against a capability before it runs (a denied action's handler never executes), meters it in joules, charges the measured cost, and anInteractionLogseals it as the next link of a hash-chained receipt. The actor is bound into the signed core, so an interaction cannot be re-attributed without breaking the chain. A joule-ui session becomes a tamper-evident ledger of who fired it, what it computed, and what it cost — verifiable by anyone holding the host's key. The metering (SandboxPowerMeter) and the capability (JCP grant) are recognized edges; the receipt, the chain, and the lifecycle are joule-ui's. SeeSPEC.md§5–§7 andexamples/metered_surface.rsfor the full loop.
The surface layer makes joule-ui a peer of the declarative-UI protocols (A2UI, MCP Apps). The interaction layer makes it the only one you can hand to an auditor: a UI whose every interaction is energy-accounted and sealed, by construction.
What is not here:
- A renderer. The renderer is owned by the host (browser app, native shell, terminal UI). joule-ui validates the surface and seals the interaction; it does not paint pixels.
- A transport. The validated spec and the interaction stream ride MCP, REST, SSE, gRPC, Web MoQ — any bytes-out protocol. Transport-agnostic.
- A "model emits React" path. The agent emits a declarative tree against the registry; arbitrary code emission is out of scope.
Why a sibling, not inside JouleClaw
The spec layer is protocol — small, stable, conformant. The renderer registry is product surface — many of them, evolving fast. Splitting them protects the tools for use line: JouleClaw stays the runtime substrate; joule-ui is the UI protocol; consumers ship their own widgets.
Licence
Specification text and protocol document: CC-BY-4.0 (see LICENSE).
Reference implementation in joule-ui-rs/: Apache-2.0.