To Tickets
Split plans, specs, or conversations into a set of tickets: tracer-bullet vertical slices, where each ticket declares the tickets that block it.
The issue tracker and triage label vocabulary should already be provided; if not, run
/setup-matt-pocock-skills
.
Process
1. Gather context
Use content already present in the conversation context. If the user passes a reference (spec path, issue number, or URL) as a parameter, retrieve and fully read its body and comments.
2. Explore the codebase (optional)
If you haven't explored the codebase yet, first understand the current state of the code. Ticket titles and descriptions should use the project's domain glossary vocabulary and comply with relevant ADRs.
Look for opportunities to refactor code in advance to make implementation easier. "Make the change easy, then make the easy change."
3. Draft vertical slices
Split the work into tracer bullet tickets.
<vertical-slice-rules>
- Each slice must run through every layer (schema, API, UI, tests) to form a narrow yet complete path; it must be a vertical slice, not a horizontal slice of a single layer
- Completed slices can be demoed or verified independently
- Each slice must be small enough to fit into a fresh context window
- Any pre-refactoring should be completed first
</vertical-slice-rules>
Provide blocking edges for each ticket: other tickets that must be completed before it can start. Tickets with no blockers can start immediately.
Wide refactors are an exception to vertical slicing. A wide refactor is a mechanical change that affects the entire codebase, such as renaming a column or retyping a shared symbol; a single edit can break thousands of call sites, making it impossible for any vertical slice to stay green independently. Do not force it into a tracer bullet; instead, follow the expand–contract sequence. First, expand: add the new form alongside the old one, keeping everything functional. Then migrate call sites in batches by blast radius (by package, directory, etc.), with each batch as a ticket blocked by the expand ticket; the old form remains, so CI stays green for each batch. Finally, contract: remove the old form in a ticket blocked by all migrate batches. Even if individual batches can't stay green, keep this sequence but have them share an integration branch, all blocking the final integrate-and-verify ticket; only commit to green at the end.
4. Quiz the user
Present the proposed split as a numbered list. Each ticket includes:
- Title: A short, descriptive name
- Blocked by: Other tickets that must be completed first (if any)
- What it delivers: The end-to-end behaviour this ticket enables
Ask the user:
- Is the granularity appropriate (too coarse or too fine)?
- Are the blocking edges correct, with each ticket only depending on the tickets that truly gate it?
- Should tickets be merged or split further?
Iterate until the user approves the split.
5. Publish the tickets to the configured tracker
Publish the approved tickets. The specific method depends on the tracker configured via
/setup-matt-pocock-skills
; the tickets are the same, only the format of blocking edges differs:
- Local files → Write one file per ticket under
.scratch/<feature-slug>/issues/<NN>-<slug>.md
, numbered starting from in dependency order (blockers first). Each file's "Blocked by" section lists the numbers/titles of the tickets it depends on. Use the per-ticket template below; never put multiple tickets in a single combined file.
- Real issue trackers (GitHub, Linear, etc.) → Publish one issue per ticket in dependency order (blockers first), allowing blocking edges to reference real identifiers. Use native blocking/sub-issue relationships if the platform supports them; otherwise, list blocking issues in each ticket's "Blocked by" section. Apply the triage label unless instructed otherwise; these tickets are inherently ready for agents to pick up.
Handle the frontier: tickets where all blockers are completed. A pure linear chain is processed top to bottom.
Do not close or modify any parent issues.
<local-ticket-template>
<NN> — <Ticket title>
What to build: The end-to-end behaviour this ticket enables from the user's perspective, not a layer-by-layer implementation list.
Blocked by: Numbers/titles of tickets that gate this one, or "None — can start immediately".
Status: ready-for-agent
</local-ticket-template>
<issue-template>
Parent
Reference to the parent issue on the tracker (omit this section if the source is not an existing issue).
What to build
The end-to-end behaviour this ticket enables from the user's perspective, not a layer-by-layer implementation.
Acceptance criteria
Blocked by
- Reference to each blocking ticket, or "None — can start immediately".
</issue-template>
Regardless of the format, avoid specific file paths or code snippets; they become outdated quickly. Exception: If a snippet from a prototype encodes a decision (state machine, reducer, schema, type shape) more precisely than prose, it can be inline with a brief note indicating it comes from the prototype. Only keep decision-rich parts, not working demos.
Use
to handle one ticket on the frontier at a time, and clear the context between tickets.