Repository navigation
Replay can leave post-condition activity history unconsumed after signals and updates #50
Copy link
Copy link
Closed
Labels
authority:githubGitHub is the authoritative lifecycle record for this workGitHub is the authoritative lifecycle record for this workcompletion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verifiedAcceptance, fixed version, and required operational evidence are publicly verifiedkind:defectA public product behavior is incorrectA public product behavior is incorrectpriority:P1High-priority product or release riskHigh-priority product or release riskrepo:sdk-pythonOwned by the Python SDK repositoryOwned by the Python SDK repositorystatus:doneDerived from the authoritative closed issue stateDerived from the authoritative closed issue state
Description
User-visible defect\n\nA signal or applied update accepted after a condition has resolved, while the workflow's successor activity is running, can retain the completed condition's workflow sequence. Cold replay currently falls back to that stale sequence after an intervening activity boundary and binds the receiver to the already-completed condition.\n\nThe completed condition will not drain receivers recorded after its terminal event. The workflow therefore reaches its next condition with stale state and remains waiting even though the durable history contains the accepted receivers and the successor activity completion.\n\n## Reproduction\n\n1. Open and satisfy condition A with a signal.\n2. Schedule activity B.\n3. While B is running, accept an update and another signal whose recorded workflow sequence still references condition A.\n4. Complete B.\n5. Replay from the full history into a condition that depends on the update and second signal.\n\nCurrent result: replay emits another condition wait.\n\nRequired result: replay applies the post-boundary receivers at their ordinary activity boundary, consumes B's durable result, and completes.\n\n## Acceptance\n\n- Treat recorded event position as authoritative once an activity, timer, child, or terminal step separates a receiver from an earlier condition, even when the receiver carries that condition's stale sequence.\n- Cover both SignalReceived and UpdateApplied in a cold-replay regression with post-condition activity history.\n- Preserve explicit selected-condition sequence binding and repeated physical wait behavior.\n- Pass the complete non-integration suite and static checks.
Metadata
Metadata
Assignees
Labels
authority:githubGitHub is the authoritative lifecycle record for this workGitHub is the authoritative lifecycle record for this workcompletion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verifiedAcceptance, fixed version, and required operational evidence are publicly verifiedkind:defectA public product behavior is incorrectA public product behavior is incorrectpriority:P1High-priority product or release riskHigh-priority product or release riskrepo:sdk-pythonOwned by the Python SDK repositoryOwned by the Python SDK repositorystatus:doneDerived from the authoritative closed issue stateDerived from the authoritative closed issue state
Activity
rmcdaniel commentedon Sep 2, 2026
Implemented, published, and independently verified.
Root cause: a receiver that followed a durable step could keep an explicit stale condition sequence when no active wait existed. Replay then reused the prior completed condition binding and could leave later activity history unconsumed.
Fix and evidence:
0833b3ce3257ea3fe8c3c5c36a2e984f19770887)eccc4ca9bea566e553fb0850ab6ea8b7cb742b71)durable-workflow 2.0.1; a clean environment installed and importeddurable-workflow==2.0.1successfullyThe acceptance boundary is satisfied: post-condition signal/update receivers remain on their correct replay boundary, subsequent activity history is consumed, and the fix is available through the default stable Python package channel.