Establish what is happening
Map both occurrence timelines
Record schedule and run IDs, due times, worker claims, starts, finishes, output keys, and terminal states for the overlapping pair. Include the configured interval and expected policy. Do not infer overlap from two dashboard rows without comparing their active windows.
Inspect lock or lease ownership
Read the lock, lease, or idempotency record around the second claim. Check owner identity, acquisition, renewal, expiry, and release. If no guard exists, mark that as a policy gap rather than assuming the scheduler should have serialized the work.
Compare short and spanning runs
Compare a run that finishes before the next due time with one deliberately spanning it. Identify where the second occurrence is queued, skipped, or started. Preserve output and side-effect evidence so simultaneous processing is not judged solely by timing.
What to carry forward
Return both run timelines, overlap policy, lock or lease evidence, output identity, and first violation. Classify the scope as intentional concurrency, missing guard, lease expiry, or scheduler timing. Keep duplicate processing unproven when run and effect records cannot be correlated.
Technical background: Rails guides.
Keep the decision with the work.
Use a Work Item in Aglet to record the problem, the evidence you have, and the next decision. Add an owner and priority, then keep updates in the discussion so the next person can follow the reasoning.
Create an account See the product workflow