httk.core.storage.identity

Canonical content identity for plain and projected frozen records.

Canonical format version 2 represents a standalone record as a type-tagged record object containing its logical identity_name and sorted field pairs. Whenever an annotated record is reached through a field, a list or tuple element, or a typed mapping value, the parent contains only a Merkle reference:

{"content_id": "<64 lowercase hex characters>", "type": "record_ref"}

The referenced digest is SHA-256 of that child’s own canonical record JSON, including its "version": 2 header. It is computed in the same encoder context as the parent so active-path cycle detection retains the complete field path. Canonical JSON uses ASCII escaping, compact separators, and sorted object keys.

The v2 value-node shapes are:

  • null; bool with a JSON boolean; int with decimal text; float with float.hex() text; string; and hexadecimal bytes;

  • rational for fractions.Fraction, decimal.Decimal, and FracScalar, with reduced "p/q" text and an explicit positive denominator (including "0/1" and "5/1");

  • structural frac_vector, surd_scalar, and surd_vector nodes, unchanged from format v1;

  • date and datetime nodes, the latter recording whether the original value was timezone-aware;

  • list and tuple nodes containing value nodes, and mapping nodes containing sorted string-key/value-node pairs;

  • custom nodes containing the exact Python type name and the tagged value returned by its registered encoder; and

  • standalone record nodes plus the record_ref nodes described above.

The format is not injective after record children are replaced by digests. Its guarantee is computational binding: producing two distinct well-formed canonical value trees, modulo the documented deliberate equivalences (shared-vs-duplicated equal children, IdentitySkip exclusions, identity_name-based record unification, Decimal equivalence with Fraction, builtin-subclass leaf unification, and annotation-normalized list/tuple values), with equal digests requires a SHA-256 collision. A record_ref is sound domain separation because user data is always enclosed in its own tagged value node and can never forge a bare reference node.

Exceptions

StorageProjectionCycleError

Raise when a projected record graph contains an active cycle.

Functions

register_canonical_encoder(python_type, encoder)

Register one deterministic encoder for an exact custom Python type.

resolve_storage_record(source, *[, as_record])

Resolve the exact record target for source without constructing it.

project_storage_record(record_type, source)

Project and validate one record level, returning field values by name.

storage_identity_name(record_type)

Return the logical identity name, independent of physical storage naming.

canonical_form(obj, *[, as_record, projector, extras])

Return the versioned, type-tagged canonical JSON for a record value.

content_id(obj, *[, as_record, projector, extras])

Return the lowercase SHA-256 content identity of obj.

Module Contents

exception httk.core.storage.identity.StorageProjectionCycleError(path, record_type)

Bases: ValueError

Raise when a projected record graph contains an active cycle.

Parameters:
  • path (str) – The canonical field path where the cycle was detected.

  • record_type (type[Any]) – The record class being projected when the cycle was found.

path
record_type
httk.core.storage.identity.register_canonical_encoder(python_type, encoder)

Register one deterministic encoder for an exact custom Python type.

Leaf values use exact-type lookup, so a registered encoder for a base class does not apply to subclasses. The encoder must return JSON-compatible data.

Parameters:
  • python_type (type[Any]) – The exact custom class to encode.

  • encoder (collections.abc.Callable[[Any], Any]) – The deterministic encoder callable.

Raises:
  • TypeError – If the type or encoder is invalid.

  • ValueError – If an encoder is already registered for the class.

httk.core.storage.identity.resolve_storage_record(source, *, as_record=None)

Resolve the exact record target for source without constructing it.

Parameters:
  • source (Any) – The source value whose storage record target is requested.

  • as_record (type[Any] | None) – An explicit record class override, if supplied.

Returns:

The validated frozen dataclass record class.

Raises:

TypeError – If the resolved target is not a frozen dataclass.

Return type:

type[Any]

httk.core.storage.identity.project_storage_record(record_type, source)

Project and validate one record level, returning field values by name.

Projection classes may declare a source class and classmethod projection; otherwise source must already be an instance of record_type. A projection used by the trusted content-id path must be deterministic for the immutable lifetime of its source: the content-id cache is governed by that immutability contract.

Parameters:
  • record_type (type[Any]) – The frozen dataclass record class to project.

  • source (Any) – A record instance or declared projection source.

Returns:

Field values present at this record level.

Raises:
  • TypeError – If the record or projection declaration is invalid.

  • ValueError – If a projection omits a required field or names an unknown one.

Return type:

collections.abc.Mapping[str, object]

httk.core.storage.identity.storage_identity_name(record_type)

Return the logical identity name, independent of physical storage naming.

Parameters:

record_type (type[Any]) – The record class whose logical identity name is requested.

Returns:

The declared identity name or the fully qualified class name.

Raises:

TypeError – If record_type is not a class or has an invalid storage declaration.

Return type:

str

httk.core.storage.identity.canonical_form(obj, *, as_record=None, projector=project_storage_record, extras=None)

Return the versioned, type-tagged canonical JSON for a record value.

Storage integrations may supply a caching projector to reuse the exact per-record mappings traversed while computing identity.

Record fields marked with IdentitySkip, or represented by stored_property, are outside the content identity. Registered custom encoders apply only to exact leaf types.

extras fold additional save-time key/value pairs into the identity of the root record only; child records never receive them. When extras is None or empty the output is byte-identical to omitting it.

Parameters:
Returns:

Versioned, type-tagged canonical JSON.

Raises:
  • TypeError – If a value or projection cannot be represented.

  • ValueError – If a projection is invalid or contains a cycle.

Return type:

str

httk.core.storage.identity.content_id(obj, *, as_record=None, projector=project_storage_record, extras=None)

Return the lowercase SHA-256 content identity of obj.

The digest covers canonical_form(), including exact-type leaf encodings and excluding fields marked with IdentitySkip.

extras fold additional save-time key/value pairs into the root record’s identity (see canonical_form()). Extras-bearing calls bypass the trusted per-instance cache entirely, so they never read or poison it.

Parameters:
Returns:

The lowercase SHA-256 hexadecimal digest.

Raises:
  • TypeError – If a value or projection cannot be represented.

  • ValueError – If a projection is invalid or contains a cycle.

Return type:

str