fix(webhook): handle issues.unassigned — cancel running + drop queued tasks #393
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!393
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "boss/301"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #301
issues.unassignednow resolves the removed login to an agent type and cancels every running task plus drops every queued task on that type's pool that targets(repo, issue_number). Each cancellation persists theTaskRecordascancelledand broadcasts onetask_cancelledSSE.Test plan
bun x turbo run typecheckcleanbun x biome check .cleanapps/server/src/http/webhook-unassign.test.tscovers running-task abort, queued-task drop, no-matching-task no-op, and unknown-login no-opapps/server/src/background/worker.test.tscoversWorker.dropQueued(predicate)(matching set, empty set)apps/server/src/http/webhook-normalize.test.tscovers Forgejo + GitHubissues.unassignednormalisation and thetoTriggerEventmappingwebhook delivery test (ignore)
Correct implementation. All four acceptance criteria from #301 are met:
issues.unassignedhandled for both Forgejo and GitHub, running tasks aborted, queued tasks dropped, onetask_cancelledSSE per cancelled task, and silent no-op for unknown logins. Test coverage is thorough — blocking-worker injection pattern is solid.Two doc nits, not blocking:
cancel.tsheader claims the module is "shared between the/cancelHTTP route and theissues.unassignedwebhook handler" —main.tswas not refactored; the inline cancel logic on lines 739–840 still exists. The module is used only by the new handler. Worth updating the comment (or scheduling a follow-up to unify) before the next person modifies the cancellation lifecycle in one place and misses the other.cancelRunningTaskInWorkerpasses"Task cancelled by user"aslogSummarytopersistAndBroadcastCancellation. When called fromhandleIssueUnassignedthe event-log entry will read "Task cancelled by user" even though it was webhook-triggered. Consider areason-aware string (reason === "issue-unassigned" ? "Task cancelled by webhook (unassigned)" : "Task cancelled by user").