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
//! The participant engine: the authoring traits, the role-gated capability
//! surface, the setup/step/reset contexts, the clock and step scheduler, the
//! launch contract, and the runner that drives them.
//!
//! Authoring uses a role attribute on a unit marker, an optional
//! `#[derive(phoxal::Config)]`, and an ordinary `Participant` implementation.
//!
//! [`metadata`] is the one public path here: the compatibility record every
//! participant artifact embeds, and its strict reader, which build-time tooling
//! reads back out of a linked binary. Nothing else in this module is a public
//! path. Whatever the framework publishes to participant authors goes out
//! through the crate-root facade in `lib.rs`, and whatever macro-generated code
//! needs goes out through `crate::__private`; modules inside the engine import
//! from the module that owns the item.
use ;
use Duration;
// The two process-boundary contracts, whose own headers document them: the
// participant-artifact metadata document, and the launch argv. Both are read by
// a *host* - the CLI stages a binary and launches it, the supervisor reads what
// it staged - so a participant profile compiles them and reads neither: it
// writes the metadata document from a role attribute's const-eval path, and it
// decodes argv rather than encoding it.
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
// `surface` is the one engine module a participant crate reaches by name: the
// role attributes emit `impl $crate::__private::surface::…` into the
// participant's own crate, so the module itself is re-exported there. It has to
// stay `pub` for that re-export to be legal; `#[doc(hidden)]` keeps it out of
// the documented surface, the same as the `__private` path it is reached by.
/// A duration as whole nanoseconds, saturating at [`u64::MAX`].
///
/// Every nanosecond count the engine carries is a `u64` - `RobotInstant` ticks
/// and the `*_ns` fields of a runtime-performance rollup alike - while
/// [`Duration::as_nanos`] is a `u128`. Narrowing it in one place is what keeps
/// the saturation identical on the cadence path and the telemetry path instead
/// of letting a second copy wrap.
pub
/// Lock `mutex`, taking the guard even when another thread panicked holding it.
///
/// Poisoning reports only that some thread unwound somewhere; it says nothing
/// about the guarded value. Everything the engine locks is a plain counter,
/// instant or channel handle updated by code that cannot unwind mid-update, so
/// the state behind a poisoned lock is exactly as consistent as behind a healthy
/// one. These locks all sit on the logging, clock and step paths, where refusing
/// to proceed would turn one unrelated thread's panic into a participant that
/// silently stops logging, stops stepping, or stops being able to date its own
/// samples - strictly worse than carrying on with the state as it stands. So
/// every lock in the engine recovers the guard rather than propagating the
/// poison.
pub