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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
//! Schedule markers for graph execution lifecycle events.
//!
//! These marker types identify when hooks are invoked during graph execution.
//! Use them with [`ScheduleId::of::<T>()`](polaris_system::plugin::ScheduleId::of)
//! for registration, or use the type-safe registration methods like
//! [`register_observer::<OnSystemStart>`](super::HooksAPI::register_observer).
//!
//! # Pure Markers
//!
//! Schedule markers are pure marker types implementing the [`Schedule`] trait.
//! Event data is provided via the unified [`GraphEvent`](super::events::GraphEvent)
//! enum, which all hooks receive.
use Schedule;
// ─────────────────────────────────────────────────────────────────────────────
// System Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before a system starts execution.
///
/// # Validation
///
/// Resources provided by `OnSystemStart` hooks are considered during validation,
/// as they are guaranteed to be available before the system runs.
///
/// Event data: [`GraphEvent::SystemStart`](super::events::GraphEvent::SystemStart)
;
/// Marker type for hooks called after a system completes successfully.
///
/// # Validation
///
/// Resources provided by `OnSystemComplete` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::SystemComplete`](super::events::GraphEvent::SystemComplete)
;
/// Marker type for hooks called when a system fails.
///
/// # Validation
///
/// Resources provided by `OnSystemError` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::SystemError`](super::events::GraphEvent::SystemError)
;
// ─────────────────────────────────────────────────────────────────────────────
// Decision Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before a decision node evaluates its predicate.
///
/// This hook fires before the decision node evaluates its predicate, allowing you
/// to inspect the input data or context before the branch is selected. Use this
/// for logging, metrics, or resource injection that should occur regardless of
/// which branch is taken.
///
/// # Validation
///
/// Resources provided by `OnDecisionStart` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::DecisionStart`](super::events::GraphEvent::DecisionStart)
;
/// Marker type for hooks called after a decision branch is selected and executed.
///
/// # Validation
///
/// Resources provided by `OnDecisionComplete` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::DecisionComplete`](super::events::GraphEvent::DecisionComplete)
;
// ─────────────────────────────────────────────────────────────────────────────
// Switch Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before a switch node evaluates its discriminator.
///
/// # Validation
///
/// Resources provided by `OnSwitchStart` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::SwitchStart`](super::events::GraphEvent::SwitchStart)
;
/// Marker type for hooks called after a switch case is selected and executed.
///
/// # Validation
///
/// Resources provided by `OnSwitchComplete` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::SwitchComplete`](super::events::GraphEvent::SwitchComplete)
;
// ─────────────────────────────────────────────────────────────────────────────
// Loop Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before a loop begins execution.
///
/// # Validation
///
/// Resources provided by `OnLoopStart` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::LoopStart`](super::events::GraphEvent::LoopStart)
;
/// Marker type for hooks called at the start of each loop iteration.
///
/// # Validation
///
/// Resources provided by `OnLoopIteration` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::LoopIteration`](super::events::GraphEvent::LoopIteration)
;
/// Marker type for hooks called after a loop completes all iterations.
///
/// # Validation
///
/// Resources provided by `OnLoopEnd` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::LoopEnd`](super::events::GraphEvent::LoopEnd)
;
// ─────────────────────────────────────────────────────────────────────────────
// Parallel Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called at the start of parallel execution.
///
/// # Validation
///
/// Resources provided by `OnParallelStart` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::ParallelStart`](super::events::GraphEvent::ParallelStart)
;
/// Marker type for hooks called after all parallel branches complete.
///
/// # Validation
///
/// Resources provided by `OnParallelComplete` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::ParallelComplete`](super::events::GraphEvent::ParallelComplete)
;
// ─────────────────────────────────────────────────────────────────────────────
// Graph-Level Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before graph execution begins.
///
/// This hook fires once at the start of graph execution, before any systems
/// are run. Providers registered on this schedule make resources available
/// to all systems in the graph.
///
/// # Validation
///
/// Resources provided by `OnGraphStart` hooks are considered during validation,
/// as they are guaranteed to be available before any system executes.
///
/// Event data: [`GraphEvent::GraphStart`](super::events::GraphEvent::GraphStart)
;
/// Marker type for hooks called after graph execution completes.
///
/// This hook fires once at the end of graph execution if the graph completes successfully. Use this
/// for final reporting, cleanup, or post-processing actions. Use `OnGraphFailure` for error handling instead.
///
/// Event data: [`GraphEvent::GraphComplete`](super::events::GraphEvent::GraphComplete)
///
/// # Validation
///
/// Resources provided by `OnGraphComplete` hooks are **not** considered during
/// validation, as they arrive after system execution.
;
/// Marker type for hooks called when graph execution fails with an error.
///
/// This hook fires once at the end of graph execution if an error occurs. Use this
/// for error reporting, cleanup, or compensating actions.
///
/// Event data: [`GraphEvent::GraphFailure`](super::events::GraphEvent::GraphFailure)
;
// ─────────────────────────────────────────────────────────────────────────────
// Scope Schedules
// ─────────────────────────────────────────────────────────────────────────────
/// Marker type for hooks called before a scope node begins execution.
///
/// This hook fires before the scope's embedded graph is executed, allowing you
/// to inspect the context policy or inject resources before the inner graph runs.
///
/// # Validation
///
/// Resources provided by `OnScopeStart` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::ScopeStart`](super::events::GraphEvent::ScopeStart)
;
/// Marker type for hooks called after a scope node completes execution.
///
/// This hook fires after the scope's embedded graph finishes and outputs are
/// merged back into the parent context.
///
/// # Validation
///
/// Resources provided by `OnScopeComplete` hooks are **not** considered during
/// validation.
///
/// Event data: [`GraphEvent::ScopeComplete`](super::events::GraphEvent::ScopeComplete)
;
// ─────────────────────────────────────────────────────────────────────────────
// Composite Schedule Type
// ─────────────────────────────────────────────────────────────────────────────
/// Composite type covering all graph execution schedules.
///
/// This type can be used with
/// [`IntoScheduleIds`](polaris_system::plugin::IntoScheduleIds) to register a
/// hook on every graph lifecycle event at once.
///
/// # Example
///
/// ```
/// # use polaris_graph::hooks::schedule::AllGraphSchedules;
/// # use polaris_graph::hooks::GraphEvent;
/// # use polaris_graph::hooks::HooksAPI;
/// # let hooks = HooksAPI::default();
///
/// hooks.register_observer::<AllGraphSchedules, _>(
/// "trace_all",
/// |event: &GraphEvent| {
/// tracing::debug!("{event}");
/// },
/// )?;
/// # Ok::<(), polaris_graph::hooks::HookRegistrationError>(())
/// ```
pub type AllGraphSchedules = ;