Skip to main content

arkhe_kernel/state/
config.rs

1//! `InstanceConfig` — caller-supplied per-instance configuration.
2//!
3//! `EffectiveConfig` (parent-derived bounds, A10 — every quota = min(parent,
4//! requested)) is composed at `Kernel::create_instance` time when parent ↔
5//! child relationships are wired.
6
7use serde::{Deserialize, Serialize};
8
9use crate::abi::{CapabilityMask, InstanceId};
10use crate::state::quota::QuotaReductionPolicy;
11
12/// Per-instance configuration supplied at `Kernel::create_instance`.
13/// All fields are pub — `InstanceConfig { field: ..., ..Default::default() }`
14/// is the idiomatic construction pattern.
15#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
16pub struct InstanceConfig {
17    /// Capability mask the kernel uses when authorizing actions
18    /// submitted under `Principal::System` from kernel-internal paths.
19    pub default_caps: CapabilityMask,
20    /// Hard upper bound on entities (0 = unlimited).
21    pub max_entities: u32,
22    /// Hard upper bound on scheduled actions (0 = unlimited).
23    pub max_scheduled: u32,
24    /// Component byte ceiling enforced per-Op in `step()`.
25    /// `0` = unlimited (default). When `> 0`, an Op whose projected
26    /// post-commit total exceeds this is denied per-Op (`EffectFailed`)
27    /// without rolling back sibling Ops.
28    pub memory_budget_bytes: u64,
29    /// Parent `InstanceId` for hierarchical quota enforcement
30    /// (`apply_quota_reduction`); `None` for root instances.
31    pub parent: Option<InstanceId>,
32    /// Policy applied when a parent's quota would drop below current
33    /// child aggregate usage. See [`QuotaReductionPolicy`].
34    pub quota_reduction: QuotaReductionPolicy,
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn config_default_is_zero_quota_reject_policy() {
43        let c = InstanceConfig::default();
44        assert_eq!(c.max_entities, 0);
45        assert_eq!(c.max_scheduled, 0);
46        assert_eq!(c.memory_budget_bytes, 0);
47        assert!(c.parent.is_none());
48        assert_eq!(c.quota_reduction, QuotaReductionPolicy::Reject);
49        assert!(c.default_caps.is_empty());
50    }
51
52    #[test]
53    fn config_clone_eq() {
54        let c1 = InstanceConfig {
55            default_caps: CapabilityMask::SYSTEM,
56            max_entities: 10,
57            max_scheduled: 100,
58            memory_budget_bytes: 1024,
59            parent: InstanceId::new(7),
60            quota_reduction: QuotaReductionPolicy::ThrottleProportional,
61        };
62        let c2 = c1.clone();
63        assert_eq!(c1, c2);
64    }
65
66    #[test]
67    fn config_field_assignment() {
68        let c = InstanceConfig {
69            max_entities: 42,
70            parent: InstanceId::new(3),
71            quota_reduction: QuotaReductionPolicy::GrandfatherExisting,
72            ..Default::default()
73        };
74        assert_eq!(c.max_entities, 42);
75        assert_eq!(c.parent, InstanceId::new(3));
76        assert_eq!(c.quota_reduction, QuotaReductionPolicy::GrandfatherExisting);
77    }
78}