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