fix: prevent duplicate review_all runs via reason-based dedup (#848)

Two problems:
1. Schedule was every 20 min but review_all cycles take 35 min,
   causing overlapping triggers that fill both slots
2. Trigger server only deduped by issue number, not by reason,
   so two review_all runs could stack up

Fixes:
- Change schedule from */20 to 0,45 (every 45 min)
- Add reason-based dedup in trigger-server.ts: reject 409 if a
  non-issue run with the same reason is already in progress

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
L 2026-02-13 01:41:11 -08:00 committed by GitHub
parent d9a18b49d3
commit 49bb39c8ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 3 deletions

View file

@ -35,7 +35,7 @@ elif [[ "${SPAWN_REASON}" == "triage" ]] && [[ -n "${SPAWN_ISSUE}" ]]; then
ISSUE_NUM="${SPAWN_ISSUE}"
WORKTREE_BASE="/tmp/spawn-worktrees/triage-${ISSUE_NUM}"
TEAM_NAME="spawn-triage-${ISSUE_NUM}"
CYCLE_TIMEOUT=300 # 5 min for issue triage
CYCLE_TIMEOUT=600 # 10 min for issue triage
elif [[ "${SPAWN_REASON}" == "review_all" ]]; then
RUN_MODE="review_all"
WORKTREE_BASE="/tmp/spawn-worktrees/security-review-all"

View file

@ -388,6 +388,22 @@ const server = Bun.serve({
}
}
// Dedup: reject if a non-issue run with the same reason is already in progress
if (!issue) {
for (const [, run] of runs) {
if (!run.issue && run.reason === reason) {
return Response.json(
{
error: "run with this reason already in progress",
reason,
running: runs.size,
},
{ status: 409 }
);
}
}
}
// Disable idle timeout for this request — the stream may be silent for
// minutes at a time while Claude thinks. 0 = no timeout.
server.timeout(req, 0);

View file

@ -4,8 +4,8 @@ on:
issues:
types: [opened, reopened]
schedule:
# Consolidated review + scan — every 20 min
- cron: '*/20 * * * *'
# Consolidated review + scan — every 45 min (must exceed 35-min cycle timeout)
- cron: '0,45 * * * *'
workflow_dispatch:
inputs:
mode: