Skip to content

symfonic.capabilities.memory.storage_key

storage_key

Versioned kind/ID storage keys; foundation only, no backend migration.

Wire grammar: symfonic.memory.storage/v1/(utf8hex:utf8hex/)+. Each complete level ends in "/", making an ancestor key a safe subtree prefix. Lowercase hex keeps all data delimiters out of the wire alphabet. In particular, keys contain no raw US, while every valid legacy TenantScope.scope_path does: even a root has a kind and ID separated by US. Thus the languages are disjoint, regardless of native-looking labels or punctuation in legacy fields.

This format does not infer kinds from v0/NULL rows, authorize their migration, or establish graph/vector persistence parity.

StorageScopeKey dataclass

StorageScopeKey(levels: tuple[tuple[str, str], ...])

Immutable v1 storage identity with exact root-first kind/ID levels.

Strings are preserved byte-for-byte as strict UTF-8 without normalization. NUL and lone surrogates are rejected at the persistence boundary. This conservative contract keeps decoded fields usable in text backends too.

identity_version property

identity_version: int

Version one retains every kind/ID pair.

key property

key: str

Canonical ASCII key, including the final complete-level terminator.

subtree_prefix property

subtree_prefix: str

Complete-level prefix selecting self and descendants, never siblings.

Only compare against canonical v1 keys. The prefix contains no SQL LIKE wildcards; text backends still need exact/case-sensitive matching. This downward subtree selection differs from ancestor visibility.

ancestor_keys

ancestor_keys() -> list[str]

Exact membership list, root through self; excludes siblings and v0.

Use this list for ancestor visibility (e.g. equality/IN), never a partial string prefix. There is no inferred or empty universal root.

Source code in src/symfonic/capabilities/memory/storage_key.py
def ancestor_keys(self) -> list[str]:
    """Exact membership list, root through self; excludes siblings and v0.

    Use this list for ancestor visibility (e.g. equality/IN), never a
    partial string prefix. There is no inferred or empty universal root.
    """
    ancestors = []
    current = _HEADER
    for kind, value in self.levels:
        current += f"{_encode_field(kind)}:{_encode_field(value)}/"
        ancestors.append(current)
    return ancestors

from_levels classmethod

from_levels(levels: Iterable[tuple[str, str]]) -> StorageScopeKey

Snapshot an iterable of immutable pairs without guessing kinds.

Source code in src/symfonic/capabilities/memory/storage_key.py
@classmethod
def from_levels(cls, levels: Iterable[tuple[str, str]]) -> StorageScopeKey:
    """Snapshot an iterable of immutable pairs without guessing kinds."""
    try:
        return cls(tuple(levels))
    except TypeError as error:
        raise MemoryContractError("storage levels must be an iterable of pairs") from error

from_scope classmethod

from_scope(scope: MemoryScope) -> StorageScopeKey

Accept only validated native v1 scopes; refuse positional v0/NULL.

Source code in src/symfonic/capabilities/memory/storage_key.py
@classmethod
def from_scope(cls, scope: MemoryScope) -> StorageScopeKey:
    """Accept only validated native v1 scopes; refuse positional v0/NULL."""
    if not isinstance(scope, MemoryScope):
        raise MemoryContractError("storage identity requires a native MemoryScope")
    scope.validate()
    if scope.identity_version != 1:
        raise MemoryContractError("ambiguous v0 scopes cannot become native storage identity")
    return cls(scope.levels)

parse classmethod

parse(key: str) -> StorageScopeKey

Reject legacy, unknown versions, malformed UTF-8 and noncanonical wire.

Source code in src/symfonic/capabilities/memory/storage_key.py
@classmethod
def parse(cls, key: str) -> StorageScopeKey:
    """Reject legacy, unknown versions, malformed UTF-8 and noncanonical wire."""
    if type(key) is not str or not key.startswith(_HEADER) or not key.endswith("/"):
        raise MemoryContractError("invalid or unsupported storage identity version")
    body = key[len(_HEADER):-1]
    try:
        levels = []
        for component in body.split("/"):
            if not _PAIR.fullmatch(component):
                raise ValueError("invalid level framing or noncanonical hex")
            kind, value = component.split(":")
            levels.append((
                bytes.fromhex(kind).decode("utf-8"),
                bytes.fromhex(value).decode("utf-8"),
            ))
        identity = cls(tuple(levels))
        if identity.key != key:
            raise ValueError("noncanonical storage identity")
        return identity
    except (ValueError, UnicodeError) as error:
        raise MemoryContractError("malformed or noncanonical storage identity") from error