Skip to content

12. Configuration: The Codex

Context and Problem Statement

Configuration fragmentation creates structural blindness. When intent is scattered across hardcoded paths, environment variables, and implicit runtime state, the system loses determinism. In a Sepulcher that bridges Host and Container, this fragmentation produces port collisions, permission mismatches, and non-reproducible infrastructure states.

A sovereign system requires a single source of truth, strict validation before manifestation, and a deterministic mapping between filesystem topology and runtime behavior.


Requirements

  • Single Source of Truth: All user intent must reside within a bounded configuration domain.
  • Type Authority: Configuration must be validated through explicit schemas before any infrastructure is generated.
  • Deterministic Discovery: Filesystem hierarchy must uniquely determine rune ownership and instance identity.
  • Fail-Fast Validation: Port conflicts, branch-owned TOML files, duplicate instance identity, and schema violations must abort loading before Quadlets are written.
  • Secret Discipline: Sensitive values must be protected from accidental exposure and validated for permission correctness.
  • Privatization Policy: Context egress thresholds and anonymization requirements must be configurable as first-class policy.
  • Autonomy Policy: Preauthorization for low-risk autonomous actions must be explicit, fail-closed Codex policy rather than an implicit model confidence shortcut.
  • Extensibility Contract: Extensions must integrate into the configuration system without custom parsers or ad-hoc loading logic.
  • Infrastructure Integrity: Configuration must be fully validated before container units are manifested.

Considered Options

Option 1: Monolithic Configuration

Placing all configuration — global settings and multi-instance infrastructure — into a single lychd.toml.

  • Pros: Easy to locate and edit.
  • Cons: Structural Degeneration. Instance identity becomes implicit. Ordering matters. Silent overwrites become possible. Extension grafting becomes fragile.

Option 2: Environment-Driven Configuration

Relying primarily on environment variables or distributed .env files.

  • Pros: Familiar pattern.
  • Cons: Opaque State. Environment variables are invisible to version control and cannot express multi-instance topology. Structural validation cannot occur before process startup.

Option 3: Layered Codex Architecture

Separating configuration into a typed Schema Layer and anchored Rune Schemas.

  • Pros:
    • Deterministic Topology: Directory structure defines rune ownership.
    • Type Enforcement: All configuration validated through Pydantic models.
    • Coupled Extension Compatibility: Built-in and private extensions inheriting RuneConfig participate in the same loading model.
    • Fail-Fast Infrastructure: Quadlets are generated only after full validation succeeds.
    • Clear Secret Model: Explicit at-rest protection and runtime boundary definition.

Decision Outcome

A layered configuration system is adopted, structured around the Codex. This ADR defines the Codex contract (global settings, rune schemas, ownership, discovery, validation, and loading order). Layout (ADR 13) defines the filesystem geography and mount topology where that contract resides.

The Codex resides at:

~/.config/lychd/

XDG path resolution and Host/Container symmetry for this domain are specified in Layout (ADR 13).

It contains two distinct domains:

  1. The Application Settings
  2. Rune Schemas

1. The Application Settings (lychd.toml)

Contains global configuration only.

Examples include:

  • Application-level settings
  • Core service configuration
  • Coven alliances
  • Global defaults

Schema authority for global settings resides in src/lychd/config/settings.py. src/lychd/config/components.py consumes the validated settings object into framework component configuration.

It carries no multi-instance infrastructure definitions.

If secret references are declared in Codex:

  • The file must be owned by the Magus.
  • File permissions must be 0600.
  • Startup validation emits a structured warning if permissions are broader.

The Global config defines global truth.


2. The Schema Layer (src/lychd/config/settings.py)

The Schema Layer provides type authority and deterministic loading.

It is implemented using Pydantic and defines:

  • Required fields
  • Strict typing
  • Secret-reference enforcement for credentials (*_secret fields)
  • Deterministic source precedence (Settings.settings_customise_sources()):
Init kwargs → Explicit Environment Overrides → Pydantic dotenv source, when enabled → `lychd.toml` → File Secrets → Model Defaults

Environment variables enter through explicit override channels in the schema loader. If .env files are enabled:

  • They must reside within the Codex boundary.
  • They must be 0600.
  • Permission violations produce warnings.

The Schema Layer validates global state before any infrastructure intent is processed.

Exact source precedence and reserved-port validation are implemented in src/lychd/config/settings.py:281:

Live snippet: src/lychd/config/settings.py:281
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> tuple[PydanticBaseSettingsSource, ...]:
        return (
            init_settings,
            env_settings,
            dotenv_settings,
            # Load from the TOML file specified in constants.py
            TomlConfigSettingsSource(settings_cls, toml_file=PATH_LYCHD_TOML),
            file_secret_settings,
        )

    @property
    def reserved_ports_map(self) -> dict[str, int]:
        """Map of Service Name -> Port."""
        return {
            "LychD Server": self.server.port,
            "Phylactery (Postgres)": self.db.port,
            "Vite (Frontend)": self.vite.port,
            "Oculus (Phoenix)": self.phoenix.ui_port,
        }

    @model_validator(mode="after")
    def check_port_conflicts(self) -> Settings:
        """Ensure no critical system ports overlap."""
        # Invert to check for duplicates: {port: [names]}
        port_map: dict[int, list[str]] = {}
        for name, port in self.reserved_ports_map.items():
            port_map.setdefault(port, []).append(name)

        # Find collisions
        errors: list[str] = []
        for port, names in port_map.items():
            if len(names) > 1:
                errors.append(f"Port {port} is claimed by multiple services: {', '.join(names)}")

        if errors:
            _msg = f"Configuration Error: {'; '.join(errors)}"
            raise ValueError(_msg)

        codex_issues = codex_permission_issues(PATH_LYCHD_TOML)
        if codex_issues:
            import warnings
            warnings.warn(
                f"codex_permissions_policy_violation: path={PATH_LYCHD_TOML} issues={codex_issues}",
                UserWarning,
                stacklevel=2,
            )

        return self


def ensure_internal_secret_fallbacks(settings: Settings) -> list[str]:
    """Ensure app/db runtime secrets exist even before Podman bind.

    This is a startup safety-net for direct process execution (development,
    tests, or any flow that boots without mounted Podman secrets). It does not
    replace bind-time Podman secret provisioning.
    """
    created: list[str] = []

    if needs_generated_secret_fallback(
        value_env_keys=("APP__SECRET_KEY", "APP_SECRET_KEY"),
        file_env_keys=("APP__SECRET_KEY_FILE", "APP_SECRET_KEY_FILE"),
        default_file=Path("/run/secrets") / settings.app.secret_key_secret,
    ):
        settings.app.set_runtime_secret_key_override(secrets.token_hex(32))
        created.append(settings.app.secret_key_secret)

    if needs_generated_secret_fallback(
        value_env_keys=("DB__PASSWORD", "DB_PASSWORD"),
        file_env_keys=("DB__PASSWORD_FILE", "DB_PASSWORD_FILE"),
        default_file=Path("/run/secrets") / settings.db.password_secret,
    ):
        settings.db.set_runtime_password_override(secrets.token_urlsafe(16))
        created.append(settings.db.password_secret)

    return created


@lru_cache(maxsize=1, typed=True)
def get_settings() -> Settings:
    settings = Settings()
    ensure_internal_secret_fallbacks(settings)
    return settings

3. Runes (Instance Scrolls)

Infrastructure intent is declared through runes.

A rune is one validated TOML configuration document under the Codex runes/ tree. It describes extension-owned intent; it is not the final runtime object and not the generated Systemd/Quadlet artifact.

Each rune class:

  • Inherits from RuneConfig
  • Declares path_fragment as the safe relative path fragment it contributes; no rune type may place TOML files directly under the rune root
  • Uses safe fragment parts: lowercase ASCII letters, digits, _, and -, length 1-50, starting and ending alphanumeric
  • Uses Python subclassing as rune path ancestry; relative_path is computed from the single direct rune parent plus the local fragment
  • Relies on runic identity and domain validation for required named instances; no base-loader singleton override exists

Rune instances are stored as TOML files under their Anchor directory.

Rune And Runic Boundary

RuneConfig.__init_subclass__() enforces rune anchor rules at class declaration time. Concrete RuneConfig subclasses declare path_fragment as a Path; the computed relative_path is relative to the Codex rune root:

Live snippet: src/lychd/config/runes/base.py:10
RUNE_PATH_PART_PATTERN = re.compile(r"^[a-z0-9](?:[a-z0-9_-]{0,48}[a-z0-9])?$")


class RuneConfig(BaseModel, ABC):
    """Base for TOML-backed Codex runes.

    A rune is one validated TOML config document under
    ``lychd.system.constants.PATH_RUNES_DIR``. Subclasses define TOML fields;
    this base validates class-level placement metadata.
    """

    model_config = ConfigDict(extra="forbid")

    def __init_subclass__(cls, **kwargs: Any) -> None:
        """Validate rune class metadata when a rune subclass is declared.

        Args:
            **kwargs: Extra subclass initialization keywords forwarded to
                ``BaseModel``.

        Raises:
            ValueError: If the subclass declares an invalid ``path_fragment``.
            TypeError: If ``path_fragment`` is not a ``Path`` or rune ancestry
                is ambiguous.

        """
        super().__init_subclass__(**kwargs)

        # ``ClassVar`` values are inherited. ``getattr(cls, "path_fragment")``
        # would therefore let a child silently reuse its parent suffix, producing
        # the wrong anchor. Require a class-local declaration instead.
        if "path_fragment" not in cls.__dict__:
            msg = f"Rune '{cls.__name__}' declares no path_fragment."
            raise ValueError(msg)
        path_fragment: Any = cls.__dict__["path_fragment"]

        # The fragment is a relative ``Path`` suffix, not a filesystem root.
        # Loader/writer code owns the absolute root via ``PATH_RUNES_DIR``.
        if not isinstance(path_fragment, Path):
            msg = f"Rune '{cls.__name__}' declares non-Path path_fragment {path_fragment!r}."
            raise TypeError(msg)
        if path_fragment.is_absolute() or path_fragment == Path():
            msg = f"Rune '{cls.__name__}' declares invalid path_fragment '{path_fragment}'. Expected relative path fragment."
            raise ValueError(msg)

        # Validate every fragment part because a fragment may contain more than
        # one suffix component. The pattern rejects traversal, uppercase drift,
        # spaces, and filesystem-looking surprises.
        for part in path_fragment.parts:
            if not RUNE_PATH_PART_PATTERN.fullmatch(part):
                pattern = RUNE_PATH_PART_PATTERN.pattern
                msg = f"Rune '{cls.__name__}' declares invalid path_fragment part '{part}'. Expected pattern: {pattern}"
                raise ValueError(msg)

        # The final path is a single parent chain plus this suffix. Multiple
        # RuneConfig parents would make that path ambiguous. Mixins that only
        # share fields should inherit BaseModel or object, not RuneConfig.
        rune_parents = [
            base for base in cls.__bases__ if issubclass(base, RuneConfig) and base is not RuneConfig
        ]
        if len(rune_parents) > 1:
            names = ", ".join(parent.__name__ for parent in rune_parents)
            msg = f"Rune '{cls.__name__}' declares multiple rune parents: {names}."
            raise TypeError(msg)
        parent = rune_parents[0] if rune_parents else None

        # Store the final path under PATH_RUNES_DIR, still relative. RuneConfig
        # computes schema-local placement; loaders/writers choose the root.
        cls.relative_path = path_fragment if parent is None else parent.relative_path / path_fragment

RuneConfig is the base contract for typed TOML runes:

Live snippet: src/lychd/config/runes/base.py:10
class RuneConfig(BaseModel, ABC):
    """Base for TOML-backed Codex runes.

    A rune is one validated TOML config document under
    ``lychd.system.constants.PATH_RUNES_DIR``. Subclasses define TOML fields;
    this base validates class-level placement metadata.
    """

    model_config = ConfigDict(extra="forbid")

    def __init_subclass__(cls, **kwargs: Any) -> None:
        """Validate rune class metadata when a rune subclass is declared.

        Args:
            **kwargs: Extra subclass initialization keywords forwarded to
                ``BaseModel``.

        Raises:
            ValueError: If the subclass declares an invalid ``path_fragment``.
            TypeError: If ``path_fragment`` is not a ``Path`` or rune ancestry
                is ambiguous.

        """
        super().__init_subclass__(**kwargs)

        # ``ClassVar`` values are inherited. ``getattr(cls, "path_fragment")``
        # would therefore let a child silently reuse its parent suffix, producing
        # the wrong anchor. Require a class-local declaration instead.
        if "path_fragment" not in cls.__dict__:
            msg = f"Rune '{cls.__name__}' declares no path_fragment."
            raise ValueError(msg)
        path_fragment: Any = cls.__dict__["path_fragment"]

        # The fragment is a relative ``Path`` suffix, not a filesystem root.
        # Loader/writer code owns the absolute root via ``PATH_RUNES_DIR``.
        if not isinstance(path_fragment, Path):
            msg = f"Rune '{cls.__name__}' declares non-Path path_fragment {path_fragment!r}."
            raise TypeError(msg)
        if path_fragment.is_absolute() or path_fragment == Path():
            msg = f"Rune '{cls.__name__}' declares invalid path_fragment '{path_fragment}'. Expected relative path fragment."
            raise ValueError(msg)

        # Validate every fragment part because a fragment may contain more than
        # one suffix component. The pattern rejects traversal, uppercase drift,
        # spaces, and filesystem-looking surprises.
        for part in path_fragment.parts:
            if not RUNE_PATH_PART_PATTERN.fullmatch(part):
                pattern = RUNE_PATH_PART_PATTERN.pattern
                msg = f"Rune '{cls.__name__}' declares invalid path_fragment part '{part}'. Expected pattern: {pattern}"
                raise ValueError(msg)

        # The final path is a single parent chain plus this suffix. Multiple
        # RuneConfig parents would make that path ambiguous. Mixins that only
        # share fields should inherit BaseModel or object, not RuneConfig.
        rune_parents = [
            base for base in cls.__bases__ if issubclass(base, RuneConfig) and base is not RuneConfig
        ]
        if len(rune_parents) > 1:
            names = ", ".join(parent.__name__ for parent in rune_parents)
            msg = f"Rune '{cls.__name__}' declares multiple rune parents: {names}."
            raise TypeError(msg)
        parent = rune_parents[0] if rune_parents else None

        # Store the final path under PATH_RUNES_DIR, still relative. RuneConfig
        # computes schema-local placement; loaders/writers choose the root.
        cls.relative_path = path_fragment if parent is None else parent.relative_path / path_fragment

    path_fragment: ClassVar[Path]
    """Relative suffix appended after the parent rune class's ``relative_path``."""

    relative_path: ClassVar[Path]
    """Computed path under ``PATH_RUNES_DIR`` where this class's TOMLs live."""

    source_file: Path | None = Field(default=None, exclude=True, repr=False)
    """Absolute source TOML file that produced this validated instance."""

Runic is only a runtime provenance protocol. Any object with .rune can be treated as a servant of the Codex backed by a validated rune; that does not make the object a rune class.

Live snippet: src/lychd/config/runes/protocols.py:1
"""Typing protocols for objects that retain rune provenance."""

from __future__ import annotations

from typing import Protocol, runtime_checkable

from lychd.config.runes.base import RuneConfig


@runtime_checkable
class Runic[T: RuneConfig](Protocol):
    """Protocol for objects configured by a Codex Rune.

    Any runtime object with ``rune: T`` satisfies this protocol structurally.
    Such objects are servants of the Codex: they retain the validated config
    that shaped them, but they are not themselves rune schemas.
    """

    @property
    def rune(self) -> T:
        """Return the validated source Rune.

        Returns:
            The ``RuneConfig`` instance used as this object's configuration
            provenance.

        """

Example structure:

~/.config/lychd/
lychd.toml
runes/
  animator/
    soulstones/
      vision.toml
      ocr.toml
    portals/
      openai.toml

The Anchor Doctrine

Each RuneConfig rune class owns exactly one anchor territory.

  • Folder location determines rune type.
  • The declared path_fragment is local to the rune class.
  • Each fragment part must match ^[a-z0-9](?:[a-z0-9_-]{0,48}[a-z0-9])?$.
  • Python subclassing is rune path ancestry and must form a single direct parent chain.
  • Mixins/composition should carry shared fields that do not need a new anchor or path fragment.
  • relative_path is the resolved Codex-root-relative anchor assembled from ancestry.
  • Anchors may not overlap.
  • No internal type= switching is permitted.
  • The filesystem hierarchy is authoritative.

Rune ownership is structural, not dynamic.

Loader enforcement for anchor scanning, branch-file rejection, top-level TOML payload, and duplicate identity rejection lives in src/lychd/config/runes/loader.py:19:

Live snippet: src/lychd/config/runes/loader.py:19
    def __init__(self, runes_dir: Path | None = None) -> None:
        """Create a loader for a concrete rune root.

        Args:
            runes_dir: Optional root directory to scan. Defaults to
                ``PATH_RUNES_DIR``.

        """
        self._runes_dir = runes_dir or PATH_RUNES_DIR

    def load_all(self, schemas: Sequence[type[RuneConfig]]) -> list[RuneConfig]:
        """Load and validate all instances for the provided rune classes.

        Args:
            schemas: Rune classes whose anchors should be scanned.

        Returns:
            Validated rune instances bound to their source filenames.

        Raises:
            ValueError: If TOML parsing, branch-file enforcement, identity
                validation, or Pydantic model validation fails.

        """
        loaded: list[RuneConfig] = []

        for cls in schemas:
            loaded.extend(self._load_class_instances(cls))

        logger.debug("runes_loaded", count=len(loaded), classes=[c.__name__ for c in schemas])
        return loaded

    def _load_class_instances(self, cls: type[RuneConfig]) -> list[RuneConfig]:
        """Load every TOML instance owned by one rune class.

        Args:
            cls: Rune class whose anchor should be scanned.

        Returns:
            Validated instances for ``cls``.

        Raises:
            ValueError: If a branch rune owns TOML files, or if payload/identity
                validation fails.

        """
        files = self._candidate_files(cls)
        if cls.__subclasses__():
            if files:
                msg = f"Branch rune class '{cls.__name__}' cannot own TOML files in '{self._anchor_dir(cls)}'."
                raise ValueError(msg)
            return []

        instances: list[RuneConfig] = []

        for file_path in files:
            payload = self._read_payload(file_path, cls)
            instance = cls.model_validate(payload)
            instance.source_file = file_path
            instances.append(instance)

        self._assert_unique_identity(files)
        return instances

    def _candidate_files(self, cls: type[RuneConfig]) -> list[Path]:
        """Find candidate TOML files for a rune anchor.

        Args:
            cls: Rune class whose anchor should be scanned.

        Returns:
            Sorted TOML files directly in the rune class's anchor.

        """
        anchor = self._anchor_dir(cls)
        if not anchor.exists():
            return []

        return sorted(anchor.glob("*.toml"))

    def _anchor_dir(self, cls: type[RuneConfig]) -> Path:
        """Resolve the active filesystem anchor for one rune class.

        Args:
            cls: Rune class whose anchor should be resolved.

        Returns:
            Absolute directory under this loader's rune root.

        """
        return self._runes_dir / cls.relative_path

    def _read_payload(self, file_path: Path, cls: type[RuneConfig]) -> dict[str, Any]:
        """Read one TOML payload and enforce rune envelope rules.

        Args:
            file_path: TOML file to read.
            cls: Rune class used to decide whether legacy envelope keys are
                allowed.

        Returns:
            Parsed TOML payload with string keys.

        Raises:
            ValueError: If the file is unreadable, malformed, or uses a legacy
                ``[model]`` envelope for a rune class that does not declare a
                ``model`` field.

        """
        try:
            parsed = tomllib.loads(file_path.read_text(encoding="utf-8"))
        except tomllib.TOMLDecodeError as exc:
            msg = f"Malformed TOML in '{file_path}'."
            raise ValueError(msg) from exc
        except OSError as exc:
            msg = f"Could not read '{file_path}'."
            raise ValueError(msg) from exc

        content: dict[str, Any] = {str(k): v for k, v in parsed.items()}
        if "model" in content and isinstance(content["model"], dict) and "model" not in cls.model_fields:
            msg = (
                f"File '{file_path}' uses legacy '[model]' envelope syntax. "
                "Rune payload must be written at TOML top level."
            )
            raise ValueError(msg)

        return content

    def _assert_unique_identity(self, files: list[Path]) -> None:
        """Reject duplicate identities after path normalization.

        Args:
            files: Candidate TOML files for that rune class.

        Raises:
            ValueError: If two files derive the same rune-local identity.

        """
        seen: set[str] = set()

        for file_path in files:
            identity = self._instance_id_from_path(file_path)
            if identity in seen:
                msg = f"Duplicate identity detected: '{identity}'."
                raise ValueError(msg)
            seen.add(identity)

    def _instance_id_from_path(self, file_path: Path) -> str:
        """Derive a stable instance identity from a TOML path.

        Args:
            file_path: TOML file path under this loader's rune root.

        Returns:
            Rune-root-relative path without the TOML suffix.

        Raises:
            ValueError: If ``file_path`` is outside this loader's rune root.

        """
        rel = file_path.relative_to(self._runes_dir)
        return str(rel.with_suffix(""))

Fragment Path Tradeoff

path_fragment keeps declarations short while preserving a concrete computed anchor:

class SoulstoneConfig(AnimatorConfig):
    path_fragment: ClassVar[Path] = Path("soulstones")

class GenericSoulstoneConfig(SoulstoneConfig):
    path_fragment: ClassVar[Path] = Path("generic")

class LlamaCppSoulstoneConfig(SoulstoneConfig):
    path_fragment: ClassVar[Path] = Path("llamacpp")

This means Python inheritance is filesystem ancestry for RuneConfig subclasses. That coupling is intentional inside the core and coupled extension path because it keeps declarations readable and makes branch/leaf topology mechanical.

The tradeoff is that schema-only reuse should not be modeled as a RuneConfig parent. Use a mixin or composed Pydantic model when shared fields should not move the class in the Codex tree:

class GenerationDefaultsMixin(BaseModel):
    temperature: float = 0.7

class LlamaCppSoulstoneConfig(SoulstoneConfig, GenerationDefaultsMixin):
    path_fragment: ClassVar[Path] = Path("llamacpp")

Provisional structural extension schemas that do not inherit RuneConfig cannot derive a parent chain; they expose a full relative_path at the current schema-intake boundary instead.

AnimatorConfig and SoulstoneConfig are abstract branch configs. They are configuration base classes, but they are not direct TOML owners. Concrete Soulstone TOML instances must live under a leaf schema such as GenericSoulstoneConfig, LlamaCppSoulstoneConfig, VllmSoulstoneConfig, or SglangSoulstoneConfig.


The Instance Doctrine

Within an Anchor:

  • One TOML file equals one instance.
  • Instance payload resides at TOML top level (arrays-of-tables are forbidden for instance encoding).
  • Instance identity is derived from relative path.
  • Duplicate identity across files is forbidden.

If a rune class has children, it is a branch namespace and may not own TOML files in its own anchor.

Leaf rune classes may define multiple instances.

Branch anchors are not profile buckets. If a branch needs reusable profiles, those profiles must be modeled as their own leaf rune family and referenced by name from the capability-bearing rune. This keeps parent/default runes single and makes many-profile configuration explicit.

Violations abort configuration loading.

Semantic Profile Doctrine

Filesystem ancestry must not masquerade as semantic defaults.

Shared defaults that apply only to a capability family, such as LLM generation settings, should become named rune/profile instances and be referenced by capability-bearing runes. For example, a generative Soulstone or Portal may reference a generation profile and add local overrides, while a web crawler or tool-only animator never receives irrelevant generation fields just because it lives under animator/.

Resolvers compute effective runtime config from:

  • named profile runes
  • runtime/family defaults
  • local rune overlays
  • request-time overrides

This keeps directory layout useful for discovery while semantic policy remains explicit and capability-scoped.


llama.cpp Preset Doctrine (--models-preset)

llama.cpp soulstones may reference a router preset .ini via a typed rune field (e.g., preset_path), allowing the Magus to preserve optimized upstream launch profiles while remaining inside Codex governance.

  • Two-Tier Intent:
    • Rune Intent: Identity, coven policy, and orchestration hints (e.g., dedicated, persistent_resident, matrix_sets).
    • Preset Intent: Router/runtime defaults and per-model launch arguments consumed by llama-server.
  • Validation Rule: Preset references must resolve to an existing readable file path before binding; unresolved preset paths are configuration errors.
  • Boundary Rule: Preset files tune model runtime behavior, but may not redefine host-level governance authority enforced by LychD (port arbitration, coven exclusivity, and orchestration ownership).
  • Precedence Awareness: Preset semantics follow upstream llama.cpp precedence (CLI > model section > global section). Codex manifests should document any CLI overrides that intentionally shadow preset values.

This doctrine preserves "Magus heritage" tuning while preventing configuration fragmentation.


The Leaf Principle

Only leaf rune classes (those without subclasses) may define multiple instances.

Non-leaf rune classes are branch namespaces only. They share fields and code defaults with descendants but do not own TOML instances. In animation, this means AnimatorConfig and SoulstoneConfig are ABC-style branch configs, not files such as runes/animator/animator.toml or runes/animator/soulstones/foo.toml.

There is no explicit singleton override in RuneConfig. If a domain requires one specific named instance, or requires that one named instance be active, that is domain validation rather than base rune authority.

This prevents ambiguous discovery, implicit polymorphic loading, and ad hoc singleton exceptions in the base loader.

4. The Configurable Contract (Extension Integration)

Configuration extensibility is governed by the structural registry of the Core.

However, per the Extension Compatibility Tiers (ADR 05), not every external organ has the same stability promise.

To resolve this Codex Paradox, rune classes follow tiered integration paths:

  • Built-in Extensions: May inherit directly from RuneConfig.
  • Private Coupled Extensions: May inherit directly from RuneConfig if the operator accepts refactor coupling.
  • Future Independent Extensions: Must wait for a versioned public schema API before LychD promises Core-refactor compatibility. The current structural scan is a provisional Python-source assimilation path, not the stable third-party contract.

Registration Doctrine (The Machinery's Translation)

Rune schema discovery is structural, not the runtime contribution ledger.

  • Built-in/Private Coupled Path: Runtime import plus RuneConfig.__subclasses__() discovery determines schema ownership. The subclass itself is the schema registration signal.
  • Provisional Crypt Source Path: CryptSourceLoader may load Python source files from the extensions directory, scan their module objects, and register Pydantic-compatible classes with a safe relative_path. This is local/provisional assimilation; it must not be described as an SDK or ABI.
Live snippet: src/lychd/extensions/discovery.py:31
        """
        if not extensions_path.exists():
            return

        for item in extensions_path.iterdir():
            if item.suffix == ".py" and not item.name.startswith("_"):
                self._load_and_translate(item)

    def _load_and_translate(self, file_path: Path) -> None:
        """Load one extension module and register rune-shaped classes.

        Args:
            file_path: Python source module path to load.

        """
        module_name = file_path.stem

        # Binary modules are deliberately excluded from this direct runtime path.
        # They need a Forge manifest and platform validation before import.
        loader = importlib.machinery.SourceFileLoader(module_name, str(file_path))

        spec = importlib.util.spec_from_loader(module_name, loader)
        if not spec or not spec.loader:
            return

        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)

        # 2. Scan the isolated module for rune-shaped classes.
        for attr_name in dir(module):
            if attr_name.startswith("_"):
                continue

            obj = getattr(module, attr_name)

            # We are looking for Classes that match the shape, not instances.
            # issubclass() fails for Protocols with non-method members.
            if isinstance(obj, type):
                has_path = hasattr(obj, "relative_path")
                has_validate = hasattr(obj, "model_validate")
                if has_path and has_validate:
                    self.codex_loader.register_schema(obj)

No extension may implement custom configuration loaders, and no dynamic type= dispatch is permitted.

Registration automatically binds the rune class to:

~/.config/lychd/runes/<relative_path>/

If an extension is installed:

  1. Its RuneConfig subclasses or structural rune classes are discovered.
  2. Their Anchors become valid Codex territories.
  3. One TOML file equals one instance and payload lives at TOML top level.
  4. Instances located in those directories are validated and loaded.
  5. Validated instances become configuration intent.
  6. A separate factory, adapter, or registration hook must hydrate that intent into runtime state when the rune is meant to do work.

Extension import + inheritance registers rune ownership under the shared loader. It does not by itself register a runtime service.

The Codex loader remains singular and authoritative.


Structural Guarantees

This model ensures:

  • Extensions cannot fragment configuration loading.
  • Configuration remains globally validated.
  • Infrastructure manifestation remains downstream of schema authority.
  • Removal of an extension invalidates only its anchor territory.

Configuration extensibility is therefore achieved without sacrificing determinism.

5. Port Arbitration

Port ownership is validated before Quadlet generation.

The validator aggregates:

  • Reserved core ports
  • Ports declared by Rune Schemas

If any collision is detected:

  • Configuration loading fails immediately.
  • No Quadlets are written.

Infrastructure is never generated from invalid state.


6. Runtime Realization (lychd init)

At runtime, initialization follows a deterministic inscription path:

  1. lychd init calls CodexService.inscribe().
  2. RuneSchemaDiscovery.discover_classes() imports configured extension package roots and discovers all allowed RuneConfig subclasses.
  3. ConfigWriter.initialize_anchors() materializes all anchor directories.
  4. ConfigWriter.inscribe_samples() writes one sample TOML per schema only when no instance file exists yet.

This keeps extension configuration registration structural (inheritance/import), not procedural. Animation follows the same path: AnimatorLoader consumes the same RuneConfig runes under runes/animator/.

Generic local runtimes are passive by default. Non-model runtimes must declare capability hints explicitly, and local OpenAI-compatible APIs must select an explicit OpenAI-compatible runtime alias or a dedicated adapter. Endpoint presence is not configuration authority for model binding.

Discovery package import, subclass traversal, and allowed-rune anchor validation (RuneSchemaDiscovery) are implemented in src/lychd/config/runes/discovery.py:37:

Live snippet: src/lychd/config/runes/discovery.py:37
    def discover_classes(self) -> list[type[RuneConfig]]:
        """Discover loadable rune classes.

        Returns:
            Deterministically sorted rune classes accepted by the discovery
            filters.

        """
        self._import_extension_packages()

        discovered: set[type[RuneConfig]] = set()
        self._collect_subclasses(RuneConfig, discovered)

        # Provisional Crypt source modules register rune-shaped classes here.
        external_schemas: set[type[RuneConfig]] = set()

        class SchemaCollector:
            def register_schema(self, schema: type[RuneConfig]) -> None:
                external_schemas.add(schema)

        loader = CryptSourceLoader(SchemaCollector())
        loader.scan_extensions(self._extensions_path)

        all_schemas = discovered | external_schemas
        filtered = [cls for cls in all_schemas if self._is_allowed_schema_module(cls, external=cls in external_schemas)]
        return sorted(filtered, key=lambda cls: (cls.__module__, cls.__qualname__))

    def _import_extension_packages(self) -> None:
        """Import configured extension package roots before subclass traversal.

        Raises:
            ImportError: If an extension package or module cannot be imported.

        """
        for package_name in self._extension_packages:
            package = importlib.import_module(package_name)
            package_path = getattr(package, "__path__", None)
            if package_path is None:
                continue
            for module in pkgutil.walk_packages(package_path, f"{package.__name__}."):
                importlib.import_module(module.name)

    def _collect_subclasses(self, parent: type[RuneConfig], discovered: set[type[RuneConfig]]) -> None:
        """Recursively collect RuneConfig subclasses.

        Args:
            parent: Rune class whose subclasses should be walked.
            discovered: Mutable set receiving discovered subclasses.

        """
        for subclass in parent.__subclasses__():
            self._collect_subclasses(subclass, discovered)
            discovered.add(subclass)

    def _is_allowed_schema_module(self, cls: type[RuneConfig], *, external: bool = False) -> bool:
        """Return whether a rune class may enter the loader set.

        Args:
            cls: Candidate rune class from subclass or Crypt source discovery.
            external: Whether the class came from Crypt source discovery.

        Returns:
            ``True`` when the class exposes the rune discovery shape or belongs to
            an allowed package.

        """
        if external and hasattr(cls, "relative_path") and hasattr(cls, "model_validate"):
            raw_path = getattr(cls, "relative_path", None)
            if raw_path is not None and not isinstance(raw_path, Path):
                msg = f"Rune '{cls.__name__}' declares non-Path relative_path {raw_path!r}."
                raise TypeError(msg)
            if raw_path is None:
                msg = f"Rune '{cls.__name__}' declares no relative_path."
                raise ValueError(msg)
            if raw_path.is_absolute() or raw_path == Path():
                msg = f"Rune '{cls.__name__}' declares invalid relative_path '{raw_path}'."
                raise ValueError(msg)
            for part in raw_path.parts:
                if not RUNE_PATH_PART_PATTERN.fullmatch(part):
                    msg = f"Rune '{cls.__name__}' declares invalid relative_path part '{part}'."
                    raise ValueError(msg)
            return True

        module = cls.__module__
        return any(module == package or module.startswith(f"{package}.") for package in self._allowed_packages)

Anchor creation and sample inscription (ConfigWriter) are implemented in src/lychd/config/runes/writer.py:16:

Live snippet: src/lychd/config/runes/writer.py:16
    """Writes rune sample TOMLs and initializes rune anchor directories."""

    def __init__(self, runes_dir: Path | None = None) -> None:
        """Create a writer for runes under a specific root.

        Args:
            runes_dir: Optional root directory to write. Defaults to
                ``PATH_RUNES_DIR``.

        """
        self._runes_dir = runes_dir or PATH_RUNES_DIR

    def initialize_anchors(self, schemas: list[type[RuneConfig]]) -> None:
        """Ensure all rune anchor directories exist."""
        for schema in schemas:
            anchor = self._anchor_dir(schema)
            anchor.mkdir(parents=True, exist_ok=True)
            logger.debug("anchor_initialized", schema=schema.__name__, anchor=str(anchor))

    def inscribe_samples(self, schemas: list[type[RuneConfig]]) -> list[Path]:
        """Write one sample TOML per rune class when no files exist yet."""
        created: list[Path] = []

        for schema in schemas:
            target = self._target_sample_file(schema)
            if target is None:
                continue

            target.parent.mkdir(parents=True, exist_ok=True)
            target.write_text(self._render_sample(schema), encoding="utf-8")
            created.append(target)
            logger.info("rune_sample_inscribed", schema=schema.__name__, path=str(target))

        return created

    def _target_sample_file(self, schema: type[RuneConfig]) -> Path | None:
        """Return sample target path if schema has no existing TOML instances."""
        if schema.__subclasses__():
            return None

        file_name = self._default_file_name(schema)

        anchor = self._anchor_dir(schema)
        existing = list(anchor.glob("*.toml")) if anchor.exists() else []
        if existing:
            return None

        return anchor / file_name

    def _anchor_dir(self, schema: type[RuneConfig]) -> Path:
        """Resolve the active filesystem anchor for one rune class.

        Args:
            schema: Rune class whose anchor should be resolved.

        Returns:
            Absolute directory under this writer's rune root.

        """
        return self._runes_dir / schema.relative_path

    def _default_file_name(self, schema: type[RuneConfig]) -> str:
        """Derive the generated TOML sample filename for a rune class.

        Args:
            schema: Rune class needing a generated sample filename.

        Returns:
            The lowercase rune class name with a ``.toml`` suffix.

        """
        return f"{schema.__name__.lower()}.toml"

    def _render_sample(self, schema: type[RuneConfig]) -> str:
        lines: list[str] = []

        for field_name, field_info in schema.model_fields.items():
            if field_name == "source_file":
                continue

            if field_info.description:
                lines.append(f"# {field_info.description}")

            if field_info.default is not PydanticUndefined:
                lines.append(f"# default: {field_info.default!r}")
            elif field_info.default_factory is not None:
                lines.append("# default: <factory>")

            value = self._sample_value(field_info.annotation, required=field_info.is_required())
            assignment = f"{field_name} = {value}"

            if field_info.is_required():
                lines.append(assignment)
            else:
                # Optional/defaulted fields are documented but commented out.
                lines.append(f"# {assignment}")

            lines.append("")

        return "\n".join(lines).rstrip() + "\n"

7. Assembly Pipeline

The configuration lifecycle proceeds in strict order:

  1. Load Global config.
  2. Validate Schema Layer.
  3. Discover Anchored Rune Schemas.
  4. Validate each instance.
  5. Enforce:
  6. Duplicate identity rejection
  7. Domain identity and policy constraints
  8. Port arbitration
  9. Only after full validation:
  10. Generate Quadlets.

Infrastructure is a manifestation of validated intent.


8. Secret Covenant

Secrets are declared by reference:

  • Codex stores secret names (*_secret) only.
  • Soulstones may map runtime env vars to secret names via secret_env_files.
  • Values live in rootless Podman secret storage.
  • Generated Quadlets bind them through Secret= directives.

Secrets:

  • Are not stored inline in lychd.toml or rune TOMLs
  • Are mounted only into units that require them
  • Are accessible to the process boundary that consumes them

Example lifecycle:

printf '%s' "$OPENAI_API_KEY" | podman secret create --replace portal_openai_main -
podman secret ls

Filesystem permissions protect secrets from other host users. They do not protect secrets from code executing within the same Quadlet unit.

If isolation from agent-level execution is required, the secret must reside in a separate service boundary.


9. Context Privatization Policy

Privatization policy is configured in the Codex and enforced by runtime dispatch:

  • portal_threshold: minimum weight requiring anonymization before portal egress.
  • forbidden_threshold: minimum weight forbidding raw portal egress.
  • require_anonymization_workflow: fail-closed if no sanitization path exists.

Canonical source is Codex (lychd.toml). Phylactery-backed policy records, when enabled for adaptive tuning, must remain equal or stricter than the Codex baseline.

Conceptual shape:

[security.privatization]
portal_threshold = 0.40
forbidden_threshold = 0.70
require_anonymization_workflow = true

10. Autonomy and Approval Policy

Autonomy policy is configured in the Codex and enforced by trusted Vessel-side gates. The baseline is fail-closed: if no policy explicitly authorizes an autonomous action, the action requires HitL (ADR 25) or is denied.

This policy exists to distinguish three different meanings that older prose sometimes compressed into "approved":

  • Live Magus approval: an explicit decision at the Altar.
  • Preauthorized Vessel policy: a bounded rule written by the Magus and validated by the system before execution.
  • Denied authority: a class of action the system may simulate, test, or report on, but may not promote.

ZTE chores are not a bypass around consent. They are a named preauthorization class for minor, reversible, well-tested work where the Codex policy, deterministic verification, identity constraints, and safety boundaries all agree.

High-stakes classes remain hard gated by live HitL regardless of confidence score:

  • core logic promotion
  • schema migration
  • destructive data deletion
  • secret or credential changes
  • network or egress broadening
  • host lifecycle authority
  • spending above configured toll limits
  • cross-identity memory sharing

Conceptual shape:

[autonomy]
default_action = "require_hitl"

[autonomy.zte]
enabled = true
max_risk = "minor"
requires_clean_checks = true
requires_snapshot = false
min_streak = 8
min_confidence = 0.95
allowed_scopes = ["docs", "tests", "non_runtime_metadata"]
forbidden_scopes = ["core_runtime", "migrations", "secrets", "host_lifecycle"]

Canonical source is Codex (lychd.toml). Phylactery-backed performance records, confidence streaks, and adaptive policy observations may tighten the effective policy or satisfy a Codex-defined predicate, but they must not loosen the Codex baseline.


11. Dual-Plane Trust Delta

Configuration is now split by trust boundary:

  • Vessel config is the only source of truth for secrets, persistence, and policy.
  • The Tomb config is a generated runtime envelope with only task-safe fields.
  • The Tomb config is derived data, never an alternate source of truth.
  • The Tomb schema forbids provider secret fields and infrastructure authority fields.
  • Provider/API keys are never serialized into Tomb payloads.
  • Narrow queue-only SAQ/Postgres execution credentials, when needed, are worker-unit credentials rather than Tomb configuration authority.
  • The Tomb cannot override queue, network, autonomy, approval, or authority policy.

Authority Matrix

Dimension Vessel (Trusted Control Plane) The Tomb (Untrusted Execution Plane)
Secrets Loaded via Podman secret references and mounted into trusted units. Provider and authority secret fields are forbidden by schema; narrow queue-only SAQ/Postgres execution credentials live at worker-unit policy.
Mounts Codex-backed config and durable state mounts. Sanitized task-scoped config artifact or read-only projection only.
Network Resolves provider and broker routes per policy. No direct secret-bearing provider routes.
Queue Ownership Owns queue workflow configuration. No queue configuration ownership.
Context Privatization Defines thresholds and anonymization policy for portal egress. Cannot lower thresholds or bypass sanitization gates.
Autonomy Policy Defines preauthorization, HitL, and denial classes. Cannot authorize promotion or broaden its action class.
Authority Boundaries Defines and signs runtime envelopes. Consumes envelope; cannot redefine authority.

Consequences

Positive

  • Deterministic Topology: Filesystem structure defines rune ownership and instance identity.
  • Fail-Fast Guarantees: Invalid configuration aborts before infrastructure generation.
  • Extension Uniformity: Coupled extensions inheriting RuneConfig integrate without custom configuration loaders.
  • Clear Trust Boundaries: Secret visibility is explicit and aligned with process boundaries.

Negative

  • Strict Structural Discipline: Incorrect directory placement or duplicate identity causes immediate failure.
  • Shared Process Trust Domain: Secrets available to a Quadlet unit are accessible to code within that unit.
  • Operational Responsibility: File permissions must be maintained to preserve at-rest protection.