"""Small shared helpers: stable JSON and the hash that identifies a config.
The hash is computed over the *effective layer set* for one instance, not over
the whole hive document: publishing a canary layer must not make every other
machine re-ack identical content. The hive and the instance compute it the
same way, so an ack can be compared by string.
"""
from __future__ import annotations
import hashlib
import json
def canonical_json(value: object) -> str:
return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
def content_hash(value: object) -> str:
digest = hashlib.sha256(canonical_json(value).encode("utf-8")).hexdigest()
return f"sha256:{digest}"