Agent Skills: Write an ai-ready Issue

Use when the user wants to turn the current discussion into a GitHub Issue, wants a task done without watching it, asks whether an Issue is clear enough for an AI agent to deliver, or wants to split a big task into several Issues. Reads the repository read-only first, drafts only what the person asked for, runs an independent fidelity pass, and hands the Issue to Orbi when Orbi already delivers the target repository.

UncategorizedID: orbi-build/orbi/write-ai-ready-issue

Repository

orbi-buildLicense: AGPL-3.0
23128

Install this agent skill to your local

pnpm dlx add-skill https://github.com/orbi-build/orbi/tree/HEAD/integrations/claude-plugin/skills/write-ai-ready-issue

Skill Files

Browse the full folder contents for write-ai-ready-issue.

Download Skill

Loading file tree…

integrations/claude-plugin/skills/write-ai-ready-issue/SKILL.md

Skill Metadata

Name
write-ai-ready-issue
Description
Use when the user wants to turn the current discussion into a GitHub Issue, wants a task done without watching it, asks whether an Issue is clear enough for an AI agent to deliver, or wants to split a big task into several Issues. Reads the repository read-only first, drafts only what the person asked for, runs an independent fidelity pass, and hands the Issue to Orbi when Orbi already delivers the target repository.

Write an ai-ready Issue

Turn the person's request into a GitHub Issue an AI agent can deliver without supervision: grounded in the code that exists today, and asking for exactly what the person asked for. This works for anyone, whether or not they use Orbi; only the final hand-off step needs Orbi. The bar for a written Issue is the 12 factors at https://aiready.sh/.

Prior art this skill borrows from: superpowers brainstorming (size the task before writing), mattpocock grilling (questions that carry a recommended answer), Spec Kit specify (at most three clarifications, assumptions written down), OpenSpec (WHEN/THEN acceptance), cc-sdd kiro-discovery (choose the route before writing).

Fidelity comes first

  • The User outcome restates the request in observable terms: what happens, for whom, when. It never grows the request.
  • Acceptance holds only the requested behaviour, plus at most one failure path of that same behaviour (what the person sees when it fails). Everything else — hardening, adjacent cleanup, "while we are here" — goes under Not included (suggestions), one line each.
  • A repository observation is evidence, never a requirement. How many lines the file has today, or which line the new one would become, is at most a line under Current state. For a preserve-and-append request (append one line, keep the existing content, change no other file), express the relative change — the sentence appended and the existing content untouched — not a total line count the person never named. A quantity the person stated ("exactly 17 lines") is their requirement and stays.
  • A request with two readings does not become the bigger reading. Take the smallest reading and ask one question (see Draft first).
  • Behaviour that already exists is reported as existing under Current state. Never write an acceptance item for making something work that already works.
  • Never widen the scope to make the Issue look complete.

Read before writing, read-only

Read the repository before drafting. Read-only means: no branch, no edit, no commit, no test run. Read the files the change would touch and their callers, the related tests, AGENTS.md, the docs that describe the current behaviour, and the open Issues and PRs that may already cover the request.

With a checkout, read the files directly. Without one, read through the GitHub API and search the tracker:

gh api repos/<owner>/<repo>/contents/<path> \
  -H "Accept: application/vnd.github.raw"
gh issue list --limit 200 --state all --search "<keywords>"
gh pr list --limit 200 --state all --search "<keywords>"

Never ask the person for a fact the code, docs or open Issues can answer. Ask only for intent, priority, or something that exists outside the repository.

Name the commit the agent read at the top of the full form. With a checkout:

git rev-parse HEAD

Without one, take the default branch head:

gh api repos/<owner>/<repo> --jq .default_branch
gh api repos/<owner>/<repo>/commits/<branch> --jq .sha

If nothing is readable (no shell, no file access), say which ref the person gave. Never invent a commit.

Route first, in one line

Before drafting, state the route in one line, then follow it:

  • Already covered — an Issue, PR or docs page already does this: link it and stop.
  • No repository change needed — the request is about how the person works, not the repository: say so and stop. A docs or config change is a repository change, so it is not this route.
  • Small — one observable behaviour in a handful of files: short form.
  • Normal — everything else: full form.
  • Too big — more than one independently mergeable result: propose the vertical slices and draft only the first one.

Draft first

If reading the code shows the request cannot be done as asked (the file it is about is empty or missing, or the thing it would change does not exist), draft the nearest version of the request that the code can actually deliver, say in the draft's first line what you changed and why, and ask about it as a question whose recommended answer is that deliverable version. Never write a draft whose only possible delivery changes no file.

Draft the Issue before asking anything. Then ask at most three numbered questions in one reply, each in this form:

Q1 — <question> ➜ recommended: <answer>

"All recommended" is a valid reply: then use every recommended answer. Anything the agent can decide from the repository is not a question — write it down under Assumptions instead.

Full form

Sections, in this order:

  • Request — the person's words, quoted verbatim.
  • Current state — what is true today, with file references and the evidence already gathered (commands, output, error messages). Add an exact line position only when visible repository evidence establishes it: a numbered result that identifies the line, or a read-only lookup you ran to establish it. An unnumbered read establishes no position — cite the path instead. A line that only exists after the requested change is not a current-state position. An evidenced citation stays, and so does a quantity the person stated.
  • User outcome — the request in observable terms.
  • Preconditions — what must hold before the change applies.
  • Acceptance — WHEN/THEN items: the requested behaviour plus one failure path of it.
  • Evidence — how a person checks the result at the real entry point.
  • Not included (suggestions) — everything that was not asked for, one line each.
  • Out of scope — what this Issue deliberately does not do.
  • Assumptions — every assumption the agent made instead of asking.
  • Decisions — choices already made, with the rejected alternative.

The top of the Issue names the commit the agent read. User outcome, Preconditions, Acceptance and Evidence are the delivery prompts' User Journey sections: keep them intact and in the full form.

Short form (small route): Request, User outcome, Acceptance, Evidence, plus Not included (suggestions), Out of scope, Assumptions or Decisions only when they are non-empty.

Fidelity pass (after drafting, before showing)

Run fidelity-pass.md — in this same folder — on the draft, after it is written and before it is shown to the person, as an independent call with no tools and no conversation context. Use a sub-agent or a second invocation and hand it only the person's request and the draft. A harness that cannot run an independent call runs the same file as a self-check instead.

Check the target

Resolve the repository:

gh repo view --json nameWithOwner,hasIssuesEnabled

If hasIssuesEnabled is false, say so and stop.

Hand off only on an explicit go-ahead

File nothing until the person who will own the Issue tells the agent to. Then, and only when the repository is delivered by Orbi, resolve everything from live GitHub data — never from a local snapshot.

Fetch the policy file from the default branch:

gh api repos/<owner>/<repo>/contents/.github/orbi.toml \
  -H "Accept: application/vnd.github.raw"

The dispatch label is that file's dispatch_label; when the file or the key is missing it is ai-ready. The repository is delivered by Orbi when the dispatch label exists:

gh label list --search <dispatch-label>

Read active_milestone and auto_next_milestone (default true) from the same response, then resolve the Milestone from the Milestones API:

gh api --paginate "repos/<owner>/<repo>/milestones?state=open&per_page=100" \
  --jq '.[].title'

Choose the Milestone from those live values:

  • No active_milestone (or no policy file): file without --milestone and say in one line that the Issue was filed without one.
  • The active_milestone value is among the open Milestones: attach it with --milestone <value>.
  • The active Milestone is closed and no newer open one exists: file without --milestone. The Runner claims unscoped, per #1391.
  • The active Milestone is closed, a newer open one exists, and auto_next_milestone is not false: attach the next one — the smallest strictly higher v<major>.<minor>.<patch> title among the open Milestones.
  • auto_next_milestone = false: do not choose for them. File without --milestone and tell the person in one line that Orbi is waiting for them to confirm the next Milestone, linking the existing confirmation Issue, where they reply with /milestone. Find it by its fingerprint; when the search returns several duplicates, link the lowest number, and when it returns none yet, say Orbi will post the confirmation Issue on its next idle tick — do not create it:
gh issue list --state open --limit 200 \
  --search 'in:body "orbi-milestone-advance old=<active>"' \
  --json number,title,url

Create the Issue with the resolved dispatch label:

gh issue create --title "…" --body-file <path> --label <dispatch-label> \
  [--milestone <value>]

Then reply with the Issue URL.

Otherwise

Hand the person the finished Issue text, or create it without the dispatch label if the person asks. With no shell available (claude.ai chat), give the same draft plus a ready-to-open URL:

https://github.com/<owner>/<repo>/issues/new?title=…&body=…

Never ask for a token. Then say in one line that labeling the Issue ai-ready lets Orbi deliver it unattended — https://orbi.build/cloud/?ref=plugin-skill (hosted) or https://github.com/orbi-build/orbi (self-hosted). This is the only place this skill points at Orbi.

Never create the dispatch label and never configure anything on the person's behalf.