Skip to content

Webhook reply hardening: dedup review fan-out, kill late thread tasks, instrument silent paths (closes #518, #520, #524)#525

Merged
FidoCanCode merged 1 commit into
mainfrom
fix-webhook-replies-and-races
Apr 15, 2026
Merged

Webhook reply hardening: dedup review fan-out, kill late thread tasks, instrument silent paths (closes #518, #520, #524)#525
FidoCanCode merged 1 commit into
mainfrom
fix-webhook-replies-and-races

Conversation

@FidoCanCode
Copy link
Copy Markdown
Owner

Summary

Test plan

  • 1832 tests, 100% coverage, ruff clean, pyright clean
  • After merge: rhencke/orly PR Phase 2: Rewrite task-cli.sh as kennel/cli.py #3-style review threads get exactly one fido reply per inline comment, no duplicates
  • After merge: late-arriving triage logs thread for comment N already resolved on GitHub — skipping queue instead of queuing
  • After merge: wait_for_pending_preempt yield timing visible in log; if any timeout, session: preempter still pending after 30.0s warning surfaces

Closes #518, #520, #524. Related to (but does not fix): #521 (which becomes a no-op once #520 lands).

…ead tasks, instrument silent paths

Three fixes for the recurring webhook misbehavior pattern:

1. **#518: dedup review fan-out.**  GitHub fires both
   pull_request_review (with the inline comments embedded) AND
   pull_request_review_comment (one per inline comment).  reply_to_review
   was iterating the inline comments and creating per-comment replies,
   while the per-comment webhook handler did the same in parallel.  The
   per-comment lock didn't serialize them — both posted clarification
   replies on the same thread (observed twice on rhencke/orly PR #3).
   reply_to_review is now a no-op for inline comments; the per-comment
   webhook is the single source of truth.

2. **#520: kill late-arriving thread tasks for resolved threads.**  When
   webhook triage queues a thread task for a comment whose thread fido
   has already auto-resolved (because an earlier in-thread task completed
   first), the worker re-does the work that's already shipped (#521).
   create_task now calls gh.is_thread_resolved_for_comment and drops the
   task on the floor when the thread is already closed.  Strict 'is True'
   check so MagicMock test stubs don't trip the guard.

3. **#524: instrument the silent triage path + bump preempt-yield
   timeout to 30s.**  reply_to_comment was silently swallowing comments
   after needs_more_context returned NO; the opus triage classifier
   logged nothing, no error fired, comment sat un-acked.  Most likely
   cause: webhook session.prompt waiting >2s for the worker to yield the
   lock.  wait_for_pending_preempt timeout 2s -> 30s; _triage now logs
   request + returned-chars and warns when category parse fails.
@FidoCanCode FidoCanCode requested a review from rhencke April 15, 2026 01:14
@FidoCanCode FidoCanCode merged commit 02d3ad5 into main Apr 15, 2026
3 checks passed
@FidoCanCode FidoCanCode deleted the fix-webhook-replies-and-races branch April 15, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Double-reply on PR review: pull_request_review and pull_request_review_comment both generate independent replies

2 participants