You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Replay redriven memo, search-attribute and signal-wait events at their reused time #235
Follow-up to #232, from the Workflow 2.19.0 review.
Gap
Workflow 2.19.0 lets redrive reuse more completed steps:
workflow#1001 reuses MemoUpserted and SearchAttributesUpserted.
workflow#1002 reuses an applied signal wait: SignalWaitOpened, SignalReceived and SignalApplied.
On the successor run these events carry reused_from_run_id and reused_recorded_at. Core replays now() after them at reused_recorded_at, via RedriveReplayClock::recordedAt().
The 2.19.0 notes say service-mode SDKs are not yet qualified for these events. If this SDK takes replay time from recorded_at or timestamp on any of these five events, a redriven workflow's now() after an upsert or signal wait comes out as the redrive time, not the source run's time. #232 only covered side effects, markers, timers and start time.
Done when
For each of the five event types, replay time prefers payload.reused_recorded_at when it is present.
Every event type this SDK actually replays has a regression fixture. It must be a redrive successor history with the reuse keys, and it must fail before the change and pass after it. Assert per-event provenance: each named event exists and carries both keys. A combined "any reused event" check isn't enough.
If this SDK doesn't consume one of these events for time at all, say so with a test proving it, rather than skipping it silently.
The SDK's regression-corpus policy guards any clock file you touch.
Ships in the next minor. Security reviews the exact head before merge.
Reopened deliberately. sdk-python#236 merged at Security-cleared exact head 909f353 (merge commit 7dbeca4; parents ab77898 + 909f353; merge tree 754119d4 equals the head tree). It qualifies only memo reuse and search-attribute value replay, plus durable-sequence identity enforcement.
Still fenced, per Security (#236 6617490380 and the attribute_types ruling 6615262197):
Search-attribute types: native Server resolves registered → declared → inferred types from namespace definitions, which an attributes-only SDK can't reconstruct.
Signal waits: Python has no signal-wait primitive.
Workflow's service fence for these step families stays in place for Python until those are resolved or explicitly scoped out.
Activity
Enforce recorded search attributes and add cancellation clock controls
Validate redrive successors and fail closed on search-attribute identity
Check an authored search-attribute tuple as its wire list
Refuse missing search attributes and bind redrive successor identity
Report a missing search-attribute update as search_attribute_update_m…
Close redrive successor validator gaps and narrow the signal-wait claim
Refuse unsequenced, duplicate and colliding durable command records
Use sdk-rust sequence reasons and scope collisions to upserts
Claim every lifecycle row's sequence for upsert collisions
Claim cancellation deliveries and their sequence spans
Fail closed on a malformed cancellation delivery span
Keep history values out of replay diagnostics; read a null span as 1
Normalize only a null scope delivery span in the cleanup lower bound
rmcdaniel commentedon Nov 3, 2026
Reopened deliberately. sdk-python#236 merged at Security-cleared exact head 909f353 (merge commit 7dbeca4; parents ab77898 + 909f353; merge tree 754119d4 equals the head tree). It qualifies only memo reuse and search-attribute value replay, plus durable-sequence identity enforcement.
Still fenced, per Security (#236 6617490380 and the attribute_types ruling 6615262197):
Workflow's service fence for these step families stays in place for Python until those are resolved or explicitly scoped out.