CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

create-issue

Create a GitHub issue in camunda/camunda with the correct template, component label, area labels, and parent link. Use when asked to create, file, or open an issue — for bugs, features, tasks, tech debt, or CVEs.

Quality

95%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

Create Issue

Creates a well-formed GitHub issue in camunda/camunda following the official templates. Prevents missing parent links, wrong component labels, and skipped required fields.

Prerequisites

gh auth status  # must succeed

If this fails, do not abort. Check whether mcp__github__* tools are available in this session; if so, use them for the rest of this skill's flow instead of the gh examples shown below.MCP tools use separate credentials, so they often keep working through a gh auth failure (stale token, sandbox restrictions, a transient rate limit), though they are not immune to failures of their own (their own rate limits, service-side restrictions). If MCP tools are not available either, retry gh auth status once before asking the user to check their authentication.

Procedure

Step 1 — Read available templates

At invocation time, list the templates from the filesystem:

ls .github/ISSUE_TEMPLATE/*.yml

The ls output from above is the authoritative list of available templates. The table below is a default mapping for the common cases — if a template appears in the filesystem but not here, read its labels: field to infer the kind/ label.

User intentTemplate filekind/ label
Bug, defect, crash, regression1. bug_report.ymlkind/bug
Feature, improvement2. feature_request.ymlkind/feature-request
Task, activity, chore3. task.ymlkind/task
Epic breakdown4. epic breakdown.ymlkind/epic
CVE, security vulnerability5. CVE.ymlkind/cve
Tech debt, cleanup6. tech debt.ymlkind/tech-debt

If the issue type is ambiguous, ask the user to pick one before proceeding.

Step 1.5 — Check for existing issues

Before drafting anything, search for likely duplicates using the issue's likely title keywords:

gh search issues '<title keywords>' --repo camunda/camunda --state open --limit 10
gh search issues '<title keywords>' --repo camunda/camunda --state closed --limit 10

--state only accepts one value at a time (open or closed), not all — run both.

If a close match turns up, surface it to the user before proceeding - show the issue number, state, and title, and ask whether to link the new work to it, comment on the existing issue instead, or proceed with a new issue anyway. Do not silently create a near-duplicate.

Step 2 — Read the template and collect field values

Read the chosen template:

cat ".github/ISSUE_TEMPLATE/<chosen>.yml"

For bug reports (1. bug_report.yml), invoke the grill-me skill before inferring fields — it builds shared understanding of impact, root cause, and reproduction path, making field inference much more accurate.

Ask the user for a free-form description of the issue. Use that description to infer values for every field in the template's body: list. For each item:

  • Skip type: markdown items (they are display-only).
  • Infer a value from the description where possible — including title, dropdown selections, and prose sections.
  • Only ask the user a follow-up question when the description does not provide enough signal to fill a field confidently. Batch all uncertain fields into a single follow-up rather than asking one at a time.
  • If validations.required: true and a value cannot be inferred, the user must provide one before proceeding.
  • If validations.required: false or absent and nothing can be inferred, leave the field empty.

Step 3 — Infer the component label

Detect which module the issue relates to from the current working directory and modified files:

git diff --name-only HEAD

Map path prefixes to component labels:

Path prefixComponent label
zeebe/ — see belowcomponent/zeebe-engine or component/zeebe-platform (fallback: component/zeebe)
operate/component/operate
webapp/client/apps/orchestration-cluster-webapp/src/tasklist/component/tasklist
identity/component/identity
optimize/component/optimize
clients/component/clients
webapp/component/c8-api
gateways/gateway-mcp/component/mcp
gateways/component/gateway
db/ or search/component/data-layer
document/component/document-handling
testing/component/camunda-process-test
qa/component/qa
load-tests/component/load-tests
.github/ or .agents/component/build-pipeline

Zeebe label split — use the conceptual layer, not the path:

  • component/zeebe-engine — application/engine layer: BPMN/DMN execution, process state, variable handling, FEEL evaluation, gRPC/REST API surface, zeebe/gateway, zeebe/engine
  • component/zeebe-platform — platform/infrastructure layer: broker internals, clustering, Raft, replication, storage (RocksDB), job streaming, zeebe/broker (infra aspects)
  • Grey areas (e.g. zeebe/broker engine logic, job streaming in zeebe/gateway): prefer the layer that is more affected; use component/zeebe as fallback when genuinely unclear

When multiple modules are touched, pick the label for the most-affected one. If uncertain, ask the user. If no files are modified, ask the user which component applies.

Step 3b: Infer the area labels

Decide from the title and body which area/* labels describe what the issue is about. The Reliability Radar dashboard groups open issues by area, so an unlabeled issue is missing from it.

Area labelUse when the issue is about
area/aiAI-related features and tooling
area/backendbackend code and services
area/bpmn-supportsupporting BPMN symbols
area/buildbuild pipeline, Maven settings, CI
area/dmnthe DMN engine or specification
area/dxdeveloper experience
area/feelthe FEEL engine or specification
area/frontendfrontend code and UI implementation
area/infrainfrastructure and environments
area/load-testsload tests, benchmarks, and the load-test tooling
area/maintainabilityrefactoring, cleanup, code health
area/metricsmetric definitions and dashboards (area/observability for broader gaps)
area/observabilitymetrics, logging, tracing, health checks, diagnosability gaps
area/performancelatency, throughput, CPU, memory or allocation overhead, scalability limits
area/projectproject management: PR templates, editor config, repository conventions
area/reliabilitydata loss, crashes, stuck or non-recovering behavior, recovery from failures
area/resiliencesurviving and degrading gracefully under faults or overload
area/securityvulnerabilities, authentication, authorization, secrets handling
area/testadding or extending test coverage
area/uxuser experience of the UI, CLI, or API ergonomics
  • The table can lag behind the repository. Check the live set with gh label list --repo camunda/camunda --search area/ --limit 100 and use any area/* label that fits better.
  • Apply every label that clearly fits, usually one, rarely more than two.
  • Apply none when nothing clearly fits. Do not ask the user when nothing fits.
  • Judge by what the issue is about, not by keywords: a test that merely mentions "performance" or a feature that mentions "logging" does not qualify.
  • area/reliability and area/resilience overlap: prefer area/reliability unless the issue is specifically about behavior under faults or overload.

Step 4 — Ask for the parent issue

Ask the user:

"Does this issue have a parent issue or epic? If so, please provide the issue number or URL."

If they provide one, verify it exists and fetch its title for display in the summary:

gh issue view <number> --repo camunda/camunda --json number,title,url

If the user says there is no parent, omit the parent link from the body.

Step 5 — Compose the issue body

Build the Markdown body directly from the template read in Step 2, mirroring exactly what the GitHub form UI produces. For each item in the template's body: list:

  • Skip type: markdown items (display-only).
  • For type: textarea items: render attributes.label as a ### Heading and the user's value as the content.
  • For type: dropdown items: render attributes.label as a ### Heading and the selected option's text verbatim as the content (e.g. <!-- Zeebe- -->). These HTML comment markers are what .github/opened_issue_labeler.yml scans on issue open to auto-apply labels.

Append a Links section at the end with the parent issue URL if one was provided.

When the body points at specific lines of repository code, use a stable GitHub permalink rather than a bare path:line. Use the github-permalink skill to build it.

Do not invent sections or use any structure other than what the template defines.

Step 6 — Propose summary and ask for approval

Before printing the summary, scan the body for sensitive data and redact it: replace UUIDs, customer/user IDs, internal hostnames, and email addresses found in any copied log output with <redacted>.

Print a clear summary and wait for explicit confirmation. Do NOT call gh issue create yet.

📋 Issue summary
────────────────────────────────────────────
Title:   <proposed title>
Type:    <bug | feature | task | tech-debt | CVE>
Labels:  kind/<type>, area/<area>... if any  (component/*, severity/*, likelihood/* applied automatically via labeler)
Parent:  https://github.com/camunda/camunda/issues/<N>  (or "none")

Body:
<full proposed body>
────────────────────────────────────────────
Create this issue? (y/N)

If the user requests changes, revise the summary and ask again before proceeding.

Step 7 — Create the issue and register the parent relationship

After the user confirms, create the issue. Pass the kind/<type> label and the area/* labels from Step 3b (if any) explicitly; the labeler does not set area/*. All other labels (component/*, severity/*, likelihood/*, affects/*) are applied automatically by .github/opened_issue_labeler.yml, which scans the body for the HTML comment markers rendered in Step 5.

body_file=$(mktemp)
printf '%s' "<body>" > "$body_file"

gh issue create \
  --repo camunda/camunda \
  --title "<title>" \
  --body-file "$body_file" \
  --label "kind/<type>" \
  --label "area/<area>"  # omit when Step 3b found no area; repeat per additional area

rm -f "$body_file"

Capture the new issue number from the returned URL. Then fetch its database ID and node ID (both needed below — the database ID for the sub-issues API, the node ID for setting the Issue Type):

gh api repos/camunda/camunda/issues/<new-issue-number> --jq '{id: .id, node_id: .node_id}'

Set the native GitHub Issue Type (bypassed by gh issue create) by resolving the type name from the template's type: field against the repo's configured issue types:

type_id=$(gh api graphql -f query='{
  repository(owner: "camunda", name: "camunda") {
    issueTypes(first: 20) { nodes { id name } }
  }
}' --jq --arg t "<type from template>" \
  '.data.repository.issueTypes.nodes[]
   | select(.name | ascii_downcase == ($t | ascii_downcase)) | .id')

gh api graphql -f query="mutation {
  updateIssue(input: {id: \"<node_id>\", issueTypeId: \"$type_id\"}) {
    issue { id }
  }
}"

If a parent was provided, register the native GitHub sub-issue relationship so the new issue appears as a child of the parent in the GitHub UI:

gh api \
  --method POST \
  repos/camunda/camunda/issues/<parent-number>/sub_issues \
  --input - <<< "{\"sub_issue_id\": <new-issue-database-id>}"

Print the URL of the created issue.

Repository

camunda/camunda

Path

.agents/skills/create-issue/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.