On this page
SpellSpace๏
Use md.SpellSpace from the public package namespace.
- class SpellSpace(*, owner_conduit_id: str, conduit_meld: ConduitMeld, owner_conduit_creations: ConduitCreations, spellspace_registry: set[SpellSpace], spellspace_pool: SpellSpacePool, spellspace_stack_state: SpellSpaceThreadState)[source]๏
Explicit scope handle for Existence.unique_per_spell_space.
- Purpose:
Represent one spellspace-bound resolution window without storing a live conduit back-reference. The conduit remains the factory for spellspaces, but the runtime scope object carries only the explicit collaborators it needs to execute, reset, and unregister itself.
Contract:
Owns one stable spellspace id and one stable owner conduit id.
Delegates runtime execution through one owned SpellSpaceMeld.
Clears spellspace-scoped instances through the injected Creations.
Unregisters itself from the injected spellspace registry on cleanup.
Does not own conduit-wide resolution caches or control-plane state.
Acts as its own context manager for the managed with conduit.enter_spellspace() as space: lane: enter_spellspace() acquires and activates the space (pool acquire plus thread-stack push) before the with statement runs, so __enter__ is a trivial self-return and __exit__ performs the LIFO pop-validated recycle. No per-cycle wrapper object exists.
Nested managed scopes are first-class: each enter_spellspace() call pushes one new independent scope onto the per-thread stack (A -> B -> C -> D to any depth), each scope owns its own spellspace-local storage, and exits must unwind in LIFO order.
One managed activation per acquisition: after __exit__ recycles the space back to the pool, re-entering the same object is a caller contract violation (the trusted-private-caller posture documented on SpellSpacePool.release); LIFO validation in pop_expected fails fast on the common misuse shapes.
Threading:
Uses an internal RLock for cleanup/reset idempotence.
The managed enter/exit lane itself is thread-confined by construction (pool deque hand-off plus per-thread stack), matching the recycle_from_managed_context confinement contract.
Lifecycle:
Created by Conduit.create_spellspace(...) or Conduit.enter_spellspace(...).
Normal cleanup returns the spellspace to its conduit-local pool.
Permanent cleanup drops all injected collaborators.
- Registration:
MELDER KERNEL - guarded, access=public. Users DRIVE it as a context manager (with conduit.enter_spellspace() as space:) and meld against the active space, but never construct or bind() it - the conduit is the factory and the guard refuses binding.
- Subsystem Context:
The scope handle of the conduit spell_space subsystem, backing Existence.unique_per_spell_space. The conduit is the factory; this object carries only the explicit collaborators it needs (an owned SpellSpaceMeld for execution, an injected Creations for its scoped instances, and the registry/pool it unregisters and recycles into). It holds NO live conduit back-reference. Managed entry lives on a per-thread stack, so nested enter_spellspace() scopes (A -> B -> C) each own their storage and must unwind LIFO.
- System Context:
This is how the DGR gives a caller an EXPLICIT, nestable resolution window without leaking conduit-wide state into it: instances resolved as unique_per_spell_space live and die with the space, and reset() clears them and bumps a version so a recycled space cannot serve stale instances. Making the space its own context manager (trivial __enter__, LIFO-validated __exit__ recycle) and confining the managed lane to one thread is what lets the pool hand spaces back and forth without per-cycle wrapper objects or cross-thread synchronization.
AGENT_ACCESS: public
- AGENT_PURPOSE:
access: public. Explicit request scope for Existence.unique_per_spell_space. Enter via conduit.enter_spellspace(); meld only while it is the ACTIVE spellspace; reset() clears spellspace-scoped instances and bumps the version.
- cleanup() None[source]๏
Cleanup this spellspace through either the reusable or permanent lane.
Contract:
Normal cleanup returns this spellspace to the conduit-local pool after reusable cleanup.
permanent_cleanup() forces the destructive lane even when a pool is attached.
- Returns:
None.
- permanent_cleanup() None[source]๏
Permanently destroy this spellspace instead of returning it to a pool.
Contract:
Flips the permanent cleanup flag immediately.
Reuses the normal cleanup entrypoint so all public teardown still flows through one surface.
- Returns:
None.
- recycle_from_managed_context() None[source]๏
Recycle one managed pooled spellspace through the fast common lane.
- Purpose:
Avoid the generic cleanup branch work on the common enter_spellspace() managed exit path, where the spellspace is untracked in the registry and is expected to return directly to the conduit-local pool after clearing only spellspace-local state.
Contract:
Valid only for live managed spellspaces acquired through the untracked pool path.
Falls back to the generic cleanup entrypoint when permanent teardown was requested or the spellspace is registry-tracked.
Clears spellspace-local creations before returning this spellspace to the pool.
Keeps collaborator references intact for later reuse.
Threading / Concurrency:
This lane runs without the spellspace RLock because managed spellspaces are thread-confined by construction: the pool's deque pop hands the object to exactly one thread, the object lives only on that thread's SpellSpaceThreadState stack, and pop_expected(...) validates LIFO ownership before this method runs. The pool's deque append on release is the hand-off point to the next acquiring thread.
The spellspace-local clear uses Creations.reset_for_pool_unlocked(): the same thread confinement that justifies skipping the spellspace lock also covers the store's internal lock on this lane. The clear remains explicit and immediate, not deferred; disposal-bearing stores still fall back to the fully locked teardown flow inside that method.
Concurrent external cleanup() / permanent_cleanup() against an in-flight managed spellspace is a caller contract violation (the object is not idle in the pool and not registry-tracked), matching the trusted-private-caller posture documented on SpellSpacePool.release(...).
- Returns:
None.
- property id: str๏
Return the stable identifier for this spellspace.
Contract:
The space's versioned identity, assigned at construction.
NOT check_cleaned() guarded, so it stays readable on a recycled or cleaned space - useful for logging a space you no longer hold.
- Threading:
Unsynchronized read; safe from any thread.
- Lifecycle / Cleanup:
Readable after cleanup, by design.
- Returns:
Unique id assigned at construction.
- Return type:
str
- property owner_conduit_id: str๏
Return the stable owner conduit id for this spellspace.
Contract:
The conduit this space belongs to, fixed at construction - a pooled space is never re-homed to a different conduit.
NOT check_cleaned() guarded, matching id.
- Threading:
Unsynchronized read; safe from any thread.
- Lifecycle / Cleanup:
Readable after cleanup, by design.
- Returns:
Owner conduit id injected at construction time.
- Return type:
str
- meld(spell: str | object | None = None, *, spell_id: str | None = None, spellframe: str | object | None = None, binding_name: str | None = None, override: dict | list | tuple | None = None) object[source]๏
Delegate one meld call through the injected Meld runtime.
- Call shape:
Positional strings are human SpellNames. Machine callers use keyword-only spell_id=..., which is forwarded positionally to the spellspace door's existing ID fast lane.
Contract:
Delegates resolution and lifecycle behavior to the shared conduit meld runtime through its spellspace front door.
Keeps human spell and machine spell_id identities mutually exclusive.
Propagates runtime failures from the meld pipeline unchanged.
- Returns:
The resolved runtime object returned by the shared meld runtime.
- Return type:
object
- Parameters:
spell -- Human SpellName string or concrete spell/frame object.
spell_id -- Optional canonical SHA256 machine identity.
override -- Optional positional or keyword override payload.