feat: add pre-dispatch verification to prevent dispatching already-done tasks#806
feat: add pre-dispatch verification to prevent dispatching already-done tasks#806marcusquinn merged 1 commit intomainfrom
Conversation
…ne tasks Add check_task_already_done() function that runs before worker dispatch. Checks three sources: (1) TODO.md [x] marker, (2) git commit history for completion evidence, (3) GitHub merged PRs. If task appears done, auto- cancels it instead of wasting an Opus session. Prevents the exact bug from backlog-10 where 6 t135 subtasks were dispatched and retried despite being completed months earlier, wasting significant compute on workers that discovered 'already done' and exited.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request implements a crucial pre-dispatch verification mechanism within the supervisor script. Its primary goal is to intelligently identify and prevent the system from re-dispatching tasks that have already been completed, thereby eliminating redundant work and optimizing resource utilization. The new logic checks multiple historical data sources to ensure tasks are only processed when truly necessary. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Mon Feb 9 20:33:18 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable pre-dispatch check to prevent re-running completed tasks, which will save resources and prevent bugs. The implementation is solid, adding a new check_task_already_done function and integrating it into the dispatch command. My review includes a high-severity suggestion to refactor a part of the new function to fix a potential crash bug and improve performance by reducing redundant git log calls. I've also included a medium-severity comment regarding adherence to the repository's style guide on error suppression.
| local commit_count=0 | ||
| commit_count=$(git -C "$project_root" log --oneline -500 --all --grep="$task_id" 2>/dev/null | wc -l | tr -d ' ') || true | ||
| if [[ "$commit_count" -gt 0 ]]; then | ||
| # Verify at least one commit looks like a completion (not just "claim" or "blocked") | ||
| local completion_evidence="" | ||
| completion_evidence=$(git -C "$project_root" log --oneline -500 --all --grep="$task_id" 2>/dev/null \ | ||
| | grep -iE "(feat|fix|refactor|chore|perf|test).*${task_id}|${task_id}.*(\(#[0-9]+\)|PR #[0-9]+|merged)" \ | ||
| | head -1) || true | ||
| if [[ -n "$completion_evidence" ]]; then | ||
| log_info "Pre-dispatch check: $task_id has completion evidence: $completion_evidence" >&2 | ||
| return 0 | ||
| fi | ||
| fi |
There was a problem hiding this comment.
This block has a potential bug and an inefficiency.
- Bug: If the
git logpipe fails,commit_countcan become an empty string. This would cause the numeric comparison[[ "$commit_count" -gt 0 ]]to fail with an "integer expression expected" error, which will terminate the script underset -e. - Inefficiency: The
git logcommand is executed twice, which can be slow on large repositories.
You can address both issues by running git log once, storing the output, and then checking if the output is non-empty before grepping for evidence. This avoids the risky numeric comparison and the redundant git log call.
| local commit_count=0 | |
| commit_count=$(git -C "$project_root" log --oneline -500 --all --grep="$task_id" 2>/dev/null | wc -l | tr -d ' ') || true | |
| if [[ "$commit_count" -gt 0 ]]; then | |
| # Verify at least one commit looks like a completion (not just "claim" or "blocked") | |
| local completion_evidence="" | |
| completion_evidence=$(git -C "$project_root" log --oneline -500 --all --grep="$task_id" 2>/dev/null \ | |
| | grep -iE "(feat|fix|refactor|chore|perf|test).*${task_id}|${task_id}.*(\(#[0-9]+\)|PR #[0-9]+|merged)" \ | |
| | head -1) || true | |
| if [[ -n "$completion_evidence" ]]; then | |
| log_info "Pre-dispatch check: $task_id has completion evidence: $completion_evidence" >&2 | |
| return 0 | |
| fi | |
| fi | |
| local log_output | |
| log_output=$(git -C "$project_root" log --oneline -500 --all --grep="$task_id" 2>/dev/null) || true | |
| if [[ -n "$log_output" ]]; then | |
| # Verify at least one commit looks like a completion (not just "claim" or "blocked") | |
| local completion_evidence | |
| completion_evidence=$(echo "$log_output" \ | |
| | grep -iE "(feat|fix|refactor|chore|perf|test).*${task_id}|${task_id}.*(\(#[0-9]+\)|PR #[0-9]+|merged)" \ | |
| | head -1) || true | |
| if [[ -n "$completion_evidence" ]]; then | |
| log_info "Pre-dispatch check: $task_id has completion evidence: $completion_evidence" >&2 | |
| return 0 | |
| fi | |
| fi |
| # Returns 0 (true) if task appears done, 1 (false) if not. | ||
| # Searches for: (1) commits with task ID in message, (2) TODO.md [x] marker, | ||
| # (3) merged PR references. Fast path: git log grep is O(log n) on packed refs. | ||
| check_task_already_done() { |
There was a problem hiding this comment.
The style guide (line 50) states that 2>/dev/null should only be used for redirecting to log files, not for blanket error suppression. This function uses it in several places (lines 2562, 2572, 2576, 2587, 2589) to suppress potential errors from grep, git, and gh. This can hide important issues like permission errors or configuration problems, making debugging harder. Consider removing these suppressions or handling errors more explicitly.
References
2>/dev/nullis acceptable ONLY when redirecting to log files, not blanket suppression. (link)
…letion matches Three bugs fixed in check_task_already_done(): 1. Substring matching: t020 was matching t020.6 commits. Added word boundary pattern that prevents parent task IDs from matching subtask commits. 2. Non-completion commits: 'chore: add t194' matched because 'chore' was in the completion evidence pattern. Now requires PR merge reference (#NNN) and excludes add/claim/queue/blocked commits. 3. GitHub PR search: added quotes around task ID to prevent substring matches. Root cause: the pre-dispatch check (PR #806) was too aggressive, cancelling 4 tasks (t020.4-6, t194) that were NOT actually done.
…letion matches (#807) Three bugs fixed in check_task_already_done(): 1. Substring matching: t020 was matching t020.6 commits. Added word boundary pattern that prevents parent task IDs from matching subtask commits. 2. Non-completion commits: 'chore: add t194' matched because 'chore' was in the completion evidence pattern. Now requires PR merge reference (#NNN) and excludes add/claim/queue/blocked commits. 3. GitHub PR search: added quotes around task ID to prevent substring matches. Root cause: the pre-dispatch check (PR #806) was too aggressive, cancelling 4 tasks (t020.4-6, t194) that were NOT actually done.



Summary
check_task_already_done()function to supervisor that runs before every worker dispatch[x]marker, git commit history (conventional commit + PR refs), GitHub merged PRsRoot Cause
The supervisor had no pre-dispatch verification. Tasks added to a batch were dispatched blindly even if they'd been completed in a prior batch. Workers would discover "already done" and exit, but the evaluator classified this as
clean_exit_no_signaland retried — wasting 3 full Opus sessions per task.Implementation
check_task_already_done(task_id, repo)returns 0 (already done) or 1 (not done):- [x] tNNNpatternghCLI available)Inserted in
cmd_dispatch()after status validation, before task claiming.