Skip to main content

agentic_identity/spawn/
types.rs

1//! Data structures for identity inheritance (spawn).
2
3use serde::{Deserialize, Serialize};
4
5use crate::identity::IdentityId;
6use crate::receipt::ReceiptId;
7use crate::trust::Capability;
8
9// ---------------------------------------------------------------------------
10// Spawn Record
11// ---------------------------------------------------------------------------
12
13/// Unique identifier for a spawn record.
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
15pub struct SpawnId(pub String);
16
17impl std::fmt::Display for SpawnId {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        write!(f, "{}", self.0)
20    }
21}
22
23/// Record of a child identity being spawned.
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct SpawnRecord {
26    pub id: SpawnId,
27    pub parent_id: IdentityId,
28    pub parent_key: String,
29    pub child_id: IdentityId,
30    pub child_key: String,
31    pub spawn_timestamp: u64,
32    pub spawn_type: SpawnType,
33    pub spawn_purpose: String,
34    pub spawn_receipt_id: ReceiptId,
35    pub authority_granted: Vec<Capability>,
36    pub authority_ceiling: Vec<Capability>,
37    pub lifetime: SpawnLifetime,
38    pub constraints: SpawnConstraints,
39    pub parent_signature: String,
40    pub child_acknowledgment: Option<String>,
41    pub terminated: bool,
42    pub terminated_at: Option<u64>,
43    pub termination_reason: Option<String>,
44}
45
46// ---------------------------------------------------------------------------
47// Spawn Type
48// ---------------------------------------------------------------------------
49
50/// Type of spawned identity.
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
52pub enum SpawnType {
53    /// Temporary, task-specific worker.
54    Worker,
55    /// Acts on behalf of parent with delegated authority.
56    Delegate,
57    /// Full copy of parent's authority (within ceiling).
58    Clone,
59    /// Subset of capabilities for a specific domain.
60    Specialist,
61    /// Custom spawn type.
62    Custom(String),
63}
64
65impl SpawnType {
66    /// Return a stable string tag.
67    pub fn as_tag(&self) -> &str {
68        match self {
69            Self::Worker => "worker",
70            Self::Delegate => "delegate",
71            Self::Clone => "clone",
72            Self::Specialist => "specialist",
73            Self::Custom(s) => s.as_str(),
74        }
75    }
76}
77
78// ---------------------------------------------------------------------------
79// Spawn Lifetime
80// ---------------------------------------------------------------------------
81
82/// Lifetime of a spawned identity.
83#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
84pub enum SpawnLifetime {
85    /// No expiration.
86    Indefinite,
87    /// Expires after a duration (seconds).
88    Duration { seconds: u64 },
89    /// Expires at a specific timestamp (microseconds since epoch).
90    Until { timestamp: u64 },
91    /// Expires when a specific task is completed.
92    TaskCompletion { task_id: String },
93    /// Expires when the parent is terminated.
94    ParentTermination,
95}
96
97impl SpawnLifetime {
98    /// Return a stable string tag.
99    pub fn as_tag(&self) -> &str {
100        match self {
101            Self::Indefinite => "indefinite",
102            Self::Duration { .. } => "duration",
103            Self::Until { .. } => "until",
104            Self::TaskCompletion { .. } => "task_completion",
105            Self::ParentTermination => "parent_termination",
106        }
107    }
108
109    /// Check if the lifetime has expired.
110    pub fn is_expired(&self, spawn_timestamp: u64) -> bool {
111        let now = crate::time::now_micros();
112        match self {
113            Self::Indefinite => false,
114            Self::Duration { seconds } => now > spawn_timestamp + (seconds * 1_000_000),
115            Self::Until { timestamp } => now > *timestamp,
116            Self::TaskCompletion { .. } => false, // Cannot determine from timestamp alone
117            Self::ParentTermination => false,     // Cannot determine without parent state
118        }
119    }
120}
121
122// ---------------------------------------------------------------------------
123// Spawn Constraints
124// ---------------------------------------------------------------------------
125
126/// Constraints on a spawned identity.
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct SpawnConstraints {
129    /// Maximum depth in the spawn tree (None = unlimited).
130    pub max_spawn_depth: Option<u32>,
131    /// Maximum number of direct children (None = unlimited).
132    pub max_children: Option<u32>,
133    /// Maximum number of total descendants (None = unlimited).
134    pub max_descendants: Option<u64>,
135    /// Whether this identity can spawn children.
136    pub can_spawn: bool,
137    /// Authority decay factor per generation (None = no decay).
138    /// Value between 0.0 and 1.0 — multiplied against parent authority.
139    pub authority_decay: Option<f32>,
140}
141
142impl Default for SpawnConstraints {
143    fn default() -> Self {
144        Self {
145            max_spawn_depth: Some(10),
146            max_children: None,
147            max_descendants: None,
148            can_spawn: true,
149            authority_decay: None,
150        }
151    }
152}
153
154// ---------------------------------------------------------------------------
155// Spawn Info (attached to spawned identity)
156// ---------------------------------------------------------------------------
157
158/// Information about a spawn attached to the child identity.
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct SpawnInfo {
161    pub spawn_id: SpawnId,
162    pub parent_id: IdentityId,
163    pub spawn_type: SpawnType,
164    pub spawn_timestamp: u64,
165    pub authority_ceiling: Vec<Capability>,
166    pub lifetime: SpawnLifetime,
167    pub constraints: SpawnConstraints,
168}
169
170// ---------------------------------------------------------------------------
171// Lineage
172// ---------------------------------------------------------------------------
173
174/// Lineage information for an identity.
175#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct Lineage {
177    pub identity: IdentityId,
178    pub root_ancestor: IdentityId,
179    pub parent_chain: Vec<IdentityId>,
180    pub spawn_depth: u32,
181    pub sibling_index: u32,
182    pub total_siblings: u32,
183}
184
185/// Result of verifying an identity's lineage.
186#[derive(Debug, Clone)]
187pub struct LineageVerification {
188    pub identity: IdentityId,
189    pub lineage_valid: bool,
190    pub all_ancestors_active: bool,
191    pub effective_authority: Vec<Capability>,
192    pub spawn_depth: u32,
193    pub revoked_ancestor: Option<IdentityId>,
194    pub is_valid: bool,
195    pub verified_at: u64,
196    pub errors: Vec<String>,
197}