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.

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.

Topic reference ยท Full contents