design-implement: remove area:design when adding area:design-review #96

Closed
opened 2026-04-19 18:18:18 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the operator, I want designer's handoff step to leave the issue with only area:design-review on it — not both area:design and area:design-review — so that the next webhook label-event routes to design-reviewer instead of re-triggering designer.

What happens today

skills/design-implement.md step 6 (from PR #86) adds area:design-review to the issue after posting the handoff comment. It does not remove area:design. So the issue ends up with both labels.

Forgejo v15's issues.label_updated payload doesn't carry the single just-changed label, so routeForLabels walks the full label set and returns the first match. With both present, area:design (first declared in LABEL_TO_ROUTE) wins → the webhook dispatches to designer again instead of design-reviewer. Designer wastefully re-implements.

Hit live today on #70 after the designer→design-reviewer loop was wired up: designer finished at 19:14, added area:design-review, webhook fired, designer got re-dispatched on the same ticket. Had to manually cancel and strip area:design to unblock the design-reviewer dispatch.

Fix

Add a step to skills/design-implement.md step 6: after add_issue_labels(area:design-review), call remove_issue_labels(area:design). That way the terminal state of the issue after designer finishes is a single area:design-review label, and the label-event route is unambiguous.

Acceptance criteria

Skill

  • skills/design-implement.md workflow §6 adds a "then remove area:design" substep using mcp__forgejo__remove_issue_labels.
  • Skill success gate: issue has area:design-review and does NOT have area:design.

Regression

  • Re-dispatch #70 via area:design — designer runs, posts handoff, label state ends with area:design-review only, design-reviewer picks up without a designer re-trigger.

Out of scope

  • Webhook-side tie-breaker (prefer newer labels, or match by event payload's single label field when present). Worth considering separately but is a bigger change; skill fix is the cheapest unblock.
  • design-review's side of the label cleanup — already does the right thing (removes area:design-review on completion per PR #86).

References

  • Observed: designer task 666c4f5c-5a72-4d2d-bb79-f4f2bdca8fc5 dispatched by mistake on #70 at 20:08 UTC, after the real run already finished.
  • skills/design-implement.md — the workflow to amend.
  • src/webhook-routing.ts:LABEL_TO_ROUTE — the order-matters map.

Dependencies

  • Blocked by: nothing.
  • Blocks: clean end-to-end area:designarea:design-review loops on future design tickets.
  • Branch off: main.
## User story As the **operator**, I want designer's handoff step to leave the issue with **only** `area:design-review` on it — not both `area:design` *and* `area:design-review` — so that the next webhook label-event routes to `design-reviewer` instead of re-triggering `designer`. ## What happens today `skills/design-implement.md` step 6 (from PR #86) adds `area:design-review` to the issue after posting the handoff comment. It does **not** remove `area:design`. So the issue ends up with both labels. Forgejo v15's `issues.label_updated` payload doesn't carry the single just-changed label, so `routeForLabels` walks the full label set and returns the first match. With both present, `area:design` (first declared in `LABEL_TO_ROUTE`) wins → the webhook dispatches to **designer** again instead of design-reviewer. Designer wastefully re-implements. Hit live today on #70 after the designer→design-reviewer loop was wired up: designer finished at 19:14, added `area:design-review`, webhook fired, designer got re-dispatched on the same ticket. Had to manually cancel and strip `area:design` to unblock the design-reviewer dispatch. ## Fix Add a step to `skills/design-implement.md` step 6: after `add_issue_labels(area:design-review)`, call `remove_issue_labels(area:design)`. That way the terminal state of the issue after designer finishes is a single `area:design-review` label, and the label-event route is unambiguous. ## Acceptance criteria ### Skill - [ ] `skills/design-implement.md` workflow §6 adds a "then remove `area:design`" substep using `mcp__forgejo__remove_issue_labels`. - [ ] Skill success gate: issue has `area:design-review` and does NOT have `area:design`. ### Regression - [ ] Re-dispatch #70 via `area:design` — designer runs, posts handoff, label state ends with `area:design-review` only, design-reviewer picks up without a designer re-trigger. ## Out of scope - **Webhook-side tie-breaker** (prefer newer labels, or match by event payload's single `label` field when present). Worth considering separately but is a bigger change; skill fix is the cheapest unblock. - **design-review's side of the label cleanup** — already does the right thing (removes `area:design-review` on completion per PR #86). ## References - Observed: designer task `666c4f5c-5a72-4d2d-bb79-f4f2bdca8fc5` dispatched by mistake on #70 at 20:08 UTC, after the real run already finished. - `skills/design-implement.md` — the workflow to amend. - `src/webhook-routing.ts:LABEL_TO_ROUTE` — the order-matters map. ## Dependencies - **Blocked by:** nothing. - **Blocks:** clean end-to-end `area:design` → `area:design-review` loops on future design tickets. - **Branch off:** `main`.
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#96
No description provided.