Skip to content

Build from a ticket

For ongoing development work where requirements live in a tracker, cascade ticket is the fastest path from a ticket ID to a tested pull request.

TrackerIdentifier formatExample
GitHub Issuesgithub:owner/repo#Ngithub:myorg/myrepo#42
Jirajira:KEY-Njira:PROJ-123
Linearlinear:KEY-Nlinear:ENG-456
Azure DevOps Boardsazure_devops:org/project/Nazure_devops:myorg/myproj/123
GitLab Issuesgitlab:group/project#Ngitlab:myteam/myrepo#42

You only need to configure a tracker once. Credentials live at ~/.config/cascade/config.yaml and are reused across all cascade ticket calls.

Terminal window
cascade configure issue jira \
--token JIRA_API_TOKEN \
--base-url https://yourcompany.atlassian.net \

Create the API token at id.atlassian.com/manage-profile/security/api-tokens. The token plus your email are sent as HTTP Basic auth (Atlassian’s standard scheme). For Jira Server / Data Center, point --base-url at your installation.

Required permissions: Browse Projects and View Issues on the project containing the tickets you want to fetch. No write scope needed for read-only ticket pulls.

Terminal window
cascade configure issue linear --token lin_api_xxx

Token from linear.app/settings/api. Tokens are workspace-scoped; if you work across multiple Linear workspaces, create one token per workspace and switch between them by editing ~/.config/cascade/config.yaml directly.

Required permissions: Read access to the team / project containing the tickets.

Terminal window
cascade configure issue github --token ghp_xxx

Uses the same Personal Access Token type as the GitHub VCS provider. You can reuse the token you already configured for cascade configure vcs github.

Required scopes on the token:

  • repo (full) if the repo is private
  • public_repo is enough if the repo is public
Terminal window
cascade configure issue azure_devops --token your_pat

Create the PAT in Azure DevOps → User Settings → Personal Access Tokens. Required scope: Work Items (Read). You do not need write access on the boards to fetch tickets.

Terminal window
cascade configure issue gitlab --token glpat-xxx
# For self-hosted GitLab:
cascade configure issue gitlab --token glpat-xxx --base-url https://gitlab.acme.io

Create the token at GitLab → Edit Profile → Access Tokens. Required scope: api (read).

In the repo where the work should land:

Terminal window
cd ~/code/myrepo
cascade ticket jira:PROJ-123

Cascade fetches the ticket, converts it to a story, then runs the full pipeline:

==> [story-jira-PROJ-123] Add cursor pagination to /api/users (from jira:PROJ-123)
✓ plan: 3 file(s) to change
✓ code: 3 file(s) generated
✓ branch: cascade/story-jira-PROJ-123/add-cursor-pagination
✓ apply: 3 file(s) written
✓ install: ok
✓ test: passed (47 passed in 0.21s)
✓ commit: e4f8a2b1
✓ push: cascade/story-jira-PROJ-123/add-cursor-pagination
✓ pr: #47
PR: #47 https://github.com/myorg/myrepo/pull/47
cost: $0.11 (6,720 in / 1,430 out tokens)

The opened PR title includes the ticket ID. The PR body links back to the ticket and includes the full original ticket text so reviewers can compare the implementation against what was asked.

For each tracker, Cascade converts the ticket into a Story with these fields:

Story fieldSource
TitleThe ticket title
DescriptionThe ticket body. Jira’s ADF (Atlassian Document Format) is flattened to plain text. Linear and GitHub markdown is preserved as-is.
Acceptance criteriaA single placeholder criterion. Run cascade ticket --no-pr first if you want to edit the story before building.
StatusSet to APPROVED automatically (tracker tickets are assumed pre-approved by whoever ticketed them).
Source linkIncluded in the story notes and the opened PR description, so reviewers can click through to the ticket.
SizeEstimated by the LLM from the description length and complexity.

Custom fields, labels, sprint info, and assignees are not currently imported. They live in the tracker.

Most tracker tickets are written for humans, not for AI agents. They often lack technical detail, file references, or acceptance criteria. Two ways to handle this:

Edit the ticket in the tracker UI, add the missing detail, then re-run cascade ticket. Cascade fetches the latest version every time.

This is the right move for teams that want tickets to be the source of truth.

Option 2: Use a prompt with the ticket context inline

Section titled “Option 2: Use a prompt with the ticket context inline”
Terminal window
cascade prompt "Implement PROJ-123 (cursor pagination on /api/users): use ?limit (default 50, max 200) and ?after (the last seen ID), wrap responses in {data: [...], cursor: '...'}, update the OpenAPI schema in docs/api.yaml"

This is the right move when the ticket is fine for humans but you have specific technical context not worth adding to the ticket itself.

Default base branch is main. For teams using develop, release/*, or feature-branch workflows:

Terminal window
cascade ticket jira:PROJ-123 --base-branch develop

This is per-call; you can also set it in cascade.yaml if your project always uses a non-main default:

default_base_branch: develop

Cascade assumes the repo it is currently in (or the one at --repo-root) is the build target.

Terminal window
cascade ticket jira:PROJ-123 --repo-root ~/code/other-repo

There is no automatic mapping from ticket to repo in this release. If your team has a convention (Jira project keys map to specific repos), wrap Cascade in a small shell script:

#!/usr/bin/env bash
# cascade-route: pick the right repo for a Jira ticket
case "$1" in
PROJ-*) cd ~/code/backend ;;
WEB-*) cd ~/code/frontend ;;
INFRA-*) cd ~/code/infrastructure ;;
*) echo "Unknown project prefix"; exit 1 ;;
esac
cascade ticket "jira:$1"

Then cascade-route PROJ-123 does the right thing.

For multiple tickets in a sprint, the loop pattern:

Terminal window
for ticket in PROJ-101 PROJ-102 PROJ-105 PROJ-110; do
echo "==> Building $ticket"
cascade ticket "jira:$ticket" --max-cost 1.00 || break
done

--max-cost aborts the loop if cumulative LLM cost exceeds the budget. || break stops on the first failure so you can investigate before continuing.

What happensWhyFix
404 Not Found from the trackerWrong identifier format, or you do not have read access to the projectDouble-check the identifier. Verify your token has Browse / Read on the right project.
401 Unauthorized from JiraWrong email or expired tokenEmail is your Atlassian login, not your display name. Tokens do not expire but can be revoked at id.atlassian.com.
Story description is emptyTicket has no body, only a titleEdit the ticket and add a description, or use cascade prompt instead with the requirements inline.
Generated code does not match what the ticket asked forAcceptance criteria were too vagueAdd Given/When/Then criteria to the ticket and re-run, or pre-extract via --no-pr and edit the story before building.
Wrong base branchDefaulted to main but you use developPass --base-branch develop, or set default_base_branch in cascade.yaml.