open-standards/jouleclaw/SPEC.md
Transaction Science fd52fc22b1 jouleclaw: wave-25 — contract CLI + signed verdict-receipt + source fetcher + revise loop
Four precision primitives closing the loop on wave-24 + adopting two
from the Lovable / Mickey Marsden talks.

- jclaw contract { verify, hash } — CLI surface for jouleclaw-contract.
  verify reads contract + evidence JSON, runs the §16.5 verifier, prints
  the verdict JSON, exits 0 / 1 / 2 for pass / bad input / failed
  verdict so CI scripts branch on the code. hash re-seals (catches
  duplicate ids + dangling claims) and prints the BLAKE3 content hash.
- jouleclaw-contract-receipt — new crate. ContractVerdict → JCR-1-shaped
  signed receipt (sibling schema "verdict-receipt/1"). Same canonical
  det-CBOR + COSE_Sign1 (alg=-8 EdDSA) envelope the cascade and policy
  streams use, under the same steward identity. Verdict carried as a
  JSON-string field with a sibling verdict_hash inside the signed core
  so it stays in the JCR-1 canonical subset (which forbids bools).
  Closes the SPEC.md §16.5 promise that "the verdict is the artifact a
  receipt links to". SPEC.md §16.7 documents the wire schema.
- jouleclaw-source — new crate. PackageSpec { ecosystem, name, version,
  subpath? } over npm/PyPI/crates.io/GitHub/URL; pluggable SourceFetcher
  trait; in-tree StaticBundleFetcher is the deterministic reference
  (no network in the trusted core). materialise() drops bundles onto
  a workspace under repos/<eco>/<name>/<version>[/<subpath>]/... with
  a bundle-hash + ClaimProvenance ready to push onto a receipt.
  Implements JouleClaw's "fresh > frozen" doctrine for third-party
  code — agents read the source their tools actually call, not the
  model's training of it.
- jouleclaw-revise — new crate. Scored review-revise loop. Composes
  (artifact, Reviser, jouleclaw-bounded::Scored, threshold, max_iters)
  with optional stall detector; emits a typed RevisionLog whose
  exit_reason is Accepted | BudgetExhausted | Stalled. The /grebloop
  shape made first-class; no model invocation in the trusted core.

Drive-by: jouleclaw-jcr1 gained pub fn cbor_to_json so sibling-receipt
bridges (policy, verdict, future ones) stop reinventing CBOR parsers.
Purely additive; 32/32 jcr1 tests still pass.

Tests: cli 10/10 (+2), contract-receipt 8/8 new, source 9/9 new,
revise 8/8 new, jcr1 32/32 unchanged. No regressions across the
existing test surface.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-03 04:12:27 -04:00

1055 lines
44 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JouleClaw v1 — Energy-Optimised AI Runtime
Status: **Draft Standard**. Reference implementation:
[`jouleclaw-rs/`](jouleclaw-rs/) (Rust workspace, Apache-2.0).
Spec text: CC-BY-4.0.
Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119.
---
## 1. Scope and doctrine
JouleClaw is a runtime + harness + agentic-layer standard for
energy-optimised AI. It applies to:
- text and code generation (LLMs, SSMs, state-space hybrids)
- multimodal understanding and generation (vision, audio, video, 3D)
- diffusion-based image / video synthesis (DDPM / LCM / Euler / Heun /
DPM++ / CFG++ / Rectified Flow and friends)
- speech recognition (Whisper-class)
- the developer-facing harness that drives the above
The **doctrine** is one sentence: capability per joule, not capability
per parameter.
Three normative consequences follow from the doctrine.
### 1.1 The cascade
A conforming runtime **MUST** dispatch every resolution through an
explicit energy-tiered cascade and **MUST** stop at the first tier
that closes the query. The tiers are:
| Tier | Wire tag | Named tag | Joule class | What it is |
|------|----------|-----------|-------------------|--------------------------------------------------|
| L0 | `L0` | Cache | picojoules | content-addressed cache hit |
| L1 | `L1` | Lawful | nanojoules | deterministic primitive (text / code only) |
| L2 | `L2` | Embed | sub-millijoules | embedding + hybrid retrieval |
| L3 | `L3` | Model | joules | local SSM / ternary / multimodal / diffusion |
| L4 | `L4` | Wire | tens of joules | remote frontier RPC (escape hatch) |
L1 (Lawful) is meaningful only for text and code modalities. For
image / audio / video / 3D generation the cascade collapses to
{L0, L2, L3, L4} — there is no deterministic compute path that
produces a high-quality image from "draw me a cat".
A conforming runtime **MUST NOT** invoke a higher-cost tier before
the lower-cost tiers have returned `Unresolvable`. Inference is the
**last resort**, not the entry point.
### 1.2 Recent knowledge over frozen weights
A conforming runtime **MUST** prefer fresh, provenance-stamped
retrieval over synthesis from frozen model weights whenever:
- the cost of the fetch + extract is below the cost of the
inference, AND
- the retrieved source's trust tier is above the operator's
configured threshold.
This is the L3.5 stage in the cascade implementation — between L2
(local index) and L3 (local model). The retriever **MUST** emit a
`ClaimProvenance` envelope (see §4) for every fact that contributes
to the resolution.
### 1.3 Honest energy provenance
Every energy reading **MUST** carry a `Provenance` tag declaring
how the value was obtained:
| Provenance | Meaning |
|----------------|--------------------------------------------------------|
| `HwShunt` | Real hardware shunt / coulomb counter (RAPL MSR, NVML cumulative-energy counter, Jetson INA3221) |
| `ModelBased` | Vendor-provided estimate from freq / voltage / utilisation (Apple IOReport, ROCm SMI, NVML `power.draw`) |
| `Estimator` | JouleClaw static cost model from arch × precision × batch tables |
The thermodynamic circuit breaker **MUST** enforce at the granularity
of the **worst** counter in the request's span. Implementations
**MUST** surface `resolution_uj()` and `min_window_ns()` so callers
can refuse to claim microjoule accuracy on platforms that cannot
deliver it.
Realistic floors:
- Intel / AMD x86 RAPL: ~1 μJ, ~10 ms window. `HwShunt`.
- Jetson INA3221: ~10 mW (integrate for energy). `HwShunt`.
- NVIDIA discrete (NVML cumulative-energy): ~1 mJ, ~50 ms. `HwShunt`.
- Apple Silicon IOReport: ~1 mJ, ~10 ms. **Model-based**, not measured.
Marketing claims of microjoule precision on Apple Silicon are
sales talk; the spec is honest about this.
- Consumer AMD GPU, ARM PMU: no usable counter. Use a calibrated
`Estimator` and surface the wider tolerance band.
---
## 2. The receipt
Every cascade walk **MUST** produce one [`Receipt`][prov]:
```json
{
"jc_receipt": "1",
"id": "<uuid v4>",
"closed_at": "<rfc 3339>",
"input_hash": "<blake3 hex of normalised input>",
"tier": "L3",
"joules_uj": 3500000,
"energy_provenance": "ModelBased",
"tools_touched": [
{
"tool_id": "model:gemma4-9b-q5_k_m",
"joules_uj": 3500000,
"energy_provenance": "ModelBased"
}
],
"claims": [
{
"source": "https://en.wikipedia.org/wiki/Gemma_(model)",
"content_hash": "<blake3 hex>",
"fetched_at": "<rfc 3339>",
"trust_tier": 9
}
],
"eoc_stage": null
}
```
Receipts are shaped to seal cleanly inside a Smart Byte signed
envelope (see the sibling [Smart Byte standard](../smart-byte/)).
The Smart Byte signature attests to receipt integrity; the receipt
itself is the auditable thermodynamic record.
A receipt's `energy_provenance` is the **worst** counter seen across
all `tools_touched` — not the best. This is normative.
[prov]: jouleclaw-rs/crates/jouleclaw-prov/src/lib.rs
---
## 3. The `.jc.toml` sidecar
A model file on disk (GGUF / safetensors / MLX) tells you tensor
shapes and quant schemes. It does NOT tell you what one forward
pass costs in joules on real hardware. The cascade auction cannot
pick the cheapest backend if every backend lies about its cost.
A `.jc.toml` sidecar travels next to the model file and declares
the energy contract. See [`jouleclaw-pack`][pack] for the schema.
Backends loading a model with a `.jc.toml` are bound to honour the
declared cost within the per-measurement `drift_factor` tolerance;
the runtime trips `CostDrift` and down-weights the backend in
future auctions when measured > declared × drift_factor.
Without a declared-cost contract, "energy-optimised inference" is
marketing. With one, it is an engineering claim a third party can
verify against the published reference-hardware corpus (see §6).
[pack]: jouleclaw-rs/crates/jouleclaw-pack/src/lib.rs
---
## 4. Provenance
Every retrieved claim that contributes to a resolution **MUST**
carry a `ClaimProvenance` envelope:
```json
{
"source": "<url, did:plc, doi, ...>",
"content_hash": "<blake3 hex of bytes as fetched>",
"fetched_at": "<rfc 3339>",
"trust_tier": 9
}
```
`trust_tier` is 0..10. Bootstrap data comes from the Wikipedia
perennial-sources list (machine-readable via the Wikimedia
Enterprise parsed-references endpoint); operators **MAY** extend the
table.
A retriever **MUST NOT** present a synthesised fact as a retrieved
claim. If the runtime falls back to model inference because no
retrieval closed the query, the receipt's `claims` array **MUST**
remain empty for that tier and the resolution carries the
`L3:Model` tag, not `L2:Embed`.
---
## 5. The MCP tool surface
The standard tool dispatch protocol is MCP (Model Context Protocol).
A conforming runtime **SHOULD** speak MCP for interop with the
Claude Code / Codex / Goose ecosystem.
Every MCP tool call **MUST** be wrapped in
`jouleclaw-mcp::dispatch_metered`, which brackets the call with
energy counter reads and pushes a `ToolTouch` entry onto the
running receipt's `tools_touched` ledger.
### 5.1 The `joule-mcp` profile
Two JouleClaw-aware endpoints **MAY** opt into a CBOR transport
profile by advertising the capability tag `x-jouleclaw/joule-mcp@1`
in their handshake. When both sides advertise it, the wire encoding
switches from JSON-RPC to length-prefixed CBOR (~30–50% lower
serialisation tax per call). When either side does not advertise,
the encoding **MUST** fall back to standard MCP JSON-RPC.
Non-JouleClaw MCP clients (Claude Code, Codex, etc.) see plain
JSON-RPC. The CBOR profile is a negotiated extension, never a
replacement.
---
## 6. Conformance
A conforming runtime **MUST** produce a `Receipt` for every published
conformance vector in [`conformance/v1/`](conformance/v1/) that matches
the canonical receipt's `tier`, `tools_touched[].tool_id`, and
`claims[].content_hash`.
The `joules_uj` field in a conforming receipt **MUST** fall within
the platform-specific drift band declared in the `.jc.toml` sidecar
for each tool / model touched. Drift beyond the band is a
non-conformance signal, not a hard failure — the runtime **SHOULD**
emit `DriftAlert` and let the operator decide whether to demote the
backend or pause the deployment.
Conformance vectors are signed at release time. Implementations
self-certify by round-tripping the public vectors and publishing
their receipts.
---
## 7. Wire format versioning
- The cascade tier wire tags (`L0`–`L4`) are stable across versions.
A future major version **MAY** add tiers (e.g. `L5:Quantum`) but
**MUST NOT** renumber existing ones.
- The `jc_receipt` field on a receipt is the schema version. This
document defines `"1"` (the cascade receipt of §2) and `"policy/1"`
(the policy receipt of §10). Unknown major → reject. Unknown minor
→ accept by ignoring unknown fields. New `jc_receipt` schemas are
added under their own prefixed namespace (`"<name>/<version>"`); the
bare numeric form `"N"` is reserved for the cascade-walk receipt.
- The `jc_pack` field on a `.jc.toml` sidecar follows the same rule.
- The `jc_workspace` field on a workspace manifest (§11) follows the
prefixed-namespace rule (`"workspace/1"`).
---
## 8. Agent identity
A long-running JouleClaw agent is identified by a stable handle
bound to an Ed25519 public key. The canonical derivation is W3C
`did:key` over multicodec Ed25519:
```
handle = "did:key:z" || base58btc(0xed 0x01 || raw_public_key_32)
```
A conforming `AgentIdentity` carries `(handle, public_key, optional
EAT attestation, optional created_at)`. A verifier **MUST** confirm
that `handle == did:key_handle(public_key)` before accepting any
signed material from that identity. Attestation envelopes
(RATS / EAT per RFC 9711) **MAY** be bound to the identity by
placing the same `handle` in the EAT `cti` claim.
Where this identity flows:
- `Receipt.steward` (§2): the cascade-receipt steward identity is the
`handle` form when self-describing.
- `PolicyReceipt.steward` (§10): same handle, same key.
- `WorkspaceManifest.owner` (§11): same handle, same key, with the
pubkey embedded so a third-party verifier needs no external mapping.
- COSE_Sign1 `kid` header on any signed envelope: same handle.
Identity rotation is out of scope for v1. KERI-based AID rotation is
the recommended substrate; this spec does not normatively constrain
the rotation mechanism.
---
## 9. The policy engine
JouleClaw runtimes **MAY** consult an out-of-process policy engine
before executing an `Action`. When they do, the engine MUST be
deny-by-default and operate at filesystem / network / process
granularity.
A conforming engine exposes the following surface:
- **`Action`** — `Filesystem { path, mode }` |
`Network { host, port, method }` |
`Process { binary, argv }`.
- **`Decision`** — `Allow { rule }` | `Deny { reason }`, where
`DenyReason` is `NoMatchingAllow` (deny-by-default) or
`ExplicitDeny { rule }`.
- **`Policy`** — ordered list of rules, plus a monotonic `version`.
A `Rule` is `(effect, agent_scope, action_predicate, name)`.
- **Evaluation rule** — explicit `Deny` rules short-circuit before
any `Allow`. First matching `Allow` wins. No matching `Allow` ⇒
deny-by-default. **MUST** record an `AuditEvent` per evaluation.
- **`AuditEvent`** — `(sequence, policy_version, agent, action,
decision)`. Sequence is monotonic within the engine instance.
- **Live policy update** — `install_policy(new)` accepts only when
`new.version > current.version`.
A conforming **out-of-process transport** is line-delimited JSON
over a duplex byte stream. One request per line, one response per
line. Operations: `evaluate`, `audit`, `audit_since`,
`policy_version`, `install_policy`. The server treats a malformed
line as an error response and keeps the stream open.
The reference engine is `jouleclaw-policy::InMemoryPolicyEngine`
(in-process) plus `jouleclaw-policy-ipc::PolicyClient` /
`jclaw-policyd` (out-of-process).
---
## 10. The policy receipt
A `PolicyReceipt` is the signed audit record for one policy
decision. It is a **sibling** of the cascade receipt in §2: same
COSE_Sign1 envelope (alg = -8 EdDSA over canonical det-CBOR), same
steward identity, but its own schema id (`"policy/1"`) and its own
wire shape.
```json
{
"jc_receipt": "policy/1",
"id": "<uuid v4>",
"closed_at": "<rfc 3339>",
"steward": "<did:key handle>",
"engine_id": "<id>",
"audit_sequence": 7,
"policy_version": 2,
"agent": "<did:key handle>",
"action": { "kind": "filesystem", "path": "/workspace/x", "mode": "read" },
"decision": { "kind": "allow", "rule": "read-workspace" }
}
```
- The canonical signed core is the det-CBOR (RFC 8949 §4.2.1
length-first map ordering) of the receipt as JSON.
- The COSE_Sign1 envelope is identical in shape to the JCR-1 v1
envelope on the cascade receipt: `protected = {1: -8, 4: steward}`,
`unprotected = {}`, `payload = canonical signed core`,
`signature = Ed25519(Sig_structure)`.
- Verifiers reject envelopes whose `kid` (in the protected header)
disagrees with the embedded `steward`.
- Conforming implementations **MUST** byte-match the three reference
vectors in
[`jouleclaw-rs/crates/jouleclaw-policy-receipt/conformance/vectors-policy.json`](jouleclaw-rs/crates/jouleclaw-policy-receipt/conformance/vectors-policy.json).
Reference verifiers in Rust, Python, and Go ship alongside the
vectors; all three produce byte-identical canonical bytes for the
same receipt.
Policy receipts and cascade receipts share the same JSONL "unified
log" file format: readers dispatch on the `jc_receipt` schema tag
(`"1"` → cascade, `"policy/1"` → policy, unknown → forward-compat
skip).
---
## 11. The agent workspace
A persistent, content-addressed workspace **MAY** be attached to a
long-running agent. The workspace's wire form is a
`WorkspaceManifest`:
```json
{
"jc_workspace": "workspace/1",
"owner": { "handle": "<did:key>", "public_key": "<hex32>" },
"entries": [
{ "path": "notes/x.md", "content_hash": "<blake3 hex>", "size": 17, "kind": "text" },
...
]
}
```
- **Path normalisation** — paths are relative `/`-joined segments.
Absolute paths, empty paths, empty segments, `.` and `..`
segments, and NUL bytes are **MUST** rejected on write.
- **Content addressing** — `content_hash` is BLAKE3 hex of the
bytes; the underlying backend stores bytes keyed by
`content_hash` so identical content is deduplicated.
- **Entry order** — entries in the manifest are sorted lexically
by `path`.
- **Manifest content-address** — the manifest's own content hash is
BLAKE3 over its canonical JSON serialisation. Identical workspace
state → identical manifest hash → identical signature.
- **Signing** — a `SignedWorkspaceManifest` carries an Ed25519
signature over the canonical manifest bytes. Verifiers MUST
check both that the embedded `owner.handle` matches the embedded
`owner.public_key` under §8 derivation, AND that the signature
verifies.
The workspace deliberately does NOT specify encryption, conflict
resolution, or multi-writer merge. Backends are single-writer; if
multi-writer is needed it composes behind a future
`WorkspaceBackend` impl with a lock service. Encryption is the
caller's job — the manifest signature covers what is observable,
not what is decrypted.
---
## 12. Skill interoperability — `SKILL.md`
JouleClaw skills are portable to the broader open-skills ecosystem
(Claude Code, OpenAI Codex, Gemini CLI, GitHub Copilot, Cursor, et
al.) via the agentskills.io `SKILL.md` format. Conformance:
- A JouleClaw-emitted `SKILL.md` MUST carry the agentskills.io
required frontmatter (`name` ≤ 64 chars matching
`^[a-z0-9]([a-z0-9-]*[a-z0-9])?$`; `description` ≤ 1024 chars).
- The deterministic JouleClaw procedure (the `Template` and
`Procedure` that let a JouleClaw cascade resolve the skill at
lookup energy) travels under `metadata.jouleclaw` as a vendor
extension. Non-JouleClaw consumers treat the Markdown body as
natural-language instructions; JouleClaw-aware consumers
reconstruct the typed Skill.
- The `body` is required by emitters — empty bodies are rejected
unless the caller opts in explicitly via a `_with_default_body`
helper (intended only for drafts).
- Unknown vendor metadata keys are preserved on round-trip.
---
## 13. Vocabulary (JSON-LD + Turtle)
JouleClaw publishes a stable IRI vocabulary so a JSON-LD parser, a
SPARQL store, or a generic third-generation agent client can read
any JouleClaw receipt as RDF without bespoke integration.
- **Namespace:** `https://jouleclaw.transaction.science/vocab/v1#`
(prefix `jc:` by convention).
- **JSON-LD context:** `https://jouleclaw.transaction.science/vocab/v1.jsonld`
(every field name in §§2, 10, 11 maps to a `jc:`-prefixed IRI with
the typed range below).
- **Turtle ontology:** `https://jouleclaw.transaction.science/vocab/v1.ttl`
(classes, enumerations, properties, ranges; CC-BY-4.0).
- **Human index:** [`https://jouleclaw.transaction.science/vocab/v1`](https://jouleclaw.transaction.science/vocab/v1).
- **Canonical source:** [`jouleclaw/vocab/`](vocab/) in this
repository.
The vocabulary is **purely additive**:
- A v1 cascade or policy receipt remains a valid JouleClaw receipt
on the wire with or without an `@context` field.
- Adding `"@context": "https://jouleclaw.transaction.science/vocab/v1.jsonld"`
to a receipt expands it into typed RDF triples (e.g.
`tier: "L3"` becomes `<receipt> jc:tier jc:Model`,
`energy_provenance: "ModelBased"` becomes
`<receipt> jc:energyProvenance jc:ModelBased`) without changing
any other field.
- The canonical signed core of a JCR-1 envelope **MUST NOT** include
`@context` &mdash; the JSON-LD context is metadata, not payload.
Producers that want to publish a JSON-LD form alongside the signed
receipt SHOULD do so in a separate field, or fetch the context
out-of-band from the published URL.
**Production default.** Conformant producers `SHOULD` emit
`@context` set to the v1 vocabulary URL on every receipt by
default, so any downstream JSON-LD parser treats the document as
typed RDF without configuration. The reference implementations
do this in [`ReceiptBuilder::seal`][rb-seal] and
[`PolicyReceiptBuilder::build`][pb-build]; the `without_context()`
opt-out is reserved for conformance-vector regeneration and
backward-compatible wire-form replay.
[rb-seal]: jouleclaw-rs/crates/jouleclaw-prov/src/lib.rs
[pb-build]: jouleclaw-rs/crates/jouleclaw-policy-receipt/src/lib.rs
The vocabulary subclasses W3C PROV-O where the alignment is exact:
- `jc:ClaimProvenance &rsubeq; prov:Entity`
- `jc:AuditEvent &rsubeq; prov:Activity`
- `jc:AgentIdentity &rsubeq; prov:Agent`
PROV-O consumers can therefore reason about a JouleClaw deployment
as a provenance graph using this one IRI mapping &mdash; no
JouleClaw-specific code beyond the standard PROV-O semantics.
**Versioning.** A future major bump publishes under
`/vocab/v2#`. v1 IRIs remain resolvable forever per the
open-standards "names are final" rule.
---
## 14. Hydra ApiDocumentation
A JouleClaw service publishing a tool surface (MCP server, the
out-of-process policy daemon, an HTTP endpoint) **SHOULD** serve a
[Hydra Core Vocabulary][hydra] `hydra:ApiDocumentation` document
at a stable discovery endpoint. Hydra is the W3C CG draft that
solved the "tool schemas live in the client's context window"
pathology for the third-generation web: the API describes itself
in a machine-readable form, a generic client reads the description
once, and the client calls every operation without ever loading a
schema into its context.
A conforming ApiDocumentation:
- Is JSON-LD using both the Hydra Core Vocabulary namespace
(`http://www.w3.org/ns/hydra/core#`) and the JouleClaw vocabulary
namespace from §13 (`jc:` prefix).
- Carries `@type: "ApiDocumentation"` at the root, a stable
`@id`, a human-readable `title` + `description`, and a
`supportedClass` list.
- Each `Class` in `supportedClass` carries
`supportedOperation` — one `Operation` per published verb. An
`Operation` declares `method`, `expects` (input class IRI;
`owl:Nothing` for parameterless), `returns` (output class IRI),
and `statusCodes`.
- The JouleClaw extension fields `jc_tool_id` (stable tool id) and
`jc_mutating` (mirror of MCP's mutation flag) MAY appear on each
operation. They reference the JouleClaw vocabulary from §13 so a
receipt emitted by that tool cross-links back to its Hydra
description.
Default mappings the reference emitter uses:
| Source field | Hydra field | Default value |
|------------------------|-----------------------|------------------------------|
| `mutating: false` | `method` | `"GET"` |
| `mutating: true` | `method` | `"POST"` |
| (none) | `expects` | `owl:Nothing` |
| (none) | `returns` | `jc:ToolResponse` |
| (none) | `statusCodes` | 200, 400, 500 |
| `name` | `jc_tool_id` | `"jouleclaw:<name>"` |
The reference emitter is `jouleclaw-hydra::ApiDocumentationBuilder`
in the workspace; the `mcp-adapter` feature provides
`From<&McpToolSchema> for ToolDescription` so an existing MCP
server emits a Hydra doc in one chained call.
A generic third-generation agent client fetches the
ApiDocumentation, validates the `@context`, and is then free to
call every tool by following the typed contract — no
out-of-band tool prompts, no schema-per-tool context bloat.
**This is the structural fix for the generation-2 "72% of context
window on tool schemas" pathology.**
[hydra]: https://www.hydra-cg.com/spec/latest/core/
---
## 15. SHACL shapes
A JouleClaw service **SHOULD** publish [SHACL][shacl] Core shapes
for every input/output class its Hydra ApiDocumentation (§14)
references. The shapes let an agent validate a candidate payload
**before** calling a tool &mdash; locally, without any model
invocation, with deterministic results.
The canonical JouleClaw v1 shape graph lives at
[`https://jouleclaw.transaction.science/vocab/v1.shapes.ttl`](https://jouleclaw.transaction.science/vocab/v1.shapes.ttl)
and covers every class in §§2, 8, 10, 11 (Receipt, PolicyReceipt,
WorkspaceManifest, WorkspaceEntry, AgentIdentity, Action with the
three subclasses, Decision with Allow and Deny subclasses,
ToolTouch, ClaimProvenance). The shapes use only SHACL Core
constraints &mdash; no SPARQL, no qualified value shapes &mdash;
so:
- A full SHACL validator (pyshacl, Apache Jena) accepts the file
directly and produces a `sh:ValidationReport` against any
candidate document.
- A lightweight in-tree validator (the reference impl is
`jouleclaw-shacl::ShapeGraph::jouleclaw_v1()`) covers the same
constraints in ~600 lines of Rust with no SPARQL engine. Compiles
to WASM so an in-browser agent can validate locally.
Constraints in use: `sh:minCount` / `sh:maxCount`, `sh:datatype`
(xsd:string, xsd:integer, xsd:nonNegativeInteger, xsd:dateTime,
xsd:double, xsd:boolean), `sh:nodeKind` (sh:IRI, sh:Literal),
`sh:in` (enumerations), `sh:pattern` (regex), `sh:minInclusive` /
`sh:maxInclusive`, and `sh:node` (nested shape delegation).
The shape file is the contract a JouleClaw operator publishes
alongside their Hydra ApiDocumentation; the lightweight validator
is the agent-side counterpart. A tool input that fails validation
**MUST NOT** be sent to the tool.
[shacl]: https://www.w3.org/TR/shacl/
---
## 16. Validation contract
A **validation contract** is the planning artifact a multi-step
JouleClaw run is judged against. It is authored *before* any
implementation work begins, lives independently of the code, and
is the only thing that decides whether a mission succeeded.
### 16.1 Shape
A contract is a JSON document with the fields:
- `jc_contract`: `"contract/1"` (this version).
- `@context`: optional JSON-LD context, defaults to
`https://jouleclaw.transaction.science/vocab/v1.jsonld`.
- `title`: free-form mission name.
- `authored_by`: `did:key:…` of the agent or person who sealed
the contract. May be empty for unsigned drafts.
- `assertions`: an ordered list of [`Assertion`](#162-assertion).
Ids **MUST** be unique within the contract.
- `features`: an ordered list of [`Feature`](#163-feature). Ids
**MUST** be unique. Each feature's `claims` **MUST** reference
only assertion ids that exist in the contract.
- `acceptance`: optional metadata controlling ship-gate rules.
The contract's content hash is BLAKE3 over the canonical JSON
serialisation; identical contracts → identical hashes. The
content hash is what a [JCR-1 receipt](#2-the-receipt) binds to
when it claims to have run against this contract.
### 16.2 Assertion
Each assertion is one falsifiable claim:
- `id`: stable string (e.g., `"A-001"`).
- `title`: one-line summary.
- `rationale`: free-form *why*. Optional.
- `priority`: one of `must_have` | `should_have` | `nice_to_have`.
- `check`: one of:
- `{ "kind": "tool", "tool_id": "…", "args_hash": "…"? }`
- `{ "kind": "artifact", "path": "…", "expected_hash": "…"? }`
- `{ "kind": "command", "command_hash": "…", "expected_exit": N }`
- `{ "kind": "checker", "checker_id": "…" }`
A `must_have` assertion that does not roll up to `verified`
**MUST** block ship. A `should_have` assertion that does not
roll up to `verified` **MUST NOT** block ship unless
`acceptance.block_on_should_have` is true.
### 16.3 Feature
Each feature is one unit of work that *claims* one or more
assertion ids it intends to satisfy:
- `id`: stable string (e.g., `"F-001"`).
- `title` + optional `description`.
- `claims`: list of assertion ids this feature covers.
A worker dispatched against a feature **SHOULD** emit
[evidence](#164-evidence) for every assertion that feature
claims; the verifier surfaces missing evidence as a gap.
### 16.4 Evidence
The verifier consumes a bag of evidence items the run produced:
- `tool_result { tool_id, args_hash?, passed }`
- `artifact_present { path, hash }`
- `command_run { command_hash, exit_code }`
- `checker_result { checker_id, passed }`
An evidence item matches an assertion when its discriminants
match the assertion's check. A matching item with `passed: true`
(or, for `command`, `exit_code == expected_exit`; for `artifact`,
`hash == expected_hash` when supplied) raises the assertion to
`verified`. Any matching failure raises the assertion to
`failed`; the verifier surfaces the disagreement rather than
silently allowing a later success to mask it.
### 16.5 Verification
The verifier is a pure function over `(contract, evidence)`. It
emits a `ContractVerdict`:
- `jc_verdict`: `"verdict/1"`.
- `contract_hash`: hex BLAKE3 of the contract.
- `passed`: boolean.
- `summary`: human-readable one-liner.
- `coverage`: a typed matrix with one row per assertion, one
column per feature, plus a per-assertion rollup
(`verified` | `claimed_unverified` | `failed` | `gap`).
- `blocking_gaps`: must-have assertion ids not rolled up to
`verified`.
- `should_have_gaps`: should-have assertion ids not rolled up
to `verified`.
Same inputs → same verdict. The verdict is the artifact a
receipt links to when reporting a multi-day run's outcome.
### 16.6 Conformance
A conforming **producer** of a contract MUST:
- Set `jc_contract` to `"contract/1"`.
- Reject duplicate assertion ids and duplicate feature ids.
- Reject features whose `claims` reference unknown assertion ids.
A conforming **verifier** of a contract MUST:
- Implement the rollup rules in §16.5 exactly: any matching
failure → `failed`; otherwise any matching pass → `verified`;
otherwise any claim → `claimed_unverified`; otherwise → `gap`.
- Block ship on any `must_have` non-`verified` rollup.
- Block ship on `should_have` non-`verified` rollups iff
`acceptance.block_on_should_have` is true.
Reference: [`crates/jouleclaw-contract`](./jouleclaw-rs/crates/jouleclaw-contract/).
SHACL shape: `jc:ValidationContractShape` at
[`vocab/v1.shapes.ttl`](./vocab/v1.shapes.ttl).
### 16.7 Verdict receipt
The §16.5 verifier emits a [`ContractVerdict`](#165-verification)
as plain JSON. To land that verdict on the unified auditable log
alongside cascade receipts (`"1"`) and policy receipts
(`"policy/1"`), wrap it in a **verdict receipt** — sibling
schema `"verdict-receipt/1"`, same canonical det-CBOR +
COSE_Sign1 envelope every other JouleClaw sibling receipt uses,
under the same steward identity.
```json
{
"jc_receipt": "verdict-receipt/1",
"id": "<uuid v4>",
"closed_at": "<rfc 3339>",
"steward": "<did:key handle>",
"engine_id": "<id>",
"audit_sequence": 7,
"contract_hash": "<hex BLAKE3 of the contract>",
"verdict": { /* ContractVerdict, verbatim */ }
}
```
Wire-format rules:
- The canonical signed core carries the verdict as a
**JSON-string** field named `verdict_json` (not a nested
object), with a sibling `verdict_hash` field set to hex BLAKE3
of the `verdict_json` bytes. This keeps the signed core inside
the JCR-1 canonical-CBOR subset (which forbids bools and
nulls) while still binding the verdict to the signature. The
wire-form JSON object surfaced to consumers MAY carry
`verdict` as a nested object for ergonomics; the signed core
is normative.
- The COSE_Sign1 envelope is identical in shape to JCR-1 v1:
`protected = {1: -8, 4: steward}`, `unprotected = {}`,
`payload = canonical signed core`, `signature =
Ed25519(Sig_structure)`.
- `contract_hash` MUST equal the BLAKE3 content hash of the
[`ValidationContract`](#161-shape) the verdict was produced
against. Verifiers consuming the unified log MAY index by
`contract_hash` without parsing the inner verdict.
Conforming producers + verifiers SHOULD reuse the existing
JCR-1 envelope tooling (verifiers reject envelopes whose `kid`
disagrees with the embedded `steward`, etc.).
Reference: [`crates/jouleclaw-contract-receipt`](./jouleclaw-rs/crates/jouleclaw-contract-receipt/).
---
## 17. Worker handoff
A **worker handoff** is the structured wire form an agent emits
at end-of-feature-work. The handoff is what makes a multi-day
run readable to the next worker (or the next session of the same
worker) — it forces the agent to write down what actually
happened rather than relying on conversational context.
### 17.1 Shape
A handoff is recorded as a `RunEvent::HandoffRecorded` variant
on the [run journal](#2-the-receipt):
- `worker`: stable worker id (typically `did:key:…`).
- `node_id`: optional graph node this handoff closes.
- `feature_id`: optional contract feature id this handoff
claims to satisfy.
- `closed_at`: epoch-seconds wall-clock.
- `completed`: list of items reported done.
- `undone`: list of items reported left undone.
- `commands`: list of `{ command_hash, argv, exit_code }`
entries observed during the work window.
- `issues_found`: list of issues the worker discovered.
- `procedures_followed`: list of skills / runbooks the worker
applied.
`command_hash` MUST be hex BLAKE3 over `argv.join("\0")`. The
hash, not the argv array, is the command's identity; the argv
is carried for human inspection only.
The handoff hash is part of the journal entry's hash chain, so
editing handoff fields after the fact breaks chain verification.
### 17.2 Conformance
A conforming **producer** of a handoff MUST:
- Set every field that is non-empty in the run; empty lists are
acceptable but the discriminator MUST be present.
- Compute `command_hash` as specified.
A conforming **consumer** of a handoff MUST:
- Accept additive fields (the variant set is open under
semver-compatible extension).
- Verify the journal's hash chain before trusting the handoff's
contents.
Reference: [`crates/jouleclaw-graph`](./jouleclaw-rs/crates/jouleclaw-graph/)
(`WorkerHandoffEvent`, `HandoffCommand`,
`RunEvent::HandoffRecorded`). SHACL shape:
`jc:WorkerHandoffShape` at
[`vocab/v1.shapes.ttl`](./vocab/v1.shapes.ttl).
---
## 18. Mission orchestrator
The **mission** primitive composes [§16 contracts](#16-validation-contract)
+ [§17 handoffs](#17-worker-handoff) + the run journal into a
three-role pipeline: **Orchestrator** authors, **Worker** does,
**Validator** judges.
### 18.1 Roles
- The **Orchestrator** authors a `ValidationContract` and a
feature plan. It does NOT execute work; it composes the plan
and the validator's expectation in one artifact.
- A **Worker** is dispatched per feature. It performs whatever
work it does (opaque to this spec) and returns a
`WorkerOutcome { handoff, evidence }`. Workers MAY be backed
by any cascade tier — deterministic tools, models, or
humans-in-the-loop.
- The **Validator** runs the §16.5 verifier over the
accumulated evidence and emits a `ContractVerdict`. The
validator's only input is `(contract, evidence)` — pure data —
so its verdict is reproducible and reviewable.
### 18.2 Dispatch
Workers MUST be dispatched in feature order, serially, when the
features mutate shared state. Read-only fan-out (parallel
search, parallel verifiers) MAY be parallel; the implementation
is the caller's choice and the spec does not require it.
Each worker's handoff MUST be recorded on the run journal
before the next worker is dispatched, so the chain stays
chronological.
### 18.3 Strictness
A `strict_workers` mode MAY refuse worker outcomes that produce
no evidence for at least one assertion the worker's feature
claims, failing fast rather than letting the validator surface
the gap later. The default behaviour is non-strict (let the
validator rollup decide).
Reference: [`crates/jouleclaw-mission`](./jouleclaw-rs/crates/jouleclaw-mission/).
---
## 19. Value report
Where a JCR-1 receipt records *what happened* (the activity),
a **value report** records *what landed* against the agent's
declared intent. The two together close the activity-vs-value
gap: activity is easy to count; value is what the user paid for.
### 19.1 Shape
A value report is a JSON document:
- `intent`: free-form natural-language intent the agent was
acting on.
- `tool_id`: tool id the call addressed.
- `checks`: per-check verdicts, each `{ check, passed,
reason? }`.
- `closure_rate`: `passed_count / checks.len()` ∈ [0, 1].
`0.0` when `checks` is empty.
- `fully_closed`: true iff `checks` is non-empty AND every
check passed.
### 19.2 Check kinds
- `status { codes }` — status code MUST appear in `codes`.
- `status_matches_contract` — status MUST be in the operation's
declared `statusCodes` menu (the Hydra contract).
- `output_hash_equals { hash }` — canonical-JSON BLAKE3 of the
body MUST equal `hash`.
- `json_pointer_equals { pointer, expected }` — RFC 6901 pointer
MUST resolve to `expected`.
Implementations MAY define additional check kinds; consumers
MUST tolerate unknown kinds and treat them as `passed: false`
with a `reason` that names the unknown kind.
### 19.3 Aggregation
The mean closure rate across a set of value reports is the
system's honest "delivered / attempted" metric — denominated in
user intent rather than joules. Reports with no checks declared
MUST be skipped in the aggregate (they convey no value
information).
Reference: [`crates/jouleclaw-hydra-client`](./jouleclaw-rs/crates/jouleclaw-hydra-client/)
(`ValueReport`, `ValueCheck`, `ValueCheckResult`,
`mean_closure_rate`).
---
## 20. What this spec deliberately does not say
- **How to build the model.** That's the model-author's concern.
JouleClaw measures and dispatches; it doesn't train.
- **Which retrieval API to use.** Brave / Tavily / Exa / Serper all
plug in through the `SearchProvider` trait. Pick whichever your
deployment permits.
- **How to ship receipts.** The receipt is produced. Transport
(HTTP / lockstep / message queue) is the deployer's choice. Smart
Byte's signed-envelope replication is the recommended substrate.
- **A specific signing key topology.** Bring your own. Smart Byte's
KERI-based AID rotation is the recommended path.
---
## 21. Adjacent techniques
This section names the architectural pattern JouleClaw implements
and lists the research communities that have, separately, solved
parts of it. The intent is not novelty-claiming. It is to make
the assembly visible so an engineer arriving from any one of those
communities can locate their work inside the cascade.
### 9.1 The architectural pattern
An LLM inference call is a render pass. A token is a frame. A
reasoning chain is a sequence of frames. A context window is a
scene graph. An agent loop is an NPC control loop. RAG is texture
streaming. A model checkpoint is a level asset. The pipeline from
prompt to response is — structurally — exactly the work a game
engine does between input poll and presented frame.
The game-engine industry was forced to solve this problem under a
fixed 150–200 W power budget twenty years ago. The five JouleClaw
cascade tiers are direct translations of game-engine architectural
primitives:
| JouleClaw tier | Game-engine primitive | What the engine actually does |
|-----------------|--------------------------------|-------------------------------|
| `L0:Cache` | texture / asset cache | Content-addressed; cheap to check; valid until invalidated |
| `L1:Lawful` | pre-baked geometry, LUTs | The work the engine *refuses to run* because the answer is already in the format |
| `L2:Embed` | BVH / spatial query | Find the closest match; do not compute from first principles |
| `L3:Model` | procedural / runtime synthesis | Invoked only when nothing baked or streamed will do |
| `L4:Wire` | server-streamed asset / CDN | The escape hatch when the local box cannot satisfy |
Each game-engine technique listed below has a near-exact
counterpart in modern AI inference that the AI industry has, so
far, declined to deploy at the same architectural rigor:
Every lever below now has a **shipped** JouleClaw realization — the
frame is no longer rhetorical; each row points at in-tree code:
| Game-engine technique | AI counterpart | JouleClaw component (shipped) |
|--------------------------------|-------------------------------------------------------------|---------------------|
| Frustum culling | Skip tiers whose `estimate_cost` returns `None` | `jouleclaw-cascade::Tier::estimate_cost` |
| Level-of-detail (LOD) | Route to the cheapest sufficient model — SLM before frontier | `jouleclaw-dispatch::ModelBankTier` (cheapest *capable* slot by measured J) |
| Deferred rendering | Do not forward-pass through 175B parameters for a token a 7B would produce identically | `jouleclaw-dispatch` cost-table over backends declaring their `J/op` |
| Physically-based rendering | One foundation model, derive specializations — not 12 full fine-tunes | (consumer concern; the spec doesn't dictate) |
| Virtual texturing | Retrieve only the context this token will attend to, not the whole 128k window | `jouleclaw-stack` RAG pipeline (`retrieve → enrich → rerank → read`, top-k only) + `jouleclaw-fresh` |
| Temporal upsampling | Reuse prior verified work; reconstruct from a small delta, not by re-running | `jouleclaw-promote` (exact yang→yin) + `jouleclaw-skill` (whole query class) |
| Nanite-style mesh streaming | Activate only the reasoner the input actually needs | `jouleclaw-dispatch` routes to the one slot, not the whole bank |
| Hardware ray tracing + denoiser | A few high-quality forward passes plus a verifier beats one large unconstrained pass | `jouleclaw-verify` (`OutputVerifier`) + `jouleclaw-approve` gate before the pass |
| Agent / NPC control loop | Bounded multi-step recursion — fan-out capped, depth bounded by the joule budget | `jouleclaw-agent` (`max_steps` + per-branch budget clamp) |
| Frame budget | `JouleBudget` walks the cascade like a render budget walks the scene graph | `jouleclaw-energy::EnergyQuota` + breaker, `jouleclaw-governor` (global), `jouleclaw-agent` (nested) |
The pattern is not new. The assembly — and the fact that every lever is
a shipped, tested crate rather than a slogan — is.
### 9.2 Five communities, one architecture
Five research communities currently hold one face each of this
architecture. They publish at different venues and do not, by and
large, talk to one another. A conforming JouleClaw runtime composes
all five of their primitives — that composition is the standard's
contribution.
| Community | Representative work | JouleClaw component |
|---|---|---|
| **Constrained decoding** | Outlines (Willard & Louf), XGrammar (Dong et al. 2024), Guidance, LMQL, Pre³, OpenAI/Anthropic structured-output APIs | `jouleclaw-decode` *(shipped)* — pure-Rust regex / CFG / JSON-schema → token-vocabulary mask |
| **Compound AI systems / DSPy** | DSPy (Khattab et al., Stanford → MIT; CAIS 2026 inaugural ACM conference, May 2026) | `jouleclaw-program` *(shipped)* — typed signatures + module compiler — and `jouleclaw-skill`, its deterministic skill-compilation realization |
| **Small / specialist models** | NVIDIA Research (Belcak & Heinrich, 2025), Microsoft Phi team, TinyML, llama.cpp | `jouleclaw-cascade` router + `jouleclaw-pack` declared-cost contracts |
| **Neurosymbolic / verifier-in-the-loop** | Lean + LLM provers, BMC + LLM (LaM4Inv), SymCode, ProofNet++, VIRF, Eidoku | `jouleclaw-verify` (`OutputVerifier` trait + `VerifierChain` + receipt integration) |
| **Energy measurement / Green Software** | Patterson et al., ML.ENERGY Leaderboard, MDPI Sensors edge-computing surveys, GSF SCI specification, AI Energy Score | `jouleclaw-energy` + the `Provenance` honesty contract + `.jc.toml` measured-cost rows |
A conforming runtime **SHOULD** be able to point at concrete
in-tree code or a registered adapter for each of the five primitives
above. A runtime that solves only one face is a research project,
not a JouleClaw implementation.
### 9.3 The three-lever ceiling
Energy reduction from a fully-naive monolithic baseline (~10¹⁸
above the Landauer floor for current generative inference per
output bit) composes multiplicatively across three independent
levers:
| Lever | Reduces by | What does it |
|-------|-----------|---------------|
| **Route to the right cell** | 10⁸–10¹⁰× | The cascade itself — `L0 / L1 / L2` close most queries without invoking a model |
| **Cache the prior work** | 10²–10⁴× | Content-addressed cache (`L0`), prior-resolution history, MRL embeddings (`L2`) |
| **Align silicon to primitive** | 10²–10⁴× | The `.jc.toml` declared-cost contract is the input data hardware co-design needs |
Stacked total: **10¹²–10¹⁸×** below the naive baseline. The "90 %
reduction" figure quoted on the marketing surface is the
conservative floor of what the three levers permit when composed
honestly.
The ceiling is not the Landauer bound — reaching the bound requires
reversible logic and zero-impedance interconnect that nobody can
engineer today. The ceiling is how disciplined the routing and the
hardware choices are.
### 9.4 The receipt is the proof, not the marketing
A runtime that produces lower receipts than the conformance vectors
demand without the per-tool-touch `Provenance` to back them is
non-conformant. JouleClaw refuses the receipts-as-marketing failure
mode that has accumulated around carbon offsets and software
sustainability claims more broadly. Every `joules_uj` figure in a
conforming receipt must trace back to either a real hardware
counter (`Provenance::HwShunt`), a documented vendor model
(`Provenance::ModelBased`), or a calibrated static estimator
(`Provenance::Estimator`) with a wider tolerance band.
The breaker enforces at the granularity of the worst counter in
the span. This is normative.
---
## 22. References
- [JouleClaw Charter](../CHARTER.md) — stewardship pattern (shared
across all five open standards)
- [Smart Byte open standard](../smart-byte/) — signed envelopes
- [EOC open standard](../eoc/) — the four-stage memoising cascade
pattern JouleClaw embodies
- [WAI open standard](../wai/) — media transport + capability
dispatch
- [OpenPay open standard](../openpay/) — the typestate-enforced
lifecycle pattern adopted by JouleClaw's cascade
- W3C PROV-O — provenance vocabulary
- RFC 9449 — DPoP (sender-constrained tokens, recommended for
ClaimProvenance envelopes that carry a fetch credential)
- Landauer, R. (1961). "Irreversibility and Heat Generation in the
Computing Process." The thermodynamic floor under everything in
this spec.