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
143 changes: 135 additions & 8 deletions .agents/skills/qa/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,138 @@ description: View the QA queue or review a specific issue

---

> **QA workflow is not configured.** `/qa` requires `QA_READY_LABEL` to be set in `.codecannon.yaml` so it can find issues waiting for QA.
>
> To enable: add `QA_READY_LABEL: ready-for-qa` (or your preferred label name) to `.codecannon.yaml` and re-run `CodeCanon/sync.sh`.
>
> Note: In trunk mode, `/ship` does not apply this label automatically — you would need to apply it manually or via a separate workflow.

Do not proceed. Stop here.
<!-- generated by CodeCanon/sync.sh | skill: qa | adapter: codex | hash: 8495a9ca | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
## What `/qa` does

`/qa` has two modes:

- **No argument** — show all issues awaiting QA.
- **Numeric argument** — walk through QA review for a specific issue.

---

## Mode A — No argument: QA queue view

Run:
```
gh issue list --label "ready-for-qa" --state open \
--json number,title,url,labels,milestone,assignees
```

Display as a numbered list. For each issue show: issue number, title, milestone (if set), and URL.

If the list is empty, say:

> "No issues are currently waiting for QA."

Do not take any other action.

---

## Mode B — Numeric argument: Review a specific issue

The argument is an issue number. Work through the following steps.

### Step 1 — Load context

```
gh issue view <number> --json number,title,body,labels,url,comments
```

Display the issue title and body.

Check whether `ready-for-qa` is currently applied to the issue. If it is **not** present, warn:

> "Issue #N does not have the ready-for-qa label. It may not be deployed to preview yet. Continue anyway? (yes/no)"

Wait. If the user says no, stop.

---

### Step 2 — Review prompt

Say:

> "Test this feature on the preview environment. When you're done, describe what you tested, what you found, and your verdict (pass or fail). Include screenshots if you have them — paste image links or drag-and-drop into GitHub directly."

**Stop. Wait for the QA person's input. Do not proceed until they provide a verdict.**

---

### Step 3 — Post findings as issue comment

Build a structured comment from their input:

```
## QA Review

**Verdict:** PASS (or FAIL)

**What was tested:**
<their description>

**Findings:**
<their findings, or "None — feature works as expected.">

**Screenshots:**
<image links if provided, or "None attached.">
```

Show the comment to the user before posting. Ask:

> "Post this to issue #N? (yes/no)"

Wait for confirmation. On yes:
```
gh issue comment <number> --body "<comment>"
```

On no, stop — do not post and do not apply labels.

---

### Step 4 — Apply verdict label

Based on the verdict:

**PASS:**
```
gh issue edit <number> --add-label "qa-passed" --remove-label "ready-for-qa"
```

**FAIL:**

Before applying labels, fetch the issue's current assignees:
```
gh issue view <number> --json assignees --jq '.assignees[].login' 2>/dev/null
```

If one or more assignees are found, prepend the following line to the comment body (above the `## QA Review` heading) in the comment that was already posted:

> cc @<assignee> — this issue needs attention.

If there are multiple assignees, include one `cc @<login>` per line. If the command errors or returns no results, omit the line silently.

```
gh issue edit <number> --add-label "qa-failed" --remove-label "ready-for-qa"
```

If the `gh issue edit` command fails because a label does not exist in the repo, report the error and say:

> "The label does not exist in this repository. Create it in GitHub Settings → Labels, then re-run `/qa <number>` from Step 4."

Do not retry automatically.

After applying labels, tell the user what was done:

- On PASS: "Issue #N marked as QA passed. The developer can now close it or promote to production."
- On FAIL: "Issue #N marked as QA failed. The developer will see the findings in the issue comments."

---

## Hard rules

- Never close an issue — verdict recording and closure are separate concerns.
- Never post the comment without showing it to the user first.
- Never apply labels without user confirmation (the confirmation in Step 3 is the single gate for both posting the comment and applying labels).
- Never merge, deploy, or take any action beyond labeling and commenting.
<!-- generated by CodeCanon/sync.sh | skill: qa | adapter: codex | hash: dc360e69 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
10 changes: 9 additions & 1 deletion .agents/skills/ship/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ EOF
)"
```

Add `--reviewer @sebastientaggart` to the `gh pr create` command above.

If a CODEOWNERS file exists, both apply: CODEOWNERS triggers automatic review requests from GitHub; the `--reviewer` flag adds the explicitly configured handles on top.

**Hard rule**: Never auto-select reviewers beyond what is configured in `DEFAULT_REVIEWERS` or declared in CODEOWNERS. Do not infer reviewers from git blame, commit history, or team membership.

Expand Down Expand Up @@ -163,6 +166,11 @@ Return to the coding loop. When fixed, run `/ship` again from Step 1.

### After merge — QA label and success report

If a linked issue number was identified in Step 3, apply the QA label:
```
gh issue edit <number> --add-label "ready-for-qa"
```
If no linked issue was found, skip silently.

Report success based on mode:
"PR merged. Issues stay open until testing confirms the fix. Run `make deploy-preview` when ready to deploy to preview."
Expand All @@ -177,4 +185,4 @@ Report success based on mode:
- When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass.
- `/ship` merges only to `dev` — never directly to `main`.
- If `make merge` fails for any reason, report it and stop — do not attempt workarounds.
<!-- generated by CodeCanon/sync.sh | skill: ship | adapter: codex | hash: a7a0480e | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
<!-- generated by CodeCanon/sync.sh | skill: ship | adapter: codex | hash: a0f3cbc1 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
11 changes: 5 additions & 6 deletions .agents/skills/start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ The argument string may contain optional inline flags after the description. Par
After parsing flags, determine the active labels in this order:

1. **Per-invocation flag** — if `--label <value>` was in `$ARGUMENTS`, use that value verbatim. Skip all remaining steps.
2. **Pool-based selection** — no label pool is configured. Fall through to step 3.
2. **Pool-based selection** — the allowed label pool is: `bug, documentation, enhancement, chore` (comma-separated). Select 1–3 labels from this pool that genuinely fit the task description and implementation approach. Do not apply labels mechanically — pick only what fits. If no pool label fits the task, fall through to step 3.
- If any selected label name contains a space (e.g. `good first issue`), quote the entire `--label` value.
3. **No label / creation** — if the pool is empty or no pool label fits:
- If `false` is `true` (case-insensitive string match): the agent **may** create a new label before applying it:
```bash
Expand All @@ -46,8 +47,6 @@ After parsing flags, determine the active labels in this order:
Use judgment — only create a label with clear reuse value. Do not create near-duplicates of existing pool labels.
- If `false` is `false` or unset: omit `--label` entirely. Proceed silently; do not inform the user.

> **Tip:** Run `/setup` to populate TICKET_LABELS from your repo's existing GitHub labels.

**Milestone resolution (three-tier, Case A only):**

After parsing flags, determine the active milestone in this order:
Expand All @@ -66,7 +65,7 @@ After parsing flags, determine the active milestone in this order:

| `$ARGUMENTS` | Description | Labels | Milestone |
|---|---|---|---|
| `Add dark mode toggle to settings page` | `Add dark mode toggle to settings page` | none (no label pool) | auto-detected |
| `Add dark mode toggle to settings page` | `Add dark mode toggle to settings page` | auto-selected from pool | auto-detected |
| `Add dark mode --label enhancement` | `Add dark mode` | `enhancement` (verbatim) | auto-detected |
| `Add dark mode --label enhancement,ux --milestone "Sprint 4"` | `Add dark mode` | `enhancement,ux` (verbatim) | `Sprint 4` |

Expand Down Expand Up @@ -227,6 +226,6 @@ When done, say: **"The code is ready for review. Please run `make dev` and test
- If already on a feature branch when `/start` is invoked, warn the user before creating another branch.
- `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor.
- The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`.
- Apply labels only when explicitly provided via `--label`. No label pool is configured.
- Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit (or create if `false` is `true`). Never apply a label not in `bug, documentation, enhancement, chore` unless `false` is `true`.
- Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation.
<!-- generated by CodeCanon/sync.sh | skill: start | adapter: codex | hash: 09fe8ca2 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
<!-- generated by CodeCanon/sync.sh | skill: start | adapter: codex | hash: f8182e62 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
143 changes: 135 additions & 8 deletions .claude/commands/qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,138 @@ View the QA queue or review a specific issue

---

> **QA workflow is not configured.** `/qa` requires `QA_READY_LABEL` to be set in `.codecannon.yaml` so it can find issues waiting for QA.
>
> To enable: add `QA_READY_LABEL: ready-for-qa` (or your preferred label name) to `.codecannon.yaml` and re-run `CodeCanon/sync.sh`.
>
> Note: In trunk mode, `/ship` does not apply this label automatically — you would need to apply it manually or via a separate workflow.

Do not proceed. Stop here.
<!-- generated by CodeCanon/sync.sh | skill: qa | adapter: claude | hash: 0ff4c0ee | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
## What `/qa` does

`/qa` has two modes:

- **No argument** — show all issues awaiting QA.
- **Numeric argument** — walk through QA review for a specific issue.

---

## Mode A — No argument: QA queue view

Run:
```
gh issue list --label "ready-for-qa" --state open \
--json number,title,url,labels,milestone,assignees
```

Display as a numbered list. For each issue show: issue number, title, milestone (if set), and URL.

If the list is empty, say:

> "No issues are currently waiting for QA."

Do not take any other action.

---

## Mode B — Numeric argument: Review a specific issue

The argument is an issue number. Work through the following steps.

### Step 1 — Load context

```
gh issue view <number> --json number,title,body,labels,url,comments
```

Display the issue title and body.

Check whether `ready-for-qa` is currently applied to the issue. If it is **not** present, warn:

> "Issue #N does not have the ready-for-qa label. It may not be deployed to preview yet. Continue anyway? (yes/no)"

Wait. If the user says no, stop.

---

### Step 2 — Review prompt

Say:

> "Test this feature on the preview environment. When you're done, describe what you tested, what you found, and your verdict (pass or fail). Include screenshots if you have them — paste image links or drag-and-drop into GitHub directly."

**Stop. Wait for the QA person's input. Do not proceed until they provide a verdict.**

---

### Step 3 — Post findings as issue comment

Build a structured comment from their input:

```
## QA Review

**Verdict:** PASS (or FAIL)

**What was tested:**
<their description>

**Findings:**
<their findings, or "None — feature works as expected.">

**Screenshots:**
<image links if provided, or "None attached.">
```

Show the comment to the user before posting. Ask:

> "Post this to issue #N? (yes/no)"

Wait for confirmation. On yes:
```
gh issue comment <number> --body "<comment>"
```

On no, stop — do not post and do not apply labels.

---

### Step 4 — Apply verdict label

Based on the verdict:

**PASS:**
```
gh issue edit <number> --add-label "qa-passed" --remove-label "ready-for-qa"
```

**FAIL:**

Before applying labels, fetch the issue's current assignees:
```
gh issue view <number> --json assignees --jq '.assignees[].login' 2>/dev/null
```

If one or more assignees are found, prepend the following line to the comment body (above the `## QA Review` heading) in the comment that was already posted:

> cc @<assignee> — this issue needs attention.

If there are multiple assignees, include one `cc @<login>` per line. If the command errors or returns no results, omit the line silently.

```
gh issue edit <number> --add-label "qa-failed" --remove-label "ready-for-qa"
```

If the `gh issue edit` command fails because a label does not exist in the repo, report the error and say:

> "The label does not exist in this repository. Create it in GitHub Settings → Labels, then re-run `/qa <number>` from Step 4."

Do not retry automatically.

After applying labels, tell the user what was done:

- On PASS: "Issue #N marked as QA passed. The developer can now close it or promote to production."
- On FAIL: "Issue #N marked as QA failed. The developer will see the findings in the issue comments."

---

## Hard rules

- Never close an issue — verdict recording and closure are separate concerns.
- Never post the comment without showing it to the user first.
- Never apply labels without user confirmation (the confirmation in Step 3 is the single gate for both posting the comment and applying labels).
- Never merge, deploy, or take any action beyond labeling and commenting.
<!-- generated by CodeCanon/sync.sh | skill: qa | adapter: claude | hash: ac0a4a39 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
10 changes: 9 additions & 1 deletion .claude/commands/ship.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ EOF
)"
```

Add `--reviewer @sebastientaggart` to the `gh pr create` command above.

If a CODEOWNERS file exists, both apply: CODEOWNERS triggers automatic review requests from GitHub; the `--reviewer` flag adds the explicitly configured handles on top.

**Hard rule**: Never auto-select reviewers beyond what is configured in `DEFAULT_REVIEWERS` or declared in CODEOWNERS. Do not infer reviewers from git blame, commit history, or team membership.

Expand Down Expand Up @@ -158,6 +161,11 @@ Return to the coding loop. When fixed, run `/ship` again from Step 1.

### After merge — QA label and success report

If a linked issue number was identified in Step 3, apply the QA label:
```
gh issue edit <number> --add-label "ready-for-qa"
```
If no linked issue was found, skip silently.

Report success based on mode:
"PR merged. Issues stay open until testing confirms the fix. Run `make deploy-preview` when ready to deploy to preview."
Expand All @@ -172,4 +180,4 @@ Report success based on mode:
- When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass.
- `/ship` merges only to `dev` — never directly to `main`.
- If `make merge` fails for any reason, report it and stop — do not attempt workarounds.
<!-- generated by CodeCanon/sync.sh | skill: ship | adapter: claude | hash: 6f05a980 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
<!-- generated by CodeCanon/sync.sh | skill: ship | adapter: claude | hash: 147893a6 | DO NOT EDIT — run CodeCanon/sync.sh to regenerate -->
Loading
Loading