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}