Skip to main content

telltale_machine/
capabilities.rs

1//! Canonical protocol-critical capability taxonomy and boundary ledger.
2//!
3//! This module is the source-of-truth boundary for Telltale's capability model.
4//! It classifies the protocol-critical capability surfaces that already exist
5//! across runtime admission, session ownership, semantic evidence/finalization,
6//! and explicit transition artifacts.
7
8use serde::{Deserialize, Serialize};
9
10/// Canonical capability class for one protocol-critical surface.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum ProtocolCriticalCapabilityClass {
14    /// Admission/profile/runtime-mode capability.
15    Admission,
16    /// Live session or fragment authority.
17    Ownership,
18    /// Evidence-bearing or finalization-bearing justification object.
19    Evidence,
20    /// Explicit handoff, cutover, or reconfiguration transition object.
21    Transition,
22}
23
24/// Lifecycle state shared by first-class capability and evidence objects.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
26#[serde(rename_all = "snake_case")]
27pub enum ProtocolCriticalCapabilityLifecycleState {
28    /// Object was issued and is available for a later semantic step.
29    Issued,
30    /// Object was consumed exactly once on its sanctioned path.
31    Consumed,
32    /// Object was rejected as invalid, insufficient, or unauthorized.
33    Rejected,
34    /// Object became unusable because later semantic state revoked it.
35    Invalidated,
36    /// Transition object committed and became canonical.
37    Committed,
38    /// Transition object rolled back and did not become canonical.
39    RolledBack,
40    /// Object aged out of its validity window.
41    Expired,
42}
43
44/// Canonical first-class artifact carried by the capability/evidence lifecycle audit.
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46pub enum ProtocolCriticalCapabilityArtifact {
47    /// Live ownership capability for one session or fragment.
48    OwnershipCapability(crate::session::OwnershipCapability),
49    /// Explicit ownership-transfer receipt.
50    OwnershipReceipt(crate::session::OwnershipReceipt),
51    /// Readiness witness for one protocol-critical check.
52    ReadinessWitness(crate::session::ReadinessWitness),
53    /// Cancellation witness for one terminated ownership path.
54    CancellationWitness(crate::session::CancellationWitness),
55    /// Timeout witness for one topology timeout.
56    TimeoutWitness(crate::session::TimeoutWitness),
57    /// Explicit delegation/handoff receipt.
58    DelegationReceipt(crate::transfer_semantics::DelegationReceipt),
59}
60
61impl ProtocolCriticalCapabilityArtifact {
62    /// Canonical capability class for this artifact.
63    #[must_use]
64    pub fn class(&self) -> ProtocolCriticalCapabilityClass {
65        match self {
66            Self::OwnershipCapability(_) => ProtocolCriticalCapabilityClass::Ownership,
67            Self::OwnershipReceipt(_) | Self::DelegationReceipt(_) => {
68                ProtocolCriticalCapabilityClass::Transition
69            }
70            Self::ReadinessWitness(_) | Self::CancellationWitness(_) | Self::TimeoutWitness(_) => {
71                ProtocolCriticalCapabilityClass::Evidence
72            }
73        }
74    }
75}
76
77/// Stable lifecycle audit record for first-class capability/evidence objects.
78#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
79pub struct ProtocolCriticalCapabilityLifecycleRecord {
80    /// Runtime tick associated with the lifecycle event, when available.
81    pub tick: Option<u64>,
82    /// Artifact whose lifecycle changed.
83    pub artifact: ProtocolCriticalCapabilityArtifact,
84    /// Lifecycle state reached by the artifact.
85    pub lifecycle: ProtocolCriticalCapabilityLifecycleState,
86    /// Optional rejection/rollback/invalidity reason.
87    pub reason: Option<String>,
88}
89
90fn from_authority_audit_record(
91    record: &crate::session::AuthorityAuditRecord,
92) -> ProtocolCriticalCapabilityLifecycleRecord {
93    use crate::session::AuthorityArtifact;
94    let artifact = match &record.artifact {
95        AuthorityArtifact::OwnershipCapability(capability) => {
96            ProtocolCriticalCapabilityArtifact::OwnershipCapability(capability.clone())
97        }
98        AuthorityArtifact::OwnershipReceipt(receipt) => {
99            ProtocolCriticalCapabilityArtifact::OwnershipReceipt(receipt.clone())
100        }
101        AuthorityArtifact::Readiness(witness) => {
102            ProtocolCriticalCapabilityArtifact::ReadinessWitness(witness.clone())
103        }
104        AuthorityArtifact::Cancellation(witness) => {
105            ProtocolCriticalCapabilityArtifact::CancellationWitness(witness.clone())
106        }
107        AuthorityArtifact::Timeout(witness) => {
108            ProtocolCriticalCapabilityArtifact::TimeoutWitness(witness.clone())
109        }
110    };
111
112    ProtocolCriticalCapabilityLifecycleRecord {
113        tick: record.tick,
114        artifact,
115        lifecycle: record.event.into(),
116        reason: record.reason.clone(),
117    }
118}
119
120fn from_delegation_audit_record(
121    record: &crate::transfer_semantics::DelegationAuditRecord,
122) -> ProtocolCriticalCapabilityLifecycleRecord {
123    let lifecycle = match record.status {
124        crate::transfer_semantics::DelegationStatus::Committed => {
125            ProtocolCriticalCapabilityLifecycleState::Committed
126        }
127        crate::transfer_semantics::DelegationStatus::RolledBack => {
128            ProtocolCriticalCapabilityLifecycleState::RolledBack
129        }
130    };
131    ProtocolCriticalCapabilityLifecycleRecord {
132        tick: Some(record.tick),
133        artifact: ProtocolCriticalCapabilityArtifact::DelegationReceipt(record.receipt.clone()),
134        lifecycle,
135        reason: record.reason.clone(),
136    }
137}
138
139/// Canonical lifecycle audit log for protocol-critical capabilities/evidence.
140#[must_use]
141pub fn capability_lifecycle_audit_log_v1(
142    authority_audit_log: &[crate::session::AuthorityAuditRecord],
143    delegation_audit_log: &[crate::transfer_semantics::DelegationAuditRecord],
144) -> Vec<ProtocolCriticalCapabilityLifecycleRecord> {
145    let mut records: Vec<_> = authority_audit_log
146        .iter()
147        .map(from_authority_audit_record)
148        .chain(
149            delegation_audit_log
150                .iter()
151                .map(from_delegation_audit_record),
152        )
153        .collect();
154    // Preserve the real intra-tick linearization from the underlying runtime
155    // logs instead of reconstructing a synthetic lifecycle order.
156    records.sort_by_key(|record| record.tick.unwrap_or(0));
157    records
158}
159
160/// One source-derived row in the protocol-critical capability boundary ledger.
161#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162pub struct ProtocolCriticalCapabilityBoundaryEntry {
163    /// Stable surface name used in docs and tests.
164    pub surface: String,
165    /// Canonical capability class for this surface.
166    pub class: ProtocolCriticalCapabilityClass,
167    /// Stable lifecycle states relevant to this surface.
168    pub lifecycle: Vec<ProtocolCriticalCapabilityLifecycleState>,
169    /// Rust module that owns the first-class surface today.
170    pub rust_module: String,
171    /// Lean module/theorem boundary that models or proves the surface today.
172    pub lean_module: String,
173    /// Short reason this surface is protocol-critical.
174    pub rationale: String,
175}
176
177fn entry(
178    surface: &str,
179    class: ProtocolCriticalCapabilityClass,
180    lifecycle: &[ProtocolCriticalCapabilityLifecycleState],
181    rust_module: &str,
182    lean_module: &str,
183    rationale: &str,
184) -> ProtocolCriticalCapabilityBoundaryEntry {
185    ProtocolCriticalCapabilityBoundaryEntry {
186        surface: surface.to_string(),
187        class,
188        lifecycle: lifecycle.to_vec(),
189        rust_module: rust_module.to_string(),
190        lean_module: lean_module.to_string(),
191        rationale: rationale.to_string(),
192    }
193}
194
195/// Source-derived protocol-critical capability boundary ledger.
196#[must_use]
197pub fn protocol_critical_capability_boundary() -> Vec<ProtocolCriticalCapabilityBoundaryEntry> {
198    use ProtocolCriticalCapabilityClass::{
199        Admission as AdmissionClass, Evidence as EvidenceClass, Ownership as OwnershipClass,
200        Transition as TransitionClass,
201    };
202    use ProtocolCriticalCapabilityLifecycleState::{
203        Committed, Consumed, Expired, Invalidated, Issued, Rejected, RolledBack,
204    };
205
206    vec![
207        entry(
208            "runtime_admission",
209            AdmissionClass,
210            &[Issued, Rejected],
211            "rust/machine/src/runtime_contracts.rs",
212            "lean/Runtime/Proofs/TheoremPack/AdmissionBoundary.lean",
213            "Admits or rejects runtime/profile execution before protocol-critical execution begins.",
214        ),
215        entry(
216            "theorem_pack_capabilities",
217            AdmissionClass,
218            &[Issued, Rejected],
219            "rust/machine/src/composition.rs",
220            "lean/Runtime/Proofs/TheoremPack/API.lean",
221            "Carries proof-backed eligibility that higher-level runtime admission consumes.",
222        ),
223        entry(
224            "ownership_capability",
225            OwnershipClass,
226            &[Issued, Invalidated, Expired, Rejected],
227            "rust/machine/src/session/overview.rs",
228            "lean/Runtime/Proofs/Conservation/Authority.lean",
229            "Proves which actor may currently mutate session-local protocol-critical state.",
230        ),
231        entry(
232            "readiness_witness",
233            EvidenceClass,
234            &[Issued, Consumed, Rejected, Invalidated, Expired],
235            "rust/machine/src/session/overview.rs",
236            "lean/Runtime/Proofs/AuthorityMetatheory.lean",
237            "Justifies a protocol-critical readiness decision under one live owner generation.",
238        ),
239        entry(
240            "authoritative_read",
241            EvidenceClass,
242            &[Issued, Consumed, Rejected],
243            "rust/machine/src/semantic_objects.rs",
244            "lean/Runtime/Proofs/Conservation/Evidence.lean",
245            "Carries evidence-bearing protocol input that may author canonical truth.",
246        ),
247        entry(
248            "materialization_proof",
249            EvidenceClass,
250            &[Issued, Consumed, Rejected],
251            "rust/machine/src/semantic_objects.rs",
252            "lean/Runtime/Proofs/Conservation/Evidence.lean",
253            "Witnesses proof-bearing success on the sanctioned materialization path.",
254        ),
255        entry(
256            "canonical_handle",
257            EvidenceClass,
258            &[Issued, Consumed, Rejected, Invalidated],
259            "rust/machine/src/semantic_objects.rs",
260            "lean/Runtime/Proofs/Conservation/Evidence.lean",
261            "Provides the strong reference required on parity-critical follow-on paths.",
262        ),
263        entry(
264            "ownership_receipt",
265            TransitionClass,
266            &[Issued, Committed, RolledBack, Rejected, Invalidated, Expired],
267            "rust/machine/src/session/overview.rs",
268            "lean/Runtime/Proofs/Conservation/Authority.lean",
269            "Stages and commits explicit ownership transfer rather than ambient authority mutation.",
270        ),
271        entry(
272            "semantic_handoff",
273            TransitionClass,
274            &[Committed, RolledBack, Rejected, Invalidated],
275            "rust/machine/src/semantic_objects.rs",
276            "lean/Runtime/Proofs/Conservation/Authority.lean",
277            "Represents explicit protocol-visible authority transfer and old-owner revocation.",
278        ),
279        entry(
280            "reconfiguration_transition",
281            TransitionClass,
282            &[Issued, Committed, RolledBack, Rejected],
283            "rust/machine/src/composition.rs",
284            "lean/Runtime/Proofs/ReconfigurationObserver.lean",
285            "Captures protocol-critical cutover and membership/runtime transition artifacts.",
286        ),
287    ]
288}
289
290/// Canonical Rust source-of-truth boundary for the first-class capability model.
291#[must_use]
292pub fn rust_first_class_capability_module_boundary() -> &'static [&'static str] {
293    &[
294        "rust/machine/src/capabilities.rs",
295        "rust/machine/src/runtime_contracts.rs",
296        "rust/machine/src/session/overview.rs",
297        "rust/machine/src/semantic_objects.rs",
298        "rust/machine/src/composition.rs",
299    ]
300}
301
302/// Canonical Lean theorem/model boundary for the first-class capability model.
303#[must_use]
304pub fn lean_first_class_capability_module_boundary() -> &'static [&'static str] {
305    &[
306        "lean/Runtime/Proofs/Capabilities.lean",
307        "lean/Runtime/Proofs/AuthorityMetatheory.lean",
308        "lean/Runtime/Proofs/Conservation/Authority.lean",
309        "lean/Runtime/Proofs/Conservation/Evidence.lean",
310        "lean/Runtime/Proofs/ReconfigurationObserver.lean",
311        "lean/Runtime/Proofs/TheoremPack/AdmissionBoundary.lean",
312    ]
313}
314
315#[cfg(test)]
316mod tests {
317    use super::*;
318
319    #[test]
320    fn capability_boundary_surfaces_are_unique_and_classified() {
321        let boundary = protocol_critical_capability_boundary();
322        assert!(
323            !boundary.is_empty(),
324            "protocol-critical capability boundary should not be empty"
325        );
326
327        let mut surfaces = std::collections::BTreeSet::new();
328        for entry in &boundary {
329            assert!(
330                surfaces.insert(entry.surface.as_str()),
331                "duplicate capability boundary surface: {}",
332                entry.surface
333            );
334            assert!(
335                !entry.lifecycle.is_empty(),
336                "capability surface must declare lifecycle states: {}",
337                entry.surface
338            );
339            assert!(
340                !entry.rust_module.is_empty() && !entry.lean_module.is_empty(),
341                "capability surface must declare both Rust and Lean boundaries: {}",
342                entry.surface
343            );
344        }
345    }
346
347    #[test]
348    fn capability_boundaries_cover_all_four_classes() {
349        let classes: std::collections::BTreeSet<_> = protocol_critical_capability_boundary()
350            .into_iter()
351            .map(|entry| entry.class)
352            .collect();
353        assert_eq!(
354            classes,
355            [
356                ProtocolCriticalCapabilityClass::Admission,
357                ProtocolCriticalCapabilityClass::Ownership,
358                ProtocolCriticalCapabilityClass::Evidence,
359                ProtocolCriticalCapabilityClass::Transition,
360            ]
361            .into_iter()
362            .collect()
363        );
364    }
365}