write-issue
Skill16 starsChanged 3 days agoApache-2.0View on GitHub
Author a new, convention-conformant GitHub issue for bbvch-ai/aihub-core — title format, the In scope / Out of scope / Accepted when body structure, area:* labels, sibling and blocked-by cross-references — then create it and add it to the AI-Scrum board (org project 37) with issue type, Priority, and Status set. Use when user says 'write an issue', 'create a GitHub issue', 'open an issue for X', 'file a bug', 'draft an epic', or 'add a story to the board'. Do NOT use for planning an existing issue's implementation (use plan-issue), breaking an issue into sub-issues (use splice-issue), or creating a PR (use create-pr).
We split this skill into the rules it gives an agent
16 rules. 0 are common, 8 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
8
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Read two recent issues to anchor on the house style — the body convention is the most distinctive part:
- Distinctive: line 24
Before drafting, ground the issue in the actual codebase — an issue written from the request alone is not actionable.
- Very specific: line 29
Resolve ambiguity with the user via the AskUserQuestion tool: before writing — at minimum the issue type (Epic/Feature/Task/Bug) and …
- Distinctive: line 32
Verify the state of every issue you plan to cite: before citing it, see "Citing other issues" under Step 3.5.
- Distinctive: line 39
Every issue has a native GitHub issue type (org-level: Task, Bug, Feature, Epic, Spike, Tech Debt).
- Very specific: line 100
Use Blocked by #NNN. as a footer only for a true dependency.
- Distinctive: line 117
Before creating the issue, re-read the whole body once, straight through, as a skeptical editor who never saw the conversation that …
- Distinctive: line 127
If a citation or an assumption turned out to be wrong mid-conversation, just cite the right thing in the final body.
- Distinctive: line 128
Don't narrate the correction ("X is wrong, actually Y").
- Distinctive: line 129
Write as if handing this to someone with zero context on the discussion that produced it.
- Very specific: line 146
Before naming any issue number as a blocker, a sibling, or "already delivered," check its real state: gh issue view <N> -R …
- Very specific: line 185
Do not add a major / minor / patch label: version labels belong on the closing PR, not the issue.
- Very specific: line 265
Parent ↔ child (Epic holds Features/Tasks): use addSubIssue (see .claude/skills/splice-issue/SKILL.md for the full pattern).
- Very specific: line 293
Conventional-commit prefix on an Epic/Feature: Only Tasks/bugs use type(scope):.
- Very specific: line 297
Out of scope without a pointer: Every excluded item names the sibling/parent issue that owns it (— see #786).
- Very specific: line 305
Citing a closed-not-planned issue as "already delivered.": Check state/stateReason before citing.
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Write Issue — Author a Convention-Conformant GitHub Issue
Draft and create a single issue on bbvch-ai/aihub-core, then place it on the AI-Scrum board (org project 37) with
the right fields. Confirm the draft with the user before creating anything — issue creation and board mutation are
side effects.
Before You Start
Read two recent issues to anchor on the house style — the body convention is the most distinctive part:
gh issue view 1452 -R bbvch-ai/aihub-core --json title,body # Feature: In/Out/Accepted-when + "Blocked by"
gh issue view 1412 -R bbvch-ai/aihub-core --json title,labels # Bug: type(scope) title + area: labelStep 0: Research the Subject and Clarify
Before drafting, ground the issue in the actual codebase — an issue written from the request alone is not actionable.
- Research the files, packages, conventions, and current behaviour the issue touches (grep/read the relevant code,
docs, and config). Name real paths in the body — e.g. the relicensing surface lives in
LICENSES.md, per-packageLICENSEfiles, and SPDX headers, not just "the licenses". - Resolve ambiguity with the user via the AskUserQuestion tool before writing — at minimum the issue type (Epic/Feature/Task/Bug) and Priority (Urgent/P0/P1/P2), plus any scope fork the request leaves open. Never guess Priority or invent scope; a wrong field or an assumed boundary sends the issue back for rework.
- Verify the state of every issue you plan to cite before citing it, see "Citing other issues" under Step 3.5. A plausible title or a closed status is not proof it covers what you think.
Carry the answers into the body (Step 3) and the board fields (Step 5).
Step 1: Decide the Issue Type
Every issue has a native GitHub issue type (org-level: Task, Bug, Feature, Epic, Spike, Tech Debt). This drives title style and body shape. The old board "Item Type" field no longer exists; "Story" is now Feature.
- Epic — a large theme that holds sub-issues. The epic set is fixed (#1056–#1072) — do NOT author new epics. New
work is always a Feature or Task filed under an existing epic. Pick the parent epic from the fixed set (e.g.
#1065 "Security, Privacy & Compliance") and wire it via
addSubIssue(Step 6). List the open epics to choose from:gh issue list -R bbvch-ai/aihub-core --state open --search "in:title Epic:" --json number,title. Only file an epic yourself if the user explicitly asks to create a new epic. - Feature — one user-facing unit of work (e.g. #1452 "Per-user overall LLM spend limits"). Plain descriptive title.
- Task / Bug — a technical/chore/bug unit. Title uses the
<type>(<scope>): <Subject>form.
Step 2: Write the Title
- Epic / Feature: plain sentence-case description. No prefix.
Per-user overall LLM spend limits,LLM models as an access-controlled resource
- Task / bug / chore:
<type>(<scope>): <Subject starting uppercase>— same grammar as PR titles (CI-enforced viasemantic-pr).- Types:
fix,feat,doc,test,chore. - Scopes:
swiss-ai-hub,iac,ci-cd,bots,dagster,deploy,ui,guards,rag,tracing,workflows,backup,sysadmin. - Examples:
fix(rag): RAG agent crashes on image nodes,feat(guards): Add retry and config to context sufficient guard,chore(ci-cd): Update SonarQube Scanner action to v6.
- Types:
Step 3: Write the Body
The standard structure (see #1452, #1451, #1449). Keep all four parts:
{1–2 sentence context paragraph: the current state, the gap, and why it matters.
Cross-reference related issues inline with #NNN — e.g. "complementing the per-tenant
envelope from #441".}
**In scope**
- {What this issue delivers, as bullets.}
**Out of scope**
- {Explicitly excluded work, each pointing at the sibling issue that owns it — e.g.
"Per-tenant spend limits — see #441 (sibling)."}
**Accepted when**
- [ ] {Behavior-oriented criterion — what works, not how it's built.}
- [ ] {Another criterion.}
---
**Blocked by #NNN.** ← only if a hard dependency existsRules:
- Accepted when is a checkbox list (
- [ ]) describing observable behavior. No endpoint paths, class names, or implementation mechanics — those change. ("Users over their hard cap are rejected at the gateway", not "add a check inLiteLLMService"). - Out of scope bullets name the sibling/parent issue that owns the excluded work. This is how the team keeps issues self-contained without scope creep.
- Use
**Blocked by #NNN.**as a footer only for a true dependency; wire the actual relationship in Step 6. For a bug, open with current-behaviour / expected-behaviour / repro, then keep Accepted when as the fix criteria:
**Current behaviour:** {what happens today, with the error/symptom}. **Expected behaviour:** {what should happen}. **Repro:** {minimal steps, or the trigger condition}. **Accepted when** - [ ] {the bug no longer reproduces under the steps above}.
Step 3.5: Writing Quality Pass (kill the AI-slop)
Before creating the issue, re-read the whole body once, straight through, as a skeptical editor who never saw the conversation that produced it. Two failure modes are specific to issues drafted during a chat, and are the most common ones here:
Structure: lead with the goal, not the drafting trail.
- The reader has no chat history. The first sentence states what this issue delivers and the value it brings. Not "after further research," "it turns out," "two of the three pieces already exist," or any other sentence that only makes sense to someone who watched the draft evolve. Goal and value first, then the current gap, then supporting detail (files, mechanisms, cross-references).
- If a citation or an assumption turned out to be wrong mid-conversation, just cite the right thing in the final body. Don't narrate the correction ("X is wrong, actually Y"). The reader never saw the wrong version.
- Write as if handing this to someone with zero context on the discussion that produced it. No "as discussed," no meta-commentary about the issue-writing process itself.
Technical specificity: hint at the mechanism, don't map the codebase.
- It's fine, often useful, to say what kind of thing is needed: "a UI component," "a Redis-backed counter," "a new field on the bucket record," "resolved per run instead of fixed at startup." That tells the reader the shape of the work without them having to read code first.
- It is not fine to string together a paragraph of class names and file paths, such as
LanguageModelResource,EmbeddingModelResource,MarkdownStructuralNodeParserResource, three more classes, and two file paths, all in one sentence. That reads like a code review comment, not an issue, and every one of those names rots the moment the code is refactored. One or two anchor references are enough when they truly clarify which part of the system is meant. Past that, cut back to the behavior and the mechanism, not the map. If a paragraph names more than two or three concrete symbols, rewrite it.
Citing other issues: verify, don't assume.
- Before naming any issue number as a blocker, a sibling, or "already delivered," check its real state:
gh issue view <N> -R bbvch-ai/aihub-core --json state,stateReason,title,body. CLOSEDis notCOMPLETED. ANOT_PLANNEDclosure (often "spliced into sub-issues," check the closing comment) means the issue itself delivered nothing. Find the actual sub-issue or PR that did the work (gh api graphqlonsubIssues), and verify that issue's state too before citing it as done.- A plausible-sounding title is not proof an issue covers what you think, read its body. Two issues with similar titles can describe entirely different mechanisms (e.g. "agents as MCP hosts via a gateway" and "an agent connecting directly to one MCP server" are not the same thing even though both involve MCP).
General anti-slop checklist, run this on the drafted body before creating:
- Meaning inflation: no "underscores the importance of," "plays a crucial role," "is a testament to," "marks a turning point." State the fact; let the reader judge importance.
- Antithesis crutch: "not just X, but Y" / "it's not about X, it's about Y" / "rather than X, Y." At most one or two uses in the whole body, and only when the contrast is backed by a concrete named thing (not a vague abstraction).
- Say each idea once: the "why this matters" point belongs in the context paragraph. Don't restate it in In scope, again in Accepted when, and again in a closing line.
- No aphorisms without a number or file behind them: a closing line that sounds wise but points at nothing concrete gets cut.
- No signal-word tics: "honestly," "really," "actually," "fundamentally." At most once in the whole body, usually zero.
- No AI vocabulary: delve, crucial (inflationary), leverage, robust, seamless, holistic, vibrant, landscape (metaphorical), foster/fostering, "valuable insights," "navigate the complexities of."
- Plain verbs: "is," not "functions as" / "serves as" / "represents."
- Vague attribution: no "users often," "this is known to cause issues" without a named symptom, file, or issue number behind it.
- Sentence rhythm: short and concrete over long compound sentences. If a sentence needs two commas and a subordinate clause to land, split it into two.
- No em-dashes: rewrite with a comma, a period, or parentheses instead. Grep the drafted body for
—before creating and fix every hit. This is one of the single most common AI tells, and older issues in this repo using it are not a reason to keep doing it.
Step 4: Create the Issue
Pick labels first:
- area: label(s) for every touched package —
area:api,area:web,area:agent,area:pipeline,area:process,area:bot,area:backup,area:deployment,area:infra,area:auth,area:github,area:other. Apply all that fit (issues commonly carry 2–3). - Do not add a
major/minor/patchlabel: version labels belong on the closing PR, not the issue. - Optional:
Good first issue,onboarding needs,Possible security concern.
gh issue create prints the new issue URL on stdout. Capture it into ISSUE_URL and derive NEW_ISSUE (the number) —
Steps 5–7 reference both:
ISSUE_URL=$(gh issue create -R bbvch-ai/aihub-core \
--title "feat(swiss-ai-hub): Subject here" \
--body "$(cat <<'EOF'
Context paragraph referencing #441.
**In scope**
- ...
**Out of scope**
- ... — see #786 (sibling).
**Accepted when**
- [ ] ...
---
**Blocked by #1451.**
EOF
)" \
--label "area:api" --label "area:auth")
NEW_ISSUE="${ISSUE_URL##*/}" # the issue number, e.g. 1457
echo "Created $ISSUE_URL (#$NEW_ISSUE)"Step 5: Add to the AI-Scrum Board and Set Fields
The AI-Scrum board is org project 37 (node id PVT_kwDOCmtSJM4BRjLz). Add the issue, then set the issue type and
the single-select board fields by option id. (Project node id and the field/option ids below verified 2026-10-02 —
re-fetch if stale, see the note at the end of this step.)
# Add the issue; capture the returned project item id.
ITEM_ID=$(gh project item-add 37 --owner bbvch-ai --url "$ISSUE_URL" --format json -q '.id')Set the fields with gh project item-edit (project id + field id + option id):
PROJECT_ID="PVT_kwDOCmtSJM4BRjLz"
# Issue type is native, not a board field: Task | Bug | Feature | Epic | Spike | Tech Debt
gh api -X PATCH "repos/bbvch-ai/aihub-core/issues/$NEW_ISSUE" -f type=Feature
# Status (field PVTSSF_lADOCmtSJM4BRjLzzg_WG-g): Backlog default below; full option ids listed after this block
gh project item-edit --id "$ITEM_ID" --project-id "$PROJECT_ID" \
--field-id "PVTSSF_lADOCmtSJM4BRjLzzg_WG-g" --single-select-option-id "f75ad846"
# Priority (field PVTSSF_lADOCmtSJM4BRjLzzg_kxEg): Urgent=ca2a2374 P0=b51e3b98 P1=8d583761 P2=0f19202d
gh project item-edit --id "$ITEM_ID" --project-id "$PROJECT_ID" \
--field-id "PVTSSF_lADOCmtSJM4BRjLzzg_kxEg" --single-select-option-id "8d583761"Field defaults for a freshly-filed issue:
- Status →
Backlog(f75ad846). UseReady to Implement(efca25cd) only if the user says it is groomed and ready to pick up. - Issue type → from Step 1 (set via the REST call above, not the board).
- Priority → ask the user; do not guess.
Urgent/P0/P1/P2. - Story Points (number field
PVTF_lADOCmtSJM4BRjLzzg_W5nk): set only when the user gives an estimate, via--field-id ... --number N.
Full Status option ids: Stateless=9b2296d7, Backlog=f75ad846, Refine Next=eef4410e, Ready to Implement=efca25cd,
Current Sprint=0141227c, On hold=98236657, In Progress=47fc9ee4, Ready to Test=e27f8bc6,
Ready to Release=28f6f4ba, Resolved=c554cb9b, Completed=026feb3e, Aborted=0cbe70c4.
If
gh projectreports a stale field/option id, re-fetch withgh project field-list 37 --owner bbvch-ai --format jsonand use the current ids.
Step 6: Wire Relationships (if any)
- Parent ↔ child (Epic holds Features/Tasks): use
addSubIssue(see.claude/skills/splice-issue/SKILL.mdfor the full pattern). - Hard dependency (matches the
**Blocked by #NNN.**footer): useaddBlockedBy.
ISSUE_ID=$(gh api graphql -F number=$NEW_ISSUE -f query='
query($number: Int!) { repository(owner: "bbvch-ai", name: "aihub-core") { issue(number: $number) { id } } }' \
-q '.data.repository.issue.id')
BLOCKING_ID=$(gh api graphql -F number=$BLOCKING_ISSUE -f query='
query($number: Int!) { repository(owner: "bbvch-ai", name: "aihub-core") { issue(number: $number) { id } } }' \
-q '.data.repository.issue.id')
gh api graphql -f query="mutation { addBlockedBy(input: { issueId: \"$ISSUE_ID\", blockingIssueId: \"$BLOCKING_ID\" }) { issue { id } } }"addSubIssue = "part of this work"; addBlockedBy = "must be done first". Never use one for the other.
Step 7: Verify
bash .claude/skills/write-issue/scripts/validate-issue.sh "$NEW_ISSUE"The script confirms the issue exists, carries at least one area:* label, has the In scope / Out of scope /
Accepted when sections (skip for pure bugs if the user opted out), and is on the AI-Scrum board with a native issue
type set. Report any gap and fix it before declaring done.
Common Mistakes
- Conventional-commit prefix on an Epic/Feature. Only Tasks/bugs use
type(scope):. Epics and Features get plain descriptive titles (#1452, #1449). - Implementation detail in Accepted when. Criteria describe behavior, not class names or endpoint paths — those churn and rot the issue. Put mechanics in the context paragraph.
- Out of scope without a pointer. Every excluded item names the sibling/parent issue that owns it (
— see #786). A bare "out of scope" bullet invites scope creep back in. - Forgetting the board. An issue not added to org project 37 is invisible to the sprint — Step 5 is not optional.
The issue type is mandatory; Status defaults to
Backlog. - Guessing Priority. Urgent/P0/P1/P2 is a product call — ask, don't assume.
- Narrating the drafting process. The body reads like a chat transcript ("this turned out to be wrong," "after digging deeper") instead of a standalone description. Lead with the goal and value; write for a reader who never saw the conversation.
- Citing a closed-not-planned issue as "already delivered." Check
state/stateReasonbefore citing. A spliced/not-planned issue delivered nothing itself; find and verify its actual completed sub-issue instead.
Other versions7 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 7
- tldraw/tldraw★ 51ksame name
- Agenta-AI/agenta★ 4.9ksame name
- yamcodes/arkenv★ 151same name
- saroj990/dockAI★ 4same name
- encoreshao/encore-skills★ 2same name
- gigio1023/agent-skills★ 2same name
- gigio1023/gigio-skills★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository50 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- docs/CLAUDE.mdCLAUDE.md
- .github/actions/CLAUDE.mdCLAUDE.md
- arc42Skill
- audit-frontendSkill
- bot-frameworkSkill
- create-or-audit-claude-mdSkill
- create-or-audit-skillSkill
- create-or-audit-subagentSkill
- create-prSkill
- dagster-pipelinesSkill
- debug-agentSkill
- debug-frontendSkill
- debug-pipelineSkill
- design-systemSkill
- docker-devSkill
- document-decisionSkill
- document-featureSkill
- explainSkill
- generate-sdkSkill
- i18nSkill
- implement-feedback-from-prSkill
- likec4-dslSkill
- lintSkill
- merge-mainSkill
- nats-eventsSkill
- plan-issueSkill
- pr-demo-videoSkill
- primevue-lookupSkill
- rclone-guideSkill
- reflectSkill
- review-diffSkill
- scaffold-agentSkill
- scaffold-api-endpointSkill
- scaffold-api-repositorySkill
- scaffold-api-serviceSkill
- scaffold-bot-handlerSkill
- scaffold-composableSkill
- scaffold-event-displaySkill
- scaffold-frontend-componentSkill
- scaffold-frontend-pageSkill
- scaffold-frontend-subpageSkill
- scaffold-pipelineSkill
- setup-bot-connectionSkill
- splice-issueSkill
- sync-agent-docsSkill
- test-scopeSkill
- update-docSkill
- verify-sdk-syncSkill
- write-docSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

