1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Signal module - Optional, best-effort signaling for hints and notifications
//!
//! ## Important: Non-Authoritative
//!
//! This module provides **optional, best-effort signaling** for hints and
//! notifications. Signals are **not authoritative** and the kernel must work
//! correctly even if all signaling infrastructure is disabled.
//!
//! ## Three Kinds of "Messages"
//!
//! There are three distinct kinds of communication in the system:
//!
//! | Kind | Example | Where it belongs |
//! | -------------------------- | ------------------------------- | ----------------------- |
//! | **Execution events** | step started, decision made | **Kernel only** (`kernel/event.rs`) |
//! | **Control signals** | cancel execution, scale workers | **Control plane** (cloud) |
//! | **Infrastructure signals** | notify UI, wake worker | **This module** (optional) |
//!
//! ## Signal Semantics
//!
//! Signals are:
//! - ✅ Non-authoritative (may be ignored)
//! - ✅ Best-effort (delivery not guaranteed)
//! - ✅ Optional (kernel works perfectly without them)
//! - ✅ For hints only (wake-up, notify, nudge)
//!
//! Signals are NOT:
//! - ❌ Execution events (use `kernel/event.rs`)
//! - ❌ State changes (use `kernel/reducer.rs`)
//! - ❌ Required for correctness
//! - ❌ Durable queues (use control plane)
//!
//! ## Invariant
//!
//! **The kernel must remain correct, deterministic, and replayable
//! even if all signaling infrastructure is disabled.**
//!
//! ## CRITICAL INVARIANT: Signals Never Drive Execution State
//!
//! SignalBus implementations MUST NOT have access to:
//! - ExecutionKernel
//! - Reducer
//! - ExecutionState
//!
//! Signals are hints only. If someone can "resume execution" via signal,
//! that is an architectural leak.
//!
//! **Enforcement**: SignalBus trait and implementations should not import
//! any kernel modules. If you find yourself needing kernel types in signal
//! code, you are violating this invariant.
//!
//! ## Use Cases
//!
//! ### Allowed Signal Uses
//! - ✅ Wake a paused execution
//! - ✅ Notify local UI
//! - ✅ Tell a worker "check for work"
//! - ✅ Hint that something changed
//!
//! ### Forbidden Signal Uses
//! - ❌ Carry execution events (use `kernel/event.rs`)
//! - ❌ Control execution state (use `kernel/reducer.rs`)
//! - ❌ Replace durable queues (use control plane)
//! - ❌ Drive orchestration logic (use control plane)
//!
//! ## Control Plane Messaging
//!
//! Authoritative messaging (Redis, Kafka, durable queues) lives in the
//! control plane (`apps/api/` or future `enact-control-plane` crate), not here.
//! The control plane:
//! - Implements durable queues
//! - Translates infra messages → kernel invocations
//! - Fans out kernel events to external systems
//!
//! The kernel does not know *how* messages travel. It only knows:
//! > "I was invoked."
use async_trait;
use Arc;
use broadcast;
pub use InMemorySignalBus;
/// Receiver for subscribed signals
pub type SignalReceiver<T> = Receiver;
/// SignalBus trait - Optional, best-effort signaling abstraction
///
/// This trait provides a non-authoritative signaling mechanism for hints
/// and notifications. Implementations should be lightweight and optional.
///
/// The kernel must work correctly even if SignalBus is disabled or fails.
/// Boxed SignalBus for dynamic dispatch
pub type DynSignalBus = ;