pub struct SettingsManager { /* private fields */ }Expand description
Thread-safe runtime settings manager.
Obtain via SettingsManager::new(persistence) then call initialize(&config).
Implementations§
Source§impl SettingsManager
impl SettingsManager
Sourcepub fn new(persistence: Arc<dyn PersistenceLayer>) -> Self
pub fn new(persistence: Arc<dyn PersistenceLayer>) -> Self
Create a new manager wrapping the given persistence layer.
Sourcepub fn with_sidecar_feature_locks(self) -> Self
pub fn with_sidecar_feature_locks(self) -> Self
Lock what a token-authenticated sidecar must keep off: skill evolution, the memory system, and the global MCP server list.
Sourcepub fn sidecar_feature_locks(&self) -> bool
pub fn sidecar_feature_locks(&self) -> bool
Whether this manager belongs to a token-authenticated sidecar, where global MCP server definitions may not be created, changed or deleted.
Sourcepub fn with_governance_runtime(
self,
mutation: GovernanceMutationHandle,
status: GovernanceStatusHandle,
) -> Self
pub fn with_governance_runtime( self, mutation: GovernanceMutationHandle, status: GovernanceStatusHandle, ) -> Self
Attach the trusted governance mutation authority used by the server boot.
Sourcepub fn with_realtime_bus(
self,
realtime_bus: Option<Arc<dyn RealtimeBus>>,
) -> Self
pub fn with_realtime_bus( self, realtime_bus: Option<Arc<dyn RealtimeBus>>, ) -> Self
Attach the runtime realtime bus used to schedule the Governance status refetch signal after coherent runtime publication.
Sourcepub async fn initialize(&self, config: &AppConfig) -> Result<BootstrapStats>
pub async fn initialize(&self, config: &AppConfig) -> Result<BootstrapStats>
Seed or reconcile settings from AppConfig into the database.
First boot: every setting is inserted with source = ConfigFile/EnvVar/Default.
Subsequent boots:
- If the DB value was set via the API (
source == Api) and it differs from the current config, the DB value is preserved andis_drift = trueis set in the in-memory cache. - Otherwise the DB value is overwritten with the new config value.
After the upsert pass the entire settings table is loaded into the in-memory cache so runtime reads are O(1).
Sourcepub async fn initialize_with_governance_default(
&self,
config: &AppConfig,
governance_enabled: bool,
) -> Result<BootstrapStats>
pub async fn initialize_with_governance_default( &self, config: &AppConfig, governance_enabled: bool, ) -> Result<BootstrapStats>
Bootstrap settings using the already-derived boot posture default.
Sourcepub async fn load_optional_persisted_value(
&self,
key: &str,
) -> Result<Option<Value>>
pub async fn load_optional_persisted_value( &self, key: &str, ) -> Result<Option<Value>>
Read a persisted value without swallowing storage errors or consulting cache.
Sourcepub async fn apply_governance_preference_plan(
&self,
plan: &GovernancePreferencePlan,
) -> Result<()>
pub async fn apply_governance_preference_plan( &self, plan: &GovernancePreferencePlan, ) -> Result<()>
Apply the seed/normalization write required by a sealed governance plan.
Sourcepub async fn ensure_run_policy_seed(&self) -> Result<()>
pub async fn ensure_run_policy_seed(&self) -> Result<()>
Seed only the run_policy namespace (type + run_policy.global default),
idempotently.
The embedded runtime has no AppConfig to run the full Self::initialize
bootstrap, but it still needs the Global run policy row to exist so hosts
can read and write run_policy.global. This registers the same canonical
schema and inherit-everything default that Self::initialize seeds, and
(via Self::register_extension) inserts the default only when the row is
absent — so it never clobbers a value already written by a host.
§Errors
Returns an error if the underlying persistence upsert of the settings type or default value fails.
Sourcepub async fn register_extension(
&self,
settings_type: SettingsType,
defaults: Vec<Settings>,
) -> Result<()>
pub async fn register_extension( &self, settings_type: SettingsType, defaults: Vec<Settings>, ) -> Result<()>
Register a new settings domain from a plugin or extension.
This is the only entry point extensions need. They never touch the
persistence layer directly. The schema field of settings_type must be
a valid JSON Schema (Draft 7); defaults provides initial values.
Sourcepub async fn get_value(&self, key: &str) -> Option<Value>
pub async fn get_value(&self, key: &str) -> Option<Value>
Get a raw JSON value by dotted key — cache-first, then DB fallback.
Sourcepub async fn get_typed<T: DeserializeOwned>(
&self,
key: &str,
) -> Result<Option<T>>
pub async fn get_typed<T: DeserializeOwned>( &self, key: &str, ) -> Result<Option<T>>
Deserialise a typed value by key.
Sourcepub async fn get_typed_for_admission<T: DeserializeOwned>(
&self,
key: &str,
) -> Result<Option<T>>
pub async fn get_typed_for_admission<T: DeserializeOwned>( &self, key: &str, ) -> Result<Option<T>>
Read an admission policy without treating failed storage as a missing key. The configured cache remains authoritative when the key is present.
§Errors
Propagates fallback storage errors and invalid serialized values.
Sourcepub async fn update_presentation_assignment(
&self,
expected: &Value,
selection: &ResourceSelection,
) -> Result<Option<Value>>
pub async fn update_presentation_assignment( &self, expected: &Value, selection: &ResourceSelection, ) -> Result<Option<Value>>
Conditionally update only Presentation intent, without replacing other policy fields.
Sourcepub async fn set_value(&self, key: &str, value: Value) -> Result<()>
pub async fn set_value(&self, key: &str, value: Value) -> Result<()>
Set a setting value via the API. The write is validated against the type’s JSON Schema before being persisted.
Sourcepub async fn set_governance_batch(
&self,
values: HashMap<String, Value>,
) -> Vec<GovernanceMutationResult>
pub async fn set_governance_batch( &self, values: HashMap<String, Value>, ) -> Vec<GovernanceMutationResult>
Apply one complete Governance namespace submission under the namespace mutex.
Sourcepub async fn list_drift(&self) -> Vec<SettingsWithMeta>
pub async fn list_drift(&self) -> Vec<SettingsWithMeta>
List all settings that are currently flagged as drifted.
Sourcepub async fn list_all_with_meta(&self) -> Vec<SettingsWithMeta>
pub async fn list_all_with_meta(&self) -> Vec<SettingsWithMeta>
List all settings with their transient metadata (for the REST API).
Sourcepub async fn list_namespace_with_meta(
&self,
type_key: &str,
) -> Vec<SettingsWithMeta>
pub async fn list_namespace_with_meta( &self, type_key: &str, ) -> Vec<SettingsWithMeta>
List settings for a specific namespace (type key prefix).
Sourcepub async fn get_with_meta(&self, key: &str) -> Option<SettingsWithMeta>
pub async fn get_with_meta(&self, key: &str) -> Option<SettingsWithMeta>
Get a single setting with its metadata.
Sourcepub async fn reset_to_default(&self, key: &str) -> Result<()>
pub async fn reset_to_default(&self, key: &str) -> Result<()>
Reset a setting to its compiled-in default by deleting the DB override.
On next boot, initialize() will reseed the default from config.
Sourcepub async fn list_types(&self) -> Result<Vec<SettingsType>>
pub async fn list_types(&self) -> Result<Vec<SettingsType>>
List all registered settings types.
Sourcepub async fn get_type(&self, key: &str) -> Result<Option<SettingsType>>
pub async fn get_type(&self, key: &str) -> Result<Option<SettingsType>>
Get a settings type by key.
Sourcepub async fn seed_providers_from_registry(
&self,
registry: &ProviderRegistry,
) -> Result<usize>
pub async fn seed_providers_from_registry( &self, registry: &ProviderRegistry, ) -> Result<usize>
Seed the env/YAML/CLI-configured providers (held in the in-memory
[ProviderRegistry] after seed_from_llm_config / seed_from_configs)
into the DB on first boot, then persist the default provider id.
Source-of-truth rule: DB-wins-after-first-boot. A provider whose Seed configured providers from the registry into the settings DB.
UAR storage is authoritative after the first successful write. Existing rows are deliberately preserved so credentials, endpoint overrides, provider enablement, and per-model enablement survive restarts.
Call this AFTER Self::initialize and BEFORE
hydrate_provider_registry_from_settings.
Sourcepub async fn upsert_provider_config(
&self,
config: &ProviderConfig,
) -> Result<()>
pub async fn upsert_provider_config( &self, config: &ProviderConfig, ) -> Result<()>
Upsert a full provider configuration to provider.{id} (insert or update).
Unlike Self::set_value, this does not require a pre-existing row: new
providers created only via the API are inserted on first save.
Sourcepub async fn delete_provider_config(&self, provider_id: &str) -> Result<()>
pub async fn delete_provider_config(&self, provider_id: &str) -> Result<()>
Remove provider.{id} from the database and cache.
Sourcepub async fn load_provider_configs_from_db(&self) -> Result<Vec<ProviderConfig>>
pub async fn load_provider_configs_from_db(&self) -> Result<Vec<ProviderConfig>>
Load all persisted provider configs from the database.
Sourcepub async fn set_default_provider_id(&self, provider_id: &str) -> Result<()>
pub async fn set_default_provider_id(&self, provider_id: &str) -> Result<()>
Persist the default provider id (llm.default_provider).
Sourcepub async fn get_default_provider_id(&self) -> Option<String>
pub async fn get_default_provider_id(&self) -> Option<String>
Read the persisted default provider id, if any.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for SettingsManager
impl !RefUnwindSafe for SettingsManager
impl !UnwindSafe for SettingsManager
impl Send for SettingsManager
impl Sync for SettingsManager
impl Unpin for SettingsManager
impl UnsafeUnpin for SettingsManager
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
U: Sized,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
U: Sized,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreimpl<T> AsyncFriendly for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Conv for T
impl<T> Conv for T
impl<T> ErasedDestructor for Twhere
T: 'static,
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].impl<T> MaybeSend for Twhere
T: Send,
impl<T> MaybeSend for Twhere
T: Send,
§impl<T> Message for T
impl<T> Message for T
§fn from_boxed(m: BoxedMessage) -> Result<Self, BoxedDowncastErr>
fn from_boxed(m: BoxedMessage) -> Result<Self, BoxedDowncastErr>
§fn box_message(self, pid: &ActorId) -> Result<BoxedMessage, BoxedDowncastErr>
fn box_message(self, pid: &ActorId) -> Result<BoxedMessage, BoxedDowncastErr>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Pointee for T
impl<T> Pointee for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<F, T, S> SimdInto<T, S> for Fwhere
T: SimdFrom<F, S>,
S: Simd,
impl<F, T, S> SimdInto<T, S> for Fwhere
T: SimdFrom<F, S>,
S: Simd,
impl<T> State for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.