“All is number.” — Pythagoras
1. Why Unified Hashing Exists
HeavenBase derives IDs, buckets, cache keys, and fingerprints from many different value kinds — ints, strings, lists, dicts, dataclass rows, Python functions, capsules, MCP tools, and more. Without a shared encoder layer, every call site ends up with its own serialization rule:salt. The encoder normalizes common Python values (including structured objects and callables) into a deterministic string before hashing; hash_id(...) is the namespaced front door when several logical parts should hash together:
These helpers are deterministic utility hashes, not authentication or password-storage primitives.
2. Core Idea
HeavenBase often needs identifiers that behave like strings because they move through JSON, database rows, object IDs, and filenames. It also sometimes benefits from values that can be interpreted as integers for ordering, bucket assignment, or index-friendly storage.md5hash(...) and crc32hash(...) return zero-padded decimal strings. That means they can live as normal string IDs, but same-length values also sort like their integer representation. crc32hash(...) defaults to length 10; md5hash(...) defaults to length 42.
This is not settled as a universal design. The integer-able string hash is a practical compatibility move for the current pre-release, not a claim that every external API should depend on this exact representation. We are still exploring the best way to achieve stability and generic usability.
3. Create a Stable ID
md5hash(...) serializes common Python values with stable JSON ordering and returns a zero-padded decimal string. The default length is 42, which matches HeavenBase’s identifier-friendly hash width.
hash_id(...) when an ID should carry a logical namespace:
4. Bucket or Order Values
Use integer digests when modulo arithmetic, deterministic sampling, sparse weights, or ordering needs a number. Usehash_int(...) or resolve_hash_int(...) when the method is runtime policy rather than a fixed ID contract.
resolve_hash_int(...) accepts md5, sha256, crc32, optional xxhash64 / xxhash128 when the xxhash package is installed, and dotted callables with the signature fn(obj, salt=None, sep="||") -> int.
crc32int(...) is the cheapest deterministic stdlib option and is used by the Sparse GRAM runtime for trigram weights and sparse-span hashes in SQL-hosted SparseGramIndex and the explicit compatibility gram backend. Exact keyword verification protects query correctness when CRC32 collisions widen the candidate set. md5int(...) is still useful for local utility IDs, and sha256int(...) is useful when a wider digest makes the intent clearer.
Keep persisted identity and integrity surfaces pinned to explicit helpers: hash_id(...) / md5hash(...) for existing object IDs, and sha256hash(...) for fingerprints and cache correctness boundaries. CRC32 is the default policy for candidate generation and deterministic sampling because those paths exact-verify or tolerate changed sample choice.
5. Fingerprint Larger Payloads
Usesha256hash(...) for hex fingerprints in manifests, config snapshots, and integrity checks.
These helpers are deterministic utility hashes, not authentication or password-storage primitives.

