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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// SPDX-License-Identifier: LGPL-3.0-only
//! `soma-som-ring` — the standalone ring execution engine for [soma(som)].
//!
//! This crate owns the cycle lifecycle (genesis + standard cycles) and the
//! registration API for the five extension relationships (BEFORE / THROUGH /
//! AFTER / AROUND / WITHIN) defined in OPUS §3.
//!
//! [soma(som)]: https://somasom.io
//!
//! ## What lives here
//!
//! | Component | Module |
//! |---|---|
//! | `RingEngine` | [`engine`] |
//! | `RingProcessor` trait | [`processor`] |
//! | `CycleObserver`, `NoOpObserver` | [`engine`] |
//! | `GenesisReport`, `CycleReport` | [`engine`] |
//! | `RingEngineError` | [`error`] |
//! | `RingCommand`, `ViewIntent`, `CommandDispatcher` | [`command`], [`dispatch`] |
//! | `FederationBridge` | [`federation`] |
//! | `Boundary` (crossing attestation) | [`boundary`] |
//!
//! Structural primitives (`Quad`, `Tree`, `Ring`, `UnitId`, the extension
//! trait family, persistence abstractions, governance trait interfaces) live
//! in the foundation crate [`soma_som_core`]. The split is the layer-purity
//! boundary: foundation primitives below, execution mechanics above.
//!
//! ## Dependencies
//!
//! ```text
//! soma-som-core ◄─── soma-som-ring
//! ```
//!
//! Zero framework dependencies: no async runtime, no HTTP server, no libc
//! bindings. Signing is injected at construction via the
//! [`soma_som_core::CrossingSigner`] trait so the engine never names a
//! concrete crypto backend.
//!
//! ## Example
//!
//! Construct a `RingEngine`, register a passthrough processor for each unit,
//! and run a single genesis cycle:
//!
//! ```
//! # fn main() -> Result<(), soma_som_ring::RingEngineError> {
//! use soma_som_core::TimingConfig;
//! use soma_som_core::quad::Quad;
//! use soma_som_core::types::{Layer, UnitId};
//! use soma_som_ring::{RingEngine, RingEngineError, RingProcessor};
//!
//! // Minimal RingProcessor — passes input through unchanged.
//! struct Echo;
//! impl RingProcessor for Echo {
//! fn process(
//! &mut self,
//! _unit: UnitId,
//! _cycle: u64,
//! input: &Quad,
//! _data: &Quad,
//! ) -> Result<Quad, RingEngineError> {
//! Ok(input.clone())
//! }
//! }
//!
//! let mut engine = RingEngine::new(TimingConfig::default());
//! engine.set_all_processors(|| Box::new(Echo));
//! assert_eq!(engine.active_units().len(), 6);
//!
//! // Genesis: bootstrap the ring with a seed.
//! let report = engine.genesis(b"example-seed")?;
//! assert!(engine.is_genesis_complete());
//! assert_eq!(report.crossing_records.len(), 12);
//! # Ok(())
//! # }
//! ```
//!
//! After genesis, drive standard cycles (each cycle traverses all 6 units +
//! the 12 crossings of the ring topology):
//!
//! ```
//! # use soma_som_core::TimingConfig;
//! # use soma_som_core::quad::Quad;
//! # use soma_som_core::types::UnitId;
//! # use soma_som_ring::{RingEngine, RingEngineError, RingProcessor};
//! # struct Echo;
//! # impl RingProcessor for Echo {
//! # fn process(
//! # &mut self,
//! # _u: UnitId,
//! # _c: u64,
//! # input: &Quad,
//! # _d: &Quad,
//! # ) -> Result<Quad, RingEngineError> {
//! # Ok(input.clone())
//! # }
//! # }
//! # fn main() -> Result<(), soma_som_ring::RingEngineError> {
//! let mut engine = RingEngine::new(TimingConfig::default());
//! engine.set_all_processors(|| Box::new(Echo));
//! engine.genesis(b"seed")?;
//!
//! let cycle = engine.cycle()?;
//! assert_eq!(cycle.cycle_index, 1);
//! assert_eq!(cycle.crossing_records.len(), 12);
//!
//! // Run 3 more cycles in a batch.
//! let reports = engine.run_cycles(3);
//! assert_eq!(reports.len(), 3);
//! assert!(reports.iter().all(|r| r.is_ok()));
//! assert_eq!(engine.cycle_index(), 4);
//! # Ok(())
//! # }
//! ```
// ── Primary re-exports ──────────────────────────────────────────────────
pub use ;
// Schema types are declared on `soma_som_core::Extension`. Consumers wanting to
// build a `CommandSchema` import it directly from `soma-som-core`:
//
// use soma_som_core::{CommandSchema, SchemaField, SchemaFieldType};
//
// `soma-som-ring` deliberately does NOT re-export these to keep the
// dependency direction honest (the trait surface owns the type) and to avoid
// a hidden semver coupling across the two crate boundaries.
pub use ;
pub use ;
pub use ;
pub use ;
pub use PassthroughProcessor;
pub use RingProcessor;