Enables safe code changes to running workflows by branching on a named
change marker. On first execution of a new workflow, patched records
the marker and returns true — the workflow takes the new code path.
On replay of a workflow that was started before the patch existed,
no marker is found and patched returns false — the old code path
is followed.
Markers are accumulated in the workflow context and written to the job
hash by the engine (via the YAML schema's job.maps) when the worker
responds — no direct hash writes from the worker.
patched does not increment the execution counter, so it can be
inserted into existing workflow code without shifting the replay
positions of other durable operations.
Lifecycle
Add the patch: wrap the new behavior with if (await patched('id')).
Keep the old behavior in the else branch.
Wait for drain: once all workflows started before the patch have
completed, the else branch is dead code.
Deprecate: replace patched with deprecatePatch and remove the
else branch.
Clean up: remove both deprecatePatch and the if wrapper,
leaving only the new code.
Enables safe code changes to running workflows by branching on a named change marker. On first execution of a new workflow,
patchedrecords the marker and returnstrue— the workflow takes the new code path. On replay of a workflow that was started before the patch existed, no marker is found andpatchedreturnsfalse— the old code path is followed.Markers are accumulated in the workflow context and written to the job hash by the engine (via the YAML schema's
job.maps) when the worker responds — no direct hash writes from the worker.patcheddoes not increment the execution counter, so it can be inserted into existing workflow code without shifting the replay positions of other durable operations.Lifecycle
if (await patched('id')). Keep the old behavior in theelsebranch.elsebranch is dead code.patchedwithdeprecatePatchand remove theelsebranch.deprecatePatchand theifwrapper, leaving only the new code.Examples