issue — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited issue (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Draft an issue whose job is to convey why the work is needed and how the author intends to approach it — written for a reader who has never seen this part of the system. An issue describes work to be done, so unlike commit and prepare-review there is no diff to read from: the raw material is the author's intent, gathered up front.
Don't narrate your work. Every step below is an operating instruction, not a script to read aloud. Don't announce what you're about to do or report the plumbing of each command. Speak only when the user must act or decide: a question you need answered, the drafted issue with its options, the final URL.
Issue = a GitHub issue or a GitLab issue. Pick the forge tool by the origin remote.
%%{ init: { 'look': 'handDrawn' } }%%
flowchart TD
Start(["/issue"]) --> Mode{Issue ref given?}
subgraph "Step 1: Resolve target"
Mode -->|Yes| Update["Update: fetch current body as baseline"]
Mode -->|No| Create["Create: new issue"]
end
subgraph "Step 2: Gather intent"
Update --> Why["Ask the WHY + consumer + acceptance"]
Create --> Why
end
subgraph "Step 3: Check for similar issues"
Why --> FromCreate{Creating a new issue?}
FromCreate -->|Yes| Search["Search forge: open + closed"]
Search --> Match{Author picks a match?}
Match -->|Yes| Reuse["Switch to update: fetch its body as baseline"]
end
subgraph "Step 4: Draft"
Tmpl["Honor forge template + anchor.* config"]
Tmpl --> Draft["Draft title + body"]
end
FromCreate -->|No, updating| Tmpl
Match -->|No, file new| Tmpl
Reuse --> Tmpl
subgraph "Step 5: Output"
Draft --> Out{Disposition?}
Out -->|Write| Forge(["Create / update issue"])
Out -->|Copy| CopyOnly(["Print for paste"])
Out -->|Edit| Revise["Revise (moor or chat)"] --> Draft
endPick the forge from the origin remote (gh for GitHub, glab for GitLab).
mktemp -u /tmp/issue-current.XXXXXX.md); Step 5 diffs the draft against it: # GitHub
gh issue view <num> --json body --jq '.body' > <current-path> # GitLab
glab issue view <iid> --output json | jq -r '.description' > <current-path>There is no diff to mine, so the author's answers are the issue. Ask for what's missing — don't draft around a gap:
Wait for answers before drafting. If the only open item is the WHY, ask:
What problem does this solve, and why does it matter? A sentence or two is enough — and who's the primary consumer of the change?
This step runs only on the create path — skip it when updating a known issue. A duplicate issue splits the discussion, so before drafting search the forge for issues that already cover this need: open ones (filing would duplicate active work) and closed ones (already done, or declined).
Distill two to four search keywords from the intent gathered in Step 2 — the subject of the work, not the WHY prose. Then search:
# GitHub — open + closed, most-recently-updated first
gh issue list --search "<keywords> sort:updated-desc" --state all --limit 10 \
--json number,title,url,state,updatedAt# GitLab — open + closed (--all), matching title and description
glab issue list --search "<keywords>" --in title,description --all --output jsonJudge the results — a keyword hit on an unrelated issue is noise, not a match. If nothing genuinely overlaps, continue to Step 4 without comment. If one or more issues plausibly cover this need, present them with the AskUserQuestion tool (header Similar issues):
#<num> <title> and tagged by state ([open] / [closed]). Picking one means this is the issue → switch to the update path: fetch its current body as the baseline (the Step 1 fetch), then draft against it.Before drafting, check whether the project ships an issue template:
.gitlab/issue_templates/*.md (respect the configured default if more than one).github/ISSUE_TEMPLATE/*.md, or the legacy .github/ISSUE_TEMPLATE.md. A .yml issue form is a structured format — don't compose prose into it; surface it and let the author fill it in the web UI.If a template exists, it's the team's required scaffolding — compose into it, don't replace it. Fill the sections it defines, preserve its checklists and headings verbatim, and strip any "delete before publishing" instruction block after following its guidance. On a structure conflict the team template wins. The composition rules live in the "Honoring a project's forge template" section of templates/issue-description.md.
anchor.* configRead the project + global anchor keys once:
git config --get-regexp '^anchor\.' 2>/dev/null--get-regexp returns the names lowercased (anchor.issuerules); match them case-insensitively. Apply the keys relevant to an issue; absent keys keep anchor's defaults — never invent a value:
<base-uri><id> from a bare id. No mention, no link.anchor.reviewBudgetMins does not apply to issues. See guides/configuring.md for the full key set.
Draft a concise imperative title (under 72 characters), then the body following the section template in templates/issue-description.md: Context, Proposed approach, Acceptance criteria, and Considerations (optional). The template owns the shape; the discipline below owns the technique.
prepare-review uses. Establish the system/business context in a sentence or two before the detail.> **Term?** …), sparingly and only where a newcomer would be lost.\n/<br> in labels).Write the drafted body to a temp file (mktemp -u /tmp/issue-draft.XXXXXX.md).
Present the change. When updating an existing issue, diff the draft against the baseline captured in Step 1 and present it in a fenced diff block:
git --no-pager diff --no-index <current-path> <draft-path>When creating a new issue, display the full title and body in a fenced code block.
Then ask the user how to proceed with the AskUserQuestion tool. Use header Disposition and these options (default first):
<draft-path>. On a 401/403 or similar auth failure, surface it and ask the user to refresh credentials — don't silently fall back to copy-only (per the fail-fast-on-auth rule).anchor assigns new issues to you. The canonical invocations — including the glab api-then-glab issue update two-step GitLab needs for a file-sourced body, and the update-from-file forms — live in the forge cookbook, sections "Issue create" and "Issue description update from a file":
# GitHub — create
gh issue create --title "<title>" --body-file <draft-path> --assignee @me
# GitHub — update
gh issue edit <num> --body-file <draft-path># GitLab — create (API form so the body can come from a file), then assign
glab api -X POST projects/:fullpath/issues -F title="<title>" -F "description=@<draft-path>"
glab issue update <iid> --assignee <username>
# GitLab — update
glab api -X PUT projects/:fullpath/issues/<iid> -F "description=@<draft-path>"After the issue lands, print its URL.
moor is the preferred edit surface but optional — check command -v moor. If present, open a one-off review of the current body vs. the draft (when updating) or the draft alone, launched via the wrapper as a background Bash call so it doesn't hold the turn open:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/review-diff.sh" --files \
<current-path> <draft-path> \
--title 'Issue body — proposed edits' \
--detail repo=<repo>Read the verdict back with the BashOutput tool (not tail / $(...)). Only REVIEW_VERDICT 0 is approval; 1 carries fix-now comments in REVIEW_OUTPUT.comments to fold in before re-presenting; 2/3/absent mean the review didn't complete — surface what happened and fall back to chat rather than treating silence as approval. (The full verdict contract matches the prepare-review skill's Step 4.) If moor isn't on PATH, fall back to chat: ask what to change, revise, and re-present.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.