12. Configuration
In plain words: Design rule 12: Configuration
Defines how settings are loaded: one typed Settings model from lychd.toml in the Settings Folder (Codex), plus validated Service Config Files (Runes) for models and services, all checked before they can generate infrastructure.
- 1Precedence is fixed: explicit values, then environment (SECTION__FIELD), then lychd.toml, then file secrets, then defaults.
- 2Unknown or obsolete fields are rejected; loading is read-only and never repairs or creates files.
- 3Each process keeps one loaded settings generation; a live config writer is designed separately.
Available Settings and Rune loading work; a live config writer and some selectors are designed.
Words on this page, decoded click one for its card
Context and decision
The CodexSettings Folder holds declared operator intent. A single typed Settings root and anchored RuneService Config File instances are read, validated, attributed, and assembled before they can project infrastructure.
Settings: one immutable generation
lychd.toml is the global Settings document under the CodexSettings Folder. Its only top-level sections are
server, orchestration, extensions, weaver, and optional archive. Settings is the sole BaseSettings model; nested
strict BaseModel sections reject unknown and obsolete fields. The public Python entry is
lychd.config.settings, not its internal section modules.
Load and retain one generation
Source precedence is fixed:
explicit construction → environment → lychd.toml → Pydantic file secrets → model defaults
Environment names use the root SECTION__FIELD grammar. There is no dotenv source and nested
sections do not load separate environment, TOML, or secret sources. Loading is read-only: it does
not create CodexSettings Folder files, repair input, generate credentials, or mutate the environment.
get_settings() retains one loaded generation per process. Runtime consumers use its stored
values; they never reopen environment variables or secret files. Reload requires an explicitly
constructed new Settings instance or a process restart. SettingsSnapshot retains a secret-free
serialized declaration and the already-loaded credentials separately in memory as SecretStr.
Each preview/apply phase revalidates its own copy without running settings sources again.
An accepted Settings field needs a real consumer. server.port is exposed today, but runtime
policy fixes the managed image listener independently of TOML. The obsolete server.host,
server.reload, server.keep_alive, and server.web.url inputs are rejected and omitted from
generated configuration. Launcher flags and environment cannot reintroduce them as CodexSettings Folder intent.
Current selections
[extensions] selects permitted built-in and CryptData Folder packages; it neither selects an application nor
creates a runtime. Settings also owns the fixed runs and rites physical queues and their
concurrency; routing can name only those queues. Global port claims and RuneService Config File port claims are
arbitrated before any unit is written.
The bounded Core BridgeChat selector uses optional [weaver.bridge] to select the registered
bridge_chat@2; omission keeps bridge_chat@1 active. Revision 2 admits exactly one of an exact
capability_key or a versioned preference. The preference grammar has schema_version = 1
and exactly two distinct route entries, each containing a literal canonical registry
capability_key of at most 512 characters and a strict integer weight from 0 through 1,000,000. Booleans, coercion,
aliases and a zero total are refused. Zero disables that route's eligibility; larger weights rank
first, with ascending canonical key breaking a tie. Weights are unitless ordinal preferences
without normalization, not traffic share or measured quality. Both declarations must satisfy the
local Chat/tools contract in
Dispatcher, including a disabled route.
Admission resolves an existing idempotent RunJob Record before considering current policy or readiness.
A fresh preference admission retains its immutable policy and weights, canonical policy digest,
safe phase observations, server-observed observation and batch times, closed exclusion codes and
selected exact key in the existing RunJob Record intent JSONB before publication. The digest is SHA-256 of
canonical typed policy bytes, including schema_version = 1, not a generated JSON Schema
fingerprint. Concurrent admission losers return the retained winner. This metadata is server-owned;
callers cannot supply or replace it. Graph state retains the selected key across pauses; replay
and restart use that key without
another preference selection. A changed Settings generation affects new admissions only.
Retention excludes free probe reasons, endpoints, principals, credentials and authentication
generations. This remains capability identity pinning rather than a durable
executable/declaration-generation fingerprint or the general portable Resolution Lock.
This admission policy preserves the existing bridge_chat@2 PatternWorkflow, calls, tools, consent,
retries and token bounds. It supplies no post-selection fallback. The AltarControl Panel must explain the
retained policy, observations, exclusions and selection at admission, the absence of fallback,
and the distinct replay/restart and new-admission semantics before this feature is published.
Display neither grants authority nor establishes current readiness. Implementation and delivery
evidence remain owned by State of Work.
An explicit revision = "3" selects the read-only ArchiveLong-term Memory answer profile and additionally
requires an archive binding with exact local-public-notes@1 profile, namespace UUID, trusted
local subject, and policy revision. It is valid only with PostgreSQL and the same-host bootstrap
custody profile. The whole binding is retained at RunJob Record admission; changed settings cannot rewrite
an admitted casting. This selector grants no remote identity, namespace access, ingestion, or
embedding capability. Intake and promotion remain separate explicit ArchiveLong-term Memory operations.
Revisions 3 and 4 continue to require their exact capability_key and their own ArchiveLong-term Memory or ScoutWeb Fetcher
binding respectively; neither accepts preference.
Exact delegated casting selection
Optional [weaver.delegation] selects revision = "2", one exact registered runtime, and
profile (read, candidate, or verify) for new /delegate admissions. Omission retains
the effect-free delegated_rite@1 reference route. The configured revision retains its runtime
binding in RunJob Record intent and GraphStep Map state; idempotent admission and restart use that retained binding,
not the current Settings generation. Unknown adapter names refuse assembly. Registration and
selection do not establish host readiness, containment, privacy, or permission to launch.
The adapter's trusted host remains responsible for effect-time admission. This selector carries no command, executable, environment, provider credential, model alias, alternate list, or fallback switch. A failure, policy refusal, or uncertain start leaves the exact casting in place; it cannot redirect to another runtime. Provider/Gate configuration and compatible-road fallback require their own admitted contracts.
Exact Creation investigation selection
Optional [weaver.creation] selects revision = "2" and one exact capability_key for
creation.investigation@2 / creation.investigate@2. Omission disables its admission. This
bounded application requires PostgreSQL, current local operator policy and its fixed
public-source profile. The captured local
shared vLLM/Qwen Chat declaration must match its generation and policy; no alias, fallback,
remote route or hardware transition is supplied by selection.
Creation retains source bytes, criteria, complete role bindings and reservation under its own case before releasing held RunJob Record delivery. Current settings cannot rewrite an existing request; an eligible explicit continuation retains the same case/profile and its original deadline. Settings carries neither source/prompt material nor a credential or authority grant. The application rechecks current credential-backed object/action policy at use. This typed selection does not introduce a general SDLC coordinator or portable Resolution Lock.
Exact finite Scavenger selection
Optional [weaver.scavenger] selects CompositionApp revision = "3" and one explicit scout
configuration with rss-public-feed@1 for the source-built scavenger.observe_market@2 PatternWorkflow.
Omission disables new Scavenger admission while retaining its exact registered PatternWorkflow for
historical resolution. The selection requires PostgreSQL and the actual same-host startup
credential owner; settings loading and assembly perform no acquisition, model readiness,
reservation or migration. It accepts no capability key, model, arbitrary source locator,
implementation name or fallback. A separately configured ordinary BridgeChat remains independent.
The first native profile permits one active ScoutWeb Fetcher binding in a fresh profile database. It cannot coexist with BridgeChat revision4's page binding. Existing page/RSS budget rows reject a changed binding without mutation; changing the selector never resets spent counters or unknown claims. The profile pins its exact native resolver/custody assertion, CA/extractor runtime, current policy, finite allowance/host ceilings and review expiry. These are declarations, not containment or source-publicness evidence. The exact advertised Bazoš PC feed and consumer projection remain owned by Scout and Scavenger.
The complete supplied campaign seed and initial filter enter Scavenger's protected application admission, never Settings or a model prompt. Their immutable consumer/digests bind the held RunJob Record before publication. Current application read/filter/delete policy is distinct from acquisition consent and expiry; configuration cannot refresh a retained grant, refetch lost material, rewrite a committed field or resurrect a tombstone. Selected assembly, API/UI and deployed evidence remain owned by State of Work.
Independent public Archive selection
Optional [archive] selects profile independently of BridgeChat. Its profile retains the exact
local-public-notes@1 schema. Existing weaver.bridge.archive configuration remains valid;
when both are supplied they must match exactly, and assembly uses one effective binding.
Omission preserves the existing BridgeChat selection and disables independent derivation.
Optional archive.derivation supplies a generation UUID and an exact Core EmbeddingBinding
(capability key, profile digest, model.embed@1). The configured registry must admit that local
static profile before assembly succeeds. An HTTP caller cannot provide an endpoint, model,
manifest or fallback. Loading settings and assembling services neither registers a generation
in PostgreSQL nor prepares a model. Explicit authorized registration retains the configured
manifest; explicit derivation requests perform bounded synchronous work.
The derivation DispatcherTraffic Controller shares the application's exact registry and lease ledger but has no RunJob Record event sink. A supplied RunJob Record UUID is caller attribution only: it neither establishes a RunJob Record relationship nor permits events or writes to that RunJob Record. The existing GraphStep Map dispatcher is unchanged.
Runes: location, provenance, semantics
A RuneService Config File is one validated top-level TOML instance in the CodexSettings Folder runes/ tree, not a runtime object
or generated unit. Each concrete RuneConfig supplies one safe path_fragment; direct Python
subclassing forms one anchor ancestry, and relative_path is computed from it. A fragment is one
segment matching ^[a-z0-9](?:[a-z0-9_-]{0,48}[a-z0-9])?$. Distinct registered schemas cannot
own the same exact anchor; nested anchors remain distinct and express declared class ancestry.
Nested non-Rune Pydantic value objects may contribute shared validated structure without joining
or branching that anchor ancestry. The delivered QuadletConfig is embedded under the quadlet
field of SoulstoneLocal Model and Phoenix RunesService Config Files and shares only the minimum OCI image invariant; it supplies
neither a RuneService Config File path nor raw unit, lifecycle, mount, network, secret, or command authority.
Generic sample generation renders required embedded values as typed TOML inline tables; maintained
hand-authored examples may use the equivalent named table form such as [quadlet].
Branch classes are namespaces and cannot own TOML files; only leaf schemas may have one or more
instances. A file's path supplies its identity and source_file provenance. Duplicate identity,
files in branch anchors, arrays-of-tables instance encoding, unsafe fragments, and schema
violations abort discovery.
Three terms describe a RuneService Config File's location. An Anchor owns a directory territory; a Fragment is its safe local path segment; and an Instance is one leaf TOML document. The instance carries provenance into runtime, but provenance is not a TOML field. Validation freezes instances so that resolvers can derive effective state without changing CodexSettings Folder intent.
Filesystem ancestry names type, not semantic defaults. Named leaf profile instances supply
family-specific defaults; a capability-bearing RuneService Config File references profiles and applies local overlays.
Resolvers combine profile, runtime/family defaults, local overlay, then request-time override.
Presets such as a llama.cpp router .ini are typed, readable references: they tune their runtime
but cannot change port arbitration, coven exclusivity, or host ownership. Upstream precedence is
CLI arguments > model-specific preset section > global [*] section; a generated CLI override
that deliberately shadows a preset value must remain visible to the operator.
General-service declarations and current model blocks
The accepted general-service RuneService Config File shape uses first-class [[capabilities]] entries. Each entry
references one registered semantic interface and exact immutable profile, declares its permitted
operations and invocation mode, and pins the runtime driver/dialect, conformance evidence, resource
envelope, and containment profile required to make that instance honest. Definitions are typed
Contributions governed by their receiving Core office or Extension DomainPlug-in Area and retain the
Registrant's registrant_id; an implementation profile separately names its concrete Provider. A
RuneService Config File selects those definitions and supplies instance-local endpoint, secret reference, lifecycle,
and explicit overlay values. It cannot redefine their schemas, licenses, or proved limits inline.
Current source delivers only [[models]]: models behind one RuneService Config File instance with closed families,
input modalities, Chat or Responses surface, tool support, context size, and generation overlays.
Streaming support and output modalities have no configurable v1 fields. Those blocks remain v1
compatibility sugar for exact admitted model-interface projections; non-model services never
invent a model_id or generation overlay merely to become loadable. Neither form encodes multiple
RuneService Config File instances.
The single GenerationProfile owns the common context, output-token, temperature and top-p
overlays. Its optional closed thinking = "qwen3.8-non-thinking" policy is model-local: only an
explicit [[models]] generation block for local vLLM Qwen3.8-27B on the Chat surface may select
it. Runtime defaults, Soulstone-wide defaults, PortalsCloud Models and other model/runtime/surface combinations
refuse a non-null policy before publication. Omission preserves the existing request. This is one
admitted self-hosted chat-template dialect, not arbitrary provider settings or model-name inference.
For the current v1 path, capability synthesis begins with text input. Field precedence is RuneService Config File hint, then live probe or adapter-discovered runtime fact, then runtime profile default. An explicit modality hint replaces discovered and default modalities; when omitted, probed modalities may enrich the runtime base. In v2, open facts are profile-specific and a live probe may establish readiness but never invent an interface, operation, language, format, dialect, or permission. Dispatcher (22) may verify a declared capability only by downgrading it.
Extension activation and application selection
Selected extension registration shims add RuneConfig types to context.runes; the loader is
given that explicit schema list and never scans packages. A Configurable extension registers its
schema through this contract, then separately registers any runtime definition or adapter in its
own domain store. Importing a package does not register it; registering a schema does not create a
service. Extensions cannot introduce custom loaders, source precedence, parsers, or type=
dispatch. Extensions (05) owns compatibility tiers.
The complete preauthorization RuneService Config File generation is validated before durable reconciliation.
Duplicate slugs fail deterministically, and an incoming RuneService Config File cannot replace a row whose durable
owner is not codex:rune. Only after those checks may one transaction refresh Rune-owned rows,
retain their usage and operator-enabled state, mark absent Rune-owned policies unavailable, and
publish newly admitted policies.
Realization and the writable Codex
init and init --dry-run derive the same LifecyclePlan. The real command rejects UID 0,
inscribes missing anchors and inactive leaf samples, and must round-trip a generated Settings TOML
through fresh validation. Marked samples are ignored until their marker is removed. bind first
uses one immutable Settings/extension/RuneService Config File generation to compile declarations, then revalidates
the foundation, secret presence, generations, and receipts under the lifecycle lock immediately
before mutation. A content-identical reconciliation is a no-op; an indeterminate mutation keeps
recovery evidence. Layout (13) owns path creation, locks, receipts, and filesystem
attestation; Privilege (10) owns trusted host executables and their permissions.
Assembly proceeds from Settings to selected schemas, then to discovered and validated RuneService Config File instances. It enforces identity, domain policy, and ports before projecting exact Scribe-owned units. Downstream registries consume that generation rather than reopening the RuneService Config File filesystem. Read, syntax, and schema-validation failures identify the source file; schema failures also retain their field diagnostics and original validation cause.
A sanctioned live CodexSettings Folder writer is designed separately from current sample writing. It must stage a typed request, validate the complete staged tree as bind would, atomically rename only after that validation, and use an explicit reload signal. It has no ambient authority from Smith or AltarControl Panel. Core promotion needs live HitLApproval Step; a narrower preauthorization must be expressly lawful. No hot reload is delivered. State of Work records this path as Designed.
Secrets, privacy, autonomy, and projections
CodexSettings Folder stores only secret references (including *_secret), never values. Settings sources resolve
the database password and application signing key once during construction into excluded,
non-repr SecretStr fields. Explicit construction and root-grammar environment values take
precedence over the existing LYCHD_DB_PASSWORD / LYCHD_APP_SECRET_KEY environment aliases,
then their *_FILE paths, then /run/secrets/<declared-name>. TOML credential values are rejected.
An absent default mount leaves the credential unset so host init and caged bind can run before
provisioning; database/web assembly rejects unset runtime credentials without further I/O.
Explicit file overrides must be readable and nonempty at Settings construction. Nested settings
models perform validation only; explicitly supplied section instances are complete overrides.
Bind preflight requires the CodexSettings Folder secret file to be Magus-owned with
group and other permissions closed. Generated caged units use file form and scope mounts to the
unit that needs them. Filesystem permissions do not isolate code within that unit.
Retired native credential selection
The host-native LYCHD_RUNTIME_SECRETS=podman-core@1 Settings source and its capture/provenance
fields are retired. Explicit use of that selector refuses before credential I/O rather than
falling back to another owner. Container startup consumes its narrowly mounted /run/secrets
inputs through the ordinary sources above. The host operator's trusted Podman secret adapter
retains its separate bind/access responsibilities; it is not application startup credential
transport. No replacement source, automatic conversion, rotation or credential export is added.
Policy and derived projections
In the accepted design, CodexSettings Folder also sets the privacy/egress baseline (thresholds, anonymization requirement, destination and purpose eligibility, non-declassifiable categories, transformer/verifier profile, receipt lifetime, revision) and autonomy baseline. The designed Policy WardSecurity Desk rejects adaptive PhylacteryMemory Vault state that is more permissive than CodexSettings Folder. Absent explicit authorization, effects require HitLApproval Step or are denied; confidence does not authorize core promotion, migrations, destructive deletion, secret changes, egress broadening, host authority, excessive spending, or cross-identity memory sharing.
VesselEngine Room configuration is the source of truth. A future TombSandbox envelope is derived, secret-free, and cannot alter queues, network, mounts, privacy, autonomy, approval, or authority. TombSandbox receives no CodexSettings Folder mount. Security (09) owns credentials and isolation; the TombSandbox delivery boundary remains Designed.
Future selectors
Application and Gateway profiles
Any further application selector requires its own accepted SpellweaverWorkflow Engine schema and
may resolve only one registered exact profile revision, such as one of the mutually exclusive
Reach deployment profiles. In Reach, for each
Discord application and Habitat partition, that immutable selection binds one authority epoch,
one Discord edge epoch, one
active PhylacteryMemory Vault, one Gateway/delivery credential owner, and the exact per-host role set. Unknown
mixtures and boolean authority switches such as trusted, use_vps, local_db, or tether
fail before Bind. The selected profile contributes no raw units: one immutable generation resolves
its exact CompositionApp/PatternWorkflow revisions and registered service roles into the
ApplicationDeploymentManifest@1, then
revalidates global ports, routes, secrets, mounts, migrations, dependencies, and resource policy
before Bind.
A change of profile or authority location requires a typed Evolution effect. Settings reload cannot perform it. The transition quiesces admission, settles or preserves external-effect identities, fences the old epochs, and revokes old routes and credential owners. Where authority moves, it transactionally restores an admitted partition. Only then does it activate the new generation; an old or simultaneous generation fails closed.
Gateway placement follows the same exact-profile law. Home and Remote
are reference placements of one separate Gateway Host role, not applications, Extension
Domains, or free configuration literals. A selected deployment profile either omits that role or
binds its exact per-host manifest, Veil routes, optional Tether generation, backend identity,
service Principals, edge secrets, firewall and management boundaries, and recovery contract.
Loose fields such as gateway=true, rpi, vps, or an arbitrary proxy target cannot assemble a
partial edge.
Palette configuration
Presentation configuration obeys the same typed-source law when it is admitted. In particular, a future Altar palette may enter only through an explicitly owned validated Settings field or another Covenant-owned typed source with declared precedence; it is never an unmodelled TOML table, raw CSS file, selector, or extension side channel. Frontend owns the finite semantic colour roles and accessibility rules, while Configuration owns loading, validation, attribution, and immutable generation. Current Settings contains no palette field and changing the accepted root shape requires an implementation and State update.
General casting selection
A future Spellweaver configuration-to-casting selector
follows the same root-shape law. Local TOML may select exact already-registered ScrollWorkflow Version, SpellStep
implementation, AgentSpec/Posture, and ContextBriefing Pack projection revisions plus bounded policy, with the
Agent references resolved only through an exact placement; the portable ScrollWorkflow Version remains canonical
JSON. Configuration never names Python imports, BaseNodes, graph edges, callables, prompts, source
bytes, credentials, or live handles, and it cannot turn schema registration into executable
activation.