plugins/pm/skills/create-tickets/SKILL.md
Create tickets via Linear MCP or generate formatted ticket text
npx skillsauth add coalesce-labs/catalyst create-ticketsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate engineering tickets from PRDs, feature specs, or task lists. Supports direct creation via Linear MCP or formatted text output.
Example: "Create tickets from thoughts/shared/pm/prds/checkout-redesign.md targeting a March 15 launch"
Output: Tickets created in Linear, or saved to thoughts/shared/pm/analyses/[feature]-tickets.md
Time: 15-30 minutes depending on PRD complexity
Optional but Recommended:
Fallback:
Ask the PM:
Read the source document and identify:
For each ticket, generate:
Title Format:
[Component] Action: Brief description
Examples:
[API] Add endpoint for user preferences[Frontend] Build preference selection UI[DB] Create user_preferences tableTicket Body:
## Context
[Link to PRD or parent epic]
## Objective
[What this ticket accomplishes]
## Acceptance Criteria
- [ ] Specific outcome 1
- [ ] Specific outcome 2
- [ ] Specific outcome 3
## Technical Notes
[API contracts, data schemas, edge cases]
## Dependencies
- Blocked by: [Other ticket]
- Blocks: [Other ticket]
## Testing Requirements
- [ ] Unit tests
- [ ] Integration tests
- [ ] Manual QA steps
## Resources
- Design: [design link]
- API Spec: [Swagger/OpenAPI]
- Related PRD: [Link]
If Linear MCP available:
Use Linear MCP to create issues directly
Set project, team, priority, labels
Link parent issues and sub-issues
Add components and labels
Fallback - Text Output:
Generate formatted ticket text
Number tickets sequentially
Provide copy-paste instructions
When creating 5+ tickets:
For each ticket, include an effort estimate using T-shirt sizing:
| Size | Time | Description | Example | | ------ | --------- | ----------------------------------------- | ----------------------------------- | | XS | <2 hours | Config change, copy update, simple fix | Update error message text | | S | Half day | Single-file change, straightforward logic | Add input validation to a form | | M | 1-2 days | Multi-file change, moderate complexity | Build a new API endpoint with tests | | L | 3-5 days | Cross-component work, integration needed | Build complete CRUD feature with UI | | XL | 1-2 weeks | Large scope, multiple systems involved | New authentication system |
Estimation rules:
Some teams prefer story points over T-shirt sizes. If the team uses story points:
| Points | Complexity | Roughly Equivalent To | | ------ | ------------------------------------- | --------------------- | | 1 | Trivial change, well-understood | XS (few hours) | | 2 | Small change, minimal unknowns | S (half day - 1 day) | | 3 | Medium change, some unknowns | M (1-2 days) | | 5 | Significant change, moderate unknowns | L (3-5 days) | | 8 | Large change, many unknowns | XL (1-2 weeks) | | 13 | Very large, high uncertainty | Split this ticket |
Which to use: Ask the PM or check existing tickets in the project management tool. Default to T-shirt sizes if unknown -- they're more intuitive for non-engineers.
Ticket format with estimate:
=== TICKET 1 ===
Title: [API] Add CRUD endpoints for user preferences
Estimate: M (1-2 days)
...
If the PM has a target launch date, work backwards from the deadline to suggest sprint assignments.
Sprint grouping logic:
Sprint 1 (Foundation & Blockers):
- Database migrations
- API contracts and core endpoints
- Infrastructure/DevOps setup
- Tickets that block everything else
Sprint 2 (Core Functionality):
- Frontend components
- Business logic implementation
- Integration between frontend and backend
- Core user flow working end-to-end
Sprint 3 (Polish & Edge Cases):
- Error handling and edge cases
- Performance optimization
- Accessibility fixes
- Documentation and help content
- QA and testing tickets
Capacity check:
When the PRD is at Team Kickoff or Planning Review stage (requirements are still fuzzy):
Adjust ticket creation:
What NOT to do:
Flag it: Start the ticket breakdown with: "Note: PRD is at [Stage] stage. Some tickets have [TBD] acceptance criteria that will be refined as requirements solidify."
Identify and mark dependencies between tickets. Use explicit notation in each ticket:
## Dependencies
- **Blocked by:** TICKET-3 (DB schema must exist before API can be built)
- **Blocks:** TICKET-7 (Frontend needs this API to integrate)
After generating all tickets, provide a dependency summary:
## Dependency Summary
TICKET-1 [DB Schema] --> TICKET-3 [API Endpoints] --> TICKET-5 [Frontend Integration]
TICKET-2 [Auth Setup] --> TICKET-4 [Protected Routes] --> TICKET-5 [Frontend Integration]
TICKET-5 [Frontend Integration] --> TICKET-6 [E2E Tests]
Critical path: TICKET-1 --> TICKET-3 --> TICKET-5 --> TICKET-6
Estimated critical path duration: 7-10 days
Independent tickets (can be done in parallel):
- TICKET-7 [Documentation] -- no blockers
- TICKET-8 [Analytics instrumentation] -- no blockers
Dependency rules:
Before creating tickets, verify:
Epic: User Preferences System
├── [DB] Create user_preferences table
├── [API] Add CRUD endpoints for preferences
├── [Frontend] Build preferences UI
└── [QA] Test preferences end-to-end
Title: [Component] Fix: Description of bug
Body:
- Current behavior: [What's broken]
- Expected behavior: [What should happen]
- Repro steps: [How to reproduce]
- Root cause: [If known]
Title: [DevOps] Setup: Description
Body:
- Current state: [What exists]
- Desired state: [What we need]
- Migration plan: [How to get there]
- Rollback plan: [How to revert if needed]
# Create parent issue (epic-level)
epic = mcp__claude_ai_Linear__create_issue({
"title": "User Preferences System",
"description": "[Epic description]",
"teamId": "team_id",
"priority": 1
})
# Create child issues
for ticket in tickets:
mcp__claude_ai_Linear__create_issue({
"title": ticket.title,
"description": ticket.body,
"teamId": "team_id",
"parentId": epic.id,
"priority": ticket.priority,
"labelIds": ticket.labels
})
=== TICKET 1 ===
Title: [Component] Action: Description
Project: [Project Name]
Type: Story
Priority: Medium
[Full ticket body]
=== TICKET 2 ===
...
❌ Vague titles: "Fix preferences" ✅ Specific titles: "[API] Fix: Preferences endpoint returns 500 on missing user"
❌ No acceptance criteria ✅ Clear checklist of outcomes
❌ Missing dependencies ✅ "Blocked by PROJ-123, Blocks PROJ-125"
❌ No technical context ✅ API contracts, data schemas, edge cases documented
❌ Orphan tickets (no epic/parent) ✅ Linked to parent epic or PRD
Remember: Great tickets save engineering hours. Invest time upfront to create clear, actionable work items.
When the PM uses /create-tickets, I automatically:
Source: PRDs in thoughts/shared/pm/prds/, or uploaded documents
Source: Linear MCP (if connected)
Source: thoughts/shared/pm/prds/, related PRDs
Source: PRDs, /feature-metrics or /impact-sizing outputs
Routing logic:
mcp__claude_ai_Linear__create_issueBefore delivering tickets, verify:
If any check fails, fix it before delivering. Bad tickets slow engineering down more than no tickets at all.
development
Migrate a single-harness repo to the dual-harness layout so both Claude Code and Codex load the same instructions and skills — AGENTS.md as the portable canonical doc, a thin CLAUDE.md `@AGENTS.md` bridge, and a `.agents/skills` dir with a `.claude/skills` symlink onto it. Use when asked to migrate to dual-harness, make this repo work in both Claude and Codex, or for agent metadata cleanup.
tools
Goal-driven senior-engineer pipeline-unstick sweep (CTL-1176 rung 3). Given the stuck/failed/needs-human set (or ONE ticket handed by the recovery router), its GOAL is to get the pipeline MOVING again — not to fix one ticket's review findings (that is phase-remediate). It runs AFTER the eyes (diagnostician evidence) and the hands (deterministic unstuck-sweep seams) have already tried, and it CONSUMES their output from a recovery-pass.json brief rather than re-diagnosing or redoing their narrow work. It acts like a senior engineer with full tool access — it resolves merge conflicts, rebases, force-pushes, merges green PRs, and re-dispatches stalled phases AUTONOMOUSLY — and escalates to the operator ONLY for a genuine value judgment / something that degrades other functionality / a real cost-benefit trade-off / a serious architecture change / an ADR conflict. On escalation it AUTHORS the operator inbox row + the push notification (executive-voiced). Dispatched as a `claude --bg` job by phase-agent-dispatch via slash command, AND invocable bare by the operator as a sweep — hence `user-invocable: true`. Ships behind CATALYST_RECOVERY_PASS (off by default — no live behavior change until shadow/enforce).
tools
Diagnose and fix Catalyst setup issues. Validates tools, database, config, OTel, direnv, and thoughts. Automatically fixes what it can — creates directories, initializes the database, sets WAL mode, runs migrations. Use for new installs, upgrades, or when something isn't working.
tools
--- name: phase-triage description: Phase agent that triages a Linear ticket — expands acronyms, classifies (feature/bug/docs/refactor/chore), identifies genuine blockers (a semantic second-pass over the backlog — NOT a prose scrape; CTL-838), estimates scope, writes triage.json, and posts a triage analysis comment to Linear. Triage completion is signaled by that comment plus the local triage.json — there is no `triaged` label. Emits phase.triage.complete.<TICKET> on success and phase.triage.fai