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
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,46 @@ version's [GitHub Release](https://github.com/ColorMath/ci/releases).

## Unreleased

MINOR. A skill gains an input shape it did not have; nothing that worked before
works differently.

### Changed

- **`bugfix` now takes a ticket key as well as a pasted report.**
`/colormath:bugfix CM-00012` reads the ticket over MCP — description, type,
every comment, and the plans if it was groomed — instead of needing the report
pasted in. Prose, a stack trace and a path to a report file all behave exactly
as before; the skill now branches on which of the three shapes it was handed.

The gap this closes is that a bug usually **is** a ticket by the time somebody
fixes it. `refine-ticket`, `implement-ticket`, `refine-initiative` and
`plan-initiative` all take a key; `bugfix` was the odd one out, so the only
way to hand it a filed bug was to copy the description out of the tracker —
which silently drops the comment thread, where a filed bug's actual
reproduction usually ends up.

Reading the thread is the point, not a side effect: the skill is told to read
**every comment**, because the environment, the repro somebody finally landed
on, and the "it also happens when…" are typically there rather than in the
description. What it must not do is treat a numbered ticket as more
authoritative than a pasted paragraph — step 1 ("find what's missing") applies
unchanged either way.

It also closes the loop: when a run started from a ticket, the skill now
`add_comment`s the outcome — PR link, merged or held, the cause, and what it
deliberately left alone — matching what `implement-ticket` already does. It
leaves the ticket's own fields and lane alone; the description is what was
reported, the comment is what happened, and whether a bug is done is the
filer's call.

`allowed-tools` gains `mcp__abacus__get_ticket`, `list_boards`, `list_tickets`
and `add_comment` — the same read set `refine-ticket` carries, plus the
comment write. A consumer with no abacus MCP server configured is unaffected:
the pasted-report path never touches those tools.

Downstream, this makes `/colormath:bugfix <key>` a command a tracker can print
next to a bug and have somebody run as-is, which it could not before.

## v3.1.0 — 2026-08-04

MINOR. Three new plugin skills and a new vendored file are additive per
Expand Down
40 changes: 33 additions & 7 deletions plugin/skills/bugfix/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: bugfix
description: Take a bug report all the way from raw report to merged fix — establish the facts the report left out (which environment, which surface, the literal repro), reproduce the defect against the running stack, fix it at the layer the invariant belongs to, add a regression test that fails without the fix, assess whether the defect already corrupted stored data and remediate that in the same PR, then hand off to /colormath:ship. Use this whenever someone reports something broken — a bug report, a pasted stack trace or error log, "why is X doing Y", "users can't Z", a production incident, a written-up findings doc — even when they never say the word "bug". Not for sweeping a whole feature area for unknown problems (that's /colormath:qa), and not for shipping a branch that's already fixed (that's /colormath:ship).
argument-hint: [the bug report — prose, a pasted error/log, or a path to a report file]
allowed-tools: Bash Read Edit Write Grep Glob Skill AskUserQuestion
description: Take a bug report all the way from raw report to merged fix — establish the facts the report left out (which environment, which surface, the literal repro), reproduce the defect against the running stack, fix it at the layer the invariant belongs to, add a regression test that fails without the fix, assess whether the defect already corrupted stored data and remediate that in the same PR, then hand off to /colormath:ship. Use this whenever someone reports something broken — a ticket key for a filed bug, a bug report, a pasted stack trace or error log, "why is X doing Y", "users can't Z", a production incident, a written-up findings doc — even when they never say the word "bug". Not for sweeping a whole feature area for unknown problems (that's /colormath:qa), and not for shipping a branch that's already fixed (that's /colormath:ship).
argument-hint: [a ticket key (CM-00012), or the report itself — prose, a pasted error/log, or a path to a report file]
allowed-tools: Bash Read Edit Write Grep Glob Skill AskUserQuestion mcp__abacus__get_ticket mcp__abacus__add_comment mcp__abacus__list_boards mcp__abacus__list_tickets
---

Turn the bug report in "$ARGUMENTS" into a merged fix.
Expand All @@ -21,10 +21,30 @@ So the spine is: **understand → reproduce → diagnose → fix → prove → r
→ ship.** Don't skip forward. In particular, don't start editing code before
you have watched the bug happen.

If "$ARGUMENTS" points at a file (a written-up report, an exported ticket, a
QA findings doc), read the whole thing first. If it's a stack trace or a log
excerpt, that's your best evidence — work backwards from the frames to the code
path, but treat the trace as the *symptom's* location, not the defect's.
**First, work out what you were handed.** A bug arrives in one of three
shapes, and they start differently:

- **A ticket key** (`CM-00012`, `cm-12` — case and zero-padding don't matter).
Call `mcp__abacus__get_ticket`, which takes the key directly. Read the whole
thing: description, type, **every comment**, and the plan and QA plan if
somebody groomed it. The comments are where the report actually lives once a
bug has been discussed — the reproduction somebody finally landed on, the
environment it was seen in, the "actually it also happens when…" that never
made it into the description. A bug filed as a ticket has usually been talked
about, and skipping the thread is how you re-derive what the thread already
settled. If "$ARGUMENTS" is a title fragment rather than a key, find it with
`list_boards` then `list_tickets`, and confirm which one you landed on before
doing anything else.
- **A file** — a written-up report, an exported ticket, a QA findings doc. Read
the whole thing first.
- **Prose, a stack trace, or a log excerpt**, pasted straight in. A trace is
your best evidence: work backwards from the frames to the code path, but
treat it as the *symptom's* location, not the defect's.

Whichever it was, the ticket or the report is still **evidence rather than a
specification**, and step 1 applies unchanged. A filed ticket is not more
authoritative than a pasted paragraph — it is the same claim with a number on
it, and the same things are missing from it.

## 1. Read the report, then find what's missing

Expand Down Expand Up @@ -227,5 +247,11 @@ anything you deliberately left for a human.
problems get written down and mentioned, not folded into the diff.
- Local state is yours to mutate while reproducing — record a baseline first so
you can put it back, and clean up the rows, files and credentials you created.
- **If it came from a ticket, close the loop on it.** When ship comes back,
`add_comment` with the outcome — the PR link, whether it merged or is held,
the cause you found, and what you deliberately left alone. Leave the ticket's
own fields alone: the description is what was reported, and the comment is
what happened. Do not move it between lanes; lane meaning is per board and
the person who filed it decides when it is done.
- Your job ends where `/colormath:ship` takes over, and ship's own rules apply
from there.