On this page

SpellSpace๏ƒ

Use md.SpellSpace from the public package namespace.

Implementation source

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.

  • Carries one lease flag, _released: the pool sets it on release and clears it on acquisition, and a released space refuses meld and purge with SpellSpaceScopeError. After permanent cleanup it stays True as a documented tombstone.

  • Every exit finishes its pool return (or destroy) when a disposal method fails - the store is emptied before any method runs - and then raises the disposal ExceptionGroup.

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 - every exit clears them before the space goes back to its pool, and a released space refuses meld, so a recycled shell cannot serve an object built through a stale handle. 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(); the block exit clears spellspace-scoped instances and returns the space to its pool; a released space refuses meld and purge.

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. A space that is already released is left as it is, so a second cleanup never pools it twice.

  • permanent_cleanup() forces the destructive lane even when a pool is attached.

  • Either lane finishes when a disposal method fails (the store is emptied before any method runs), then the disposal ExceptionGroup propagates.

Raises:

ExceptionGroup -- Disposal failures, after the space is pooled or destroyed.

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; a space that is already released (or destroyed) returns at once.

  • 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, restoring temporary hooks after disposal and before idle publication.

  • Finishes the hook reset and pool release when a disposal method fails (the store was swapped empty first), then the disposal ExceptionGroup propagates.

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(...).

Raises:

ExceptionGroup -- Disposal failures, after the space is back in its pool.

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=.... A warm id meld is served here from the spellspace door's fast-door entry; any other id meld is forwarded positionally to the 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.

  • Warm id lane (2026-09-26): a spell_id=... meld with no spell, spellframe or binding_name reads the door's fast-door entry and applies the same guard ladder and arms as SpellSpaceMeld.meld (plain, non-empty dict override, bound existing object). A hit returns without entering the door; a miss or any failed guard continues in the door, so results, errors and the cache-emit check are identical to calling the door.

  • Warm name/class lane (2026-09-27): a meld("Name") or meld(spell=Cls) with no spellframe or binding_name reads the door's name/class registry with the same guards and arms; the door mints that entry after one successful meld of the shape, so a hit and the door agree. An unhashable spell, an instance or a callable as spell are misses and continue in the door.

  • Propagates runtime failures from the meld pipeline unchanged.

  • A space released to its pool raises SpellSpaceScopeError before any lookup; a permanently cleaned one raises RuntimeError.

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.

purge(spell: str | object | None = None, *, spell_id: str | None = None, spellframe: str | object | None = None, binding_name: str | None = None, purge_all: bool = True) → int[source]๏ƒ

Purge a registered target's retained creations from this SpellSpace.

Purpose:

Expose request-local retirement through the owned SpellSpaceMeld door while keeping this explicit scope usable.

Contract:

  • SpellSpaceMeld authorizes only many and unique_per_spell_space.

  • The target store is always this space's own Creations. No conduit, Spell owner, lineage-root or cluster team store can be selected.

  • Identity normalization follows meld's name/type/frame/id rules.

  • Purge does not exit the scope, pop its stack or return it to a pool.

Parameters:
  • spell -- Logical name, class/function reference or application instance. An instance is inspected for its class before ordinary lookup. The original reference is retained for single-object removal.

  • spell_id -- A version's spell_id, mutually exclusive with spell. It names exactly that version - active or parked, the owner conduit's Book's own or a borrowed copy - and this space's entries of it.

  • spellframe -- Optional frame/type used by ordinary binding discovery.

  • binding_name -- Optional binding name within that frame.

  • purge_all -- True removes every retained local entry for the target. False requires an instance as spell and removes only that object.

Returns:

Removed local creation count; zero when none are retained.

Return type:

int

Raises:
  • ValueError -- If selectors conflict, no target is supplied, or single-object removal is requested without an instance.

  • KeyError -- If no version this space's Book can see carries the spell_id, or normal meld discovery cannot find the binding.

  • RuntimeError -- If permanently cleaned or the target has a broader lifetime.

  • SpellSpaceScopeError -- If this space was released to its pool.

  • TypeError -- If purge_all is not a bool.

  • ExceptionGroup -- Disposal failures after selected local entries have been removed.

Threading / Lifecycle:

Creations uses this space's store lock and releases it before disposal. Direct manual use needs no active managed stack entry. Managed thread confinement and pool ownership rules remain unchanged; a returned/recycled space refuses purge until it is acquired again.

Topic reference ยท Full contents