dizzy.engine.dagstore.canonical¶
dizzy.engine.dagstore.canonical
¶
Canonical JSON for hashing — RFC 8785 (JCS) on a deliberately narrowed subset.
This is the single serialization the content hash is computed over. Transport codecs may re-encode events however they like; this form is the identity-bearing one, so it must be reproducible byte-for-byte in any language. The house rules that narrow plain JSON down to something a hash can tolerate:
- No floats. Amounts, durations, scores travel as ints or decimal strings. (JCS does define float serialization, but requiring every future Rust/TS worker to reproduce ECMAScript float formatting is a portability trap.)
- Ints stay inside ±(2^53 − 1). Beyond that, ECMAScript-style serializers switch to exponent notation while Python would print full decimal — so the range where the two agree is the only range allowed.
- Absent ≠ null. Both are representable and hash differently; emitters must omit absent fields. This module can't enforce the convention, but it round-trips both faithfully so violations are at least visible.
- Object keys sort by UTF-16 code units (per JCS), not Python's code-point order. The two differ only for keys containing astral-plane characters.
NotCanonicalizable
¶
Bases: ValueError
The value falls outside the hashed subset (float, big int, non-str key…).
Source code in dizzy/src/dizzy/engine/dagstore/canonical.py
33 34 | |
canonical_json(value)
¶
Serialize value to canonical JSON bytes (UTF-8).
Deterministic: equal values (regardless of dict insertion order) always produce identical bytes. Raises NotCanonicalizable for anything outside the hashed subset.
Source code in dizzy/src/dizzy/engine/dagstore/canonical.py
89 90 91 92 93 94 95 96 97 98 | |