Called at the END of every attempt (10.1) — every outcome, with the
attempt's AttemptRecord (timing, outcome, category, the
retry-or-stop decision): a stage's own (record.kind === 'stage', under a
retry policy, a timeoutMs or a run deadline), and the calls it makes
('call', scope.$call) and outside attempts it reports ('observed')
during the stage (P2). A stage attempt fires before onStageRetry when it
is retried, and before onError / onStageExecuted for the last.
structuredError is the attempt's served error (raw included unless the
policy masked it; never for an observed attempt); absent for a success or
a pause.
Event arithmetic: one per attempt — for a stage, the number of attempts it
made plus one per call or observed attempt (filter on record.kind).
OptionaltraversalContext: TraversalContextCalled when a stage triggers break (early termination).
OptionaltraversalContext: TraversalContextOptionalreason: string
Optional string passed to scope.$break(reason).
OptionalpropagatedFromSubflow: string
When set, this break was raised on the
parent because an inner subflow (this id) broke with propagateBreak
enabled. Used by recorders to distinguish originating vs propagated
breaks and render them accordingly.
Called when a decider selects a branch. Most valuable for LLM context.
Optionalrationale: stringOptionaldeciderDescription: stringOptionaltraversalContext: TraversalContextOptionalevidence: DecisionEvidenceCalled when a stage throws an error, with its SERVED form: for a stage's own failure that is
RedactionRule.retainStageError (the diagnostic policy applied once), elsewhere extractErrorInfo.
OptionaltraversalContext: TraversalContextCalled when a fork executes all children in parallel.
OptionaltraversalContext: TraversalContextCalled on loop iteration (back-edge traversal).
Optionaldescription: stringOptionaltraversalContext: TraversalContextCalled on linear continuation from one stage to the next.
Optionaldescription: stringOptionaltraversalContext: TraversalContextCalled when a pausable stage pauses execution.
OptionaltraversalContext: TraversalContextCalled when a paused stage is resumed.
OptionaltraversalContext: TraversalContextCalled once per top-level executor.run(), AFTER the last stage commits.
output is the retained form of the chart's return. NOT fired on pause (the run
didn't end; it suspended) or on uncaught error. Subflow-traversers do
NOT fire this event — they fire onSubflowExit.
OptionaltraversalContext: TraversalContextCalled once per top-level executor.run() when traversal throws a
NON-pause error, BEFORE the exception propagates to run()'s caller.
This is the TERMINAL counterpart to onRunEnd — it closes the run
boundary symmetrically so every onRunStart is followed by exactly
one of onRunEnd (clean) or onRunFailed (error). Without it, a
live monitor sees onRunStart then silence on a failed run and can't
tell "still running" from "crashed."
Errors STILL throw — this is the observable terminal signal, not a recovery mechanism (no routing, no error-subflow). Pause is NOT an error, so it does not fire this. Subflow-traversers do NOT fire it; their errors propagate to the parent and surface at the top level.
OptionaltraversalContext: TraversalContextOptionalfailure: TerminalFailureContextCalled once per top-level executor.run(), BEFORE the first stage executes.
input is the retained form of run({input}) after schema validation;
the run's key/path redaction applies before dispatch. See FlowRunEvent.
Subflow-traversers do NOT fire this event — they fire onSubflowEntry.
OptionaltraversalContext: TraversalContextCalled when a selector picks a subset of children.
OptionaltraversalContext: TraversalContextOptionalevidence: SelectionEvidenceCalled when a stage completes its main work. Fires for ALL stage
kinds ('linear', 'decider', 'fork', 'selector', 'subflow-mount')
AFTER the corresponding specialized event (onDecision, onFork,
onSelected, onSubflowEntry). For linear stages, fires after
the stage function returns.
Consumers tracking "did this stage run?" use this event uniformly
and switch on stageType for kind-specific work.
Called when an attempt at a stage with a declared retry policy failed
AND another attempt will run. Fires after that attempt's onAttempt,
after its staged writes are discarded and BEFORE the backoff wait, so a
live monitor learns "retrying in 500 ms" when the decision is made, not
after the wait.
Event arithmetic: an exhausted policy fires attempts - 1 of these and
then one onError; a retryOn that declines fires ZERO of these and one
onError. The final attempt never fires this event.
OptionaltraversalContext: TraversalContextCalled when entering a subflow (nested context boundary).
OptionalsubflowId: stringOptionaldescription: stringOptionaltraversalContext: TraversalContextOptionalmappedInput: Record<string, unknown>Called when exiting a subflow.
OptionalsubflowId: stringOptionaltraversalContext: TraversalContextOptionaloutputState: Record<string, unknown>OptionalonCalled when a fork child failed and the run's throttlingErrorChecker
classified its error as throttling (9.39.0). The child's failure takes
its ordinary path too; this only names it as throttling.
OptionaltraversalContext: TraversalContext
Returns accumulated narrative sentences in execution order.