import threading
from enum import Enum
from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, Union
from melder.nexus.configuration.nexus_frame_mode import (
NexusFrameMode,
)
from melder.nexus.configuration.rift_space_type import RiftSpaceType
from melder.nexus.configuration.rift_validation_mode import RiftValidationMode
from melder.utilities.general_base.cleanable import Cleanable
from melder.crystallizer.crystallizer import Crystallizer
from melder.crystallizer.crystals.nexus_crystal import NexusCrystal
from melder.utilities.helpers.general_helpers import EnumHelpers
from melder.utilities.helpers.id_builder import IDBuilder
[docs]
class NexusConfiguration(Cleanable):
"""
Internal
Process-wide configuration for `Nexus`.
Purpose:
Hold central Nexus governance and default-programming behavior without
pushing per-Rift room/history semantics up into the process-wide layer.
Contract:
- Mutable until frozen.
- Stores typed properties in one property bag.
- Governs process-wide creation/access policy, Nexus-frame topology,
target-frame restrictions, and per-Rift defaults.
- Once finalized, property mutation is disallowed.
Lifecycle:
Owned by `Nexus` once a user explicitly engages it and installs a
configuration. Cleanup clears all stored properties and freezes the
object permanently.
Threading:
Mutable until frozen; after finalization the property bag is read-only,
so concurrent reads need no coordination.
Registration:
MELDER KERNEL - guarded. Installed into `Nexus` by the user through
`Nexus.configure(...)`.
Subsystem Context:
The process-wide policy object for the AR layer, deliberately distinct
from per-Rift configuration snapshots and from
`NexusFrameConfiguration` (authored per managed frame).
System Context:
The mutable-then-frozen shape is the same lifecycle Melder uses for
`SpellbookConfiguration`, `AetherConfiguration`, and the crystallizer
and mutation-research configurations. That consistency is deliberate:
an agent that has learned one configuration lane can drive all of them.
What belongs here versus on a Rift is the real boundary this class
draws. Process-wide governance - creation and access gates, frame
topology mode, target-frame restrictions, Rift budgets, and the
projection refresh barrier - lives here because it must be answered
identically for every Rift. Per-Rift room and history semantics stay
down on the Rift, because they legitimately differ between Rifts and
pushing them up would force one Rift's choice onto all of them.
AGENT_ACCESS: public
AGENT_PURPOSE:
access: public. Process-wide AR policy: creation/access gates, frame topology mode,
target-frame restrictions, Rift budgets, and the projection refresh barrier. Mutable
until frozen. Per-Rift settings belong on RiftConfiguration.
"""
__slots__ = Cleanable.__slots__ + [
"_id",
"_lock",
"_frozen",
"_activated",
"_properties",
"available_properties",
]
def __init__(self) -> None:
"""
Internal
Initialize an empty Nexus configuration.
Contract:
- STARTS GENUINELY EMPTY, BY DESIGN. `_properties` holds nothing, so a
bare configuration cannot be frozen until it is seeded -
`validate()` raises on the first missing key. This is not a defect:
`Nexus` seeds its own configuration with `with_defaults()`, and the
restore lane seeds defaults inside `load_recorded_dictionary()`
before overlaying recorded values. Starting empty is what lets that
lane report which keys were REJECTED and which were BACKFILLED,
which a pre-populated constructor would hide.
- Because this class is exported, code constructing one DIRECTLY must
call `with_defaults()` (or `load_default_dictionary()`) first, then
override. Setting only the properties you care about leaves the
object unfreezable.
- Establishes `available_properties`, the declared TYPE TABLE for all
25 settable properties. That table is the whole schema: it decides
which keys `set_property` accepts and what type each demands, so a
key absent from it can never be set.
- Two properties declare `(str, NoneType)` - the creation and access
token values - so `None` is a legal stored value for those and only
those.
- This is a PROPERTY BAG, not a slot-based configuration. Values live
in a dict keyed by name rather than as attributes, which is why the
`with_*` methods all funnel through `set_property`.
Owned State:
Owns `_id`, `_lock`, `_frozen`, the `_properties` bag, and the
`available_properties` type table. Borrows nothing.
Threading:
Creates the reentrant lock that serializes every later property
write; construction itself needs no synchronization because the
object is not yet shared.
Lifecycle / Cleanup:
Born mutable and unfrozen. It becomes immutable at `freeze()`, which
validates first and is idempotent afterwards.
Returns:
None.
"""
super().__init__()
self._id: str = IDBuilder.create_id()
self._lock: threading.RLock = threading.RLock()
self._frozen: bool = False
# Two bits, never one. `_frozen` says the policy can no longer change;
# `_activated` says the caller has declared it ready to install. A
# frozen configuration is NOT a ready one - the same split Crystallizer
# and MutationResearch configurations have always carried.
self._activated: bool = False
self._properties: Dict[str, object] = {}
self.available_properties: Dict[str, Union[Type, Tuple[Type, ...]]] = {
"allow_rift_creation": bool,
"creation_token_required": bool,
"creation_token_value": (str, type(None)),
"allow_direct_rift_access": bool,
"rift_access_token_required": bool,
"rift_access_token_value": (str, type(None)),
"allow_external_rift_registration": bool,
"allow_nested_rift_creation": bool,
"max_active_rift_count": int,
"nexus_frame_mode": NexusFrameMode,
"default_nexus_frame_name": str,
"auto_create_nexus_frames": bool,
"max_nexus_frame_count": int,
"allowed_target_frame_names": tuple,
"denied_target_frame_names": tuple,
"allow_target_frame_override": bool,
"allow_multiple_target_frames": bool,
"max_target_frame_count": int,
"projection_refresh_gate_enabled": bool,
"projection_refresh_gate_timeout_seconds": (int, float),
"projection_refresh_gate_poll_interval_seconds": (int, float),
"default_space_type": RiftSpaceType,
"default_auto_activate_on_program": bool,
"default_auto_create_space": bool,
"default_validation_mode": RiftValidationMode,
}
@property
def id(self) -> str:
"""
Purpose:
Return the stable identity for this configuration object.
Returns:
str: Stable configuration identifier.
"""
self.check_cleaned()
return self._id
@property
def frozen(self) -> bool:
"""
Purpose:
Return whether further mutation is forbidden.
Returns:
bool: True when the configuration is finalized.
"""
self.check_cleaned()
return self._frozen
[docs]
def cleanup(self) -> None:
"""
Internal
Idempotently cleanup the configuration and clear all state.
Contract:
- Marks the object cleaned and frozen.
- Clears the property bag and available-property registry.
- Leaves the object permanently unusable after cleanup.
Returns:
None.
"""
if self._cleaned:
return
with self._lock:
if self._cleaned:
return
self._cleaned = True
self._frozen = True
self._properties.clear()
self.available_properties.clear()
del self._properties
del self.available_properties
del self._lock
del self._id
[docs]
def set_property(self, key: str, value: object) -> None:
"""
Internal
Set one configuration property before finalize().
Args:
key:
Property name.
value:
Property value.
Contract:
- Rejects mutation after freeze().
- Normalizes enum-backed and frame-list-backed values before storage.
- Enforces the declared type contract for every property.
Returns:
None.
Raises:
RuntimeError: If the configuration is already frozen.
ValueError: If the property name is unknown.
TypeError: If the supplied value does not satisfy the declared type.
"""
self.check_cleaned()
if self._frozen:
raise RuntimeError("Cannot modify NexusConfiguration after freeze().")
if key not in self.available_properties:
raise ValueError("Unknown NexusConfiguration property: '{0}'.".format(key))
expected_type = self.available_properties[key]
converted_value = self._convert_property_value_if_needed(key, value)
if not isinstance(expected_type, tuple):
expected_type = (expected_type,)
if not isinstance(converted_value, expected_type):
expected_names = ", ".join(t.__name__ for t in expected_type)
raise TypeError(
"Invalid type for property '{0}': expected {1}, got {2}.".format(
key,
expected_names,
type(converted_value).__name__,
)
)
self._properties[key] = converted_value
[docs]
def get_property(self, key: str) -> object:
"""
Internal
Return one configuration property value.
Args:
key:
Property name.
Contract:
- Returns the currently stored property value exactly as normalized
during `set_property(...)`.
Returns:
object: Stored property value.
Raises:
KeyError: If the property has not been set.
"""
self.check_cleaned()
return self._properties[key]
[docs]
def get_configuration_dictionary(self) -> Dict[str, object]:
"""
Return a snapshot of the properties this configuration currently holds.
Purpose:
Let a host compare two configurations - for example a policy it was
handed against the one installed on the root - without reading the
private property bag.
Contract:
- Returns a NEW dict of every property currently set, name to value.
Changing the returned dict never changes this configuration.
- Values are the stored objects BY REFERENCE (no deep copy, no
serialization); a property that was never set is absent, not defaulted.
- Never validates, freezes, activates or emits a recorded twin, and
works in every lifecycle state until cleanup.
Threading:
Taken under the configuration lock, so the snapshot never sees a
half-applied write.
Lifecycle / Cleanup:
Guarded by `check_cleaned()`.
Raises:
RuntimeError: If the configuration has been cleaned.
Returns:
Dict[str, object]: Property name to stored value.
"""
self.check_cleaned()
with self._lock:
return dict(self._properties)
[docs]
def has_property(self, key: str) -> bool:
"""
Internal
Return whether a property has been set.
Args:
key:
Property name.
Contract:
- Returns presence only; does not validate semantic completeness.
Returns:
bool: True when present.
"""
self.check_cleaned()
return key in self._properties
[docs]
def load_default_dictionary(self) -> None:
"""
Internal
Load the standard default property set for Nexus master-user engagement.
Contract:
- Populates every required Nexus-governance field.
- Uses the easy-start defaults agreed for master-user Nexus setup:
`single` Nexus-frame mode, `default` target frame, and no token
requirements.
Returns:
None.
"""
self.check_cleaned()
defaults: Dict[str, Any] = {
"allow_rift_creation": True,
"creation_token_required": False,
"creation_token_value": None,
"allow_direct_rift_access": True,
"rift_access_token_required": False,
"rift_access_token_value": None,
"allow_external_rift_registration": True,
"allow_nested_rift_creation": False,
"max_active_rift_count": 0,
"nexus_frame_mode": NexusFrameMode.single,
"default_nexus_frame_name": "aetheric_frame_system",
"auto_create_nexus_frames": True,
"max_nexus_frame_count": 1,
"allowed_target_frame_names": ("default",),
"denied_target_frame_names": tuple(),
"allow_target_frame_override": False,
"allow_multiple_target_frames": False,
"max_target_frame_count": 1,
"projection_refresh_gate_enabled": True,
"projection_refresh_gate_timeout_seconds": 30.0,
"projection_refresh_gate_poll_interval_seconds": 0.1,
"default_space_type": RiftSpaceType.static,
"default_auto_activate_on_program": True,
"default_auto_create_space": False,
"default_validation_mode": RiftValidationMode.strict,
}
for key, value in defaults.items():
self.set_property(key, value)
[docs]
def load_recorded_dictionary(
self,
recorded_properties: Dict[str, Any],
) -> Dict[str, List[str]]:
"""
Reload lane: apply one RECORDED property payload as configuration
truth and seal.
Purpose:
The restore/reload counterpart to `load_default_dictionary`.
A sealed world rebuilds from its recorded values - never from
present-day defaults - and the reload lane loads and freezes
in one motion.
Contract:
- Defaults land first as the backfill floor, then every
recorded key OVERWRITES its default (recorded truth wins);
keys the record did not carry are returned under
"backfilled" so nothing defaults silently.
- Recorded values re-typed by the emission scalar filter
convert back on the way in: registry-typed enums accept
their recorded member NAME; registry-typed tuples accept
recorded lists (re-tupled element-wise).
- A recorded value the property system still refuses is
skipped and returned under "rejected" as "key: reason";
nothing is silently coerced (the per-key exception capture
is documented best-effort collection for the caller's
shortfall reporting).
- SEALS WITHOUT EMISSION: enable has not happened yet, so the
twin emission belongs to `Nexus.enable`, which calls
`emit_configured_twin_when_recording` for pre-frozen
configurations.
Args:
recorded_properties:
Property name -> recorded value mapping (one sealed,
JSON-safe NexusCrystal configuration_payload).
Returns:
Dict[str, List[str]]:
{"rejected": ["key: reason", ...],
"backfilled": [key, ...]}.
Raises:
RuntimeError: If the configuration is cleaned or already
frozen.
ValueError: If the reloaded property set fails validation at
the internal seal.
"""
self.check_cleaned()
if self._frozen:
raise RuntimeError(
"NexusConfiguration is already frozen; the reload lane "
"requires a fresh configuration object."
)
self.load_default_dictionary()
rejected: List[str] = []
applied: List[str] = []
for key, value in dict(recorded_properties).items():
try:
self.set_property(key, self._coerce_recorded_value(key, value))
applied.append(key)
except Exception as error:
# Best-effort collection by contract: the refusal reason
# rides back to the caller for shortfall reporting.
rejected.append("{0}: {1}".format(key, error))
backfilled = sorted(
key for key in self.available_properties.keys()
if key not in applied
)
# Reload seals: load it in, freeze it. The seal bypasses freeze()
# deliberately - emission belongs to the enable step, and this
# configuration is not enabled yet.
if not self.validate():
raise ValueError("NexusConfiguration validation failed.")
self._frozen = True
return {"rejected": rejected, "backfilled": backfilled}
def _coerce_recorded_value(self, key: str, value: Any) -> Any:
"""
Convert one recorded value back to its registered property type.
Contract:
- Enum-typed keys accept the recorded member NAME (string).
- Tuple-typed keys accept recorded lists (re-tupled with
elements passed through as recorded).
- Everything else passes through untouched; `set_property`
remains the type authority and refuses what it refuses.
Args:
key:
Property name (used to look up the registered type).
value:
The recorded value.
Returns:
Any: The conversion best matching the registered type.
"""
expected = self.available_properties.get(key)
if (
isinstance(expected, type)
and issubclass(expected, Enum)
and isinstance(value, str)
):
return EnumHelpers.convert_enum_and_check(value, expected)
if expected is tuple and isinstance(value, list):
return tuple(value)
return value
[docs]
def validate(self) -> bool:
"""
Internal
Validate that all required properties exist and the governance schema is
self-consistent.
Contract:
- Ensures every declared property has a value.
- Enforces cross-field invariants such as single-frame mode budget,
Nexus-frame mode budget, target-frame allow/deny coherence, and
target-frame caps.
Returns:
bool: True when the configuration is valid.
Raises:
ValueError: If a required property is missing or a cross-field
invariant is violated.
"""
self.check_cleaned()
for key in self.available_properties.keys():
if key not in self._properties:
raise ValueError("Missing required configuration property: '{0}'.".format(key))
max_active_rift_count = self.get_property("max_active_rift_count")
nexus_frame_mode = self.get_property("nexus_frame_mode")
default_nexus_frame_name = self.get_property("default_nexus_frame_name")
allowed_target_frame_names = self.get_property("allowed_target_frame_names")
denied_target_frame_names = self.get_property("denied_target_frame_names")
max_nexus_frame_count = self.get_property("max_nexus_frame_count")
allow_multiple_target_frames = self.get_property("allow_multiple_target_frames")
max_target_frame_count = self.get_property("max_target_frame_count")
projection_refresh_gate_timeout_seconds = self.get_property(
"projection_refresh_gate_timeout_seconds"
)
projection_refresh_gate_poll_interval_seconds = self.get_property(
"projection_refresh_gate_poll_interval_seconds"
)
if not isinstance(max_active_rift_count, int):
raise TypeError("max_active_rift_count must remain an int.")
if not isinstance(nexus_frame_mode, NexusFrameMode):
raise TypeError("nexus_frame_mode must remain a NexusFrameMode.")
if not isinstance(default_nexus_frame_name, str):
raise TypeError("default_nexus_frame_name must remain a str.")
if not isinstance(allowed_target_frame_names, tuple) or not all(
isinstance(frame_name, str)
for frame_name in allowed_target_frame_names
):
raise TypeError(
"allowed_target_frame_names must remain a tuple[str, ...]."
)
if not isinstance(denied_target_frame_names, tuple) or not all(
isinstance(frame_name, str)
for frame_name in denied_target_frame_names
):
raise TypeError(
"denied_target_frame_names must remain a tuple[str, ...]."
)
if not isinstance(max_nexus_frame_count, int):
raise TypeError("max_nexus_frame_count must remain an int.")
if not isinstance(allow_multiple_target_frames, bool):
raise TypeError(
"allow_multiple_target_frames must remain a bool."
)
if not isinstance(max_target_frame_count, int):
raise TypeError("max_target_frame_count must remain an int.")
if not isinstance(
projection_refresh_gate_timeout_seconds,
(int, float),
):
raise TypeError(
"projection_refresh_gate_timeout_seconds must remain numeric."
)
if not isinstance(
projection_refresh_gate_poll_interval_seconds,
(int, float),
):
raise TypeError(
"projection_refresh_gate_poll_interval_seconds must remain numeric."
)
allowed_target_frame_names = self._normalize_frame_names(
allowed_target_frame_names,
)
denied_target_frame_names = self._normalize_frame_names(
denied_target_frame_names,
)
if max_active_rift_count < 0:
raise ValueError("max_active_rift_count must be >= 0.")
if not default_nexus_frame_name:
raise ValueError("default_nexus_frame_name cannot be empty.")
if max_nexus_frame_count < 1:
raise ValueError("max_nexus_frame_count must be >= 1.")
if max_target_frame_count < 1:
raise ValueError("max_target_frame_count must be >= 1.")
if nexus_frame_mode == NexusFrameMode.single and max_nexus_frame_count != 1:
raise ValueError("max_nexus_frame_count must be 1 when nexus_frame_mode is single.")
if not allow_multiple_target_frames and max_target_frame_count != 1:
raise ValueError("max_target_frame_count must be 1 when allow_multiple_target_frames is False.")
if projection_refresh_gate_timeout_seconds <= 0:
raise ValueError("projection_refresh_gate_timeout_seconds must be > 0.")
if projection_refresh_gate_poll_interval_seconds <= 0:
raise ValueError(
"projection_refresh_gate_poll_interval_seconds must be > 0."
)
return True
[docs]
def freeze(self) -> None:
"""
Internal
Validate and freeze the configuration.
Contract:
- Calls `validate()` first.
- Idempotent when already frozen.
Returns:
None.
Raises:
ValueError: If validation fails.
"""
self.check_cleaned()
if self._frozen:
return
if not self.validate():
raise ValueError("NexusConfiguration validation failed.")
self._frozen = True
self.emit_configured_twin_when_recording()
[docs]
def finalize(self) -> "NexusConfiguration":
"""
Fluent
Validate and freeze the configuration, then return `self`.
Contract:
- Returns this same configuration instance after freezing it.
- Does not allocate or clone a detached configuration object.
Returns:
NexusConfiguration: This configuration instance.
"""
self.freeze()
return self
@property
def activated(self) -> bool:
"""
Return whether this policy object has been marked ready to install.
Contract:
- REPORTS THE POLICY OBJECT, NOT THE NEXUS. A `True` here means the
caller finished authoring and called `activate()`; it says nothing
about whether `Nexus.activate(...)` was ever reached. Two objects,
two bits.
- Independent of `frozen`. Freezing settles the values; activating
declares them ready. A frozen-but-unactivated configuration is the
normal state after `finalize()`.
Threading:
Unsynchronized read of a plain flag; a snapshot only.
Lifecycle / Cleanup:
Guarded by `check_cleaned()`.
Raises:
RuntimeError: If the configuration has been cleaned.
Returns:
bool: True once `activate()` has run on this object.
"""
self.check_cleaned()
return self._activated
[docs]
def activate(self) -> "NexusConfiguration":
"""
Validate, freeze, and mark this configuration active.
Purpose:
The activation rung this configuration never had. Crystallizer and
mutation-research configurations have always carried it, and their
roots take an ALREADY-ACTIVATED policy object. Nexus had no such
rung because `enable()` sealed the configuration on the caller's
behalf - which is why it was the one subsystem out of four where
the caller could not settle policy before installing it.
Guidance:
The normal final authoring step before `Nexus.activate(configuration)`.
It changes only this policy object's readiness.
Contract:
- Freezes and marks this policy object ready. It does NOT enable or
activate the Nexus singleton; that is a separate call.
- Idempotent: `freeze()` is idempotent and the flag is a plain set
with no side effect attached.
- `finalize()` remains freeze-only. The two verbs are different
rungs and neither implies the other.
Threading:
State transitions are applied under the configuration lock.
Lifecycle / Cleanup:
Guarded by `check_cleaned()` through `freeze()`.
Raises:
RuntimeError: If the configuration has been cleaned.
ValueError: If validation fails during freeze.
Returns:
NexusConfiguration: This activated configuration instance.
"""
self.freeze()
with self._lock:
self._activated = True
return self
[docs]
def build(self) -> "NexusConfiguration":
"""
Fluent alias for `finalize()`.
Contract:
- Preserves the builder-style API used elsewhere in the runtime.
- Returns this same configuration instance after finalize/freeze.
Returns:
NexusConfiguration: This configuration instance.
"""
return self.finalize()
[docs]
def with_defaults(self) -> "NexusConfiguration":
"""
Fluent
Load the standard Nexus defaults and return `self`.
Contract:
- Delegates to `load_default_dictionary()`.
- Applies the default process-wide governance/property set in-place.
- Leaves the configuration mutable until `freeze()` or `finalize()`.
Returns:
NexusConfiguration: This configuration instance.
"""
self.load_default_dictionary()
return self
[docs]
def with_rift_creation_enabled(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether Nexus may create new Rifts.
Args:
enabled:
True to permit Rift creation/programming under the remaining
policy gates.
Contract:
- The master gate for creating or programming Rifts. Every other
creation policy below only narrows this; with it False no token or
nesting setting can permit creation.
- Writes the `allow_rift_creation` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_rift_creation", enabled)
return self
[docs]
def with_creation_token_required(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether Rift creation/programming requires a creation token.
Args:
enabled:
True to require `creation_token_value` during creation.
Contract:
- Demands a creation token. Setting this True without also setting a
token value leaves creation unreachable rather than open - the
requirement is checked, the value is not defaulted.
- Writes the `creation_token_required` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("creation_token_required", enabled)
return self
[docs]
def with_creation_token(
self,
token_value: Optional[str],
) -> "NexusConfiguration":
"""
Fluent
Set the process-wide creation token value for Nexus.
Args:
token_value:
Optional creation token string. `None` clears the token value.
Contract:
- CREDENTIAL MATERIAL. Accepts `None` explicitly to clear it. Treat the
stored value as a secret: do not log it, print it, or copy it into
tickets or documentation.
- Writes the `creation_token_value` property, declared as `str or None`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("creation_token_value", token_value)
return self
[docs]
def with_direct_rift_access(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether callers may retrieve live Rift objects directly from Nexus.
Args:
enabled:
True to allow direct live-Rift access under the remaining
policy gates.
Contract:
- Whether callers may reach a Rift directly rather than through Nexus
routing. Independent of the creation gates - a frame can permit
access while refusing creation.
- Writes the `allow_direct_rift_access` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_direct_rift_access", enabled)
return self
[docs]
def with_rift_access_token_required(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether direct live-Rift access requires a token.
Args:
enabled:
True to require `rift_access_token_value` for direct Rift
retrieval.
Contract:
- Demands an access token on the read path. Independent of
`creation_token_required`; the two protect different operations and
neither implies the other.
- Writes the `rift_access_token_required` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("rift_access_token_required", enabled)
return self
[docs]
def with_rift_access_token(
self,
token_value: Optional[str],
) -> "NexusConfiguration":
"""
Fluent
Set the token value used for direct live-Rift access.
Args:
token_value:
Optional Rift-access token string. `None` clears the token.
Contract:
- CREDENTIAL MATERIAL. Accepts `None` explicitly to clear it. Treat the
stored value as a secret: do not log it, print it, or copy it into
tickets or documentation.
- Writes the `rift_access_token_value` property, declared as `str or None`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("rift_access_token_value", token_value)
return self
[docs]
def with_allow_external_rift_registration(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether Nexus may program externally created Rift shells.
Args:
enabled:
True to permit external Rift registration/programming.
Contract:
- Whether Rifts constructed outside this Nexus may register into it.
This is the trust boundary for foreign objects entering the
registry.
- Writes the `allow_external_rift_registration` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_external_rift_registration", enabled)
return self
[docs]
def with_allow_nested_rift_creation(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether running Rifts may create nested Rifts.
Args:
enabled:
True to permit nested Rift creation flows.
Contract:
- Whether a Rift may itself create further Rifts. Leaving this False
keeps the Rift topology one level deep and bounds fan-out.
- Writes the `allow_nested_rift_creation` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_nested_rift_creation", enabled)
return self
[docs]
def with_max_active_rift_count(
self,
count: int,
) -> "NexusConfiguration":
"""
Fluent
Set the cap on concurrently registered active Rifts.
Args:
count:
Maximum number of active Rifts. `0` means unlimited.
Contract:
- `0` MEANS UNLIMITED, not "none allowed". Validation requires `>= 0`,
so there is no way to express a hard zero cap through this setter -
use `with_rift_creation_enabled(False)` for that.
- Writes the `max_active_rift_count` property, declared as `int`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("max_active_rift_count", count)
return self
[docs]
def with_nexus_frame_mode(
self,
mode: Union[NexusFrameMode, str],
) -> "NexusConfiguration":
"""
Fluent
Set the internal Nexus frame topology mode.
Args:
mode:
Frame-topology mode enum or string.
Contract:
- CROSS-FIELD RULE: `single` requires `max_nexus_frame_count == 1`.
Selecting `single` without also setting that count to 1 makes
`validate()` and therefore `freeze()` raise.
- Writes the `nexus_frame_mode` property, declared as `NexusFrameMode`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("nexus_frame_mode", mode)
return self
[docs]
def with_default_nexus_frame_name(
self,
frame_name: str,
) -> "NexusConfiguration":
"""
Fluent
Set the default Nexus-owned internal frame name.
Args:
frame_name:
Frame name used in `single` mode and as the base name
in other modes.
Contract:
- MUST BE NON-EMPTY at validation. An empty string is accepted by
`set_property` (it satisfies the declared `str` type) and only
rejected later at freeze.
- Writes the `default_nexus_frame_name` property, declared as `str`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("default_nexus_frame_name", frame_name)
return self
[docs]
def with_auto_create_nexus_frames(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether the runtime may auto-create internal Nexus frames when Rift
activation later resolves them through `Aether`.
Args:
enabled:
True to auto-create required Nexus frames on engagement or
state creation.
Contract:
- Whether a missing target frame is created on demand rather than
refused. With it False, routing to an unknown frame is an error
instead of a side effect.
- Writes the `auto_create_nexus_frames` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("auto_create_nexus_frames", enabled)
return self
[docs]
def with_max_nexus_frame_count(
self,
count: int,
) -> "NexusConfiguration":
"""
Fluent
Set the cap on Nexus-assigned internal frames.
Args:
count:
Maximum number of internal Nexus frames allowed.
Contract:
- MUST BE >= 1; zero is rejected at validation. CROSS-FIELD RULE: it
must be exactly 1 when `nexus_frame_mode` is `single`.
- Writes the `max_nexus_frame_count` property, declared as `int`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("max_nexus_frame_count", count)
return self
[docs]
def with_allowed_target_frame_names(
self,
frame_names: Sequence[str],
) -> "NexusConfiguration":
"""
Fluent
Set the allow-list for targetable frames.
Args:
frame_names:
Sequence of permitted target frame names.
Contract:
- Stored as a TUPLE. A list is normalized on the way in, and every
element must be a str or validation rejects the whole collection.
- Writes the `allowed_target_frame_names` property, declared as `tuple[str, ...]`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allowed_target_frame_names", frame_names)
return self
[docs]
def with_denied_target_frame_names(
self,
frame_names: Sequence[str],
) -> "NexusConfiguration":
"""
Fluent
Set the deny-list for targetable frames.
Args:
frame_names:
Sequence of denied target frame names.
Contract:
- Stored as a TUPLE, normalized like the allow-list. Deny is evaluated
as its own collection; this setter does not reconcile it against
`allowed_target_frame_names`.
- Writes the `denied_target_frame_names` property, declared as `tuple[str, ...]`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("denied_target_frame_names", frame_names)
return self
[docs]
def with_target_frame_override(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether callers may override the allowed target-frame selection.
Args:
enabled:
True to allow per-Rift target-frame override requests.
Contract:
- Whether a caller may name a target frame that differs from the
configured default.
- Writes the `allow_target_frame_override` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_target_frame_override", enabled)
return self
[docs]
def with_multiple_target_frames(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether Nexus may target multiple external frames across its Rifts.
Args:
enabled:
True to permit more than one distinct target frame.
Contract:
- CROSS-FIELD RULE: when False, `max_target_frame_count` MUST be 1.
Turning this off without resetting that count to 1 makes
`validate()` and therefore `freeze()` raise.
- Writes the `allow_multiple_target_frames` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("allow_multiple_target_frames", enabled)
return self
[docs]
def with_max_target_frame_count(
self,
count: int,
) -> "NexusConfiguration":
"""
Fluent
Set the cap on distinct target frames Nexus may use.
Args:
count:
Maximum number of distinct target frames.
Contract:
- MUST BE >= 1; zero is rejected at validation. CROSS-FIELD RULE: it
must be exactly 1 when `allow_multiple_target_frames` is False.
- Writes the `max_target_frame_count` property, declared as `int`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("max_target_frame_count", count)
return self
[docs]
def with_projection_refresh_gate(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether ACL-driven projection refresh uses the RiftGate drain
barrier.
Args:
enabled:
True to block new entrants, wait for in-flight work to drain,
refresh projections/viewers, then reopen gates.
Contract:
- Whether projection reads wait for a refresh to settle rather than
returning immediately. The timeout and poll interval below only
matter when this is enabled.
- Writes the `projection_refresh_gate_enabled` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("projection_refresh_gate_enabled", enabled)
return self
[docs]
def with_projection_refresh_gate_timeout_seconds(
self,
timeout_seconds: Union[int, float],
) -> "NexusConfiguration":
"""
Fluent
Set the timeout used while waiting for impacted Rift gates to drain.
Args:
timeout_seconds:
Positive timeout in seconds.
Contract:
- MUST BE > 0; zero and negatives are rejected at validation, so the
gate can never be configured to give up instantly or wait forever.
- Writes the `projection_refresh_gate_timeout_seconds` property, declared as `int or float`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property(
"projection_refresh_gate_timeout_seconds",
timeout_seconds,
)
return self
[docs]
def with_projection_refresh_gate_poll_interval_seconds(
self,
interval_seconds: Union[int, float],
) -> "NexusConfiguration":
"""
Fluent
Set the poll interval used while waiting for impacted Rift gates to
drain.
Args:
interval_seconds:
Positive poll interval in seconds.
Contract:
- MUST BE > 0. Nothing enforces that it is smaller than the timeout, so
an interval larger than the timeout is accepted and yields a single
poll attempt.
- Writes the `projection_refresh_gate_poll_interval_seconds` property, declared as `int or float`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property(
"projection_refresh_gate_poll_interval_seconds",
interval_seconds,
)
return self
[docs]
def with_default_space_type(
self,
space_type: Union[RiftSpaceType, str],
) -> "NexusConfiguration":
"""
Fluent
Set the default room type for newly created Rifts.
Args:
space_type:
Default room-kind enum or string.
Contract:
- The space type new Rift spaces take when the caller does not name one.
Accepts the enum or its string name; conversion is checked.
- Writes the `default_space_type` property, declared as `RiftSpaceType`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("default_space_type", space_type)
return self
[docs]
def with_default_auto_activate_on_program(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether newly programmed Rifts activate automatically.
Args:
enabled:
True to mark new Rifts active during programming.
Contract:
- Whether a programmed Rift activates immediately rather than waiting
for an explicit activation.
- Writes the `default_auto_activate_on_program` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("default_auto_activate_on_program", enabled)
return self
[docs]
def with_default_auto_create_space(
self,
enabled: bool = True,
) -> "NexusConfiguration":
"""
Fluent
Set whether newly programmed Rifts auto-create an initial room.
Args:
enabled:
True to create the initial room automatically.
Contract:
- Whether a missing space is created on demand rather than refused.
- Writes the `default_auto_create_space` property, declared as `bool`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("default_auto_create_space", enabled)
return self
[docs]
def with_default_validation_mode(
self,
mode: Union[RiftValidationMode, str],
) -> "NexusConfiguration":
"""
Fluent
Set the default validation posture for newly created Rifts.
Args:
mode:
Validation mode enum or string.
Contract:
- The default strictness applied to Rift contents. Accepts the enum or
its string name; conversion is checked.
- Writes the `default_validation_mode` property, declared as `RiftValidationMode`. ALL enforcement
lives in `set_property`: it rejects unknown keys, enforces the
declared type, normalizes enum and frame-list values, and refuses
any write once the configuration is frozen. This method adds no
validation of its own.
- MUTATES THIS OBJECT and returns `self`; it is not a copying builder.
- EVERY declared property is REQUIRED at freeze - `validate()` raises
on the first missing key. Start from `with_defaults()` and override,
rather than setting properties individually.
Threading:
Serialized by `set_property` under the configuration lock.
Lifecycle / Cleanup:
Guarded via `set_property`; refused after freeze.
Raises:
RuntimeError: If the configuration is already frozen.
TypeError: If the value does not satisfy the declared type.
Returns:
NexusConfiguration: This configuration instance.
"""
self.set_property("default_validation_mode", mode)
return self
def _convert_property_value_if_needed(self, key: str, value: object) -> object:
"""
Internal
Normalize enum-backed and sequence-backed properties before storage.
Args:
key:
Property name being assigned.
value:
Candidate property value.
Returns:
object: The normalized property value.
Raises:
TypeError: If a frame-name collection is invalid.
ValueError: If an enum conversion or frame-name normalization fails.
"""
if key == "nexus_frame_mode":
return EnumHelpers.convert_enum_and_check(value, NexusFrameMode)
if key == "default_space_type":
if value == "dynamic":
value = RiftSpaceType.codegen
return EnumHelpers.convert_enum_and_check(value, RiftSpaceType)
if key == "default_validation_mode":
return EnumHelpers.convert_enum_and_check(value, RiftValidationMode)
if key in {"allowed_target_frame_names", "denied_target_frame_names"}:
return self._normalize_frame_names(value)
return value
def _normalize_frame_names(self, value: object) -> Tuple[str, ...]:
"""
Internal
Normalize a target-frame allow-list or deny-list into an immutable tuple.
Args:
value:
Candidate frame-name collection.
Contract:
- Rejects single strings to avoid accidental character splitting.
- Deduplicates frame names while preserving order.
- Rejects empty frame names.
Returns:
Tuple[str, ...]: Normalized immutable frame-name sequence.
Raises:
TypeError: If the input is not a sequence of strings.
ValueError: If any frame name is empty.
"""
if isinstance(value, str):
raise TypeError("Frame-name collections must be sequences of strings, not a single string.")
if not isinstance(value, Sequence):
raise TypeError("Frame-name collections must be sequences of strings.")
normalized_frame_names = []
for frame_name in value:
if not isinstance(frame_name, str):
raise TypeError("Frame-name collections must contain only strings.")
if not frame_name:
raise ValueError("Frame names cannot be empty.")
if frame_name not in normalized_frame_names:
normalized_frame_names.append(frame_name)
return tuple(normalized_frame_names)