Issue ↔ Spec

SkillProductivity

Lets your agent publish a spec document to a specs repo and create matching GitHub and Linear issues for it.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Issue ↔ Spec skill

About this capability

Publishes a Compozy spec set to compozy-specs and mirrors it into a GitHub + Linear issue pair — or starts from a bare issue and authors the spec first.

What this skill tells your AI

The instructions your AI receives, as published by compozy/compozy in .agents/skills/cy-issue-to-spec/SKILL.md and read by ahel’s review.

One feature lives in three places: the working spec set under .compozy/tasks/<slug>/, its published folder in the compozy/compozy-specs repo, and its mirror — a GitHub issue and a Linear issue that read identically. This skill moves a feature between those places and leaves all three agreeing.

Branches

Starting pointEnter at
A spec set already exists under .compozy/tasks/<slug>/Step 1
A GitHub issue exists carrying no spec behind itStep 0

Step 0 — Author the spec

Only when starting from a bare issue.

Read the issue and restate its scope in one sentence. When it bundles separable features, split it first: retitle the original to the narrower scope, open a second issue for the remainder, and cross-link both — then spec one of them.

Activate cy-spec-preflight, then cy-create-spec. Offer cy-spec-peer-review after the user approves the spec. Run cy-create-tasks last.

Done when: .compozy/tasks/<slug>/ holds _spec.md (or _prd.md + _techspec.md), its companions, adrs/, and _tasks.md, and the user has approved the spec.

Step 1 — Stage the spec set

Run the staging helper (mutating — writes into the specs repo working tree):

python3 .agents/skills/cy-issue-to-spec/scripts/publish-spec.py \
  --spec-dir .compozy/tasks/<slug> \
  --specs-repo <specs-repo-checkout> \
  --repo-root "$(pwd)"

It publishes _*.md, task_NN.md, and adrs/*.md; it leaves analysis/, qa/, memory/, evidence/, reviews-*/, state.yaml, and handoff notes in the workspace. Pass --include '<glob>' for a document that carries spec content under a name outside those patterns, and --archived when the workstream is already closed.

The folder is named YYYY-MM-DD-<slug>, dated by when the work began: the source folder's own date prefix when it carries one, else state.yaml's created_at, else the earliest document. Active specs sit at the repo root; closed ones under _archived/.

Done when: the helper exits 0, reporting the staged path, file count, and a clean scan.

Step 2 — Resolve the report

The helper scrubs machine-local paths and repairs ../adrs/ links itself. Two findings need a decision:

  • A surviving local path or a possible secret exits the helper non-zero. Edit the staged document, then re-run the scan.
  • A broken relative link points at something the filter left behind. Either publish that material too, or accept the dangling reference — the repo README already tells readers that older documents point at files they will not find.

Done when: every reported path, secret, and link is fixed or consciously accepted.

Step 3 — Index and push

Add one row to the specs repo README.md, in the Active or Archived table: the folder link, one sentence on what the spec covers, the tracking-issue link, and the Documents column naming its shape (spec, prd + techspec, brief + techspec, …). Newest first.

Commit as docs: add <slug> spec set and push.

Done when: every relative link in the README resolves and the commit is on main.

Step 4 — Write the issue body

Read .agents/skills/cy-issue-to-spec/references/issue-body.md in full and build the body against it.

Done when: the body opens with the spec-set link block and every section of the skeleton is either written or deliberately absent.

Step 5 — Open the mirror

Create or update the GitHub issue: title matching the spec's subject, labels roadmap + planned (removing needs-plan), the Step 4 body, and a closing Roadmap item tracked in Linear: [CY-NNN](…) line.

Create or update the Linear issue with the same title and the same body, swapping the footer for Tracked on GitHub: <url>. Linear renders GitHub callout syntax as plain text — convert a > [!NOTE] block to a bold sentence.

Verify with the audit helper (read-only):

python3 .agents/skills/cy-issue-to-spec/scripts/check-tracker-sync.py --linear-json <export>

Save the Linear MCP list_issues result to a file first; without --linear-json the helper audits only the GitHub half.

Done when: the helper exits 0 with no defects, and both issues carry a link to each other.

Reference

  • Publishing an already-archived spec skips Step 0 and Step 4's tracking link when no issue exists — the README row is then the only index entry.
  • Renaming a published folder breaks the links already sitting in both trackers; update the issue bodies in the same change.
  • references/issue-body.md — the issue-body skeleton and where each part comes from in the spec.
  • scripts/publish-spec.pymutating; stages, scrubs, scans, and link-checks a spec set.
  • scripts/check-tracker-sync.pyread-only; audits titles, states, and links across the mirror.

Signals

GitHub stars
3k
Forks
177
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
cy-issue-to-spec
Source
github.com/compozy/compozy