The client sealed any transport-supplied joules figure as HwShunt, in all three clients (Rust lib.rs, Go jclaw_hydra.go, Python client.py), though TransportResponse.joules_uj carries no grade: a transport with an estimate, or a figure of unknown origin, had it sealed as a hardware reading. TransportResponse now carries the grade of the meter that produced the figure (Rust joules_provenance: Option<Provenance>, plus with_joules; Go JoulesProvenance string; Python joules_provenance), and one rule, graded_joules / GradedJoules, decides what is sealed in every client: the figure at its stated grade; an ungraded figure (or, in Go/Python, a grade that is not HwShunt/ModelBased/Estimator) as Estimator; no figure as a zero Estimator. The conformance vectors carry no touch and are unchanged; Go and Python still verify 9/9. Tests (each fails before on HwShunt): Rust an_ungraded_transport_figure_ is_sealed_as_an_estimate, a_graded_transport_figure_keeps_its_grade; Go TestUngradedJoulesAreSealedAsEstimates, TestGradedJoulesKeepTheirGrade; Python tests/test_energy_grade.py (pytest). Co-Authored-By: Claude Opus 5.5 <[email protected]>
61 lines
2.6 KiB
Markdown
61 lines
2.6 KiB
Markdown
# JouleClaw Hydra-Client conformance
|
|
|
|
Cross-language conformance for the third-generation Hydra client.
|
|
Rust + Python + Go reference implementations all produce
|
|
byte-for-byte identical BLAKE3 input/output hashes against the
|
|
vectors below.
|
|
|
|
## Files
|
|
|
|
| File | What |
|
|
|------|------|
|
|
| [`call-reports.json`](call-reports.json) | 5 dispatch vectors + 4 SHACL-validation vectors. Each pairs an input (Hydra API doc + operation name + payload) with the canonical expected CallReport (tool_id, status, input_hash, output_hash, status_matches_contract, body). |
|
|
|
|
## How the three implementations agree
|
|
|
|
Every implementation:
|
|
|
|
1. Parses the Hydra `ApiDocumentation` from the JSON-LD in the vector.
|
|
2. Looks up the operation by `jc_tool_id`.
|
|
3. Validates the input against the embedded SHACL shapes for `https://example.com/Tool#AppendInput` (open-world default elsewhere).
|
|
4. Dispatches via an echo-mode `MockTransport` — the same canonical form: `{ "echo": <input> }`, status 200, no measured energy.
|
|
5. Computes BLAKE3 over lexically-sorted, no-whitespace canonical JSON of input and output.
|
|
6. Returns a `CallReport` with the hex BLAKE3 digests.
|
|
|
|
The three implementations live at:
|
|
|
|
| Language | Path |
|
|
|----------|------|
|
|
| Rust | [`crates/jouleclaw-hydra-client/src/lib.rs`](../src/lib.rs) |
|
|
| Python | [`crates/jouleclaw-hydra-client/clients/python/jclaw_hydra/`](../clients/python/jclaw_hydra/) |
|
|
| Go | [`crates/jouleclaw-hydra-client/clients/go/`](../clients/go/) |
|
|
|
|
## Running
|
|
|
|
```bash
|
|
# Rust (regenerator; also the oracle)
|
|
cargo run -p jouleclaw-hydra-client --example gen_conformance_vectors
|
|
|
|
# Python (requires `pip install blake3`; the energy-grade tests also pytest)
|
|
python3 crates/jouleclaw-hydra-client/clients/python/tests/test_conformance.py
|
|
python3 -m pytest crates/jouleclaw-hydra-client/clients/python/tests/
|
|
|
|
# Go (uses lukechampine.com/blake3 via go.mod)
|
|
cd crates/jouleclaw-hydra-client/clients/go && go test -v ./...
|
|
```
|
|
|
|
All three MUST print `PASS` for every vector. A mismatch on ANY
|
|
implementation is a divergence to fix on that side — the canonical
|
|
oracle is the Rust producer (which is what generates the vectors).
|
|
|
|
## Scope
|
|
|
|
- **In:** the cross-language Hydra-client surface — Hydra parse,
|
|
SHACL validate, dispatch via Transport, BLAKE3 hash over
|
|
canonical JSON, CallReport emission.
|
|
- **Out:** the wire form of cascade receipts and policy receipts
|
|
is covered by separate conformance suites at
|
|
`crates/jouleclaw-jcr1/conformance/` and
|
|
`crates/jouleclaw-policy-receipt/conformance/`. The Hydra client
|
|
produces `ToolTouch`-shaped touches that drop into those streams;
|
|
it does not itself produce signed receipts.
|