# config **Category**: universal **Path**: `universal/config/config` **Archived from**: `openspec/archive/2026-04-24-enterprise-config/` --- ## Purpose Layered configuration management for the Suaveplan monorepo. Five typed layers (defaults, file, object, env, CLI) are resolved in priority order, deep-merged, optionally validated via a caller-supplied Zod-compatible schema, and exposed through an immutable `ConfigStore` with hot-reload and subscription support. ## Requirements ## Constants ```ts LAYER_PRIORITIES: { DEFAULTS: 0; FILE: 10; OBJECT: 20; ENV: 30; CLI: 40 } MASK_STRING: "****" TRUTHY_STRINGS: string[] FALSY_STRINGS: string[] ``` --- ## Error Codes | Code | Severity | Retryable | Trigger | |---|---|---|---| | `CONFIG_MISSING` | `error` | `false` | Required config key not present | | `CONFIG_INVALID_TYPE` | `error` | `false` | Value has wrong type | | `CONFIG_PARSE_FAILED` | `error` | `false` | Layer resolution threw | | `CONFIG_FILE_NOT_FOUND` | `error` | `false` | File layer content unavailable | | `CONFIG_ENV_NOT_SET` | `error` | `false` | Required env var absent | | `CONFIG_RELOAD_FAILED` | `error` | `true` | Reload aborted or layer re-resolution threw | | `CONFIG_VALIDATION_FAILED` | `fatal` | `false` | Validator threw | --- ## Core API ```ts class ConfigError extends SuaveplanError function createConfig(options: CreateConfigOptions): ConfigStore interface ConfigErrorDetail { path?: string; message: string } interface MergeResult { data: ConfigData; layers: ResolvedLayer[] } interface ResolvedLayer { name: string; priority: number; data: ConfigData } ``` --- ## Store ```ts function createConfigStore(options: ConfigStoreOptions): ConfigStore interface ConfigStoreOptions { data: T sensitive: string[] } interface ConfigStore { get(key: K): unknown has(key: string): boolean toJSON(): Readonly toMasked(): Readonly reload(signal?: AbortSignal): Promise subscribe(listener: (next: Readonly) => void): () => void } ``` --- ## Layers ```ts function defaultsLayer(defaults: T): ConfigLayer function objectLayer(data: ConfigData, priority?: number): ConfigLayer function envLayer(options: EnvLayerOptions): ConfigLayer function fileLayer(options: FileLayerOptions): ConfigLayer function cliLayer(options: CliLayerOptions): ConfigLayer function parseArgs(args: string[], mapping: Record): Record ``` --- ## Types ```ts type ConfigData = Record interface ConfigLayer { readonly name: string readonly priority: number resolve(): ConfigData teardown?(): void } type ConfigValidator = (data: ConfigData) => T type EnvironmentOverrides = Record> interface CreateConfigOptions { layers: ConfigLayer[] validate?: ConfigValidator sensitive?: string[] environments?: EnvironmentOverrides environment?: string logger?: LoggerLike } interface EnvLayerOptions { prefix?: string mapping: Record source?: Record } interface CliLayerOptions { args: string[] mapping: Record } interface FileLayerOptions { content: ConfigData watchBus?: EventBusLike watchEvent?: string } ``` --- ## Utils ```ts function deepMerge(base: T, override: Partial): T function mergeLayers(layers: Array<{ name: string; data: ConfigData }>): ConfigData function getByPath(obj: ConfigData, path: string): unknown function hasByPath(obj: ConfigData, path: string): boolean function setByPath(obj: ConfigData, path: string, value: unknown): ConfigData function maskSensitive(data: ConfigData, sensitive: string[], mask?: string): ConfigData function coerceValue(raw: string): unknown ``` --- ## Zod Schemas - `EnvLayerOptionsSchema` - `CliLayerOptionsSchema` - `FileLayerOptionsSchema` - `ConfigStoreOptionsSchema` - `CreateConfigOptionsSchema` --- ## OTel Instrumentation | Signal | Name | Attributes | |---|---|---| | Span | `config.create` | `config.layer_count`, `config.environment` | | Counter | `config.get_total` | `config.hit` (bool) | | Counter | `config.reload_total` | — | | Histogram | `config.reload_duration_ms` | — | | Histogram | `config.merge_duration_ms` | `config.layer_count` | --- ## Dependencies | Package | Role | |---|---| | `@suaveplan/error` | `SuaveplanError` base class, `defineCodes` | | `@suaveplan/types` | `LoggerLike`, `EventBusLike` | | `@suaveplan/events` | `EventBus` for file-layer watch mode | | `@suaveplan/env` | `coerceValue` boolean/numeric token reference | | `@opentelemetry/api` | OTel spans, counters, histograms | | `zod` | Zod schemas for all public option types | | `tslib` | TS runtime helpers |