From 2b1c33c339a03dbc4866417b0423683b627f9cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:15:29 +0100 Subject: [PATCH 1/3] fix(skills/reporting-a-skill-gap): act on a match closed without a fix Step 3 gave a branch for a closed match only when a version fixed it. An issue closed as a duplicate or as not planned fit no branch. The plain `gh issue view` shows only CLOSED, so the agent also could not tell the close reasons apart. In a baseline with a standing grant, one agent commented on the declined issue and one filed a new issue. Neither told the user first that the maintainers had declined the gap. Both gave the missing reproduction as the reason. Step 3 now reads the close reason with `--json stateReason`. A duplicate leads to the issue that it duplicates, through the `duplicateOf` field. For a gap closed as not planned, the agent tells the user and files nothing, also under a standing grant. It files a new issue only for a difference that the maintainers' reason does not cover, and the new issue names the closed one. A new Red flags row answers the "it had no reproduction" reason. Fixes #81 Co-Authored-By: Claude Opus 5.5 --- skills/reporting-a-skill-gap/SKILL.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/skills/reporting-a-skill-gap/SKILL.md b/skills/reporting-a-skill-gap/SKILL.md index d1f41a8..498f9d2 100644 --- a/skills/reporting-a-skill-gap/SKILL.md +++ b/skills/reporting-a-skill-gap/SKILL.md @@ -39,11 +39,19 @@ Open the installed skill, `${CLAUDE_PLUGIN_ROOT}/skills//SKILL.md`, and fi gh issue list --repo OWNER/REPO --state all --search " " --limit 20 ``` -Run a second search with other words if the first finds nothing. The list shows titles only, so open each plausible match with `gh issue view --repo OWNER/REPO --comments` before you pick a branch below. Then: +Run a second search with other words if the first finds nothing. The list shows titles only, so open each plausible match with `gh issue view --repo OWNER/REPO --comments` before you pick a branch below. That view shows a closed issue as `CLOSED` but not why it was closed, so for each closed match also run: + +``` +gh issue view --repo OWNER/REPO --json stateReason --jq .stateReason +``` + +It prints `COMPLETED`, `NOT_PLANNED`, or `DUPLICATE`. Then: - **An open issue covers the same gap:** comment on it instead of filing a new one. The comment adds your reproduction and evidence (see the template's comment form). If the issue already has a reproduction of the same case, tell the user and stop. -- **A closed issue covers it, fixed in a version newer than the installed one:** tell the user to update the plugin. File nothing. -- **A closed issue covers it and the installed version has the fix:** it is a regression. File a new issue and name the closed one in `## Evidence`. +- **A closed issue covers it, closed as `DUPLICATE`:** follow it to the issue it duplicates and pick the branch for that issue instead. Do not comment on the duplicate. Get the number with `gh api graphql -f query='query{repository(owner:"OWNER",name:"REPO"){issue(number:){duplicateOf{number}}}}' --jq '.data.repository.issue.duplicateOf.number'`. If it prints an empty line, take the number from the closing comment. +- **A closed issue covers it, closed as `NOT_PLANNED`:** the maintainers declined this gap. Tell the user, with the reason from the thread, and file nothing: no new issue, and no comment on the closed one. This holds under a standing grant too, because a grant lets a report land without a prompt and does not decide whether one is due. A reproduction that the closed issue lacks is not a difference. File a new issue only when your case differs from the closed one in a way the maintainers' reason does not cover, such as another section or another failure. The new issue names the closed one and the difference in `## Evidence`. +- **A closed issue covers it, closed as `COMPLETED` and fixed in a version newer than the installed one:** tell the user to update the plugin. File nothing. +- **A closed issue covers it, closed as `COMPLETED`, and the installed version has the fix:** it is a regression. File a new issue and name the closed one in `## Evidence`. - **No match:** file a new issue. ## Step 4: draft the body from the template @@ -91,4 +99,5 @@ Do not edit the installed copy of the skill under `${CLAUDE_PLUGIN_ROOT}`: the p | "I'll mention the project so they see it was a real case" | The repository is public. The generic shape is the real case; the names add only risk. | | "It's only a test key, I'll mask it" | Leave it out. A masked key still tells a reader what kind of secret leaked and where. | | "This is probably new, I'll skip the search" | A second issue splits the thread. Search first; a reproduction is worth more on the existing issue. | +| "It was closed as not planned, but it had no reproduction, and the user asked me to report" | The maintainers declined the gap, not the report's form. Tell the user and file nothing. A new issue needs a difference that their reason does not cover. | | "I'll fix the installed skill file so it works now" | The cache is overwritten on update, and the fix needs the maintainer's RED baseline. Report it and keep the hand-added instruction in your prompts. | From 92c6db205ab851f20de3813ea53478672e88e597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:26:29 +0100 Subject: [PATCH 2/3] fix(skills/reporting-a-skill-gap): scope GraphQL calls to the plugin's repository Step 1 asked for the repository in the path of every `gh api` call. A GraphQL call has no such path, so the rule conflicted with the `duplicateOf` query in Step 3, and an agent could reject or rewrite that query. Step 1 now asks for the path in a REST call, and for `repository(owner:"OWNER",name:"REPO")` in the query of a GraphQL call. Co-Authored-By: Claude Opus 5.5 --- skills/reporting-a-skill-gap/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/reporting-a-skill-gap/SKILL.md b/skills/reporting-a-skill-gap/SKILL.md index 498f9d2..f95b5ac 100644 --- a/skills/reporting-a-skill-gap/SKILL.md +++ b/skills/reporting-a-skill-gap/SKILL.md @@ -27,7 +27,7 @@ The issue goes to the plugin's repository, never to the repository of the curren 1. Read `${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json`. Its `repository` field holds the URL of the plugin's repository. Take `OWNER/REPO` from it (`https://github.com/OWNER/REPO` gives `OWNER/REPO`). Its `version` field is the plugin version for the report. 2. If the file or the field is missing, ask the user for the repository. Do not take it from a README, a marketplace file, or the current remote. -3. Pass `--repo OWNER/REPO` on every `gh issue` command this skill runs, and name the repository in the path of every `gh api` call (`repos/OWNER/REPO/...`): `gh api` takes no `--repo`. +3. Pass `--repo OWNER/REPO` on every `gh issue` command this skill runs. `gh api` takes no `--repo`, so name the repository in the path of every REST call (`repos/OWNER/REPO/...`), and in the query of every GraphQL call (`repository(owner:"OWNER",name:"REPO")`). ## Step 2: locate the gap in the skill From a0995ef48ac5de1b826331617e89360f54e6b8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:31:03 +0100 Subject: [PATCH 3/3] fix(skills/reporting-a-skill-gap): handle a closed match with no recorded close reason GitHub's schema allows `stateReason` to be null, and then `--jq .stateReason` prints an empty line, which matched no branch of Step 3. The agent now takes the reason from the closing comment, and asks the user which branch applies when the comment does not say. Co-Authored-By: Claude Opus 5.5 --- skills/reporting-a-skill-gap/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/reporting-a-skill-gap/SKILL.md b/skills/reporting-a-skill-gap/SKILL.md index f95b5ac..a3490d7 100644 --- a/skills/reporting-a-skill-gap/SKILL.md +++ b/skills/reporting-a-skill-gap/SKILL.md @@ -45,7 +45,7 @@ Run a second search with other words if the first finds nothing. The list shows gh issue view --repo OWNER/REPO --json stateReason --jq .stateReason ``` -It prints `COMPLETED`, `NOT_PLANNED`, or `DUPLICATE`. Then: +It prints `COMPLETED`, `NOT_PLANNED`, or `DUPLICATE`. If it prints an empty line, GitHub recorded no reason: take it from the closing comment, and if the comment does not say, ask the user which branch applies. Then: - **An open issue covers the same gap:** comment on it instead of filing a new one. The comment adds your reproduction and evidence (see the template's comment form). If the issue already has a reproduction of the same case, tell the user and stop. - **A closed issue covers it, closed as `DUPLICATE`:** follow it to the issue it duplicates and pick the branch for that issue instead. Do not comment on the duplicate. Get the number with `gh api graphql -f query='query{repository(owner:"OWNER",name:"REPO"){issue(number:){duplicateOf{number}}}}' --jq '.data.repository.issue.duplicateOf.number'`. If it prints an empty line, take the number from the closing comment.