Skip to main content

behavior/effects/
sending.rs

1//! Typed send effects, their composition contract, and event ownership.
2
3use crate::{
4    Behavior, BirthProtocol, BirthProtocolProduct, ChildDelivery, ChildInput, ComposedEvent,
5    Delivery, EstablishedDelivery, InjectEvent, Inside, NoBirthProtocols, Protocol,
6    RecipientAddress,
7};
8use core::future::{self, Future};
9use std::vec;
10
11/// Total settlement of one statically selected action item.
12///
13/// Rejection and dependency blocking retain the complete original item.
14/// Interpreter corruption does the same. Accepted items are consumed and leave
15/// only the capability's promised receipt. Whether an item was attempted at all
16/// belongs to [`SettledItem`], so a concrete interpreter cannot fabricate that
17/// product-level fact.
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub enum ItemSettlement<Item, Accepted, Rejection, Prerequisite> {
20    /// The capability consumed the item and returned its promised receipt.
21    Accepted(Accepted),
22    /// The capability lawfully rejected the complete item.
23    Rejected { item: Item, reason: Rejection },
24    /// A declared prerequisite did not commit, so the item remains untouched.
25    Blocked {
26        item: Item,
27        prerequisite: Prerequisite,
28    },
29    /// The interpreter violated its contract while the item remained owned.
30    Corrupt { item: Item, fault: InterpreterFault },
31}
32
33/// Product-owned evidence that an action item was attempted or left untouched.
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35pub enum SettledItem<Item, Settlement> {
36    /// The concrete interpreter returned the item's complete settlement.
37    Attempted(Settlement),
38    /// Product traversal stopped at an earlier corrupt item.
39    Unattempted(Item),
40}
41
42/// Completion state of one total static product traversal.
43///
44/// Both variants own the complete settlement shape. `Corrupt` contains the
45/// factual committed prefix, the exact corrupt item, and every later item as
46/// [`SettledItem::Unattempted`].
47#[derive(Clone, Copy, Debug, Eq, PartialEq)]
48pub enum Interpretation<Settlement> {
49    Complete(Settlement),
50    Corrupt(Settlement),
51}
52
53impl<Settlement> Interpretation<Settlement> {
54    /// Transform the complete settlement shape without changing whether the
55    /// interpreter completed or corrupted.
56    #[must_use]
57    pub fn map<Mapped>(self, map: impl FnOnce(Settlement) -> Mapped) -> Interpretation<Mapped> {
58        match self {
59            Self::Complete(settlement) => Interpretation::Complete(map(settlement)),
60            Self::Corrupt(settlement) => Interpretation::Corrupt(map(settlement)),
61        }
62    }
63
64    /// Recover the complete owned settlement shape.
65    #[must_use]
66    pub fn into_settlement(self) -> Settlement {
67        match self {
68            Self::Complete(settlement) | Self::Corrupt(settlement) => settlement,
69        }
70    }
71}
72
73/// Read-only control-flow status of one complete retained settlement product.
74#[derive(Clone, Copy, Debug, Eq, PartialEq)]
75pub enum SettlementStatus {
76    /// Every item was attempted and accepted.
77    Accepted,
78    /// At least one item was lawfully rejected or blocked and none corrupted.
79    Rejected,
80    /// Interpretation corrupted or left an unattempted suffix.
81    Corrupt,
82}
83
84impl SettlementStatus {
85    #[must_use]
86    pub const fn combine(self, later: Self) -> Self {
87        match (self, later) {
88            (Self::Corrupt, _) | (_, Self::Corrupt) => Self::Corrupt,
89            (Self::Rejected, _) | (_, Self::Rejected) => Self::Rejected,
90            (Self::Accepted, Self::Accepted) => Self::Accepted,
91        }
92    }
93}
94
95/// Lossless status projection over an exact retained settlement value.
96pub trait ClassifySettlement {
97    /// Inspect every member without consuming or rewriting the settlement.
98    fn settlement_status(&self) -> SettlementStatus;
99}
100
101impl<Item, Accepted, Rejection, Prerequisite> ClassifySettlement
102    for ItemSettlement<Item, Accepted, Rejection, Prerequisite>
103{
104    fn settlement_status(&self) -> SettlementStatus {
105        match self {
106            Self::Accepted(_) => SettlementStatus::Accepted,
107            Self::Rejected { .. } | Self::Blocked { .. } => SettlementStatus::Rejected,
108            Self::Corrupt { .. } => SettlementStatus::Corrupt,
109        }
110    }
111}
112
113impl<Item, Settlement> ClassifySettlement for SettledItem<Item, Settlement>
114where
115    Settlement: ClassifySettlement,
116{
117    fn settlement_status(&self) -> SettlementStatus {
118        match self {
119            Self::Attempted(settlement) => settlement.settlement_status(),
120            Self::Unattempted(_) => SettlementStatus::Corrupt,
121        }
122    }
123}
124
125impl<Settlement> ClassifySettlement for Interpretation<Settlement>
126where
127    Settlement: ClassifySettlement,
128{
129    fn settlement_status(&self) -> SettlementStatus {
130        match self {
131            Self::Complete(settlement) => settlement.settlement_status(),
132            Self::Corrupt(_) => SettlementStatus::Corrupt,
133        }
134    }
135}
136
137impl<Settlement> ClassifySettlement for Vec<Settlement>
138where
139    Settlement: ClassifySettlement,
140{
141    fn settlement_status(&self) -> SettlementStatus {
142        let mut status = SettlementStatus::Accepted;
143        for settlement in self {
144            status = status.combine(settlement.settlement_status());
145        }
146        status
147    }
148}
149
150impl ClassifySettlement for crate::Never {
151    fn settlement_status(&self) -> SettlementStatus {
152        match *self {}
153    }
154}
155
156/// One concrete value that can occur in [`crate::Actions`].
157///
158/// The capability item owns its settlement vocabulary. Every conforming
159/// interpreter therefore agrees on the exact accepted receipt, rejection,
160/// and prerequisite types for that item. Interpreter corruption is the one
161/// shared [`InterpreterFault`] sum.
162///
163/// A runtime cannot substitute a different rejection type for the same item:
164///
165/// ```compile_fail,E0308
166/// struct Request;
167/// struct RequiredRejection;
168/// struct RuntimeRejection;
169/// impl behavior::ActionItem for Request {
170///     type Accepted = (); type Rejection = RequiredRejection; type Prerequisite = behavior::Never;
171///     type Custody = (Option<Self>, Option<Self::Reply>);
172///     type Input<'a> = &'a mut Option<Self> where Self: 'a;
173///     type Reply = behavior::ItemSettlement<Self, (), RequiredRejection, behavior::Never>;
174///     fn prepare_interpretation(progress: &mut Option<behavior::InterpretationProgress<Self, Self::Custody, Self::Reply>>) { behavior::prepare_item::<Self>(progress); }
175///     fn interpretation_input<'a>(custody: &'a mut Self::Custody) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)> where Self: 'a {
176///         let (input, received) = custody;
177///         match (&*input, &*received) { (Some(_), None) => Some((input, received)), _ => None }
178///     }
179///     fn finish_interpretation(progress: &mut Option<behavior::InterpretationProgress<Self, Self::Custody, Self::Reply>>) { behavior::finish_item::<Self>(progress); }
180/// }
181/// struct Runtime;
182/// impl behavior::InterpretItem<Request, (), behavior::Here> for Runtime {
183///     fn interpret_item<'a>(&'a mut self, input: &'a mut Option<Request>, received: &'a mut Option<<Request as behavior::ActionItem>::Reply>) -> impl core::future::Future<Output = ()> + Send + 'a where Request: 'a {
184///         async move {
185///             if received.is_some() { return; }
186///             let Some(item) = input.take() else { return; };
187///             *received = Some(behavior::ItemSettlement::Rejected { item, reason: RuntimeRejection });
188///         }
189///     }
190/// }
191/// ```
192pub trait ActionItem: Sized + Send {
193    type Accepted: Send;
194    type Rejection: Send;
195    type Prerequisite: Send;
196    type Custody;
197    type Input<'a>
198    where
199        Self: 'a;
200    type Reply;
201
202    fn prepare_interpretation(
203        progress: &mut Option<
204            InterpretationProgress<
205                Self,
206                Self::Custody,
207                ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>,
208            >,
209        >,
210    );
211    fn interpretation_input<'a>(
212        custody: &'a mut Self::Custody,
213    ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
214    where
215        Self: 'a;
216    fn finish_interpretation(
217        progress: &mut Option<
218            InterpretationProgress<
219                Self,
220                Self::Custody,
221                ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>,
222            >,
223        >,
224    );
225
226    /// Keep an accepted value only while it still carries terminal custody.
227    ///
228    /// The default discharges and destroys the receipt. An implementation
229    /// returning `Some` must return the same owned value on every later offer;
230    /// it must not perform an effect or consume authority still promised by
231    /// that value. This decision does not change settlement status.
232    fn retain_accepted(_: Self::Accepted) -> Option<Self::Accepted> {
233        None
234    }
235}
236
237/// Exact result of one action item within an interpreted action product.
238///
239/// The inner sum records the capability attempt. The outer sum preserves an
240/// untouched item when an earlier corrupt item stopped ordered traversal.
241pub type ActionItemResult<
242    Item,
243    Accepted = <Item as ActionItem>::Accepted,
244    Rejection = <Item as ActionItem>::Rejection,
245    Prerequisite = <Item as ActionItem>::Prerequisite,
246> = SettledItem<Item, ItemSettlement<Item, Accepted, Rejection, Prerequisite>>;
247
248/// A broken interpreter invariant, distinct from expected capability rejection.
249#[derive(Clone, Copy, Debug, Eq, PartialEq)]
250pub enum InterpreterFault {
251    MissingCapability,
252    CorruptTraversal,
253}
254
255/// Exact reason one structural parent report was not accepted.
256#[derive(Clone, Copy, Debug, Eq, PartialEq)]
257pub enum ParentReportReason {
258    ClosedParentControlLane,
259}
260
261/// Concrete interpreter ownership port for one exact typed action item.
262///
263/// `Item`, `RootEvent`, and `Path` select the capability statically. Distinct
264/// delivery and runtime-request values remain distinct implementations without
265/// an erased envelope, registry, or runtime lookup.
266pub trait InterpretItem<Item, RootEvent, Path>: Send
267where
268    Item: ActionItem,
269{
270    fn interpret_item<'a>(
271        &'a mut self,
272        input: Item::Input<'a>,
273        received: &'a mut Option<Item::Reply>,
274    ) -> impl Future<Output = ()> + Send + 'a
275    where
276        Item: 'a;
277}
278
279/// Caller-owned cold input, partial normal interpretation, or acquired result.
280///
281/// Partial custody retains all available typed facts across producer disposal.
282/// This is not source admission, native failure, or an actor protocol value.
283pub enum InterpretationProgress<Input, Custody, Settlement> {
284    Original(Input),
285    Interpreting(Custody),
286    Completed(Interpretation<Settlement>),
287}
288
289/// Static settlement product determined solely by one concrete sends value.
290///
291/// Every action item declares its own accepted, rejection, and prerequisite
292/// types. A containing product therefore has one settlement type under every
293/// conforming interpreter. `unattempted` preserves every item untouched after
294/// an earlier corrupt item stops traversal.
295///
296/// A runtime cannot select another settlement product for the same sends value:
297///
298/// ```compile_fail,E0308
299/// struct RuntimeSettlement;
300///
301/// fn runtime_selected<Runtime>(
302///     progress: &mut Option<behavior::InterpretationProgress<
303///         behavior::InterpreterRequests<behavior::ReportToParent<u8>>,
304///         <behavior::InterpreterRequests<behavior::ReportToParent<u8>> as
305///             behavior::SendSettlements>::InterpretationCustody,
306///         RuntimeSettlement,
307///     >>,
308///     runtime: &mut Runtime,
309/// ) -> impl core::future::Future<Output = ()> + Send
310/// where
311///     Runtime: behavior::InterpretItem<
312///         behavior::ReportToParent<u8>,
313///         (),
314///         behavior::Here,
315///     >,
316/// {
317///     <behavior::InterpreterRequests<behavior::ReportToParent<u8>> as
318///         behavior::InterpretSends<Runtime, (), behavior::Here>>::interpret(
319///             progress,
320///             runtime,
321///         )
322/// }
323/// ```
324pub trait SendSettlements: Sized {
325    type Settlements: Send + ClassifySettlement;
326    type SourceCustody: Send;
327    type InterpretationCustody;
328
329    fn prepare_interpretation(
330        progress: &mut Option<
331            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
332        >,
333    );
334    fn finish_interpretation(
335        progress: &mut Option<
336            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
337        >,
338    );
339    // Replaces consuming unattempted(self), so custom traversal does not own
340    // the parent's remaining sibling while other sibling facts stay acquired.
341    fn unattempted(
342        progress: &mut Option<
343            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
344        >,
345    );
346}
347
348/// Static interpretation of one complete sends value at an absolute event path.
349///
350/// Implementations are monomorphized over `Interpreter`; there is no erased
351/// envelope, runtime lane lookup, or downcast. `RootEvent` is the event type
352/// ultimately enqueued for the actor and `Path` is the current send owner's
353/// absolute position in it. Lawful rejection and blocking continue to later
354/// independent items. Corruption stops interpretation but retains the exact
355/// fault item and every untouched suffix value in the settlement shape.
356pub trait InterpretSends<Interpreter, RootEvent, Path>: SendSettlements + Send {
357    fn interpret(
358        progress: &mut Option<
359            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
360        >,
361        interpreter: &mut Interpreter,
362    ) -> impl Future<Output = ()> + Send;
363}
364
365/// The lane owned by the current named send product.
366pub enum Own {}
367
368/// Static evidence that a sends type contains one request lane.
369///
370/// Implementations append the input exactly once to that lane and leave every
371/// other lane unchanged. `Path` distinguishes repeated request types without
372/// erasing their position or choosing a lane at runtime.
373///
374/// [`Own`] selects a named product's own semantic lane. [`SendLayer`] carries
375/// wrapper-owned and inner effects as explicit named fields; request routing
376/// remains a compile-time proof rather than a runtime lane lookup.
377pub trait SendInput<Input, Path> {
378    fn emit(&mut self, input: Input);
379}
380
381/// Send effects emitted by a pure actor transition.
382///
383/// Values compose without interpreting them. This keeps communications and
384/// interpreter requests inside the explicit [`crate::Actions`] boundary.
385pub trait SendEffects: Sized {
386    fn empty() -> Self;
387    fn append(&mut self, other: Self);
388
389    #[must_use]
390    fn combine(mut self, other: Self) -> Self {
391        self.append(other);
392        self
393    }
394
395    /// Append one request to its statically selected semantic lane.
396    fn send<Input, Path>(&mut self, input: Input)
397    where
398        Self: SendInput<Input, Path>,
399    {
400        <Self as SendInput<Input, Path>>::emit(self, input);
401    }
402
403    /// Build a send product containing one request in its selected lane.
404    #[must_use]
405    fn sending<Input, Path>(input: Input) -> Self
406    where
407        Self: SendInput<Input, Path>,
408    {
409        let mut sends = Self::empty();
410        sends.send(input);
411        sends
412    }
413}
414
415/// Static projection of intentional logical destinations from one concrete
416/// sends product.
417///
418/// Implementations mirror the product's [`InterpretSends`] traversal without
419/// inspecting values. Only [`Delivery<P>`] contributes `P`; exact established
420/// deliveries, creator-local child deliveries and inputs, and interpreter
421/// requests contribute nothing. Named products append their field projections
422/// in interpretation order, preserving repeated protocol occurrences.
423///
424/// Custom named sends products must implement this trait explicitly. There is
425/// deliberately no blanket `Vec<T>` implementation that could silently treat
426/// an unknown delivery representation as having no logical destination.
427///
428/// ```compile_fail,E0277
429/// struct OpaqueSends;
430/// impl behavior::SendEffects for OpaqueSends {
431///     fn empty() -> Self { Self }
432///     fn append(&mut self, _: Self) {}
433/// }
434/// impl<E> behavior::SendsFor<E> for OpaqueSends {}
435/// struct Actor;
436/// impl behavior::Protocol for Actor { type Addr = behavior::MailAddr; type Msg = (); }
437/// impl behavior::Behavior for Actor {
438///     type Protocol = Self;
439///     type Event = behavior::User<behavior::MailAddr, ()>;
440///     type Sends = OpaqueSends;
441///     type Ph = behavior::Never;
442///     type Error = behavior::Never;
443///     type Birth = behavior::NoBirths;
444///     fn transition(&mut self, _: behavior::ActiveTurn, _: Self::Event)
445///         -> behavior::BehaviorActed<Self> { Ok(behavior::Actions::cont()) }
446/// }
447/// fn require_complete<B: behavior::LogicalHostRequirements>() {}
448/// require_complete::<Actor>();
449/// ```
450pub trait LogicalDeliveryProtocols: SendEffects {
451    /// Ordered, duplicate-preserving logical protocol occurrences.
452    type Protocols: BirthProtocolProduct;
453}
454
455/// Proof that send effects are lawful for one complete event type.
456///
457/// Ordinary communications are independent of `Event`. Interpreter requests
458/// that return a local fact are not: their continuation must select an exact
459/// member of `Event`. Composite products implement this trait structurally,
460/// reindexing only their wrapped behavior effects through an outer event
461/// injection.
462///
463/// An un-reindexed return to the emitter cannot be paired with an added outer event
464/// layer:
465///
466/// ```compile_fail
467/// struct Request;
468/// impl behavior::InterpreterRequest for Request {
469///     type ReturnToEmitter = behavior::ReturnsToEmitter<u8, behavior::Here>;
470///     type LogicalProtocols = behavior::NoBirthProtocols;
471/// }
472/// fn lawful<E, F: behavior::SendsFor<E>>() {}
473/// type Inner = behavior::EventLayer<u8, behavior::User<behavior::MailAddr, ()>>;
474/// type Outer = behavior::EventLayer<(), Inner>;
475/// lawful::<Outer, behavior::InterpreterRequests<Request>>();
476/// ```
477pub trait SendsFor<Event>: SendEffects {}
478
479/// One action whose exact interpretation result returns to its live source.
480///
481/// [`ActionItem`] determines the complete result. An implementation selects
482/// only the actor receiving it, so an action cannot discard a rejected or
483/// unattempted value or reinterpret its status. Bombay admits the exact input
484/// through [`SourceAdmission`] or keeps it in lifecycle custody.
485pub trait SourceAction: ActionItem {
486    /// Actor-owned ingress selection for the result.
487    type Source;
488}
489
490/// Ordered actions whose normalized results return to their emitting actor.
491///
492/// This product is interpreter-facing machinery. Aggregate builders expose
493/// domain operations, not this structural lane.
494pub struct SourceActions<Item> {
495    items: Vec<Item>,
496}
497
498impl<Item> SourceActions<Item> {
499    /// Number of requests retained in authored order.
500    #[must_use]
501    pub fn len(&self) -> usize {
502        self.items.len()
503    }
504
505    /// Report whether this ordered request lane contains no items.
506    #[must_use]
507    pub fn is_empty(&self) -> bool {
508        self.items.is_empty()
509    }
510
511    /// Consume the lane into its requests in authored order.
512    #[must_use]
513    pub fn into_items(self) -> Vec<Item> {
514        self.items
515    }
516}
517
518impl<Item> SendEffects for SourceActions<Item> {
519    fn empty() -> Self {
520        Self { items: Vec::new() }
521    }
522
523    fn append(&mut self, mut other: Self) {
524        self.items.append(&mut other.items);
525    }
526}
527
528impl<Item> SendInput<Item, Own> for SourceActions<Item> {
529    fn emit(&mut self, input: Item) {
530        self.items.push(input);
531    }
532}
533
534impl<Item> LogicalDeliveryProtocols for SourceActions<Item> {
535    type Protocols = crate::NoBirthProtocols;
536}
537
538impl<Event, Item> SendsFor<Event> for SourceActions<Item> where Item: SourceAction {}
539
540/// Exact results for one [`SourceActions`] lane.
541///
542/// Closed admission retains values in this same product. There is no second
543/// residual representation and no inverse conversion.
544pub struct SourceSettlements<Item>
545where
546    Item: SourceAction,
547{
548    inputs: Vec<ActionItemResult<Item>>,
549}
550
551impl<Item> SourceSettlements<Item>
552where
553    Item: SourceAction,
554{
555    fn new(inputs: Vec<ActionItemResult<Item>>) -> Self {
556        Self { inputs }
557    }
558
559    /// Transfer every retained input in authored order.
560    #[must_use]
561    pub fn into_inputs(self) -> Vec<ActionItemResult<Item>> {
562        self.inputs
563    }
564}
565
566impl<Item> ClassifySettlement for SourceSettlements<Item>
567where
568    Item: SourceAction,
569{
570    fn settlement_status(&self) -> SettlementStatus {
571        self.inputs.settlement_status()
572    }
573}
574
575impl<Item> SendSettlements for SourceActions<Item>
576where
577    Item: SourceAction,
578{
579    type Settlements = SourceSettlements<Item>;
580    type SourceCustody = (
581        Option<ActionItemResult<Item>>,
582        vec::IntoIter<ActionItemResult<Item>>,
583        Option<Result<(), ActionItemResult<Item>>>,
584    );
585    type InterpretationCustody = Vec<
586        Option<
587            InterpretationProgress<
588                Item,
589                Item::Custody,
590                ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
591            >,
592        >,
593    >;
594    fn prepare_interpretation(
595        progress: &mut Option<
596            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
597        >,
598    ) {
599        if matches!(progress, Some(InterpretationProgress::Original(_))) {
600            match progress.take() {
601                Some(InterpretationProgress::Original(original)) => {
602                    *progress = Some(InterpretationProgress::Interpreting(
603                        original
604                            .items
605                            .into_iter()
606                            .map(|item| Some(InterpretationProgress::Original(item)))
607                            .collect(),
608                    ));
609                }
610                retained => *progress = retained,
611            }
612        }
613    }
614    fn finish_interpretation(
615        progress: &mut Option<
616            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
617        >,
618    ) {
619        let Some(InterpretationProgress::Interpreting(rows)) = progress else {
620            return;
621        };
622        if let Some(received) = finish_item_rows::<Item>(rows) {
623            *progress = Some(InterpretationProgress::Completed(match received {
624                Interpretation::Complete(items) => {
625                    Interpretation::Complete(SourceSettlements::new(items))
626                }
627                Interpretation::Corrupt(items) => {
628                    Interpretation::Corrupt(SourceSettlements::new(items))
629                }
630            }));
631        }
632    }
633    fn unattempted(
634        progress: &mut Option<
635            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
636        >,
637    ) {
638        match progress.take() {
639            Some(InterpretationProgress::Original(original)) => {
640                let items = original.items;
641                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
642                    SourceSettlements::new(
643                        items.into_iter().map(SettledItem::Unattempted).collect(),
644                    ),
645                )));
646            }
647            retained => *progress = retained,
648        }
649    }
650}
651
652impl<Interpreter, RootEvent, Path, Item> InterpretSends<Interpreter, RootEvent, Path>
653    for SourceActions<Item>
654where
655    Interpreter: InterpretItem<Item, RootEvent, Path>,
656    Item: SourceAction,
657    Item::Custody: Send,
658{
659    fn interpret(
660        progress: &mut Option<
661            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
662        >,
663        interpreter: &mut Interpreter,
664    ) -> impl Future<Output = ()> + Send {
665        async move {
666            Self::prepare_interpretation(progress);
667            let Some(InterpretationProgress::Interpreting(rows)) = progress else {
668                return;
669            };
670            for row in rows {
671                match row.as_ref() {
672                    Some(InterpretationProgress::Completed(Interpretation::Corrupt(_))) => break,
673                    Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {
674                        continue;
675                    }
676                    Some(InterpretationProgress::Original(_))
677                    | Some(InterpretationProgress::Interpreting(_)) => {}
678                    None => return,
679                }
680                settle_item::<Item, Interpreter, RootEvent, Path>(row, interpreter).await;
681                Item::finish_interpretation(row);
682                match row.as_ref() {
683                    Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {}
684                    _ => break,
685                }
686            }
687            Self::finish_interpretation(progress);
688        }
689    }
690}
691
692/// Bombay ownership port for one exact current-actor system input.
693///
694/// Success transfers the input to the existing actor loop. Closed admission
695/// returns the unchanged input to the current lifecycle host.
696///
697/// An event without the exact source ingress cannot implement this port:
698///
699/// ```compile_fail,E0277
700/// struct EventWithoutInput;
701/// struct Owner;
702/// struct Input;
703/// struct Host;
704/// impl behavior::SourceAdmission<EventWithoutInput, Owner, Input> for Host {
705///     fn admit_source(&mut self, input: &mut Option<Input>, reply: &mut Option<Result<(), Input>>)
706///         -> impl core::future::Future<Output = ()> + Send
707///     {
708///         async move {
709///             if let Some(input) = input.take() { *reply = Some(Err(input)); }
710///         }
711///     }
712/// }
713/// ```
714pub trait SourceAdmission<RootEvent, Source, Input>: Send
715where
716    RootEvent: crate::EventIngress<Source, Input>,
717{
718    fn admit_source(
719        &mut self,
720        input: &mut Option<Input>,
721        reply: &mut Option<Result<(), Input>>,
722    ) -> impl Future<Output = ()> + Send;
723}
724
725/// Result of offering at most one ordered source settlement.
726pub enum SourceCustody<Residual> {
727    /// No source input remains in the complete residual product.
728    Exhausted(Residual),
729    /// No live-source input remains, but exact terminal custody is required.
730    Retained(Residual),
731    /// Exactly one source input transferred; the residual remains in custody.
732    Admitted(Residual),
733    /// Admission closed; the residual contains the current and untouched suffix.
734    Closed(Residual),
735}
736
737impl<Residual> SourceCustody<Residual> {
738    /// Transform the complete residual without changing its custody state.
739    #[must_use]
740    pub fn map<Mapped>(self, map: impl FnOnce(Residual) -> Mapped) -> SourceCustody<Mapped> {
741        match self {
742            Self::Exhausted(residual) => SourceCustody::Exhausted(map(residual)),
743            Self::Retained(residual) => SourceCustody::Retained(map(residual)),
744            Self::Admitted(residual) => SourceCustody::Admitted(map(residual)),
745            Self::Closed(residual) => SourceCustody::Closed(map(residual)),
746        }
747    }
748}
749
750/// Static one-at-a-time source admission for one complete settlement product.
751/// The actual source product before offering, its outside partial owner, or
752/// its acquired complete normal result. Native causes remain runtime-owned.
753pub enum SourceProgress<Settlement, Custody> {
754    Original(Settlement),
755    Offering(Custody),
756    Completed(SourceCustody<Settlement>),
757}
758
759pub trait SourceSettlementCustody<Host, RootEvent>: Sized {
760    type Custody: Send;
761
762    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>);
763
764    fn offer_next_to_source(
765        custody: &mut Self::Custody,
766        host: &mut Host,
767    ) -> impl Future<Output = ()> + Send;
768
769    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>);
770}
771
772pub(super) async fn offer_source_in_order<Host, RootEvent, Earlier, Later>(
773    custody: &mut (
774        Option<SourceProgress<Earlier, Earlier::Custody>>,
775        Option<SourceProgress<Later, Later::Custody>>,
776    ),
777    host: &mut Host,
778) where
779    Host: Send,
780    Earlier: SourceSettlementCustody<Host, RootEvent> + Send,
781    Later: SourceSettlementCustody<Host, RootEvent> + Send,
782{
783    match &custody.0 {
784        Some(SourceProgress::Original(_)) => Earlier::prepare_source(&mut custody.0),
785        Some(SourceProgress::Offering(_) | SourceProgress::Completed(_)) | None => {}
786    }
787    if let Some(SourceProgress::Offering(earlier)) = &mut custody.0 {
788        {
789            Earlier::offer_next_to_source(earlier, host).await;
790        }
791        Earlier::finish_source(&mut custody.0);
792    }
793    match &custody.0 {
794        Some(SourceProgress::Completed(
795            SourceCustody::Exhausted(_) | SourceCustody::Retained(_),
796        )) => {}
797        Some(SourceProgress::Completed(SourceCustody::Admitted(_) | SourceCustody::Closed(_)))
798        | Some(SourceProgress::Original(_) | SourceProgress::Offering(_))
799        | None => return,
800    }
801    match &custody.1 {
802        Some(SourceProgress::Original(_)) => Later::prepare_source(&mut custody.1),
803        Some(SourceProgress::Offering(_) | SourceProgress::Completed(_)) | None => {}
804    }
805    if let Some(SourceProgress::Offering(later)) = &mut custody.1 {
806        {
807            Later::offer_next_to_source(later, host).await;
808        }
809        Later::finish_source(&mut custody.1);
810    }
811}
812
813impl<Host, RootEvent, Earlier, Later> SourceSettlementCustody<Host, RootEvent> for (Earlier, Later)
814where
815    Host: Send,
816    Earlier: SourceSettlementCustody<Host, RootEvent> + Send,
817    Later: SourceSettlementCustody<Host, RootEvent> + Send,
818{
819    type Custody = (
820        Option<SourceProgress<Earlier, Earlier::Custody>>,
821        Option<SourceProgress<Later, Later::Custody>>,
822    );
823
824    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
825        let original = match progress.take() {
826            Some(SourceProgress::Original(original)) => original,
827            progress_ => {
828                *progress = progress_;
829                return;
830            }
831        };
832        // No child method is called until BOTH original child owners are stored.
833        *progress = Some(SourceProgress::Offering((
834            Some(SourceProgress::Original(original.0)),
835            Some(SourceProgress::Original(original.1)),
836        )));
837    }
838
839    fn offer_next_to_source(
840        custody: &mut Self::Custody,
841        host: &mut Host,
842    ) -> impl Future<Output = ()> + Send {
843        offer_source_in_order::<Host, RootEvent, Earlier, Later>(custody, host)
844    }
845
846    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
847        // Child finalization has already borrowed each child slot separately.
848        // This total structural combination calls no child or host method.
849        let completed = match progress.take() {
850            Some(SourceProgress::Offering((
851                Some(SourceProgress::Completed(SourceCustody::Admitted(earlier))),
852                Some(SourceProgress::Original(later)),
853            ))) => SourceCustody::Admitted((earlier, later)),
854            Some(SourceProgress::Offering((
855                Some(SourceProgress::Completed(SourceCustody::Closed(earlier))),
856                Some(SourceProgress::Original(later)),
857            ))) => SourceCustody::Closed((earlier, later)),
858            Some(SourceProgress::Offering((
859                Some(SourceProgress::Completed(SourceCustody::Exhausted(earlier))),
860                Some(SourceProgress::Completed(later)),
861            ))) => later.map(|later| (earlier, later)),
862            Some(SourceProgress::Offering((
863                Some(SourceProgress::Completed(SourceCustody::Retained(earlier))),
864                Some(SourceProgress::Completed(later)),
865            ))) => match later {
866                SourceCustody::Exhausted(later) | SourceCustody::Retained(later) => {
867                    SourceCustody::Retained((earlier, later))
868                }
869                SourceCustody::Admitted(later) => SourceCustody::Admitted((earlier, later)),
870                SourceCustody::Closed(later) => SourceCustody::Closed((earlier, later)),
871            },
872            progress_ => {
873                *progress = progress_;
874                return;
875            }
876        };
877        *progress = Some(SourceProgress::Completed(completed));
878    }
879}
880
881impl<Host, RootEvent, Item> SourceSettlementCustody<Host, RootEvent> for SourceSettlements<Item>
882where
883    Host: SourceAdmission<RootEvent, Item::Source, ActionItemResult<Item>>,
884    RootEvent: crate::EventIngress<Item::Source, ActionItemResult<Item>>,
885    Item: SourceAction,
886{
887    type Custody = (
888        Option<ActionItemResult<Item>>,
889        vec::IntoIter<ActionItemResult<Item>>,
890        Option<Result<(), ActionItemResult<Item>>>,
891    );
892
893    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
894        let original = match progress.take() {
895            Some(SourceProgress::Original(original)) => original,
896            progress_ => {
897                *progress = progress_;
898                return;
899            }
900        };
901        if original.inputs.is_empty() {
902            *progress = Some(SourceProgress::Completed(SourceCustody::Exhausted(
903                original,
904            )));
905            return;
906        }
907        let mut remaining = original.inputs.into_iter();
908        let input = remaining.next();
909        *progress = Some(SourceProgress::Offering((input, remaining, None)));
910    }
911
912    fn offer_next_to_source(
913        custody: &mut Self::Custody,
914        host: &mut Host,
915    ) -> impl Future<Output = ()> + Send {
916        async move {
917            if custody.2.is_none() {
918                host.admit_source(&mut custody.0, &mut custody.2).await;
919            }
920        }
921    }
922
923    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
924        let completed = match progress.take() {
925            Some(SourceProgress::Offering((None, remaining, Some(Ok(()))))) => {
926                SourceCustody::Admitted(Self::new(remaining.collect()))
927            }
928            Some(SourceProgress::Offering((None, remaining, Some(Err(input))))) => {
929                let Some(capacity) = remaining.len().checked_add(1) else {
930                    *progress = Some(SourceProgress::Offering((
931                        None,
932                        remaining,
933                        Some(Err(input)),
934                    )));
935                    return;
936                };
937                let mut retained = Vec::with_capacity(capacity);
938                retained.push(input);
939                retained.extend(remaining);
940                SourceCustody::Closed(Self::new(retained))
941            }
942            progress_ => {
943                *progress = progress_;
944                return;
945            }
946        };
947        *progress = Some(SourceProgress::Completed(completed));
948    }
949}
950
951impl<Host, RootEvent> SourceSettlementCustody<Host, RootEvent> for NoSends {
952    type Custody = Self;
953    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
954        *progress = match progress.take() {
955            Some(SourceProgress::Original(original)) => Some(SourceProgress::Completed(
956                SourceCustody::Exhausted(original),
957            )),
958            progress => progress,
959        };
960    }
961    fn offer_next_to_source(
962        _: &mut Self::Custody,
963        _: &mut Host,
964    ) -> impl Future<Output = ()> + Send {
965        future::ready(())
966    }
967    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
968        *progress = match progress.take() {
969            Some(SourceProgress::Original(original) | SourceProgress::Offering(original)) => Some(
970                SourceProgress::Completed(SourceCustody::Exhausted(original)),
971            ),
972            retained => retained,
973        };
974    }
975}
976
977impl<Host, RootEvent, Item> SourceSettlementCustody<Host, RootEvent> for Vec<ActionItemResult<Item>>
978where
979    Item: ActionItem,
980{
981    type Custody = (Self, vec::IntoIter<ActionItemResult<Item>>);
982    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
983        *progress = match progress.take() {
984            Some(SourceProgress::Original(original)) if original.is_empty() => Some(
985                SourceProgress::Completed(SourceCustody::Exhausted(original)),
986            ),
987            Some(SourceProgress::Original(original)) => {
988                Some(SourceProgress::Offering((Vec::new(), original.into_iter())))
989            }
990            progress => progress,
991        };
992    }
993    fn offer_next_to_source(
994        custody: &mut Self::Custody,
995        _: &mut Host,
996    ) -> impl Future<Output = ()> + Send {
997        async move {
998            for settlement in custody.1.by_ref() {
999                let settlement = match settlement {
1000                    SettledItem::Attempted(ItemSettlement::Accepted(accepted)) => {
1001                        Item::retain_accepted(accepted).map(|accepted| {
1002                            SettledItem::Attempted(ItemSettlement::Accepted(accepted))
1003                        })
1004                    }
1005                    settlement => Some(settlement),
1006                };
1007                if let Some(settlement) = settlement {
1008                    custody.0.push(settlement);
1009                }
1010            }
1011        }
1012    }
1013    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
1014        *progress = match progress.take() {
1015            Some(SourceProgress::Offering((retained, remaining)))
1016                if remaining.as_slice().is_empty() =>
1017            {
1018                if retained.is_empty() {
1019                    Some(SourceProgress::Completed(SourceCustody::Exhausted(
1020                        retained,
1021                    )))
1022                } else {
1023                    Some(SourceProgress::Completed(SourceCustody::Retained(retained)))
1024                }
1025            }
1026            progress => progress,
1027        };
1028    }
1029}
1030
1031impl<Host, RootEvent> SourceSettlementCustody<Host, RootEvent> for Vec<crate::Never> {
1032    type Custody = Self;
1033    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
1034        *progress = match progress.take() {
1035            Some(SourceProgress::Original(original)) => Some(SourceProgress::Completed(
1036                SourceCustody::Exhausted(original),
1037            )),
1038            progress => progress,
1039        };
1040    }
1041    fn offer_next_to_source(
1042        _: &mut Self::Custody,
1043        _: &mut Host,
1044    ) -> impl Future<Output = ()> + Send {
1045        future::ready(())
1046    }
1047    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
1048        *progress = match progress.take() {
1049            Some(SourceProgress::Original(original) | SourceProgress::Offering(original)) => Some(
1050                SourceProgress::Completed(SourceCustody::Exhausted(original)),
1051            ),
1052            retained => retained,
1053        };
1054    }
1055}
1056
1057impl<Host, RootEvent, Owned, Inner> SourceSettlementCustody<Host, RootEvent>
1058    for SendLayer<Owned, Inner>
1059where
1060    Host: Send,
1061    Owned: SourceSettlementCustody<Host, RootEvent> + Send,
1062    Inner: SourceSettlementCustody<Host, RootEvent> + Send,
1063{
1064    type Custody = <(Inner, Owned) as SourceSettlementCustody<Host, RootEvent>>::Custody;
1065    fn prepare_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
1066        *progress = match progress.take() {
1067            Some(SourceProgress::Original(original)) => Some(SourceProgress::Offering((
1068                Some(SourceProgress::Original(original.inner)),
1069                Some(SourceProgress::Original(original.owned)),
1070            ))),
1071            progress => progress,
1072        };
1073    }
1074    fn offer_next_to_source(
1075        custody: &mut Self::Custody,
1076        host: &mut Host,
1077    ) -> impl Future<Output = ()> + Send {
1078        offer_source_in_order::<Host, RootEvent, Inner, Owned>(custody, host)
1079    }
1080    fn finish_source(progress: &mut Option<SourceProgress<Self, Self::Custody>>) {
1081        let custody = match progress.take() {
1082            Some(SourceProgress::Offering(custody)) => custody,
1083            retained => {
1084                *progress = retained;
1085                return;
1086            }
1087        };
1088        // The concrete Core tuple finish is total and calls no child methods.
1089        let mut product = Some(SourceProgress::Offering(custody));
1090        <(Inner, Owned) as SourceSettlementCustody<Host, RootEvent>>::finish_source(&mut product);
1091        *progress = match product {
1092            Some(SourceProgress::Original((inner, owned))) => {
1093                Some(SourceProgress::Original(Self::new(owned, inner)))
1094            }
1095            Some(SourceProgress::Offering(custody)) => Some(SourceProgress::Offering(custody)),
1096            Some(SourceProgress::Completed(reply)) => Some(SourceProgress::Completed(
1097                reply.map(|(inner, owned)| Self::new(owned, inner)),
1098            )),
1099            None => None,
1100        };
1101    }
1102}
1103
1104/// An interpreter request that produces no later fact for the emitting actor.
1105pub enum NoReturnToEmitter {}
1106
1107/// An interpreter request whose later `Input` returns to the emitting actor at
1108/// `Path`, relative to the effect lane that owns the request.
1109pub struct ReturnsToEmitter<Input, Path>(core::marker::PhantomData<fn(Input, Path)>);
1110
1111/// Local-return contract declared by one interpreter-facing request.
1112pub trait ReturnToEmitterFor<Event> {}
1113
1114impl<Event> ReturnToEmitterFor<Event> for NoReturnToEmitter {}
1115
1116impl<Event, Input, Path> ReturnToEmitterFor<Event> for ReturnsToEmitter<Input, Path> where
1117    Event: InjectEvent<Input, Path>
1118{
1119}
1120
1121/// Declares only the continuation returning to the actor that emitted this
1122/// interpreter request. Destinations owned by a child, parent, ancestor, or
1123/// established actor are separate capabilities and are not reindexed when the
1124/// emitter is wrapped. `LogicalProtocols` lists possible logical destinations
1125/// of the request in declaration order, independently of any value's selected
1126/// variant; exact and creator-local destinations contribute none.
1127pub trait InterpreterRequest {
1128    type ReturnToEmitter;
1129    type LogicalProtocols: BirthProtocolProduct;
1130}
1131
1132/// Transfer one owned report to the emitter's established parent.
1133///
1134/// The request is an ordinary typed send effect. Its interpreter uses the
1135/// already-established creator/child relationship, attaches the emitter's
1136/// exact creator-local nonce, and injects a [`crate::ChildReport`] into the
1137/// parent's closed event algebra. It performs no address or protocol lookup.
1138/// A root behavior has no parent capability and therefore cannot interpret
1139/// this request.
1140#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1141pub struct ReportToParent<R> {
1142    /// Complete report value transferred to the parent.
1143    pub report: R,
1144}
1145
1146impl<R> ReportToParent<R> {
1147    /// Construct one structural parent report.
1148    #[must_use]
1149    pub const fn new(report: R) -> Self {
1150        Self { report }
1151    }
1152
1153    /// Recover ownership of the complete report value.
1154    #[must_use]
1155    pub fn into_inner(self) -> R {
1156        self.report
1157    }
1158}
1159
1160impl<R> InterpreterRequest for ReportToParent<R> {
1161    type ReturnToEmitter = NoReturnToEmitter;
1162    type LogicalProtocols = NoBirthProtocols;
1163}
1164
1165impl<R> ActionItem for ReportToParent<R>
1166where
1167    R: Send,
1168{
1169    type Custody = (Option<Self>, Option<Self::Reply>);
1170    type Input<'a>
1171        = &'a mut Option<Self>
1172    where
1173        Self: 'a;
1174    type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1175
1176    fn prepare_interpretation(
1177        progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1178    ) {
1179        prepare_item::<Self>(progress);
1180    }
1181    fn interpretation_input<'a>(
1182        custody: &'a mut Self::Custody,
1183    ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1184    where
1185        Self: 'a,
1186    {
1187        let (input, received) = custody;
1188        if input.is_some() && received.is_none() {
1189            Some((input, received))
1190        } else {
1191            None
1192        }
1193    }
1194    fn finish_interpretation(
1195        progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1196    ) {
1197        finish_item::<Self>(progress);
1198    }
1199
1200    type Accepted = ();
1201    type Rejection = ParentReportReason;
1202    type Prerequisite = crate::Never;
1203}
1204
1205/// Send effects containing no communications or interpreter requests.
1206///
1207/// A behavior layer that adds an event lane but emits nothing of its own uses
1208/// this named value rather than an ambiguous `()`.
1209#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1210pub struct NoSends;
1211
1212impl SendEffects for NoSends {
1213    fn empty() -> Self {
1214        Self
1215    }
1216
1217    fn append(&mut self, _: Self) {}
1218}
1219
1220impl LogicalDeliveryProtocols for NoSends {
1221    type Protocols = NoBirthProtocols;
1222}
1223
1224impl<Event> SendsFor<Event> for NoSends {}
1225
1226impl SendSettlements for NoSends {
1227    type Settlements = Self;
1228    type SourceCustody = Self;
1229    type InterpretationCustody = Self;
1230    fn prepare_interpretation(
1231        progress: &mut Option<
1232            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1233        >,
1234    ) {
1235        match progress.take() {
1236            Some(InterpretationProgress::Original(original)) => {
1237                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
1238                    original,
1239                )))
1240            }
1241            retained => *progress = retained,
1242        }
1243    }
1244    fn finish_interpretation(
1245        progress: &mut Option<
1246            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1247        >,
1248    ) {
1249        Self::prepare_interpretation(progress);
1250    }
1251    fn unattempted(
1252        progress: &mut Option<
1253            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1254        >,
1255    ) {
1256        match progress.take() {
1257            Some(InterpretationProgress::Original(original)) => {
1258                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
1259                    original,
1260                )))
1261            }
1262            retained => *progress = retained,
1263        }
1264    }
1265}
1266
1267impl ClassifySettlement for NoSends {
1268    fn settlement_status(&self) -> SettlementStatus {
1269        SettlementStatus::Accepted
1270    }
1271}
1272
1273impl<Interpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path> for NoSends {
1274    fn interpret(
1275        progress: &mut Option<
1276            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1277        >,
1278        _: &mut Interpreter,
1279    ) -> impl Future<Output = ()> + Send {
1280        async move {
1281            Self::prepare_interpretation(progress);
1282        }
1283    }
1284}
1285
1286/// Send effects introduced by one wrapper around inner send effects.
1287///
1288/// `owned` contains effects introduced by the current behavior layer and
1289/// `inner` contains effects of the wrapped interaction. The structural
1290/// [`SendsFor`] implementation is the composition law:
1291///
1292/// ```text
1293/// Event'   = OwnedEvent + InnerEvent
1294/// Effects' = OwnedEffects × InnerEffects
1295/// ```
1296///
1297/// Owned return to the emitters target `Event'`; inner return to the emitters target
1298/// `InnerEvent` and are therefore lifted through the same `Inner` injection.
1299/// Established actor, child, and ancestor destinations are unaffected because
1300/// they are not return to the emitters.
1301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1302pub struct SendLayer<Owned, Inner> {
1303    pub owned: Owned,
1304    pub inner: Inner,
1305}
1306
1307impl<Owned, Inner> SendLayer<Owned, Inner> {
1308    #[must_use]
1309    pub const fn new(owned: Owned, inner: Inner) -> Self {
1310        Self { owned, inner }
1311    }
1312}
1313
1314impl<Owned: SendEffects, Inner: SendEffects> SendEffects for SendLayer<Owned, Inner> {
1315    fn empty() -> Self {
1316        Self::new(Owned::empty(), Inner::empty())
1317    }
1318
1319    fn append(&mut self, other: Self) {
1320        self.owned.append(other.owned);
1321        self.inner.append(other.inner);
1322    }
1323}
1324
1325impl<Owned, Inner> LogicalDeliveryProtocols for SendLayer<Owned, Inner>
1326where
1327    Owned: LogicalDeliveryProtocols,
1328    Inner: LogicalDeliveryProtocols,
1329{
1330    // Interpretation preserves authored inner-to-outer wrapper order.
1331    type Protocols = <Inner::Protocols as BirthProtocolProduct>::Append<Owned::Protocols>;
1332}
1333
1334impl<Event, OwnedEffects, InnerEffects> SendsFor<Event> for SendLayer<OwnedEffects, InnerEffects>
1335where
1336    Event: ComposedEvent,
1337    OwnedEffects: SendsFor<Event>,
1338    InnerEffects: SendsFor<Event::Inner>,
1339{
1340}
1341
1342impl<Owned, Inner> SendSettlements for SendLayer<Owned, Inner>
1343where
1344    Owned: SendSettlements,
1345    Inner: SendSettlements,
1346{
1347    type Settlements = SendLayer<Owned::Settlements, Inner::Settlements>;
1348    // Actual old associated SourceCustody body is retained unchanged.
1349    type SourceCustody = (
1350        Option<SourceProgress<Inner::Settlements, Inner::SourceCustody>>,
1351        Option<SourceProgress<Owned::Settlements, Owned::SourceCustody>>,
1352    );
1353    type InterpretationCustody = SendLayer<
1354        Option<InterpretationProgress<Owned, Owned::InterpretationCustody, Owned::Settlements>>,
1355        Option<InterpretationProgress<Inner, Inner::InterpretationCustody, Inner::Settlements>>,
1356    >;
1357
1358    fn prepare_interpretation(
1359        progress: &mut Option<
1360            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1361        >,
1362    ) {
1363        if matches!(progress, Some(InterpretationProgress::Original(_))) {
1364            match progress.take() {
1365                Some(InterpretationProgress::Original(layer)) => {
1366                    *progress = Some(InterpretationProgress::Interpreting(SendLayer::new(
1367                        Some(InterpretationProgress::Original(layer.owned)),
1368                        Some(InterpretationProgress::Original(layer.inner)),
1369                    )));
1370                }
1371                other => *progress = other,
1372            }
1373        }
1374        // Both originals are installed. Each actual interpret operation
1375        // prepares only its own child; untouched siblings stay Original.
1376    }
1377
1378    fn finish_interpretation(
1379        progress: &mut Option<
1380            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1381        >,
1382    ) {
1383        let Some(InterpretationProgress::Interpreting(layer)) = progress else {
1384            return;
1385        };
1386        // Total structural extraction only. Child preparation/finalization
1387        // borrows the outside child slots in the actual traversal below.
1388        if !matches!(
1389            (&layer.inner, &layer.owned),
1390            (
1391                Some(InterpretationProgress::Completed(_)),
1392                Some(InterpretationProgress::Completed(_))
1393            )
1394        ) {
1395            return;
1396        }
1397        match progress.take() {
1398            Some(InterpretationProgress::Interpreting(SendLayer {
1399                owned: Some(InterpretationProgress::Completed(owned)),
1400                inner: Some(InterpretationProgress::Completed(inner)),
1401            })) => {
1402                let combined = match (inner, owned) {
1403                    (Interpretation::Complete(inner), Interpretation::Complete(owned)) => {
1404                        Interpretation::Complete(SendLayer::new(owned, inner))
1405                    }
1406                    (
1407                        Interpretation::Complete(inner) | Interpretation::Corrupt(inner),
1408                        Interpretation::Corrupt(owned),
1409                    )
1410                    | (Interpretation::Corrupt(inner), Interpretation::Complete(owned)) => {
1411                        Interpretation::Corrupt(SendLayer::new(owned, inner))
1412                    }
1413                };
1414                *progress = Some(InterpretationProgress::Completed(combined));
1415            }
1416            other => *progress = other,
1417        }
1418    }
1419
1420    fn unattempted(
1421        progress: &mut Option<
1422            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1423        >,
1424    ) {
1425        // Install child originals but do not run prepare callbacks: these are
1426        // untouched children after another owner's actual corrupt fact.
1427        if matches!(progress, Some(InterpretationProgress::Original(_))) {
1428            match progress.take() {
1429                Some(InterpretationProgress::Original(layer)) => {
1430                    *progress = Some(InterpretationProgress::Interpreting(SendLayer::new(
1431                        Some(InterpretationProgress::Original(layer.owned)),
1432                        Some(InterpretationProgress::Original(layer.inner)),
1433                    )));
1434                }
1435                other => *progress = other,
1436            }
1437        }
1438        if let Some(InterpretationProgress::Interpreting(layer)) = progress {
1439            Inner::unattempted(&mut layer.inner);
1440            Owned::unattempted(&mut layer.owned);
1441        }
1442        Self::finish_interpretation(progress);
1443    }
1444}
1445
1446impl<Owned, Inner> ClassifySettlement for SendLayer<Owned, Inner>
1447where
1448    Owned: ClassifySettlement,
1449    Inner: ClassifySettlement,
1450{
1451    fn settlement_status(&self) -> SettlementStatus {
1452        self.inner
1453            .settlement_status()
1454            .combine(self.owned.settlement_status())
1455    }
1456}
1457
1458impl<Input, Path, Owned, Inner> SendInput<Input, Path> for SendLayer<Owned, Inner>
1459where
1460    Owned: SendInput<Input, Path>,
1461{
1462    fn emit(&mut self, input: Input) {
1463        self.owned.emit(input);
1464    }
1465}
1466
1467impl<Interpreter, RootEvent, Path, Owned, Inner> InterpretSends<Interpreter, RootEvent, Path>
1468    for SendLayer<Owned, Inner>
1469where
1470    Interpreter: Send,
1471    Owned: InterpretSends<Interpreter, RootEvent, Path> + Send,
1472    Inner: InterpretSends<Interpreter, RootEvent, Inside<Path>> + Send,
1473    Owned::InterpretationCustody: Send,
1474    Inner::InterpretationCustody: Send,
1475{
1476    fn interpret(
1477        progress: &mut Option<
1478            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1479        >,
1480        interpreter: &mut Interpreter,
1481    ) -> impl Future<Output = ()> + Send {
1482        async move {
1483            Self::prepare_interpretation(progress);
1484            let Some(InterpretationProgress::Interpreting(layer)) = progress else {
1485                return;
1486            };
1487            <Inner as InterpretSends<Interpreter, RootEvent, Inside<Path>>>::interpret(
1488                &mut layer.inner,
1489                interpreter,
1490            )
1491            .await;
1492            Inner::finish_interpretation(&mut layer.inner);
1493            match &layer.inner {
1494                Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {
1495                    <Owned as InterpretSends<Interpreter, RootEvent, Path>>::interpret(
1496                        &mut layer.owned,
1497                        interpreter,
1498                    )
1499                    .await;
1500                    Owned::finish_interpretation(&mut layer.owned);
1501                }
1502                Some(InterpretationProgress::Completed(Interpretation::Corrupt(_))) => {
1503                    Owned::unattempted(&mut layer.owned);
1504                }
1505                _ => return,
1506            }
1507            Self::finish_interpretation(progress);
1508        }
1509    }
1510}
1511
1512impl<T> SendEffects for Vec<T> {
1513    fn empty() -> Self {
1514        Vec::new()
1515    }
1516
1517    fn append(&mut self, mut other: Self) {
1518        Vec::append(self, &mut other);
1519    }
1520}
1521
1522impl<P: Protocol> LogicalDeliveryProtocols for Vec<Delivery<P>> {
1523    type Protocols = BirthProtocol<P, NoBirthProtocols>;
1524}
1525
1526impl<P: Protocol, Occurrence> LogicalDeliveryProtocols for Vec<ChildDelivery<P, Occurrence>> {
1527    type Protocols = NoBirthProtocols;
1528}
1529
1530impl<Child, Source, Input, Occurrence> LogicalDeliveryProtocols
1531    for Vec<ChildInput<Child, Source, Input, Occurrence>>
1532where
1533    Child: Behavior,
1534{
1535    type Protocols = NoBirthProtocols;
1536}
1537
1538impl<P> LogicalDeliveryProtocols for Vec<EstablishedDelivery<P>>
1539where
1540    P: Protocol,
1541    P::Addr: RecipientAddress,
1542{
1543    type Protocols = NoBirthProtocols;
1544}
1545
1546impl LogicalDeliveryProtocols for Vec<crate::Never> {
1547    type Protocols = NoBirthProtocols;
1548}
1549
1550impl<Event, T> SendsFor<Event> for Vec<T> {}
1551
1552impl<Item> SendSettlements for Vec<Item>
1553where
1554    Item: ActionItem,
1555{
1556    type Settlements = Vec<ActionItemResult<Item>>;
1557    type SourceCustody = (Self::Settlements, vec::IntoIter<ActionItemResult<Item>>);
1558    type InterpretationCustody = Vec<
1559        Option<
1560            InterpretationProgress<
1561                Item,
1562                Item::Custody,
1563                ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1564            >,
1565        >,
1566    >;
1567    fn prepare_interpretation(
1568        progress: &mut Option<
1569            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1570        >,
1571    ) {
1572        prepare_items(progress);
1573    }
1574    fn finish_interpretation(
1575        progress: &mut Option<
1576            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1577        >,
1578    ) {
1579        finish_items(progress);
1580    }
1581    fn unattempted(
1582        progress: &mut Option<
1583            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1584        >,
1585    ) {
1586        unattempted_items(progress);
1587    }
1588}
1589
1590/// Prepare an ordinary request and its independent outside reply destination.
1591/// Construction calls no interpreter and transfers no containing sibling.
1592pub fn prepare_item<Item>(
1593    progress: &mut Option<
1594        InterpretationProgress<
1595            Item,
1596            Item::Custody,
1597            ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1598        >,
1599    >,
1600) where
1601    Item: ActionItem<
1602        Custody = (
1603            Option<Item>,
1604            Option<
1605                ItemSettlement<
1606                    Item,
1607                    <Item as ActionItem>::Accepted,
1608                    <Item as ActionItem>::Rejection,
1609                    <Item as ActionItem>::Prerequisite,
1610                >,
1611            >,
1612        ),
1613    >,
1614{
1615    if !matches!(progress, Some(InterpretationProgress::Original(_))) {
1616        return;
1617    }
1618    match progress.take() {
1619        Some(InterpretationProgress::Original(item)) => {
1620            *progress = Some(InterpretationProgress::Interpreting((Some(item), None)));
1621        }
1622        retained => *progress = retained,
1623    }
1624}
1625
1626/// Finalize only an acquired reply after its original input was consumed.
1627/// Surviving input with a reply, or absent input without a reply, stays owned.
1628pub fn finish_item<Item>(
1629    progress: &mut Option<
1630        InterpretationProgress<
1631            Item,
1632            Item::Custody,
1633            ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1634        >,
1635    >,
1636) where
1637    Item: ActionItem<
1638        Custody = (
1639            Option<Item>,
1640            Option<
1641                ItemSettlement<
1642                    Item,
1643                    <Item as ActionItem>::Accepted,
1644                    <Item as ActionItem>::Rejection,
1645                    <Item as ActionItem>::Prerequisite,
1646                >,
1647            >,
1648        ),
1649    >,
1650{
1651    if !matches!(
1652        progress,
1653        Some(InterpretationProgress::Interpreting((None, Some(_))))
1654    ) {
1655        return;
1656    }
1657    match progress.take() {
1658        Some(InterpretationProgress::Interpreting((None, Some(received)))) => {
1659            let interpretation = match received {
1660                received @ ItemSettlement::Corrupt { .. } => Interpretation::Corrupt(received),
1661                received => Interpretation::Complete(received),
1662            };
1663            *progress = Some(InterpretationProgress::Completed(interpretation));
1664        }
1665        retained => *progress = retained,
1666    }
1667}
1668
1669/// Loan only the current lower input and its outside reply destination.
1670/// The producer returns unit; the caller finalizes after producer disposal.
1671/// Empty input or an occupied destination remains an incomplete owned fact.
1672pub fn settle_item<'a, Item, Interpreter, RootEvent, Path>(
1673    progress: &'a mut Option<
1674        InterpretationProgress<
1675            Item,
1676            Item::Custody,
1677            ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1678        >,
1679    >,
1680    interpreter: &'a mut Interpreter,
1681) -> impl Future<Output = ()> + Send + 'a
1682where
1683    Item: ActionItem + 'a,
1684    Interpreter: InterpretItem<Item, RootEvent, Path> + 'a,
1685{
1686    Item::prepare_interpretation(progress);
1687    let attempt = match progress {
1688        Some(InterpretationProgress::Interpreting(custody)) => Item::interpretation_input(custody)
1689            .map(|(input, received)| {
1690                <Interpreter as InterpretItem<Item, RootEvent, Path>>::interpret_item(
1691                    interpreter,
1692                    input,
1693                    received,
1694                )
1695            }),
1696        _ => None,
1697    };
1698    // Only the already-declared Send host future is retained. No whole custody,
1699    // parent loan, metadata, or finalization callback is captured here.
1700    async move {
1701        if let Some(attempt) = attempt {
1702            attempt.await;
1703        }
1704    }
1705}
1706
1707fn prepare_items<Item>(
1708    progress: &mut Option<
1709        InterpretationProgress<
1710            Vec<Item>,
1711            Vec<
1712                Option<
1713                    InterpretationProgress<
1714                        Item,
1715                        Item::Custody,
1716                        ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1717                    >,
1718                >,
1719            >,
1720            Vec<ActionItemResult<Item>>,
1721        >,
1722    >,
1723) where
1724    Item: ActionItem,
1725{
1726    if !matches!(progress, Some(InterpretationProgress::Original(_))) {
1727        return;
1728    }
1729    match progress.take() {
1730        Some(InterpretationProgress::Original(items)) => {
1731            let rows = items
1732                .into_iter()
1733                .map(|item| Some(InterpretationProgress::Original(item)))
1734                .collect();
1735            *progress = Some(InterpretationProgress::Interpreting(rows));
1736        }
1737        retained => *progress = retained,
1738    }
1739}
1740
1741fn finish_item_rows<Item>(
1742    rows: &mut Vec<
1743        Option<
1744            InterpretationProgress<
1745                Item,
1746                Item::Custody,
1747                ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1748            >,
1749        >,
1750    >,
1751) -> Option<Interpretation<Vec<ActionItemResult<Item>>>>
1752where
1753    Item: ActionItem,
1754{
1755    for row in rows.iter_mut() {
1756        if matches!(row, Some(InterpretationProgress::Interpreting(_))) {
1757            Item::finish_interpretation(row);
1758        }
1759    }
1760    let corrupt = rows.iter().position(|row| {
1761        matches!(
1762            row,
1763            Some(InterpretationProgress::Completed(Interpretation::Corrupt(
1764                _
1765            )))
1766        )
1767    });
1768    let complete = rows.iter().enumerate().all(|(index, row)| {
1769        if corrupt.is_some_and(|corrupt| index > corrupt) {
1770            matches!(row, Some(InterpretationProgress::Original(_)))
1771        } else {
1772            matches!(row, Some(InterpretationProgress::Completed(_)))
1773        }
1774    });
1775    if !complete {
1776        return None;
1777    }
1778    let mut remaining = core::mem::take(rows).into_iter();
1779    let mut received_rows = Vec::with_capacity(remaining.len());
1780    while let Some(row) = remaining.next() {
1781        match row {
1782            row @ Some(InterpretationProgress::Original(_))
1783            | row @ Some(InterpretationProgress::Completed(_)) => received_rows.push(row),
1784            row => {
1785                *rows = received_rows
1786                    .into_iter()
1787                    .chain(core::iter::once(row))
1788                    .chain(remaining)
1789                    .collect();
1790                return None;
1791            }
1792        }
1793    }
1794    let settled = received_rows
1795        .into_iter()
1796        .filter_map(|row| match row {
1797            Some(InterpretationProgress::Original(item)) => Some(SettledItem::Unattempted(item)),
1798            Some(InterpretationProgress::Completed(
1799                Interpretation::Complete(received) | Interpretation::Corrupt(received),
1800            )) => Some(SettledItem::Attempted(received)),
1801            _ => None,
1802        })
1803        .collect();
1804    Some(match corrupt {
1805        Some(_) => Interpretation::Corrupt(settled),
1806        None => Interpretation::Complete(settled),
1807    })
1808}
1809
1810fn finish_items<Item>(
1811    progress: &mut Option<
1812        InterpretationProgress<
1813            Vec<Item>,
1814            Vec<
1815                Option<
1816                    InterpretationProgress<
1817                        Item,
1818                        Item::Custody,
1819                        ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1820                    >,
1821                >,
1822            >,
1823            Vec<ActionItemResult<Item>>,
1824        >,
1825    >,
1826) where
1827    Item: ActionItem,
1828{
1829    let Some(InterpretationProgress::Interpreting(rows)) = progress else {
1830        return;
1831    };
1832    if let Some(received) = finish_item_rows(rows) {
1833        *progress = Some(InterpretationProgress::Completed(received));
1834    }
1835}
1836
1837async fn interpret_items<Item, Interpreter, RootEvent, Path>(
1838    progress: &mut Option<
1839        InterpretationProgress<
1840            Vec<Item>,
1841            Vec<
1842                Option<
1843                    InterpretationProgress<
1844                        Item,
1845                        Item::Custody,
1846                        ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1847                    >,
1848                >,
1849            >,
1850            Vec<ActionItemResult<Item>>,
1851        >,
1852    >,
1853    interpreter: &mut Interpreter,
1854) where
1855    Item: ActionItem,
1856    Item::Custody: Send,
1857    Interpreter: InterpretItem<Item, RootEvent, Path>,
1858{
1859    prepare_items(progress);
1860    let Some(InterpretationProgress::Interpreting(rows)) = progress else {
1861        return;
1862    };
1863    for row in rows {
1864        match row.as_ref() {
1865            Some(InterpretationProgress::Completed(Interpretation::Corrupt(_))) => return,
1866            Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => continue,
1867            Some(InterpretationProgress::Original(_))
1868            | Some(InterpretationProgress::Interpreting(_)) => {}
1869            None => return,
1870        }
1871        settle_item::<Item, Interpreter, RootEvent, Path>(row, interpreter).await;
1872        Item::finish_interpretation(row);
1873        match row.as_ref() {
1874            Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {}
1875            _ => return,
1876        }
1877    }
1878}
1879
1880fn unattempted_items<Item>(
1881    progress: &mut Option<
1882        InterpretationProgress<
1883            Vec<Item>,
1884            Vec<
1885                Option<
1886                    InterpretationProgress<
1887                        Item,
1888                        Item::Custody,
1889                        ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
1890                    >,
1891                >,
1892            >,
1893            Vec<ActionItemResult<Item>>,
1894        >,
1895    >,
1896) where
1897    Item: ActionItem,
1898{
1899    if !matches!(progress, Some(InterpretationProgress::Original(_))) {
1900        return;
1901    }
1902    match progress.take() {
1903        Some(InterpretationProgress::Original(items)) => {
1904            let untouched = items.into_iter().map(SettledItem::Unattempted).collect();
1905            *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
1906                untouched,
1907            )));
1908        }
1909        other => *progress = other,
1910    }
1911}
1912
1913impl<Interpreter, RootEvent, Path, P> InterpretSends<Interpreter, RootEvent, Path>
1914    for Vec<Delivery<P>>
1915where
1916    Interpreter: InterpretItem<Delivery<P>, RootEvent, Path>,
1917    P: Protocol,
1918    P::Addr: Send,
1919    P::Msg: Send,
1920{
1921    fn interpret(
1922        progress: &mut Option<
1923            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1924        >,
1925        interpreter: &mut Interpreter,
1926    ) -> impl Future<Output = ()> + Send {
1927        async move {
1928            interpret_items(progress, interpreter).await;
1929            Self::finish_interpretation(progress);
1930        }
1931    }
1932}
1933
1934impl<Interpreter, RootEvent, Path, P, Occurrence> InterpretSends<Interpreter, RootEvent, Path>
1935    for Vec<ChildDelivery<P, Occurrence>>
1936where
1937    Interpreter: InterpretItem<ChildDelivery<P, Occurrence>, RootEvent, Path>,
1938    P: Protocol,
1939    P::Msg: Send,
1940{
1941    fn interpret(
1942        progress: &mut Option<
1943            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1944        >,
1945        interpreter: &mut Interpreter,
1946    ) -> impl Future<Output = ()> + Send {
1947        async move {
1948            interpret_items(progress, interpreter).await;
1949            Self::finish_interpretation(progress);
1950        }
1951    }
1952}
1953
1954impl<Interpreter, RootEvent, Path, Child, Source, Input, Occurrence>
1955    InterpretSends<Interpreter, RootEvent, Path>
1956    for Vec<ChildInput<Child, Source, Input, Occurrence>>
1957where
1958    Interpreter: InterpretItem<ChildInput<Child, Source, Input, Occurrence>, RootEvent, Path>,
1959    Child: Behavior,
1960    Child::Event: crate::ChildInputIngress<Source, Input>,
1961    Input: Send,
1962{
1963    fn interpret(
1964        progress: &mut Option<
1965            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1966        >,
1967        interpreter: &mut Interpreter,
1968    ) -> impl Future<Output = ()> + Send {
1969        async move {
1970            interpret_items(progress, interpreter).await;
1971            Self::finish_interpretation(progress);
1972        }
1973    }
1974}
1975
1976impl<Interpreter, RootEvent, Path, P> InterpretSends<Interpreter, RootEvent, Path>
1977    for Vec<EstablishedDelivery<P>>
1978where
1979    Interpreter: InterpretItem<EstablishedDelivery<P>, RootEvent, Path>,
1980    P: Protocol,
1981    P::Addr: RecipientAddress,
1982    <P::Addr as RecipientAddress>::Established<P>: Send,
1983    P::Msg: Send,
1984{
1985    fn interpret(
1986        progress: &mut Option<
1987            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
1988        >,
1989        interpreter: &mut Interpreter,
1990    ) -> impl Future<Output = ()> + Send {
1991        async move {
1992            interpret_items(progress, interpreter).await;
1993            Self::finish_interpretation(progress);
1994        }
1995    }
1996}
1997
1998impl SendSettlements for Vec<crate::Never> {
1999    type Settlements = Self;
2000    type SourceCustody = Self;
2001    type InterpretationCustody = Self;
2002    fn prepare_interpretation(
2003        progress: &mut Option<
2004            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2005        >,
2006    ) {
2007        match progress.take() {
2008            Some(InterpretationProgress::Original(original)) => {
2009                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
2010                    original,
2011                )))
2012            }
2013            retained => *progress = retained,
2014        }
2015    }
2016    fn finish_interpretation(
2017        progress: &mut Option<
2018            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2019        >,
2020    ) {
2021        Self::prepare_interpretation(progress);
2022    }
2023    fn unattempted(
2024        progress: &mut Option<
2025            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2026        >,
2027    ) {
2028        match progress.take() {
2029            Some(InterpretationProgress::Original(original)) => {
2030                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
2031                    original,
2032                )))
2033            }
2034            retained => *progress = retained,
2035        }
2036    }
2037}
2038
2039impl<Interpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path>
2040    for Vec<crate::Never>
2041{
2042    fn interpret(
2043        progress: &mut Option<
2044            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2045        >,
2046        _: &mut Interpreter,
2047    ) -> impl Future<Output = ()> + Send {
2048        async move {
2049            Self::prepare_interpretation(progress);
2050        }
2051    }
2052}
2053
2054impl<T> SendInput<T, Own> for Vec<T> {
2055    fn emit(&mut self, input: T) {
2056        self.push(input);
2057    }
2058}
2059
2060/// Requests interpreted by the runtime local to the emitting actor.
2061///
2062/// The request itself is interpreted by the runtime local to the emitting
2063/// actor. A request may carry a separate typed logical or exact destination;
2064/// its [`InterpreterRequest::LogicalProtocols`] reports any possible logical
2065/// destination. This lane keeps ordinary deliveries and interpreter operations
2066/// statically distinct.
2067#[derive(Debug, Clone, PartialEq, Eq)]
2068pub struct InterpreterRequests<M> {
2069    requests: Vec<M>,
2070}
2071
2072impl<M> InterpreterRequests<M> {
2073    #[must_use]
2074    pub fn new(requests: Vec<M>) -> Self {
2075        Self { requests }
2076    }
2077    #[must_use]
2078    pub fn one(request: M) -> Self {
2079        Self::new(vec![request])
2080    }
2081    #[must_use]
2082    pub fn as_slice(&self) -> &[M] {
2083        &self.requests
2084    }
2085    pub fn iter(&self) -> core::slice::Iter<'_, M> {
2086        self.requests.iter()
2087    }
2088    #[must_use]
2089    pub fn len(&self) -> usize {
2090        self.requests.len()
2091    }
2092    #[must_use]
2093    pub fn is_empty(&self) -> bool {
2094        self.requests.is_empty()
2095    }
2096    pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
2097        self.requests.extend(requests);
2098    }
2099    #[must_use]
2100    pub fn into_requests(self) -> Vec<M> {
2101        self.requests
2102    }
2103}
2104
2105impl<M> core::ops::Index<usize> for InterpreterRequests<M> {
2106    type Output = M;
2107    fn index(&self, index: usize) -> &Self::Output {
2108        &self.requests[index]
2109    }
2110}
2111
2112impl<M> IntoIterator for InterpreterRequests<M> {
2113    type Item = M;
2114    type IntoIter = std::vec::IntoIter<M>;
2115    fn into_iter(self) -> Self::IntoIter {
2116        self.requests.into_iter()
2117    }
2118}
2119
2120impl<'a, M> IntoIterator for &'a InterpreterRequests<M> {
2121    type Item = &'a M;
2122    type IntoIter = core::slice::Iter<'a, M>;
2123    fn into_iter(self) -> Self::IntoIter {
2124        self.requests.iter()
2125    }
2126}
2127
2128impl<M> SendEffects for InterpreterRequests<M> {
2129    fn empty() -> Self {
2130        Self::new(Vec::new())
2131    }
2132    fn append(&mut self, mut other: Self) {
2133        self.requests.append(&mut other.requests);
2134    }
2135}
2136
2137impl<M: InterpreterRequest> LogicalDeliveryProtocols for InterpreterRequests<M> {
2138    type Protocols = M::LogicalProtocols;
2139}
2140
2141impl<Event, M> SendsFor<Event> for InterpreterRequests<M>
2142where
2143    M: InterpreterRequest,
2144    M::ReturnToEmitter: ReturnToEmitterFor<Event>,
2145{
2146}
2147
2148impl<M> SendInput<M, Own> for InterpreterRequests<M> {
2149    fn emit(&mut self, input: M) {
2150        self.requests.push(input);
2151    }
2152}
2153
2154impl<Request> SendSettlements for InterpreterRequests<Request>
2155where
2156    Request: ActionItem,
2157{
2158    type Settlements = Vec<ActionItemResult<Request>>;
2159    type SourceCustody = (Self::Settlements, vec::IntoIter<ActionItemResult<Request>>);
2160    type InterpretationCustody = Vec<
2161        Option<
2162            InterpretationProgress<
2163                Request,
2164                Request::Custody,
2165                ItemSettlement<
2166                    Request,
2167                    Request::Accepted,
2168                    Request::Rejection,
2169                    Request::Prerequisite,
2170                >,
2171            >,
2172        >,
2173    >;
2174    fn prepare_interpretation(
2175        progress: &mut Option<
2176            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2177        >,
2178    ) {
2179        if matches!(progress, Some(InterpretationProgress::Original(_))) {
2180            match progress.take() {
2181                Some(InterpretationProgress::Original(original)) => {
2182                    *progress = Some(InterpretationProgress::Interpreting(
2183                        original
2184                            .requests
2185                            .into_iter()
2186                            .map(|item| Some(InterpretationProgress::Original(item)))
2187                            .collect(),
2188                    ));
2189                }
2190                retained => *progress = retained,
2191            }
2192        }
2193    }
2194    fn finish_interpretation(
2195        progress: &mut Option<
2196            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2197        >,
2198    ) {
2199        let Some(InterpretationProgress::Interpreting(rows)) = progress else {
2200            return;
2201        };
2202        if let Some(received) = finish_item_rows::<Request>(rows) {
2203            *progress = Some(InterpretationProgress::Completed(received));
2204        }
2205    }
2206    fn unattempted(
2207        progress: &mut Option<
2208            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2209        >,
2210    ) {
2211        match progress.take() {
2212            Some(InterpretationProgress::Original(original)) => {
2213                let items = original.requests;
2214                *progress = Some(InterpretationProgress::Completed(Interpretation::Complete(
2215                    items.into_iter().map(SettledItem::Unattempted).collect(),
2216                )));
2217            }
2218            retained => *progress = retained,
2219        }
2220    }
2221}
2222
2223impl<Interpreter, RootEvent, Path, Request> InterpretSends<Interpreter, RootEvent, Path>
2224    for InterpreterRequests<Request>
2225where
2226    Interpreter: InterpretItem<Request, RootEvent, Path>,
2227    Request: ActionItem,
2228    Request::Custody: Send,
2229{
2230    fn interpret(
2231        progress: &mut Option<
2232            InterpretationProgress<Self, Self::InterpretationCustody, Self::Settlements>,
2233        >,
2234        interpreter: &mut Interpreter,
2235    ) -> impl Future<Output = ()> + Send {
2236        async move {
2237            Self::prepare_interpretation(progress);
2238            let Some(InterpretationProgress::Interpreting(rows)) = progress else {
2239                return;
2240            };
2241            for row in rows {
2242                match row.as_ref() {
2243                    Some(InterpretationProgress::Completed(Interpretation::Corrupt(_))) => break,
2244                    Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {
2245                        continue;
2246                    }
2247                    Some(InterpretationProgress::Original(_))
2248                    | Some(InterpretationProgress::Interpreting(_)) => {}
2249                    None => return,
2250                }
2251                settle_item::<Request, Interpreter, RootEvent, Path>(row, interpreter).await;
2252                Request::finish_interpretation(row);
2253                match row.as_ref() {
2254                    Some(InterpretationProgress::Completed(Interpretation::Complete(_))) => {}
2255                    _ => break,
2256                }
2257            }
2258            Self::finish_interpretation(progress);
2259        }
2260    }
2261}
2262
2263#[cfg(test)]
2264mod tests {
2265    use super::*;
2266
2267    #[test]
2268    fn send_accumulation_obeys_identity_and_associativity() {
2269        let values = vec![1, 2];
2270        assert_eq!(Vec::new().combine(values.clone()), values);
2271        assert_eq!(values.clone().combine(Vec::new()), values);
2272
2273        let left = vec![1].combine(vec![2]).combine(vec![3]);
2274        let right = vec![1].combine(vec![2].combine(vec![3]));
2275        assert_eq!(left, right);
2276    }
2277
2278    #[test]
2279    fn vector_and_service_lanes_emit_and_iterate_in_order() {
2280        assert!(<Vec<u8> as SendEffects>::empty().is_empty());
2281        let mut vector = Vec::new();
2282        <Vec<u8> as SendInput<u8, Own>>::emit(&mut vector, 1);
2283        assert_eq!(vector, [1]);
2284
2285        let mut services = InterpreterRequests::one(2);
2286        services.extend([4, 5]);
2287        <InterpreterRequests<u8> as SendInput<u8, Own>>::emit(&mut services, 3);
2288        assert!(!services.is_empty());
2289        assert_eq!(services.as_slice(), [2, 4, 5, 3]);
2290        let borrowed = (&services).into_iter().copied().collect::<Vec<_>>();
2291        assert_eq!(borrowed, [2, 4, 5, 3]);
2292        let owned = services.into_iter().collect::<Vec<_>>();
2293        assert_eq!(owned, [2, 4, 5, 3]);
2294
2295        let requests = InterpreterRequests::new(vec![4, 5]).into_requests();
2296        assert_eq!(requests, [4, 5]);
2297    }
2298
2299    #[test]
2300    fn source_and_interpreter_lanes_report_complete_ordered_contents() {
2301        let empty = <SourceActions<u8> as SendEffects>::empty();
2302        assert!(empty.is_empty());
2303        assert_eq!(empty.len(), 0);
2304
2305        let mut prefix = <SourceActions<u8> as SendEffects>::empty();
2306        <SourceActions<u8> as SendInput<u8, Own>>::emit(&mut prefix, 1);
2307        <SourceActions<u8> as SendInput<u8, Own>>::emit(&mut prefix, 2);
2308        let mut suffix = <SourceActions<u8> as SendEffects>::empty();
2309        <SourceActions<u8> as SendInput<u8, Own>>::emit(&mut suffix, 3);
2310        <SourceActions<u8> as SendInput<u8, Own>>::emit(&mut suffix, 4);
2311        prefix.append(suffix);
2312        assert!(!prefix.is_empty());
2313        assert_eq!(prefix.len(), 4);
2314        let items = prefix.into_items();
2315        assert_eq!(items, [1, 2, 3, 4]);
2316
2317        let requests = InterpreterRequests::new(vec![5, 6, 7]);
2318        assert_eq!(requests.len(), 3);
2319    }
2320
2321    struct Returning;
2322
2323    impl InterpreterRequest for Returning {
2324        type ReturnToEmitter = ReturnsToEmitter<u8, crate::Here>;
2325        type LogicalProtocols = NoBirthProtocols;
2326    }
2327
2328    fn lawful<Event, Effects: SendsFor<Event>>() {}
2329
2330    #[test]
2331    fn local_return_proofs_compose_through_exact_event_layers() {
2332        type Inner = crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>;
2333        type Outer = crate::EventLayer<(), Inner>;
2334
2335        lawful::<Inner, InterpreterRequests<Returning>>();
2336        lawful::<Outer, SendLayer<NoSends, InterpreterRequests<Returning>>>();
2337    }
2338
2339    #[test]
2340    fn send_layer_emits_into_its_designated_owned_lane() {
2341        let mut effects = SendLayer::new(Vec::<u8>::new(), Vec::<u16>::new());
2342        <SendLayer<Vec<u8>, Vec<u16>> as SendInput<u8, Own>>::emit(&mut effects, 7);
2343        assert_eq!(effects.owned, [7]);
2344        assert!(effects.inner.is_empty());
2345    }
2346
2347    #[derive(Debug, PartialEq, Eq)]
2348    enum Seen {
2349        Inner(u8),
2350        Outer(u16),
2351    }
2352
2353    struct Trace(Vec<Seen>);
2354
2355    type TraceEvent =
2356        crate::EventLayer<u16, crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>>;
2357
2358    impl ActionItem for u8 {
2359        type Custody = (Option<Self>, Option<Self::Reply>);
2360        type Input<'a>
2361            = &'a mut Option<Self>
2362        where
2363            Self: 'a;
2364        type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
2365        fn prepare_interpretation(
2366            progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
2367        ) {
2368            prepare_item::<Self>(progress);
2369        }
2370        fn interpretation_input<'a>(
2371            custody: &'a mut Self::Custody,
2372        ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
2373        where
2374            Self: 'a,
2375        {
2376            let (input, received) = custody;
2377            match (&*input, &*received) {
2378                (Some(_), None) => Some((input, received)),
2379                _ => None,
2380            }
2381        }
2382        fn finish_interpretation(
2383            progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
2384        ) {
2385            finish_item::<Self>(progress);
2386        }
2387
2388        type Accepted = ();
2389        type Rejection = crate::Never;
2390        type Prerequisite = crate::Never;
2391    }
2392
2393    impl ActionItem for u16 {
2394        type Custody = (Option<Self>, Option<Self::Reply>);
2395        type Input<'a>
2396            = &'a mut Option<Self>
2397        where
2398            Self: 'a;
2399        type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
2400        fn prepare_interpretation(
2401            progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
2402        ) {
2403            prepare_item::<Self>(progress);
2404        }
2405        fn interpretation_input<'a>(
2406            custody: &'a mut Self::Custody,
2407        ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
2408        where
2409            Self: 'a,
2410        {
2411            let (input, received) = custody;
2412            match (&*input, &*received) {
2413                (Some(_), None) => Some((input, received)),
2414                _ => None,
2415            }
2416        }
2417        fn finish_interpretation(
2418            progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
2419        ) {
2420            finish_item::<Self>(progress);
2421        }
2422
2423        type Accepted = ();
2424        type Rejection = crate::Never;
2425        type Prerequisite = crate::Never;
2426    }
2427
2428    impl InterpretItem<u8, TraceEvent, crate::Inside<crate::Here>> for Trace {
2429        fn interpret_item<'a>(
2430            &'a mut self,
2431            input: &'a mut Option<u8>,
2432            received: &'a mut Option<<u8 as ActionItem>::Reply>,
2433        ) -> impl Future<Output = ()> + Send + 'a
2434        where
2435            u8: 'a,
2436        {
2437            async move {
2438                if received.is_some() {
2439                    return;
2440                }
2441                let Some(request) = input.take() else {
2442                    return;
2443                };
2444                self.0.push(Seen::Inner(request));
2445                *received = Some(ItemSettlement::Accepted(()));
2446            }
2447        }
2448    }
2449
2450    impl InterpretItem<u16, TraceEvent, crate::Here> for Trace {
2451        fn interpret_item<'a>(
2452            &'a mut self,
2453            input: &'a mut Option<u16>,
2454            received: &'a mut Option<<u16 as ActionItem>::Reply>,
2455        ) -> impl Future<Output = ()> + Send + 'a
2456        where
2457            u16: 'a,
2458        {
2459            async move {
2460                if received.is_some() {
2461                    return;
2462                }
2463                let Some(request) = input.take() else {
2464                    return;
2465                };
2466                self.0.push(Seen::Outer(request));
2467                *received = Some(ItemSettlement::Accepted(()));
2468            }
2469        }
2470    }
2471
2472    #[tokio::test]
2473    async fn structural_interpretation_visits_every_lane_inner_to_outer() {
2474        let effects = SendLayer::new(
2475            InterpreterRequests::new(vec![3_u16, 5]),
2476            SendLayer::new(InterpreterRequests::one(2_u8), NoSends),
2477        );
2478        let mut trace = Trace(Vec::new());
2479
2480        let mut progress = Some(InterpretationProgress::Original(effects));
2481        <_ as InterpretSends<_, TraceEvent, crate::Here>>::interpret(&mut progress, &mut trace)
2482            .await;
2483        let Some(InterpretationProgress::Completed(Interpretation::Complete(settlement))) =
2484            progress
2485        else {
2486            panic!("the exact structural trace must complete every lane");
2487        };
2488        assert_eq!(
2489            settlement.owned,
2490            [
2491                SettledItem::Attempted(ItemSettlement::Accepted(())),
2492                SettledItem::Attempted(ItemSettlement::Accepted(()))
2493            ]
2494        );
2495        assert_eq!(
2496            settlement.inner.owned,
2497            [SettledItem::Attempted(ItemSettlement::Accepted(()))]
2498        );
2499        let NoSends = settlement.inner.inner;
2500
2501        assert_eq!(trace.0, [Seen::Inner(2), Seen::Outer(3), Seen::Outer(5)]);
2502    }
2503}