Fix #81: treat assigned PRs as first-class work items#82
Merged
Conversation
Add a standalone-PR handler so Clayde can address review feedback on PRs
that were not created through the normal issue → plan → implement flow.
Changes:
- github.py: add is_pull_request_item() helper — checks html_url for /pull/
- safety.py: add filter_pr_reviews() — keeps only whitelisted-user reviews,
excluding the bot's own
- tasks/pr_work.py: new task module; run(pr_url) fetches PR context, filters
reviews by whitelist, invokes Claude, posts summary comment
- prompts/pr_work.j2: new Jinja2 template for PR review work
- orchestrator.py:
- _handle_standalone_pr() — mirrors _handle_issue() but keyed by PR URL;
checks for new whitelisted review activity and invokes pr_work.run()
- _is_pr_tracked_as_issue() — guards against double-handling a PR that was
opened by Clayde for a tracked issue
- main() dispatch — routes PR items to _handle_standalone_pr, issue items
to _handle_issue as before
- Tests: full coverage for new functions across test_github.py,
test_safety.py, test_orchestrator.py, and new test_tasks_pr_work.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
atithepkaewsomsri23-ui
approved these changes
May 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #81.
Makes assignment the single signal for Clayde to work. Previously the poll loop only acted on assigned issues; a PR assigned directly to Clayde (with no parent issue) was never picked up. This PR adds a standalone-PR handler so Clayde can address review feedback on such PRs.
Changes
New:
github.is_pull_request_item(item)Checks
html_urlfor/pull/to distinguish PR items from issue items in the list returned byget_assigned_issues()(which already returns both, since GitHub models PRs as issues).New:
safety.filter_pr_reviews(reviews, github_username)Returns only reviews authored by whitelisted users, excluding the bot's own reviews. Parallel to the existing
filter_comments()gate for issue content.New:
tasks/pr_work.py+prompts/pr_work.j2run(pr_url)fetches PR metadata + filtered reviews, invokes Claude with a focused "address this review" prompt, and posts a summary comment on the PR. State is keyed by PR URL instate.json(the same"issues"dict, since it already holds arbitrary URL keys).Updated:
orchestrator.py_handle_standalone_pr(g, url)— mirrors_handle_issue()but operates on a PR URL; detects new whitelisted review activity, handles pure-approval, crash-recovery (in_progress), and usage-limit retry._is_pr_tracked_as_issue(pr_url, issues_state)— prevents double-handling: if a PR URL already appears aspr_urlin any issue state entry (i.e. Clayde opened it for a tracked issue), the standalone handler skips it.main()dispatch — iterates all assigned items, routes PR items to_handle_standalone_prand issue items to_handle_issueas before.Behaviour unchanged for issue flow
The existing plan → approval → implement → PR lifecycle is fully preserved. The
_is_pr_tracked_as_issueguard ensures that PRs Clayde created for issues are never double-handled.Tests
325 tests pass. New coverage:
test_github.py—is_pull_request_itemtest_safety.py—filter_pr_reviewstest_orchestrator.py—_is_pr_tracked_as_issue, dispatch inmain(), full_handle_standalone_prsuite (skip, invoke, first-time, pure-approval, crash-recovery, error-clearing, usage-limit)tests/test_tasks_pr_work.py(new) —pr_work.run,_format_reviewsRecommended reading order
src/clayde/github.py—is_pull_request_item(trivial helper)src/clayde/safety.py—filter_pr_reviewssrc/clayde/prompts/pr_work.j2— the new promptsrc/clayde/tasks/pr_work.py— the new tasksrc/clayde/orchestrator.py— dispatch logic,_handle_standalone_pr,_is_pr_tracked_as_issue🤖 Generated with Claude Code