Back to the collection
to-tickets·Development

to-tickets guide: split a specification into verifiable tickets

On this page

Split a plan into small, end-to-end tasks with acceptance criteria and explicit blocking dependencies.

Install and prepare

Run the following in your project terminal, then use the prompt below in Claude Code. This installs editable, project-scoped skill files.

Command
npx skills@latest add mattpocock/skills --skill to-tickets --skill setup-matt-pocock-skills --agent claude-code

For Codex, replace claude-code with codex in the command and /to-tickets with $to-tickets in the prompt. With the complete Claude Code plugin, select /mattpocock-skills:to-tickets instead; avoid installing the same skills twice.

Prepare a specification, issue link or sufficiently detailed conversation. Configure the tracker with setup-matt-pocock-skills. GitHub, GitLab and local Markdown have built-in templates; describe your workflow for Linear or another custom tracker. If you also use triage, install it first so setup includes the triage-label configuration.

Your first task

Adapt the scenario and paths to your project, then enter this in the agent conversation:

Prompt
/to-tickets specs/team-purchases.md
Show the proposed tickets and blocking relationships first. Each ticket should demonstrate a complete behavior, rather than splitting all database work, all APIs and all pages. Write local tickets after we agree.

Work through the task

Slice by demonstrable behavior

A first ticket might let an administrator allocate one seat and grant learner access across the required data, API, UI and tests. Later tickets can add bulk allocation or seat recovery. Each finished ticket should deliver an independently explainable result.

Check real dependencies

Seat recovery may depend on allocation, while help copy may not block implementation. Review each Blocked by field and remove dependencies added only to produce a neat sequence. Unblocked work can proceed in parallel when it has its own acceptance conditions.

Publish the agreed breakdown

The workflow presents numbered tickets, delivered behavior and dependencies for you to refine. After agreement, local mode writes one file per ticket under .scratch/<feature>/issues/; a remote tracker receives issues in dependency order with blocking links.

Check the result

Each ticket needs a concrete deliverable, acceptance conditions and blockers. Pick an unblocked ticket and check that a fresh agent could start from it and the linked spec without guessing the missing conversation.

Common questions

How should a repository-wide rename be split? The workflow supports expanding the new form, migrating callers in batches and removing the old form afterward.

Does implementation start automatically? Start that separately after ticket creation.

I got one combined local document. Ask for one file per ticket so the work can be assigned independently.

Quiz the split before publishing tickets

For every ticket, ask: what new behavior can I demo when this is done? If the answer is only that all database tables or APIs exist, it lacks an observable result; merge it with adjacent work or rewrite it as a vertical slice. A fresh session should be able to finish each ticket from its inputs, expected behavior, acceptance check, blockers, and linked spec. File line numbers become stale and should not carry the requirement. Review the numbered list and adjust granularity before it is sent to the tracker.

Challenge the blocker graph too. Reclaiming a seat may depend on assigning one, while help text need not wait. The first startable ticket should have no blockers; only genuinely independent tickets can run in parallel. If a tiny change becomes a dozen tickets, the tool may be unnecessary or the slices too small: one-session work can go straight to implementation. A wide mechanical migration is an exception; expand the new form, migrate uses in batches, and remove the old form last instead of forcing it into ordinary feature slices.

Use notification preferences to test vertical slicing

Suppose the spec lets users control email and in-app notifications separately. Ask: “Use to-tickets to produce independently demoable work. The first ticket lets a user turn off email alerts and retain that choice after signing in again, including necessary persistence, API, settings UI, and tests. Show the dependency graph before publishing.” A later ticket can add in-app alerts; do not start with an “all database work” ticket.

For each ticket, name an acceptance check that fails at the base commit and a behavior a fresh session can demonstrate when done. Remove edges added merely to make a tidy sequence. If a wide mechanical change truly cannot stay green as separate slices, consider the documented expand–migrate–contract exception. Review the list before publishing so a small change does not become a dozen issues.

Map every spec invariant to a ticket

For a large spec, run a reverse-coverage check: list every invariant and read/write path on one side, then identify its owning ticket and end-to-end acceptance test on the other. In one migration, an initial set of 16 tickets covered producer jobs and cutover but omitted hydration of the full model consumed by old read APIs. Ticket-level proxy checks passed while some UI paths were empty. Give “preserve existing behavior” a read-side test, not just a job-success check. After publishing tickets remotely, read their bodies back to ensure the acceptance criteria did not become empty or placeholders.

References

  1. to-tickets — SKILL.mdmattpocock
  2. mattpocock/skills — READMEmattpocock
  3. setup-matt-pocock-skills — configuration workflowMatt Pocock
  4. to-tickets official usage guideMatt Pocock
  5. to-tickets can leave PRD requirements orphanedexwer
  6. to-tickets: verify each published issue body actually landederikpr1994
Found outdated or incorrect information? Let us know