fix(webhook): handle issues.unassigned — cancel running + drop queued tasks for removed assignee #301
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#301
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
User story
As an operator, I want unassigning an agent from a Forgejo issue to cancel that agent's running task and drop its queued tasks for that issue, so that stale work does not keep executing after I've reassigned the issue to someone else.
Current behaviour
apps/server/src/http/webhook.ts:160-212handlesissues.assigned,labeled,label_updated,closed— but notunassigned. Today:Running tasks have the same problem: A keeps executing even after unassignment, because
/cancelis never called.Acceptance criteria
Webhook
issues.unassignedbranch alongsideassignedinwebhook.ts. Payload carries the removed assignee atpayload.assignee.login(Forgejo v15 fires one event per removed user, same shape asassigned).handleIssueUnassigned(repo, issue, removedAssignee)inwebhook-handlers.ts:forgejo_user→ type).currentTask.request.issue_number === issue.number && .repo === repo: call the existing abort path (same one/canceluses).request.issue_number === issue.number && .repo === repo: drop from the queue and mark theTaskRecordascancelledwithfinished_at = Date.now().task_cancelledSSE event per cancelled/dropped task so the dashboard refreshes.Worker
worker.tsexposes adropQueued(predicate: (task) => boolean): TaskRecord[]method (returns dropped tasks for the handler to persist + SSE-broadcast). Keep it narrow — one predicate shape so tests don't explode.Tests
webhook-handlers.test.ts:issues.unassignedwith a running task on that issue → abort called, record status =cancelled.webhook-handlers.test.ts:issues.unassignedwith queued tasks only → queue shrinks, records persist ascancelled.webhook-handlers.test.ts: unassigning an agent that has no running/queued task for that issue → silent no-op, no errors, no SSE noise.worker.test.ts:dropQueued(predicate)removes matching entries, leaves non-matching intact, returns dropped tasks.Out of scope
pull_request.unassigned— PR flows use review-request, not assignee, for dispatch. Unless a follow-up proves otherwise.References
apps/server/src/http/webhook.ts:160-212— dispatch switch to extendapps/server/src/http/webhook-handlers.ts—handleIssueAssignedfor the mirror-image patternapps/server/src/main.ts:685—/cancelhandler; share its abort pathapps/server/src/background/worker.ts— queue internals