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
//! The gated-publish seam: the single home of the registration protocol
//! every fiber-lifecycle-bound resource crosses (ADR 0015).
//!
//! The protocol, fixed: gate (lock-free liveness assert) → journal
//! lock → under-lock recheck → [`PublishStep::publish`] (fallible — a
//! refusal means *nothing happened*: nothing published, no cleanup
//! obligation committed) → cleanup-obligation push. The variable part —
//! what to publish — crosses the section as a [`PublishStep`], a
//! crate-only trait: no user-implementable bound, no closure, no `dyn`
//! dispatch inside the section (ADR 0010 decision 1's law, in the trait
//! spelling of the entry-enum it ratified).
//!
//! # Nesting posture (the crate's lock-order audit at landing, ADR 0015)
//!
//! The canonical nesting is **disposables outside, store inside**:
//! every resource-publishing step with a semantic-owner store takes that
//! store's bookkeeping lock beneath the disposables guard this module holds.
//! Unifying on that direction reversed
//! exactly one pre-existing edge — `provide`'s slots ∋ disposables —
//! and the audit of the crate's full nesting map (eight nesting sites
//! across six distinct lock pairs at landing time) found the reversal
//! cycle-free. The exact publisher set has evolved since that landing
//! audit; the retained v3 invariant is the direction, not a store inventory:
//! no semantic-owner store path takes its bookkeeping lock and then the
//! cleanup journal lock. Drains run cleanups with no guard held, so a
//! withdrawal firing during drain never re-enters this order.
use crateCleanup;
use crateFiber;
/// What a gated push publishes inside its critical section. Crate-only
/// by visibility — the section stays free of user-implementable code
/// (ADR 0010 decision 1). The enum → trait move is ADR 0015's: one enum
/// cannot carry every publisher's payload shape without infecting every
/// caller's signature.
pub ;
pub
pub
/// Publish nothing — the plain effect-push step.
pub ;
/// The gated, atomic core every registration path crosses: gate →
/// lock → recheck → publish → push, all fixed code (ADR 0010's
/// `push_gated` shape, promoted from a `Fiber` method to the seam).
///
/// The cleanup obligation arrives already wrapped in the journal's
/// normalized [`Cleanup`] shape: construction and any result conversion
/// are caller-side, so nothing user-owned executes inside the section.
pub