The Hook System
Hooks are implemented through thehook.Notifier interface. When an event fires, the engine calls Notifier.Notify() with the event type, the workflow run ID, and the task run ID (if applicable). The notifier then executes the referenced template — typically by submitting a new single-task sub-workflow or dispatching the template through the broker.
Hook execution is fire-and-forget: if a hook template fails, that failure is reported to the errsink.ErrorSink but does not affect the phase of the triggering task or the overall workflow state. This ensures hooks never block the primary execution path.
To enable hooks, inject a hook.Notifier implementation when creating the engine:
Where Hooks Are Declared
Hooks can be attached at two levels.Workflow-level hooks
Declared on
spec.hooks. Fire once for the entire workflow run based on the workflow’s terminal phase.Task-level hooks
Declared on individual DAG task nodes via the
hooks field. Fire when that specific task transitions phases.Workflow-Level Hooks
Workflow-level hooks are declared onspec.hooks and fire based on the overall workflow outcome:
Workflow Hook Events
onExit is an always-run hook — use it for cleanup, notification, or audit logging that must happen regardless of outcome.
Task-Level Hooks
Task-level hooks are declared on DAG task nodes (call sites), not on the template definition. This means the same template can have different hooks depending on where it is called from:Task Hook Events
onSuspend and onResume are meaningful only for tasks that use the suspend/resume pattern. They fire on every suspend/resume cycle, not just the first.
Suspend/Resume Hook Lifecycle
The full hook sequence for a task that suspends once then completes:1
Task dispatched to executor
onStart fires.2
Executor returns ExecCodeSuspended
Task moves to
PhaseSuspended. onSuspend fires.3
Engine.Resume() called with approval payload
Task is re-dispatched with merged inputs.
onResume fires.4
Executor returns ExecCodeSucceeded
Task moves to
PhaseSucceeded. onSuccess fires.5
Exit hook runs
onExit fires (always runs on terminal phases).Cancellation Hooks
Cancel hooks fire when a workflow is stopped viaEngine.Cancel(). Workflow-level onCancel fires once for the workflow; task-level onCancel fires for each task that was non-terminal at the time of cancellation:
Hook Reference Format
Each hook is an object with a singletemplate field naming the template to execute:
spec.templates list. The engine does not pass the triggering task’s inputs or outputs to the hook template automatically — design your hook templates to be self-contained or read state from an external store if needed.
Hook templates run as standalone task invocations. They execute after the phase transition is committed to the store, so the triggering task’s final phase and outputs are already readable when the hook runs.
Fire-and-Forget Semantics
Hook execution is intentionally decoupled from the primary workflow phase machine:- A hook template that fails is reported to the
errsink.ErrorSinkbut does not change the triggering task’s phase. - Hook failures do not trigger retries or cascade to the workflow’s terminal phase.
- If no
hook.Notifieris configured (theWithHookNotifieroption is omitted), hook declarations in the workflow document are silently ignored — the workflow runs normally without notifications.