A complete, tested utility for canonical hashing and digesting of JSON values.
A complete, tested building block for the Retsumdk ecosystem. Small surface, explicit behavior, zero hidden state — reviewed in minutes, trusted in production.
- Deterministic, stable normalization of JSON-serializable input
- SHA-256 digesting over a canonical form
- Structured, validated result shape with a passing test suite
pip install -r requirements.txt
pytest -qAny time a piece of state is stored, cached, compared, or synced, someone eventually asks: "is this value the same as that value?" Naive equality fails across process boundaries — {'a': 2, 'b': 1} and {'b': 1, 'a': 2} are equal as Python dicts but serialize differently. state-persistence collapses every JSON-serializable value into one deterministic canonical string, then hashes it, so equality becomes a cheap digest comparison instead of a structural deep-compare.
input value
│
▼
normalize() ── sorted keys, compact separators, default=str for exotic types
│
▼
canonical string
│
▼
digest() ── hashlib (sha256 by default) → 64-char hex digest
from state_persistence import normalize, digest, run
normalize({"b": 1, "a": 2})
# '{"a":2,"b":1}' — key order in the input dict does not matter
digest({"k": "v"})
# 64-char hex digest, stable across runs and processes
run({"hello": "world"})
# {
# "input_type": "dict",
# "canonical": '{"hello":"world"}',
# "length": 17,
# "digest": "93a23971a914e5eacbf0a8d25154cda309c3c1c72fbb9914d47c60f3cb681588"
# }Running the module directly prints a structured result for a sample payload:
python state_persistence.py| Function | Signature | Returns |
|---|---|---|
normalize |
(value: Any) -> str |
Deterministic canonical string: sorted-key compact JSON for dicts/lists, str(value) for scalars |
digest |
(value: Any, algorithm: str = "sha256") -> str |
Hex digest of the canonical form; any hashlib algorithm name works |
run |
(input_data: Any = None) -> dict |
Structured result: input_type, canonical, length, digest |
- Order invariance —
normalize({'b': 1, 'a': 2}) == normalize({'a': 2, 'b': 1}). Keys are sorted at every nesting level. - Compact separators — no spaces:
'{"a":2}', never'{"a": 2}'. - Non-JSON-native values — objects the JSON encoder can't handle (e.g.
datetime.date) are stringified viadefault=str, sodate(2026, 9, 23)canonicalizes as"2026-09-23". - Scalars bypass JSON —
normalize('x')is'x', hashed as UTF-8 bytes directly. - Unknown algorithms raise —
digest(value, "nope")raisesAttributeErrorfromhashliblookup; there is no silent fallback. - Empty input defaults —
run()with no argument canonicalizes{}rather than raising.
An agent checkpoint store keeps one snapshot per workflow step. Two snapshots of the same logical state must not produce two rows. Instead of deep-comparing nested structures on every read, store digest(state) alongside each snapshot and index on it — equal digests collapse duplicates, and any drift in a single nested key produces a different digest immediately.
state-persistence/
├── state_persistence.py # normalize / digest / run implementation
├── test_state_persistence.py # pytest suite (determinism, stability, result shape)
├── pyproject.toml # packaging metadata
├── requirements.txt # pytest
└── .github/workflows/ci.yml # CI on push and pull_request
pip install -r requirements.txt
pytest -q| Test | Behavior verified |
|---|---|
test_normalize_deterministic |
Key order in the input dict cannot change the canonical string |
test_digest_stable |
Same value → same digest, for scalars and nested structures |
test_run_shapes_result |
run() returns input_type, positive length, and a 64-char hex digest |
MIT © Retsumdk