NAVIGATION
ELOWEN DOCUMENTATION

Last updated: 10 October 2026

Browse documentation · Configuration storage
Developer reference

Configuration storage

Configuration storage boundary

ConfigStore retains its public configuration types, general defaults and validators. The provider codec in src/store/config/brainProviders.ts owns DEFAULT_OPENAI_COMPATIBILITY; callers use sanitizeBrainProviders(input) without supplying defaults. ConfigStore reads and brainProviders(input) use this same normalizer, while src/brain/providers.ts imports the baseline directly for openAiCompatibilityFor(entry) during Chat Completions registration. Missing or malformed compatibility fields resolve independently to the unchanged conservative baseline; non-OpenAI entries retain no compatibility block. Omitted API keys retain the current key on provider edits, and stored keys never enter the public provider view: get() maps each provider to apiKeySet and drops the key (src/store/configStore.ts:893). The codec performs no database or network operations and adds only per-entry validation; its stored type comes from its existing membership list without importing ConfigStore. The web compatibility parity test reads the codec owner to pin the browser defaults.

src/store/config/limits.ts owns the private brain/runtime bound tables and runtime defaults. The brain table is initialized once from the store's canonical public defaults, avoiding a runtime import cycle or a second copy (src/store/configStore.ts:352). Web parity tests read both owners and keep the existing browser tables pinned to the same bounds, including the stream heartbeat floor. They compare source text, because the web may not import the daemon: web/tests/modules/settings/brainLimitsParity.test.ts and runtimeLimitsParity.test.ts read src/store/configStore.ts and src/store/config/limits.ts, and the floor is mirrored in web/lib/streamWatchdog.ts.

update checks problem-reporting consent and the expected revision under the write lock before calling private validatePatch and prepareStoredPatch (src/store/configStore.ts:1412-1423). Preparation keeps the existing field merge and validation order. A provider patch then cascades account/settings references before writing the settings row, records changed consent and clears the outbox when disabled, all inside the same locked SQLite transaction. The provider catalog prune (retainProviderModels) runs in that locked callback too, but it only edits the in-memory /models snapshot and requests a background pass, so it is not rolled back with the write (src/store/configStore.ts:1426-1436, src/brain/providerModelCatalog.ts:357-366). The problem-reporting callback runs only after commit. An omitted provider patch performs no cascade/catalog effect; an unchanged reporting flag emits no consent event or callback. The settings API remains the real consumer of this boundary.

The existing retired-config, live-call and key-account raw cleanups share private migrateRaw (src/store/configStore.ts:1086, :1119-1120, :1133-1134). Each mutator explicitly returns whether it changed the document. Missing, malformed, non-object and unchanged rows receive no write and keep their original bytes/revision; changed rows retain unrelated keys and advance the revision once (src/store/configStore.ts:1069-1081). Historical matching conditions are unchanged. This helper is local to ConfigStore and adds no migration registry, boot hook or database access cost.