open-standards/joulehook/README.md
Transaction Science b0ea7eda50 joulehook: the deployable meter — joulehook-proxy (OpenAI-shaped base_url proxy)
The meter seam's deployable form (SPEC §4 Proxy): point a host's model base_url at
joulehook-proxy and every call is capped + sealed. Per request it injects the
configured joule ceiling (inject_ceiling), forwards to the Mesh upstream, and seals
the response's usage.energy as an efficiency/1 receipt (bridge_receipt_default).
tiny_http server + ureq client. Integration-tested against a localhost mock upstream:
the mock echoes the injected ceiling (7mJ) and the proxy seals the efficiency receipt;
an unreachable upstream is a 502, not a panic. Also dedups the meter steward into
joulehook-meter (METER_STEWARD + bridge_receipt_default). 24 tests; clippy-clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-04 20:38:32 -04:00

84 lines
4.7 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.

# JouleHook — Metered, Gated, Attested Agent Work in Any Host
*Provisional name — the steward may rename; the profile string `joulehook/1` and the
seam names are the stable surface.*
The energy-accounting and methodology-gating you build for one coding agent is worth
little if it's trapped in that one agent. JouleHook carries it into the editors
developers already use — **Claude Code, Cursor, Windsurf, Antigravity, Zed, JetBrains,
OpenCode** — without forking any of them.
It rests on one finding: **no host lets an extension observe its agent's tokens or
intercept its native tools** — but every host exposes the same three seams, and
JouleHook is the normative contract over them:
> **A per-action *gate*, a model-call *meter*, and a *receipt* surface. Bind those
> three to a decide-outside-the-model grant check, an honest energy meter, and a
> sealed receipt, and any agent's work becomes a metered, gated transaction — from
> one core.**
JouleHook does not replace the host's agent. It is the **host-binding layer** for the
sibling standards: **JCP** decides and grants, **Mesh** meters at the model front
door, **`jcp-efficiency`** is the receipt. JouleHook adds the seam contract and the
per-host conformance profiles that make them portable.
- **Licence:** Apache-2.0 for reference code ([`LICENSE`](LICENSE)); CC-BY-4.0 for
specification text ([`LICENSE-SPEC`](LICENSE-SPEC)).
- **Status:** v0.1.0 draft. Specification published ([`SPEC.md`](SPEC.md)); reference
workspace `joulehook-rs/` ships the **gate binding** (`joulehook-hook`) for the
`claude-code` **and** `hooks-family` profiles — one PreToolUse hook that gates by
JCP capability (decided outside the model, every decision sealed) and speaks the
native decision format of Claude Code, Cursor, Windsurf, and Antigravity behind a
`--host` selector; `joulehook-statusline`, the in-editor joule meter (honest `est`
from Claude Code's own tokens); and `joulehook-mcp`, an MCP server that surfaces
the sealed decisions as **verified, human-readable** resources in any MCP-speaking
editor. The `claude-code` `full` profile installs today
([`joulehook-rs/INSTALL.md`](joulehook-rs/INSTALL.md)); the enforcing Mesh-proxy
meter + a site land next.
## The three seams
| Seam | Host mechanisms | What rides it |
|---|---|---|
| **Gate** | `PreToolUse`-hook family; ACP `request_permission` | allow / deny / rewrite, decided outside the model, sealed |
| **Meter** | `base_url` proxy; OTel `gen_ai.*` | tokens→joules, honest provenance, enforceable joule ceiling |
| **Receipt** | MCP resources; status line; panel | hash-chained, verifiable `efficiency/1` + decision receipts |
## Conformance profiles
`claude-code` (reference) · `hooks-family` (Cursor / Windsurf / Antigravity) · `acp`
(Zed / JetBrains / Neovim) · `opencode` · `cline` · `vscode` (Open-VSX) · `meter-only`
(Continue, any OTel host). See [`SPEC.md §6`](SPEC.md).
## The honest limit
A host-side adapter alone cannot meter the host agent's own tokens; a complete energy
figure requires the Meter seam (proxy or OTel). An adapter that claims whole-session
energy without a bound meter is non-conformant ([`SPEC.md §7`](SPEC.md)).
## What's here
```
joulehook/
├── SPEC.md — the normative standard (§1–§9)
├── README.md — this file
├── joulehook-rs/ — reference implementation
│ └── crates/
│ ├── joulehook-hook — ✅ the PreToolUse gate CLI for the hook family
│ │ (Claude Code / Cursor / Windsurf / Antigravity via --host;
│ │ wraps jcp-bridge::LocalToolGate for the JCP check + seal)
│ │ + joulehook-statusline — ✅ the in-editor joule meter
│ ├── joulehook-mcp — ✅ the receipt-surface MCP server (sealed decisions →
│ │ verified MCP resources, any MCP-speaking editor)
│ ├── joulehook-meter — ✅ the meter-seam binding: inject a grant's budget as
│ │ the Mesh joule ceiling (enforce) + bridge Mesh's
│ │ usage.energy into an efficiency/1 receipt
│ └── joulehook-proxy — ✅ the deployable meter: an OpenAI-shaped base_url
│ proxy that caps + seals every model call
└── conformance/v1/ — ✅ reproducible vectors: per-host decision encodings
(decisions.json) + a byte-deterministic sealed deny receipt
(deny-receipt.hex + receipt.json, verified-decode)
```
JouleHook is one of the [Transaction Science open standards](../README.md).
Transaction Science is the steward, not the proprietor.