Skip to content

symfonic.capabilities.memory.layers

layers

The five memory layers, and the one place their order is decided.

The Pentad is the framework's existing vocabulary (symfonic.memory.types); this module restates it as a StrEnum on the capability side so a port signature never has to reach into the legacy package to name a layer. The strings are identical, which is what makes the migration a re-import rather than a data conversion.

The ladder exists for one reason: two memories that tie on score still need a defined relative position, and "whichever the backend yielded first" is not one. It is a rendering order, not a precedence claim โ€” nothing here says a semantic fact matters more than an episode.

MemoryLayer

Bases: StrEnum

The five layers of the Pentad memory model.

EPISODIC class-attribute instance-attribute

EPISODIC = 'episodic'

Narrative events, scenarios, and timestamps (When/Where).

PROCEDURAL class-attribute instance-attribute

PROCEDURAL = 'procedural'

Skills, code snippets, and workflows (How).

PROSPECTIVE class-attribute instance-attribute

PROSPECTIVE = 'prospective'

Commitments, reminders, and pending tasks (Future).

SEMANTIC class-attribute instance-attribute

SEMANTIC = 'semantic'

Permanent facts and graph entities (What).

WORKING class-attribute instance-attribute

WORKING = 'working'

Active conversation context, session-scoped (Now).

layer_index

layer_index(layer: MemoryLayer) -> int

Position of layer on the ladder; lower renders earlier.

Source code in src/symfonic/capabilities/memory/layers.py
def layer_index(layer: MemoryLayer) -> int:
    """Position of ``layer`` on the ladder; lower renders earlier."""
    return LAYER_LADDER.index(layer)

resolve_layer

resolve_layer(value: str | MemoryLayer) -> MemoryLayer

Turn a caller's layer string into a member, or refuse it in-hierarchy.

MemoryLayer('reflective') raises a bare :class:ValueError, which a caller guarding on :class:~.errors.MemoryCapabilityError would miss. Every way of naming a layer wrong reports the same way.

Source code in src/symfonic/capabilities/memory/layers.py
def resolve_layer(value: str | MemoryLayer) -> MemoryLayer:
    """Turn a caller's layer string into a member, or refuse it in-hierarchy.

    ``MemoryLayer('reflective')`` raises a bare :class:`ValueError`, which a
    caller guarding on :class:`~.errors.MemoryCapabilityError` would miss. Every
    way of naming a layer wrong reports the same way.
    """
    try:
        return MemoryLayer(value)
    except ValueError as exc:
        raise MemoryContractError(
            f"{value!r} is not a memory layer; the Pentad is "
            f"{[member.value for member in LAYER_LADDER]}. An unrecognised layer is refused "
            "rather than guessed at โ€” a misfiled memory is retrieved by the wrong turn."
        ) from exc