diff --git a/server/internal/handler/comment.go b/server/internal/handler/comment.go index 83929845..a21bb61c 100644 --- a/server/internal/handler/comment.go +++ b/server/internal/handler/comment.go @@ -239,12 +239,9 @@ func (h *Handler) isReplyToMemberThread(parent *db.Comment, content string, issu // enqueues a task for each mentioned agent. Skips self-mentions, agents that // are already the issue's assignee (handled by on_comment), and agents with // on_mention trigger disabled. +// Note: no status gate here — @mention is an explicit action and should work +// even on done/cancelled issues (the agent can reopen the issue if needed). func (h *Handler) enqueueMentionedAgentTasks(ctx context.Context, issue db.Issue, comment db.Comment, authorType, authorID string) { - // Don't trigger on terminal statuses. - if issue.Status == "done" || issue.Status == "cancelled" { - return - } - mentions := util.ParseMentions(comment.Content) for _, m := range mentions { if m.Type != "agent" { diff --git a/server/internal/handler/issue.go b/server/internal/handler/issue.go index cd38e338..71da2edd 100644 --- a/server/internal/handler/issue.go +++ b/server/internal/handler/issue.go @@ -471,20 +471,16 @@ func (h *Handler) canAssignAgent(ctx context.Context, r *http.Request, agentID, } // shouldEnqueueAgentTask returns true when an issue assignment should trigger -// the assigned agent. Only fires for "todo" status — assignment means "start -// fresh work", so the agent shouldn't be triggered on issues already in -// progress, blocked, or done. +// the assigned agent. No status gate — assignment is an explicit human action, +// so it should trigger regardless of issue status (e.g. assigning an agent to +// a done issue to fix a discovered problem). func (h *Handler) shouldEnqueueAgentTask(ctx context.Context, issue db.Issue) bool { - if issue.Status != "todo" { - return false - } return h.isAgentTriggerEnabled(ctx, issue, "on_assign") } // shouldEnqueueOnComment returns true if a member comment on this issue should -// trigger the assigned agent. Unlike on_assign (todo only), on_comment fires -// for any non-terminal status — comments are conversational and can happen at -// any stage of active work (todo, in_progress, in_review, blocked). +// trigger the assigned agent. Fires for any non-terminal status — comments are +// conversational and can happen at any stage of active work. func (h *Handler) shouldEnqueueOnComment(ctx context.Context, issue db.Issue) bool { // Don't trigger on terminal statuses (done, cancelled). if issue.Status == "done" || issue.Status == "cancelled" {