behavior/exit.rs
1//! `Exit` — the trace-exit vocabulary: the `R` corner of the verdict family
2//! (`Step<Ph, Exit>`, ADR-0029) that a stopped fold rides out on. Moved
3//! in-crate when the `behavior-reference` crate was retired; it is the
4//! core's own vocabulary now, not a shared one.
5
6use crate::behavior::Address;
7
8/// How a fold ends. The `R` parameter of the become verdict (`Step<Ph, Exit>`):
9/// a `Stop` carries one of these; the driver also mints `Collected` when the
10/// mailbox drains with no self-stop.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum Exit<A: Address> {
13 /// Clean self-stop (`Flow::Stop(Normal)`'s image).
14 Normal,
15 /// Sources exhausted — the mailbox-closed / ref-count-collection image.
16 Collected,
17 /// A watch layer propagated a linked peer's death, carrying its address.
18 LinkDied(A),
19 /// A supervision layer stopped because it could no longer preserve its
20 /// child topology.
21 SupervisionFailed(SupervisionFailureReason),
22}
23
24/// Why a supervisor could no longer preserve its child topology.
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum SupervisionFailureReason {
27 /// A restart policy admitted the worker termination, but a later restart
28 /// constraint denied the requested replacement set.
29 RestartDenied(RestartDenial),
30 /// The stable proxy itself stopped and therefore cannot accept a fresh
31 /// worker incarnation at its existing address.
32 StableChildStopped,
33}
34
35/// Why an otherwise eligible replacement set was denied.
36///
37/// The vocabulary is deliberately exhaustive. Additional restart gates must
38/// expose their concrete denial here (or in a future statically composed sum)
39/// rather than hiding it behind an open or erased reason type.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum RestartDenial {
42 /// The replacement set would exceed the configured restart budget.
43 BudgetExceeded {
44 /// Replacement attempts currently retained in the restart window.
45 restarts_in_window: usize,
46 /// Number of workers the selected strategy would replace.
47 replacements_requested: usize,
48 /// Configured maximum replacements in one window.
49 maximum_restarts: u32,
50 },
51}
52
53/// Why actor execution terminated abnormally.
54///
55/// The reason value stays with the interpreter: heterogeneous behavior and
56/// environment errors, panic payloads, and executor cancellation details are
57/// runtime plumbing. Observation carries only the statically known terminal
58/// domain. Every variant is abnormal; the distinction is preserved for
59/// supervision policy and truthful traces.
60///
61/// This classification is Bombay policy layered over the actor algebra. It
62/// does not add an effect to a behavior transition: interpreters mint a
63/// `Crash` only when execution terminates without an [`Exit`].
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum Crash {
66 /// `Behavior::init` or `Behavior::step` returned its declared error.
67 Failed,
68 /// The interpreter could not execute an emitted effect and terminated the
69 /// actor.
70 EnvironmentFailed,
71 /// Actor execution unwound through a panic.
72 Panicked,
73 /// The executor cancelled actor execution before normal completion.
74 Cancelled,
75}