Workflow Status
You can monitor the status of the workflow by calling the running() method, which returns true if the workflow is still running and false if it has completed or failed.
while ($workflow->running());
Status Values
The status() method returns string statuses:
reserved
pending
running
waiting
cancelled
terminated
completed
failed
reservedmeans an instance id has been created but the first start command has not been accepted yetpendingmeans the run exists and has work ready to be claimedrunningmeans a workflow task is actively leased to a workerwaitingmeans the run is blocked on a durable resume source such as an activity, timer, or named signalcancelledmeans an accepted engine-level cancel command closed the current runterminatedmeans an accepted engine-level terminate command force-closed the current runcompleted,failed,cancelled, andterminatedare terminal run states
When a run uses continueAsNew(), the old run ends with status = completed and closed_reason = continued. Waterline keeps that run in the completed bucket while still surfacing the exact closed_reason so operators can see that the instance rolled forward into a newer run.
running() returns true for pending, running, and waiting.
Signals, Updates, and Commands
Named signal waits, explicit update commands, and attemptSignal() / signal() external input are supported. Cancellation and termination are not modeled as ordinary user-defined signals. They remain explicit runtime commands on Workflow\V2\WorkflowStub, which means Waterline and command history can distinguish a run that failed from a run that was cancelled, terminated, or updated on purpose.
Those command outcomes are also exposed over webhook routes:
POST /webhooks/instances/{workflowId}/updates/{update}
POST /webhooks/instances/{workflowId}/cancel
POST /webhooks/instances/{workflowId}/terminate
Accepted update commands leave the run open while mutating replay-safe workflow state. Accepted cancel and terminate commands move the run into cancelled or terminated. Rejected commands leave the run status unchanged and currently include run-state outcomes such as rejected_not_started and rejected_not_active, plus contract-validation outcomes such as rejected_unknown_signal and rejected_unknown_update.
Waterline keeps the actual run status as cancelled or terminated, keeps status_bucket = failed as the compatibility bridge for both states, and also exposes is_terminal = true on list/detail payloads. Current Waterline builds use that raw status to offer dedicated failed, cancelled, and terminated list views, so operator-driven closures no longer have to hide inside the generic failed screen even though older bucket-oriented consumers can still rely on the shared failed bucket.
State Machine
This is the state machine for a workflow status.