run.events() yields NikaRunEvent — the SDK’s lifecycle vocabulary, with
dotted kinds like task.started and the task id on event.task:
task.started, run.settled, …) are the
SDK’s owned vocabulary; the untouched engine frame rides on event.raw.
event.task is present only on frames that named a task — guard it.
For the one-task mock hello, the published package emits exactly six
events: run.started → task.scheduled → task.started →
task.completed → engine.event (the engine’s workflow_completed
frame) → run.settled (succeeded). Longer workflows emit more — never
assert a fixed count. Engine protocol frames surface as engine.event
with the original frame preserved on event.raw; native and HTTP
transports differ in exactly which raw frames exist.
The kind set is additive: keep a default branch so unknown events stay
visible to diagnostics without crashing an older interface. Never infer
completion from the last recognized kind; use run.result().
result.settlement carries the engine’s full settlement, including cause,
elapsed time, task tally, spend and error when present. Remote replay and
attachment preserve it even after the event cursor has passed the settlement.
Unknown evidence stays absent; an interrupted job need not have a runtime
settlement. A paused result ends this observation leg and event view while
leaving the durable job available for a later engine-owned resume.
Each event subscriber has a bounded queue. A slow consumer receives
NikaEventBufferOverflowError instead of silent loss. Tune a view with
bufferSize, bounded by the client’s eventBufferSize.
An AbortSignal stops only its observer. It does not end engine work. Call
run.cancel() when cancellation is intended.
Run and cancel
Open the view and await terminal settlement.
Receipts
Move from transient presentation to durable proof.