diff --git a/.agents/scripts/supervisor/deploy.sh b/.agents/scripts/supervisor/deploy.sh index 75c6239b4f..c561db09b5 100755 --- a/.agents/scripts/supervisor/deploy.sh +++ b/.agents/scripts/supervisor/deploy.sh @@ -1440,7 +1440,7 @@ dismiss_bot_reviews() { # Find bot reviews with CHANGES_REQUESTED state local bot_reviews - bot_reviews=$(echo "$reviews_json" | jq -r '.[] | select(.state == "CHANGES_REQUESTED" and (.user.login == "coderabbitai" or .user.login == "gemini-code-assist[bot]")) | .id' 2>/dev/null || echo "") + bot_reviews=$(echo "$reviews_json" | jq -r '.[] | select(.state == "CHANGES_REQUESTED" and (.user.login | test("^(coderabbitai|gemini-code-assist|copilot)"))) | .id' 2>/dev/null || echo "") if [[ -z "$bot_reviews" ]]; then log_debug "dismiss_bot_reviews: no blocking bot reviews found for PR #${pr_number}" diff --git a/.agents/scripts/supervisor/pulse.sh b/.agents/scripts/supervisor/pulse.sh index 6368f1a6cb..cf402a2a45 100755 --- a/.agents/scripts/supervisor/pulse.sh +++ b/.agents/scripts/supervisor/pulse.sh @@ -598,18 +598,41 @@ cmd_pulse() { # verify_failed: PR was already merged and deployed, but # post-merge verification failed. Put back to 'deployed' # so Phase 3b (verify queue) can re-run verification. - # Do NOT mark complete — the quality check still needs to pass. - log_info " Phase 3b2: $stale_id (verify_failed) — PR #$pr_number merged, resetting to deployed for re-verification" - db "$SUPERVISOR_DB" "UPDATE tasks SET - status = 'deployed', - error = NULL, - updated_at = strftime('%Y-%m-%dT%H:%M:%SZ','now') - WHERE id = '$escaped_stale_id';" 2>/dev/null || true - db "$SUPERVISOR_DB" "INSERT INTO state_log (task_id, from_state, to_state, timestamp, reason) - VALUES ('$escaped_stale_id', 'verify_failed', 'deployed', - strftime('%Y-%m-%dT%H:%M:%SZ','now'), - 'Phase 3b2: reset for re-verification (PR #$pr_number merged)');" 2>/dev/null || true - sync_issue_status_label "$stale_id" "deployed" "phase_3b2" 2>>"$SUPERVISOR_LOG" || true + # Cap retries to prevent infinite deployed→verify_failed loop (t1075). + local verify_reset_count + verify_reset_count=$(db "$SUPERVISOR_DB" " + SELECT COUNT(*) FROM state_log + WHERE task_id = '$escaped_stale_id' + AND from_state = 'verify_failed' + AND to_state = 'deployed';" 2>/dev/null || echo "0") + local max_verify_retries=3 + + if [[ "$verify_reset_count" -ge "$max_verify_retries" ]]; then + # Exhausted verification retries — mark permanently failed + log_error " Phase 3b2: $stale_id exhausted $max_verify_retries verification retries — marking failed" + db "$SUPERVISOR_DB" "UPDATE tasks SET + status = 'failed', + error = 'Verification failed after $max_verify_retries retries — manual fix needed', + updated_at = strftime('%Y-%m-%dT%H:%M:%SZ','now') + WHERE id = '$escaped_stale_id';" 2>/dev/null || true + db "$SUPERVISOR_DB" "INSERT INTO state_log (task_id, from_state, to_state, timestamp, reason) + VALUES ('$escaped_stale_id', 'verify_failed', 'failed', + strftime('%Y-%m-%dT%H:%M:%SZ','now'), + 'Phase 3b2: verification exhausted ($verify_reset_count/$max_verify_retries retries)');" 2>/dev/null || true + sync_issue_status_label "$stale_id" "failed" "phase_3b2" 2>>"$SUPERVISOR_LOG" || true + else + log_info " Phase 3b2: $stale_id (verify_failed) — PR #$pr_number merged, resetting to deployed for re-verification (attempt $((verify_reset_count + 1))/$max_verify_retries)" + db "$SUPERVISOR_DB" "UPDATE tasks SET + status = 'deployed', + error = NULL, + updated_at = strftime('%Y-%m-%dT%H:%M:%SZ','now') + WHERE id = '$escaped_stale_id';" 2>/dev/null || true + db "$SUPERVISOR_DB" "INSERT INTO state_log (task_id, from_state, to_state, timestamp, reason) + VALUES ('$escaped_stale_id', 'verify_failed', 'deployed', + strftime('%Y-%m-%dT%H:%M:%SZ','now'), + 'Phase 3b2: reset for re-verification attempt $((verify_reset_count + 1))/$max_verify_retries (PR #$pr_number merged)');" 2>/dev/null || true + sync_issue_status_label "$stale_id" "deployed" "phase_3b2" 2>>"$SUPERVISOR_LOG" || true + fi else # blocked: PR merged but task stuck in blocked state. # Advance to deployed and mark complete. diff --git a/.agents/scripts/supervisor/todo-sync.sh b/.agents/scripts/supervisor/todo-sync.sh index fa4b755026..2b7fb9dd84 100755 --- a/.agents/scripts/supervisor/todo-sync.sh +++ b/.agents/scripts/supervisor/todo-sync.sh @@ -313,6 +313,35 @@ process_verify_queue() { ensure_db + # Recover tasks stuck in 'verifying' state (t1075) + # If a pulse crashes mid-verification, tasks stay in 'verifying' forever. + # Reset any task that has been in 'verifying' for more than 5 minutes back to 'deployed'. + local stuck_verifying + stuck_verifying=$(db -separator '|' "$SUPERVISOR_DB" " + SELECT id FROM tasks + WHERE status = 'verifying' + AND updated_at < strftime('%Y-%m-%dT%H:%M:%SZ', 'now', '-5 minutes') + ORDER BY id; + " 2>/dev/null || echo "") + + if [[ -n "$stuck_verifying" ]]; then + while IFS='|' read -r stuck_id; do + [[ -z "$stuck_id" ]] && continue + log_warn " $stuck_id: stuck in 'verifying' for >5min — resetting to 'deployed'" + local escaped_stuck_id + escaped_stuck_id=$(sql_escape "$stuck_id") + db "$SUPERVISOR_DB" "UPDATE tasks SET + status = 'deployed', + error = NULL, + updated_at = strftime('%Y-%m-%dT%H:%M:%SZ','now') + WHERE id = '$escaped_stuck_id';" 2>/dev/null || true + db "$SUPERVISOR_DB" "INSERT INTO state_log (task_id, from_state, to_state, timestamp, reason) + VALUES ('$escaped_stuck_id', 'verifying', 'deployed', + strftime('%Y-%m-%dT%H:%M:%SZ','now'), + 'process_verify_queue: recovered from stuck verifying state (>5min timeout)');" 2>/dev/null || true + done <<<"$stuck_verifying" + fi + # Find deployed tasks that need verification local deployed_tasks local where_clause="t.status = 'deployed'" diff --git a/.agents/scripts/tech-stack-helper.sh b/.agents/scripts/tech-stack-helper.sh index 9428f46468..001028a292 100755 --- a/.agents/scripts/tech-stack-helper.sh +++ b/.agents/scripts/tech-stack-helper.sh @@ -26,7 +26,6 @@ init_log_file # Common message constants readonly HELP_SHOW_MESSAGE="Show this help" -readonly USAGE_COMMAND_OPTIONS="Usage: $0 [command] [options]" readonly HELP_USAGE_INFO="Use '$0 help' for usage information" # Cache constants diff --git a/.agents/subagent-index.toon b/.agents/subagent-index.toon index e41224f80f..fb97d451f0 100644 --- a/.agents/subagent-index.toon +++ b/.agents/subagent-index.toon @@ -21,7 +21,7 @@ pro,gemini-2.5-pro,Capable large context grok,grok-3,Research and real-time web knowledge --> - -