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