fix(board): Triage column hides type:bug and type:chore tickets #619

Closed
opened 2026-04-30 22:34:50 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As an operator triaging the planner board, I want bugs and chores without an assignee to appear in the Triage column alongside user stories, so that no actionable backlog ticket is invisible just because of its type label.

Background

Filed today (2026-04-30):

  • #615type:bug for the stuck CI pill
  • #618type:chore for the redundant Unassigned filter toggle

Neither appeared in the planner board's Triage column. Cause: apps/server/src/domain/views/board.ts:382-383 defines isUserStory as issue.labels.includes("type:user-story"), and the Triage gutter loop at line 532 hard-filters by if (!isUserStory(issue)) continue;. Bugs and chores never enter the column.

The dispatch side is fine — mcp__forgejo__* issues.assigned webhook has no user-story gate, so manually assigning a type:bug to dev still dispatches normally. The blind spot is purely the board surface.

This violates the global label convention in ~/.claude/CLAUDE.md ("each issue gets exactly one area label and one type label") — operators following the convention land tickets that the board pretends do not exist.

Acceptance criteria

Filter

  • Rename isUserStory (apps/server/src/domain/views/board.ts:382) to isTriageable (or similar) and accept any of type:user-story, type:bug, type:chore. Update the call site at line 532.
  • Update the function docstring at lines 378-381 to document the broadened set.
  • Triage column gutter dedup (runningIssueKeys at lines 518-523) and sort logic (line 559) are unaffected — keep as-is.

Server tests

  • Extend apps/server/src/domain/views/board.test.ts (or wherever the Triage projection is tested — grep for unassigned / Triage): a type:bug + a type:chore issue with no assignee land in the unassigned column, alongside the existing type:user-story case.
  • An issue with neither label (e.g. type:meta only) is not picked up — meta tickets are tracking, not work.
  • An issue with both type:user-story and type:bug (rare but legal) is picked up exactly once.

Web

  • No web changes needed; the column header already reads Triage. (Don't rename it to "Backlog" or anything else here — separate concern.)

Out of scope

  • Per-type icons or styling inside the Triage column to distinguish bug vs chore vs user-story (small polish; file separately if useful).
  • Changing the dispatch side. The dispatcher already accepts any type label.
  • type:meta inclusion — those are explicitly tracking issues that should not be picked up by an agent.
  • Adjusting STATUS_ORDER in apps/web/src/components/board/use-board-keymap.ts:23 — the "unassigned" entry refers to the column status string, not the type label, and stays the same.

References

  • apps/server/src/domain/views/board.ts:378-383isUserStory definition
  • apps/server/src/domain/views/board.ts:525-559 — Triage column build loop
  • ~/.claude/CLAUDE.md — global label conventions: one area + one type label per issue
  • Tickets affected today: #615, #618 (assigned manually as a workaround until this lands)
## User story As an operator triaging the planner board, I want bugs and chores without an assignee to appear in the Triage column alongside user stories, so that no actionable backlog ticket is invisible just because of its type label. ## Background Filed today (2026-04-30): - `#615` — `type:bug` for the stuck CI pill - `#618` — `type:chore` for the redundant Unassigned filter toggle Neither appeared in the planner board's Triage column. Cause: `apps/server/src/domain/views/board.ts:382-383` defines `isUserStory` as `issue.labels.includes("type:user-story")`, and the Triage gutter loop at line 532 hard-filters by `if (!isUserStory(issue)) continue;`. Bugs and chores never enter the column. The dispatch side is fine — `mcp__forgejo__*` `issues.assigned` webhook has no user-story gate, so manually assigning a `type:bug` to dev still dispatches normally. The blind spot is purely the board surface. This violates the global label convention in `~/.claude/CLAUDE.md` ("each issue gets exactly one area label and one type label") — operators following the convention land tickets that the board pretends do not exist. ## Acceptance criteria ### Filter - [ ] Rename `isUserStory` (`apps/server/src/domain/views/board.ts:382`) to `isTriageable` (or similar) and accept any of `type:user-story`, `type:bug`, `type:chore`. Update the call site at line 532. - [ ] Update the function docstring at lines 378-381 to document the broadened set. - [ ] Triage column gutter dedup (`runningIssueKeys` at lines 518-523) and sort logic (line 559) are unaffected — keep as-is. ### Server tests - [ ] Extend `apps/server/src/domain/views/board.test.ts` (or wherever the Triage projection is tested — grep for `unassigned` / `Triage`): a `type:bug` + a `type:chore` issue with no assignee land in the `unassigned` column, alongside the existing `type:user-story` case. - [ ] An issue with neither label (e.g. `type:meta` only) is **not** picked up — meta tickets are tracking, not work. - [ ] An issue with both `type:user-story` and `type:bug` (rare but legal) is picked up exactly once. ### Web - [ ] No web changes needed; the column header already reads `Triage`. (Don't rename it to "Backlog" or anything else here — separate concern.) ## Out of scope - Per-type icons or styling inside the Triage column to distinguish bug vs chore vs user-story (small polish; file separately if useful). - Changing the dispatch side. The dispatcher already accepts any type label. - `type:meta` inclusion — those are explicitly tracking issues that should not be picked up by an agent. - Adjusting `STATUS_ORDER` in `apps/web/src/components/board/use-board-keymap.ts:23` — the `"unassigned"` entry refers to the column status string, not the type label, and stays the same. ## References - `apps/server/src/domain/views/board.ts:378-383` — `isUserStory` definition - `apps/server/src/domain/views/board.ts:525-559` — Triage column build loop - `~/.claude/CLAUDE.md` — global label conventions: one area + one type label per issue - Tickets affected today: `#615`, `#618` (assigned manually as a workaround until this lands)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#619
No description provided.