/** * feature-settings.ts, the binding layer between domain settings keys and the * internal capability gates, plus the per-feature settings metadata surfaces * render. * * Every platform capability is configured through a first-class settings key * in its natural domain (behavior.compactionStrategy, sandbox.enabled, * notifications.adaptiveSuppression, ...). There is no separate enablement * namespace: at boot the runtime derives each internal gate's state from its * bound settings key, and the live bridge keeps them in sync afterwards. * The internal gate registry (flags.ts) and its kill-switch manager survive as * implementation detail only, surfaces render FEATURE_SETTINGS, never that * registry as a category of its own. * * Binding kinds: * - boolean : the key's boolean value is the feature's enablement. * - enum : the feature is active while the key's value is in enabledValues * (several features can share one key, e.g. telemetry.otelMode * drives both the in-process instrumentation and remote export). * - constant: the capability has no separate off switch; its own domain keys * (listed in its settings association) govern runtime activation * directly and only the internal kill switch can force it off. */ import type { ConfigKey } from '../../config/schema-types.js'; import type { ConfigManager } from '../../config/manager.js'; import type { FeatureFlagManager } from './manager.js'; import type { FlagState } from './types.js'; export type FeatureEnablementKind = 'boolean' | 'enum' | 'constant'; export interface FeatureSettingsBinding { readonly featureId: string; /** The scalar settings key that decides (or, for constant, represents) enablement. */ readonly key: ConfigKey; readonly kind: FeatureEnablementKind; /** For kind 'enum': the key values for which the feature is active. */ readonly enabledValues?: readonly string[]; } /** Every capability's enablement binding, one entry per registry id. */ export declare const FEATURE_SETTINGS_BINDINGS: readonly FeatureSettingsBinding[]; export declare function getFeatureSettingsBinding(featureId: string): FeatureSettingsBinding | null; /** * Registry-membership check: composition fails LOUDLY when a gate id it * references has no FEATURE_SETTINGS binding. This is the defect class where * a never-registered id silently reads as "disabled" forever, no settings * key could ever turn it on, so the gated capability ships dead. Called by * the gates helpers (gates.ts) on every referenced id. */ export declare function assertFeatureGateIdRegistered(flagId: string, context: string): void; /** Derive one feature's state from a settings value per its binding. */ export declare function deriveFeatureState(binding: FeatureSettingsBinding, value: unknown): FlagState; /** * Derive every feature's desired state from the live config. Used at boot to * seed the gate manager; because each settings default matches the registry * default (enforced by test), deriving on a fresh config is a no-op. */ export declare function deriveFeatureStates(configManager: Pick): Record; /** * Live bridge from domain settings changes to the in-process gate manager. * Subscribes each bound key once and forwards the derived state for every * feature bound to it. Runtime-toggleable gates apply immediately; startup * gates record an honest pending-restart marker (see * FeatureFlagManager.applyConfigState). Constant bindings need no * subscription, their domain keys act directly on the subsystems that read * them. */ export declare function bindFeatureSettingsBridge(configManager: Pick, featureFlags: Pick): () => void; /** One feature as the settings surfaces render it. */ export interface FeatureSetting { readonly id: string; readonly name: string; /** Real description of behavior and options (feeds under-cursor docs). */ readonly description: string; /** Top-level settings domain the feature lives in (its config category). */ readonly domain: string; /** How the feature is turned on/off. */ readonly enablement: { readonly key: ConfigKey; readonly kind: FeatureEnablementKind; readonly enabledValues?: readonly string[]; }; /** Every scalar settings key that configures this feature (enablement key first). */ readonly settings: readonly ConfigKey[]; /** True when enablement changes only take effect after a process restart. */ readonly restartRequired: boolean; /** Whether a stock configuration has the feature active. */ readonly defaultEnabled: boolean; /** * False when the capability cannot operate in this build at all, the gate * refuses it regardless of its settings key. * * A surface rendering `operable: false` must SAY SO where the control is, * rather than drawing a switch that flips cleanly and does nothing. The * reason to show is {@link inoperableDetail}. */ readonly operable: boolean; /** Why it cannot operate, written for a user; null when it can. */ readonly inoperableDetail: string | null; } /** * The per-feature settings metadata surfaces consume: domain, option shapes * (enablement key + associated tuning keys, each described in CONFIG_SCHEMA), * and real behavior descriptions. Ordered by the registry declaration order. */ export declare const FEATURE_SETTINGS: readonly FeatureSetting[]; //# sourceMappingURL=feature-settings.d.ts.map