Skip to main content

liminal_protocol/wire/
closure.rs

1use crate::algebra::{ResourceDimension, ResourceVector, WideResourceVector};
2
3use super::{
4    AttachEnvelope, BindingEpoch, DeliverySeq, EnrollmentEnvelope, LeaveEnvelope, ParticipantId,
5    RecordAdmissionEnvelope, RepaymentEdgeTag,
6};
7
8/// Participant-cursor-progress edge payload on the wire.
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub struct ParticipantCursorProgressEdge {
11    /// Participant whose cursor is the witness.
12    pub participant_id: ParticipantId,
13    /// Binding epoch that received the relevant suffix or marker.
14    pub binding_epoch: BindingEpoch,
15    /// Continuous cursor boundary witness.
16    pub through_seq: DeliverySeq,
17    /// Exact delivered marker when marker acknowledgement is required.
18    pub marker_delivery_seq: Option<DeliverySeq>,
19}
20
21/// Clear state or one of the seven stored repayment edges.
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum RepaymentEdge {
24    /// No edge; legal only at zero debt.
25    None,
26    /// Observer projection through an exact sequence.
27    ObserverProjection {
28        /// Required observer boundary.
29        through_seq: DeliverySeq,
30    },
31    /// Physical compaction of an exact retained range.
32    PhysicalCompaction {
33        /// First retained sequence before completion.
34        from_floor: DeliverySeq,
35        /// Inclusive sequence that must be compacted.
36        through_seq: DeliverySeq,
37    },
38    /// Delivery of an exact marker to an exact binding.
39    MarkerDelivery {
40        /// Affected participant.
41        participant_id: ParticipantId,
42        /// Binding epoch that must receive the marker.
43        binding_epoch: BindingEpoch,
44        /// Marker sequence.
45        marker_delivery_seq: DeliverySeq,
46    },
47    /// Participant cursor or marker progress.
48    ParticipantCursorProgress(ParticipantCursorProgressEdge),
49    /// Fenced detached credential recovery.
50    DetachedCredentialRecovery {
51        /// Detached participant.
52        participant_id: ParticipantId,
53        /// Delivered marker anchoring recovery.
54        marker_delivery_seq: DeliverySeq,
55        /// Prior dead binding epoch.
56        prior_binding_epoch: BindingEpoch,
57    },
58    /// Leave-only release of an undelivered marker.
59    DetachedMarkerRelease {
60        /// Detached participant.
61        participant_id: ParticipantId,
62        /// Undelivered marker anchor.
63        marker_delivery_seq: DeliverySeq,
64        /// Last dead binding epoch.
65        last_dead_binding_epoch: BindingEpoch,
66    },
67    /// Leave-only release of a detached cursor witness.
68    DetachedCursorRelease {
69        /// Detached participant.
70        participant_id: ParticipantId,
71        /// Last dead binding epoch.
72        last_dead_binding_epoch: BindingEpoch,
73    },
74}
75
76impl RepaymentEdge {
77    /// Returns the stable tagged-union selector.
78    #[must_use]
79    pub const fn tag(self) -> RepaymentEdgeTag {
80        match self {
81            Self::None => RepaymentEdgeTag::None,
82            Self::ObserverProjection { .. } => RepaymentEdgeTag::ObserverProjection,
83            Self::PhysicalCompaction { .. } => RepaymentEdgeTag::PhysicalCompaction,
84            Self::MarkerDelivery { .. } => RepaymentEdgeTag::MarkerDelivery,
85            Self::ParticipantCursorProgress(_) => RepaymentEdgeTag::ParticipantCursorProgress,
86            Self::DetachedCredentialRecovery { .. } => RepaymentEdgeTag::DetachedCredentialRecovery,
87            Self::DetachedMarkerRelease { .. } => RepaymentEdgeTag::DetachedMarkerRelease,
88            Self::DetachedCursorRelease { .. } => RepaymentEdgeTag::DetachedCursorRelease,
89        }
90    }
91}
92
93/// Exact common envelope alternatives for closure-checked operations.
94#[derive(Clone, Debug, PartialEq, Eq)]
95pub enum ClosureCheckedEnvelope {
96    /// Enrollment admission.
97    Enrollment(EnrollmentEnvelope),
98    /// Credential attach or supersession.
99    CredentialAttach(AttachEnvelope),
100    /// Live or detached terminal Leave.
101    Leave(LeaveEnvelope),
102    /// Ordinary record admission.
103    RecordAdmission(RecordAdmissionEnvelope),
104}
105
106/// Unchanged-prestate suffix shared by every closure refusal scope.
107#[derive(Clone, Copy, Debug, PartialEq, Eq)]
108pub struct ClosureSnapshot {
109    /// Identity slots currently owning marker capacity credits.
110    pub marker_capacity_credits: u64,
111    /// Live marker anchors.
112    pub marker_anchors: u64,
113    /// Entry debt.
114    pub entry_debt: u64,
115    /// Byte debt.
116    pub byte_debt: u64,
117    /// Current clear/edge state.
118    pub repayment_edge: RepaymentEdge,
119    /// Sequence claims owned by the current edge.
120    pub edge_sequence_claims: u64,
121    /// Admission-order position claims owned by the current edge.
122    pub edge_order_position_claims: u64,
123    /// Exact current edge recovery-claim occupancy.
124    pub edge_k_remaining: ResourceVector,
125    /// Exact componentwise `cap - B` headroom.
126    pub k_headroom: WideResourceVector,
127    /// Activated churn cycles already used.
128    ///
129    /// This is a protocol count and therefore uses the frozen primitive
130    /// register's `u64` width. R-C4's tighter `u32::MAX` bound constrains valid
131    /// values but does not narrow their serialized representation.
132    pub episode_churn_used: u64,
133    /// Churn cycles this transaction would add.
134    pub delta_cycles: u64,
135    /// Configured episode churn limit in the protocol's `u64` limit domain.
136    pub episode_churn_limit: u64,
137}
138
139/// Capacity-specific closure refusal suffix.
140#[derive(Clone, Copy, Debug, PartialEq, Eq)]
141pub struct ClosureCapacityReason {
142    /// First failing component.
143    pub dimension: ResourceDimension,
144    /// Simulated maximum required amount.
145    pub required: u128,
146    /// Configured component limit.
147    pub limit: u128,
148}
149
150/// Exact closure refusal tagged body; no optional capacity field bag exists.
151#[derive(Clone, Copy, Debug, PartialEq, Eq)]
152pub enum ClosureRefusalReason {
153    /// Componentwise entry or byte capacity failure.
154    Capacity(ClosureCapacityReason),
155    /// Recovery would violate the current detached edge fence.
156    RecoveryFence,
157    /// A delivered marker still awaits acknowledgement.
158    DeliveredMarkerAwaitingAck,
159    /// Optional lifecycle churn would exceed the episode limit.
160    EpisodeChurnLimit,
161}
162
163/// Complete marker-closure capacity outcome payload.
164#[derive(Clone, Debug, PartialEq, Eq)]
165pub struct MarkerClosureCapacityExceeded {
166    /// Exact triggering request envelope.
167    pub request: ClosureCheckedEnvelope,
168    /// Unchanged closure state disclosed by the outcome.
169    pub snapshot: ClosureSnapshot,
170    /// Selected exact scope and scope-specific suffix.
171    pub reason: ClosureRefusalReason,
172}