Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .github/workflows/claude-issue-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,28 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 3
# Three trigger paths, each with its own gate:
# - issues.opened/reopened → skip bot-opened issues
# - issues.opened/reopened → skip bot-opened issues; skip
# `no-triage` (humans or other agents
# own the work).
# - issue_comment.created → skip bots, skip self-loop (routine's
# own comments contain "Triaged by
# Claude Code"), skip /triage (handled
# by slash-command-dispatch path).
# by slash-command-dispatch path);
# skip `no-triage` issues (same reason
# as above).
# Both issue and PR comments fire — the
# routine receives `is_pr` to branch on.
# - repository_dispatch → always allow (slash-dispatch already
# gated by member-association check)
# gated by member-association check;
# manual /triage intentionally overrides
# the `no-triage` label).
if: >-
(
github.event_name == 'issues' &&
github.event.issue.user.type != 'Bot' &&
!endsWith(github.event.issue.user.login, '[bot]') &&
github.event.sender.type != 'Bot'
github.event.sender.type != 'Bot' &&
!contains(github.event.issue.labels.*.name, 'no-triage')
) ||
(
github.event_name == 'issue_comment' &&
Expand All @@ -65,7 +72,8 @@ jobs:
github.event.sender.type != 'Bot' &&
!startsWith(github.event.comment.body, '/triage') &&
!contains(github.event.comment.body, 'Triaged by Claude Code') &&
!contains(github.event.comment.body, 'Fixed by Claude Code')
!contains(github.event.comment.body, 'Fixed by Claude Code') &&
!contains(github.event.issue.labels.*.name, 'no-triage')
) ||
github.event_name == 'repository_dispatch'
defaults:
Expand Down
33 changes: 33 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,39 @@ a file outside your scope, stop and record it in your reply instead.
`git log --name-only --oneline -<N>` (N = number of agent commits), then look
for the same file appearing in more than one entry.

## Issue Triage Bot

A Claude Code routine ("issue triage", wired in
`.github/workflows/claude-issue-triage.yml`) fires automatically on every
new issue and on every non-`/triage` comment. It reads the issue body,
decides whether to clarify, defer, or open a draft PR, and posts back via
comment. PRs it opens land on `claude/issue-<N>-<slug>` branches, are
labeled `claude-triaged`, and the issue carries `claude-triaging` while
the routine is actively running.

**Coordination rules:**

- **Do not open a new PR for an unlabeled issue without checking the
triage state first.** If the issue carries `claude-triaging` the bot is
actively working — your work will collide. If it carries
`claude-triaged` the bot has already produced (or deferred to) a PR;
find that PR before starting fresh work.

- **Apply `no-triage` at issue creation when you (human or designated
agent) plan to do the work.** The label short-circuits the workflow
`if:` gate so the routine never fires. Labels added after the fact do
not retroactively cancel an in-flight run.

- **Manual `/triage` overrides the `no-triage` label.** The
slash-command-dispatch path is gated only by member-association — use
it when you explicitly want the bot to engage on a `no-triage` issue.

- **Stale `claude-triaged` draft PRs lose parallel races.** When a
human-authored PR for the same issue lands on main first, the bot's
draft becomes superseded. Prefer closing-as-superseded over rebasing —
always check recent main commits before investing time in a rebase of
a triage-managed draft.

## Additional Important Reminders

**NEVER**:
Expand Down
Loading