Ownership belongs to the attempt
A scoring worker can be slow without being finished. If recovery gives its job to another worker, both still know the same job ID. WF2 adds a fresh UUID for each attempt, validates it and conditionally claims the NEW row as SCORING.
The next step reads the row back. Model processing continues only when the stored state is SCORING and its token matches the one generated for that job. The worker checks that it owns the claim instead of assuming the claim node succeeded.
Carry ownership through to the final write
READY_A and failure updates match three values: job ID, SCORING state and claim token. The ready result is read back before dispatch. Recovery repeats the same conditions when a claim reaches thirty minutes or has a missing or invalid claim time.
If another attempt has acquired a different token, the old completion or release should no longer match. The filters are present in the exports; their behavior under competing Data Tables operations hasn't been exercised in this review.
A lease can't take back a provider request
Expiry makes the row reclaimable, but the original worker may still be waiting for a model response. Token checks can reject its later state update without cancelling that request or preventing another provider call. The active-claim cap is also a separate, soft concurrency limit.
I'd test the overlap directly: pause worker A after verification, let B reclaim the row, then resume A and confirm that it cannot overwrite B. Provider calls and downstream messages need their own observation. The historical audit includes replay and concurrency checks, but its unfinished acceptance checklist isn't a passing test result.
Attempt ownership from acquisition through stale-claim recovery
The old token is carried into completion and release filters. A newer token must not be overwritten by the earlier worker or reaper.
Scoring attempt
Data Tables
Recovery and rejection
Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.
Choose a component to explore
Select a numbered component on the map or use the component menu. Its details and connections will appear here.
No component selected.
All connections (11)
- 01 · Fresh attempt token → 02 · Conditional claimValidated claim payload · Direct call
- 02 · Conditional claim → 03 · Current job rowNEW → SCORING · Direct call
- 03 · Current job row → 04 · Verify ownershipRead back current token · Response / return
- 04 · Verify ownership → 06 · Requirement extraction and scoringOwnership verified · Direct call
- 04 · Verify ownership → 05 · Do not advance this attemptMismatch or no claim · Blocked / denied
- 06 · Requirement extraction and scoring → 08 · Token-qualified transitionResult or failure · Direct call
- 08 · Token-qualified transition → 03 · Current job rowConditional state update · Direct call
- 03 · Current job row → 07 · Stale-claim scanScheduled claim snapshot · Async task
- 07 · Stale-claim scan → 09 · Release observed stale claimCarry observed old token · Direct call
- 09 · Release observed stale claim → 03 · Current job rowMatching stale claim → NEW · Direct call
- 09 · Release observed stale claim → 05 · Do not advance this attemptNewer token no longer matches · Blocked / denied