The finalized-issue boilerplate promises "reopen and I'll triage again from
scratch," but github_events.route() dropped issues.reopened to the ignored
skip branch (only opened/closed handled), while pull_request.reopened was
already routed. A user following the instruction got silence.
Route issues.reopened like issues.opened (submitter-attributable triage_issue,
same per-user rate budget) and dispatch it in queue._dispatch(). triage_issue
now tears down a stale finalized workspace (merged/closed/abandoned) before
re-provisioning, mirroring the maintainer directive-reopen teardown so the
re-triage branches afresh from default instead of a merged/deleted branch.
Fixes#5891
- log the worker thread's exception when a workspace op raises during
caller cancellation, so a persistently failing setup surfaces instead
of being buried behind CancelledError.
- raise on a timed-out (124) git symbolic-ref probe in the repo-exists
path, matching the rev-parse probes, instead of silently accepting the
caller-supplied branch.
- assert the subprocess timeout is passed in the two _chown_workspace
test fakes so a refactor cannot silently drop the bound.
Op: correct
Restores: spec:indeterminate-git-probes-raise-not-silently-proceed
Workspace setup/teardown (git clone/fetch, worktree add/remove, chown)
ran synchronously on the asyncio dispatcher loop, so one stalled
subprocess froze the entire process.
- Offload every ensure_workspace/remove_workspace call to a worker thread
via a new _run_workspace_op helper that drains the thread to completion
on cancellation, so a cancelled event cannot reap/release a slot the
setup thread still owns.
- Serialize same-repo setup with a per-repo threading.RLock while letting
distinct repos run concurrently.
- Bound the direct git/chown subprocesses with a 120s timeout
(returncode 124); treat a timed-out branch probe as an error rather
than "branch absent" to avoid silently rebasing a follow-up onto the
default branch and losing the PR's commits.
- When a timed-out worktree remove leaves the checkout behind, rmtree it
and run `git worktree prune` so the pool's dangling registration cannot
trip a later worktree add for the same path.
Adds regression tests for event-loop liveness, cancellation-safe offload,
per-repo lock serialization, subprocess timeout mapping, the branch-probe
timeout guard, and worktree-prune after a failed remove.
Op: correct
Restores: spec:dispatcher-event-loop-never-blocks-on-workspace-io
- Included authorizes_impl field when attaching threads to directives.
- Added a test case to ensure the author authorization flag is preserved during directive hydration.
- Added `is_implementation_authorizer` check requiring OWNER or allowlisted maintainer to authorize implementation work.
- Blocked `gh_push_branch` and `gh_open_pr` for unclassified/enhancement/proposal issues without explicit directive authorization.
- Auto-allowed bug and documentation issues without requiring a directive.
- Propagated `authorizes_impl` flag through events, server, tasks, and worker bindings.
- Added `review_pr` task that checks out PR head in a detached worktree, classifies rank/type/area, and posts a batched GitHub review as `event=COMMENT`.
- Added four new host tools: `fetch_pr`, `classify_pr`, `pr_review_comment`, and `submit_pr_review`; review tools self-gate on `review_mode`, push/open-PR tools refuse when `review_mode` is set.
- Added sqlite staging table `pr_review_comments` with `stage_review_comment`, `list_staged_review_comments`, and `clear_staged_review_comments` DAOs.
- Routed `pull_request.opened/reopened/ready_for_review` to `review_pr` and extended `pull_request.closed` cleanup to any tracked PR regardless of author.
- Normalized reviewer-bot matching by stripping a trailing `[bot]` suffix when resolving configured bot logins.
- Fetched PR thread history for followup comments without directives and carried it through task execution.
- Updated followup prompt rendering to include prior conversation context for handle_comment tasks.