pub enum SuspendTrigger {
DagPosition,
ValidationExhausted {
task_name: String,
retry_count: u32,
last_attempt: String,
validation_errors: Vec<ValidationErrorWire>,
},
AgentUnable {
task_name: String,
unable: UnableRecord,
},
AgentVariant {
task_name: String,
variant: String,
payload: Value,
},
}Expand description
Why the engine suspended execution at a checkpoint. This is the canonical
wire-shape for the trigger discriminator on EngineEvent::Suspended;
Stream 4 (#149 + #156 approach C) populates the AgentUnable variant,
and Stream 6 (this stream, #156 approach B) populates
ValidationExhausted.
Serde-tagged with an internal "kind" discriminator so deserializers can
match on a single field without peeking at shape. Each variant carries
its payload inline — there is no sidecar unable_payload / exhaustion
field on Suspended itself.
Spec: docs/superpowers/specs/2026-04-18-epa-checkpoint-validation-design.md.
The wire shape is locked per the Wave-1 round-3 tracker decision
(“Suspended wire shape (S4 ↔ S6) = S6’s embedded-payload shape”).
Variants§
DagPosition
The DAG reached an explicit checkpoint cp(...) call site. This is
today’s only behaviour; the variant carries no payload because the
checkpoint’s own expects: schema fully describes what comes back
on resume.
ValidationExhausted
The task’s on_validation_exhausted: property fired: all
validation retries consumed without producing a payload that passes
the parse→schema→custom pipeline. Studio / SDKs render the last
failing attempt + its errors so the human can correct in place.
Fields
validation_errors: Vec<ValidationErrorWire>AgentUnable
Reserved for Stream 4 (#149 + #156 approach C) — emitted when a
task with a T | Unable return type produces an Unable value and
the flow routes it to a checkpoint via on unable <cp>. Shape is
invariant across Stream 4’s four on unable forms: the payload is
always the Unable record (reason/missing/category). Not produced
by the engine in Stream 6 — defined here because Stream 6 owns the
canonical SuspendTrigger type so Stream 4’s engine-emit site is
pure code addition, no wire-shape change.
AgentVariant
Emitted when a task whose declared return type is a discriminated
union A | B | ... | Unable produces a non-Unable variant and the
flow routes that variant to a checkpoint via on <Variant> <cp>.
variant is the canonical record name (PascalCase, matches the
source identifier); payload is the parsed record (with the
kind discriminator stripped). Studio renders a generic
“agent returned variant
AgentUnable remains a specialization for the Unable arm —
rather than AgentVariant { variant: "Unable", ... } — to
preserve the existing Studio rendering path from #157 (zero-day
compat).
Trait Implementations§
Source§impl Clone for SuspendTrigger
impl Clone for SuspendTrigger
Source§fn clone(&self) -> SuspendTrigger
fn clone(&self) -> SuspendTrigger
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SuspendTrigger
impl Debug for SuspendTrigger
Source§impl Default for SuspendTrigger
impl Default for SuspendTrigger
Source§fn default() -> SuspendTrigger
fn default() -> SuspendTrigger
Source§impl<'de> Deserialize<'de> for SuspendTrigger
impl<'de> Deserialize<'de> for SuspendTrigger
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for SuspendTrigger
impl PartialEq for SuspendTrigger
Source§fn eq(&self, other: &SuspendTrigger) -> bool
fn eq(&self, other: &SuspendTrigger) -> bool
self and other values to be equal, and is used by ==.