Skip to content

Ticket-Driven Development

Use tickets to guide AI agents through structured development workflows.

Difficulty: Intermediate Time: 15 minutes

What You'll Build

A workflow that:

  • Uses tickets to define work
  • Has agents implement changes
  • Tracks progress automatically
  • Links conversations to tickets

Ticket-Driven DevelopmentTBD: Replace with screenshot of ticket-driven workflow

Prerequisites

The Workflow

┌──────────┐    ┌───────────┐    ┌──────────┐    ┌──────────┐
│  Create   │───→│   Plan    │───→│ Implement│───→│  Review  │
│  Ticket   │    │   Agent   │    │   Agent  │    │   Agent  │
└──────────┘    └───────────┘    └──────────┘    └──────────┘
      │               │               │               │
      └───────────────┴───────────────┴───────────────┘
                      All linked to ticket

Step 1: Create a Well-Structured Ticket

Good tickets guide agents effectively.

Ticket Structure

yaml
id: T-042
title: Add user profile avatar upload
type: feature
priority: medium
status: planned

description: |
  ## Overview
  Users should be able to upload and change their profile avatar.

  ## Requirements
  - Accept JPEG, PNG, GIF (max 5MB)
  - Crop to square aspect ratio
  - Store in cloud storage
  - Display in header and profile page

  ## Technical Notes
  - Use existing FileUpload component
  - Store in S3 bucket
  - Generate thumbnails (64px, 128px, 256px)

  ## Acceptance Criteria
  - [ ] User can upload image from profile settings
  - [ ] Image is cropped to square
  - [ ] Thumbnails are generated
  - [ ] Avatar displays throughout app
  - [ ] Old avatar is replaced on re-upload

subtasks:
  - title: Design upload UI
    status: pending
  - title: Implement backend upload endpoint
    status: pending
  - title: Add image processing
    status: pending
  - title: Update profile display components
    status: pending
  - title: Write tests
    status: pending

Step 2: Create Development Agents

Planning Agent

yaml
name: Technical Planner
description: Creates implementation plans from tickets

systemPrompt: |
  You are a senior developer creating implementation plans.

  Given a ticket:
  1. Analyze requirements thoroughly
  2. Break down into concrete tasks
  3. Identify dependencies and order
  4. Note potential challenges
  5. Estimate complexity

  Output a detailed, actionable plan.

model: claude-opus-4-6
thinkingLevel: think-hard

mcpServers:
  - sciorex-tickets

allowedTools:
  - tool: Read
    allowed: true
  - tool: Glob
    allowed: true
  - tool: Grep
    allowed: true

Implementation Agent

yaml
name: Feature Developer
description: Implements features based on plans

systemPrompt: |
  You are a skilled developer implementing features.

  Follow the plan closely:
  - Write clean, tested code
  - Follow existing patterns
  - Update subtask status as you progress
  - Ask for clarification when needed

model: claude-sonnet-5-0
thinkingLevel: think

mcpServers:
  - sciorex-tickets
  - sciorex-interactions

allowedTools:
  - tool: Read
    allowed: true
  - tool: Write
    allowed: true
  - tool: Edit
    allowed: true
  - tool: Glob
    allowed: true
  - tool: Grep
    allowed: true
  - tool: Bash
    allowed: true

Review Agent

yaml
name: Code Reviewer
description: Reviews implementations against requirements

systemPrompt: |
  You are a thorough code reviewer.

  Check implementations against:
  - Ticket requirements
  - Acceptance criteria
  - Code quality standards
  - Test coverage

  Provide specific, actionable feedback.

model: claude-sonnet-5-0
thinkingLevel: think

mcpServers:
  - sciorex-tickets

Step 3: The Development Session

Start with Planning

  1. Open a chat with Technical Planner
  2. Link to the ticket
  3. Request a plan:
Plan the implementation for ticket T-042 (avatar upload feature).
Review the existing codebase for relevant patterns.

The agent will:

  • Read the ticket details
  • Explore the codebase
  • Create a detailed plan

Implement with Tracking

  1. Switch to Feature Developer
  2. Continue in the same ticket context:
Implement the plan for T-042. Start with the first subtask.
Update subtask status as you complete each one.

The agent will:

  • Follow the plan
  • Write code
  • Mark subtasks complete via MCP
  • Ask questions when stuck

Review Before Completion

  1. Switch to Code Reviewer
  2. Request review:
Review the implementation for T-042 against the requirements.
Check all acceptance criteria are met.

Step 4: Automate with a Flow

Create a flow for repeatable ticket processing:

┌────────────┐    ┌──────────┐    ┌───────────┐    ┌────────────┐
│ Ticket      │───→│ Planner  │───→│ Developer │───→│ Condition  │
│ Updated     │    │ Agent    │    │ Agent     │    │ (passed?)  │
└────────────┘    └──────────┘    └───────────┘    └────────────┘

                                        ┌────────────────┴────────────────┐
                                        ▼                                 ▼
                                   [passed]                          [default]
                                        │                                 │
                                        ▼                                 ▼
                                 ┌──────────┐                      ┌──────────┐
                                 │ Mark Done│                      │ Fix Loop │
                                 └──────────┘                      └──────────┘

Flow Configuration

json
{
  "name": "Ticket Development Pipeline",
  "nodes": [
    {
      "id": "trigger",
      "type": "trigger",
      "label": "Ticket Updated",
      "config": {},
      "position": { "x": 0, "y": 0 },
      "triggerType": "ticket-updated",
      "triggerConfig": {
        "ticketFilter": {
          "status": "in_progress"
        }
      }
    },
    {
      "id": "plan",
      "type": "agent",
      "label": "Plan",
      "config": {},
      "position": { "x": 250, "y": 0 },
      "agentId": "technical-planner",
      "inputMapping": {
        "ticketId": "trigger.input.ticketId"
      },
      "outputMapping": {},
      "worktreeMode": "new",
      "worktreeConfig": {
        "label": "ticket-implementation",
        "baseBranch": "main",
        "autoMergeOnSuccess": true,
        "cleanupOnComplete": true
      }
    },
    {
      "id": "implement",
      "type": "agent",
      "label": "Implement",
      "config": {},
      "position": { "x": 500, "y": 0 },
      "agentId": "feature-developer",
      "inputMapping": {
        "plan": "nodes.plan.output",
        "ticketId": "trigger.input.ticketId"
      },
      "outputMapping": {},
      "worktreeMode": "inherit",
      "inheritWorktreeFromNodeId": "plan"
    },
    {
      "id": "review",
      "type": "agent",
      "label": "Review",
      "config": {},
      "position": { "x": 750, "y": 0 },
      "agentId": "code-reviewer",
      "inputMapping": {
        "ticketId": "trigger.input.ticketId",
        "implementation": "nodes.implement.output"
      },
      "outputMapping": {},
      "worktreeMode": "inherit",
      "inheritWorktreeFromNodeId": "plan"
    },
    {
      "id": "checkPassed",
      "type": "condition",
      "label": "Review Passed?",
      "config": {},
      "position": { "x": 1000, "y": 0 },
      "conditions": [
        {
          "path": "nodes.review.output.passed",
          "operator": "eq",
          "value": true
        }
      ],
      "targetNodeId": "markDone",
      "defaultTargetNodeId": "fixLoop"
    },
    {
      "id": "markDone",
      "type": "ticket_action",
      "label": "Mark Done",
      "config": {},
      "position": { "x": 1250, "y": -100 },
      "action": "update_status",
      "actionParams": {
        "ticketId": "trigger.input.ticketId",
        "status": "done"
      }
    },
    {
      "id": "fixLoop",
      "type": "agent",
      "label": "Fix Issues",
      "config": {},
      "position": { "x": 1250, "y": 100 },
      "agentId": "feature-developer",
      "inputMapping": {
        "feedback": "nodes.review.output",
        "ticketId": "trigger.input.ticketId"
      },
      "outputMapping": {},
      "worktreeMode": "inherit",
      "inheritWorktreeFromNodeId": "plan",
      "reuseSessionOnLoop": true
    },
    {
      "id": "endSuccess",
      "type": "end",
      "label": "Done",
      "config": {},
      "position": { "x": 1500, "y": -100 },
      "endType": "success"
    },
    {
      "id": "endFixed",
      "type": "end",
      "label": "Fixed",
      "config": {},
      "position": { "x": 1500, "y": 100 },
      "endType": "success"
    }
  ],
  "edges": [
    { "id": "e1", "source": "trigger", "target": "plan" },
    { "id": "e2", "source": "plan", "target": "implement" },
    { "id": "e3", "source": "implement", "target": "review" },
    { "id": "e4", "source": "review", "target": "checkPassed" },
    { "id": "e5", "source": "checkPassed", "target": "markDone", "label": "passed" },
    { "id": "e6", "source": "checkPassed", "target": "fixLoop", "label": "needs fixes" },
    { "id": "e7", "source": "markDone", "target": "endSuccess" },
    { "id": "e8", "source": "fixLoop", "target": "endFixed" }
  ],
  "variables": {},
  "maxIterations": 5
}

Key features in this flow:

  • Worktree isolation: The planner creates a new worktree, and subsequent agents inherit it — all work happens in an isolated branch
  • Session reuse: The fix loop agent uses reuseSessionOnLoop: true to continue its previous conversation
  • Auto-merge: On success, the worktree branch merges back to main

Best Practices

Ticket Quality

ElementPurpose
Clear titleQuick identification
Detailed descriptionFull context
Acceptance criteriaDefinition of done
Technical notesImplementation hints
SubtasksProgress tracking

Agent Instructions

  • Reference ticket explicitly: "for ticket T-042"
  • Request status updates: "mark subtasks complete"
  • Ask for ticket context: "read the ticket requirements"

Session Linking

Always link sessions to tickets:

  1. Set ticket context before starting
  2. Or archive completed sessions to tickets

Example: Bug Fix Workflow

yaml
# Ticket
id: T-099
title: Fix login timeout on slow connections
type: bug
priority: high

description: |
  Users on slow connections get logged out unexpectedly.

  ## Steps to Reproduce
  1. Throttle network to 3G
  2. Attempt login
  3. Wait 10 seconds

  ## Expected
  Login completes successfully

  ## Actual
  Session times out, user sees error

  ## Technical Context
  - Auth timeout is 5 seconds
  - Should be increased or made configurable

Agent conversation:

You: Fix bug T-099. Read the ticket and investigate the issue.

Agent: I've read ticket T-099. The issue is a 5-second auth timeout.
       Let me search for the timeout configuration...

       Found it in src/config/auth.ts:15
       The AUTH_TIMEOUT is hardcoded at 5000ms.

       I'll make this configurable with a higher default.
       [Makes changes]

       Done. I've:
       1. Added AUTH_TIMEOUT to environment config
       2. Set default to 30000ms (30 seconds)
       3. Updated the auth service to use the config

       Marking ticket as ready for review.

Tips

  • Write good tickets: Garbage in, garbage out
  • Use subtasks: Break work into trackable pieces
  • Link everything: Sessions, commits, discussions
  • Review before closing: Verify requirements are met
  • Update status: Keep tickets current
  • Use worktrees: Isolate ticket work in dedicated branches

Sciorex is proprietary software.