What happened
When two identical irreversible actions (e.g. two send_message calls with the same inputs) land in the same parallel batch, ActivityLogGuard.begin() records INTENT for the first one, then sees that same INTENT row for the second call and treats it as a crashed prior attempt. It downgrades the row to FAILED and blocks the second call with "a previous attempt was interrupted ... may have already happened," even though the first call is still genuinely running, not crashed.
begin()'s DONE branch already has an age check (DONE_DEDUP_WINDOW_SECONDS) before treating a completed row as stale enough to let a repeat through. The INTENT branch (the final else in begin(), app/triggers/activity_log.py) has no equivalent check, so it can't tell "this row belongs to a batch mate still running" from "this row is an attempt that crashed minutes or hours ago."
What I expected
A parallel duplicate that's still genuinely executing shouldn't be told it might have already fired with no record. Only a row old enough to plausibly be a crash should get the "may have happened, verify" treatment.
Steps to reproduce
Driving ActivityLog/ActivityLogGuard directly, matching how execute_parallel dispatches (both begin() calls fire before either action's complete() is reached):
guard.begin("send_message", {"to": "alice", "text": "hi"}, "sess-1") returns GuardDecision(proceed=True, ...) and records INTENT.
- Immediately after, before anything calls
guard.complete(...) for call 1, the same call again: guard.begin("send_message", {"to": "alice", "text": "hi"}, "sess-1") returns GuardDecision(proceed=False, note="... was NOT executed. A previous attempt ... was interrupted ...").
Call 1 hasn't crashed, it's still in flight, but the second legitimate parallel call gets blocked and the LLM is told the action may have already gone out.
Environment
Reproduced against dev @ 55b12be2 in a clean python:3.12-slim container, driving the real app/triggers/activity_log.py module directly, no mocks.
Logs / screenshots
Call A: GuardDecision(proceed=True, idem_key='sess-1:send_message:82ccaf390655b439', stored_output=None, note=None)
Call B: GuardDecision(proceed=False, idem_key='sess-1:send_message:82ccaf390655b439', stored_output=None,
note="send_message was NOT executed. A previous attempt with these exact inputs was interrupted
before its outcome could be recorded ...")
What happened
When two identical irreversible actions (e.g. two
send_messagecalls with the same inputs) land in the same parallel batch,ActivityLogGuard.begin()recordsINTENTfor the first one, then sees that sameINTENTrow for the second call and treats it as a crashed prior attempt. It downgrades the row toFAILEDand blocks the second call with "a previous attempt was interrupted ... may have already happened," even though the first call is still genuinely running, not crashed.begin()'sDONEbranch already has an age check (DONE_DEDUP_WINDOW_SECONDS) before treating a completed row as stale enough to let a repeat through. TheINTENTbranch (the finalelseinbegin(),app/triggers/activity_log.py) has no equivalent check, so it can't tell "this row belongs to a batch mate still running" from "this row is an attempt that crashed minutes or hours ago."What I expected
A parallel duplicate that's still genuinely executing shouldn't be told it might have already fired with no record. Only a row old enough to plausibly be a crash should get the "may have happened, verify" treatment.
Steps to reproduce
Driving
ActivityLog/ActivityLogGuarddirectly, matching howexecute_paralleldispatches (bothbegin()calls fire before either action'scomplete()is reached):guard.begin("send_message", {"to": "alice", "text": "hi"}, "sess-1")returnsGuardDecision(proceed=True, ...)and records INTENT.guard.complete(...)for call 1, the same call again:guard.begin("send_message", {"to": "alice", "text": "hi"}, "sess-1")returnsGuardDecision(proceed=False, note="... was NOT executed. A previous attempt ... was interrupted ...").Call 1 hasn't crashed, it's still in flight, but the second legitimate parallel call gets blocked and the LLM is told the action may have already gone out.
Environment
Reproduced against
dev@55b12be2in a cleanpython:3.12-slimcontainer, driving the realapp/triggers/activity_log.pymodule directly, no mocks.Logs / screenshots