Skip to main content
Stacks are linear chains of dependent issues that form a cohesive unit of work. Inspired by Graphite’s stacked PRs, tk automatically detects stacks in your issue graph and provides tools to work with them efficiently.

What is a Stack?

A stack is a maximal linear chain where:
  • Each issue depends on exactly one predecessor (except the root)
  • Each issue has at most one dependent (except the tip)
Stacks are detected automatically from your issue dependencies. You don’t need to explicitly create them.

Why Use Stacks?

1. Structured Feature Development

Break large features into incremental, reviewable pieces:
# Create a stack of issues for authentication
tk create "Auth: Base service setup" -t feature -p 1
# Created: tk-auth1

tk create "Auth: Login endpoint" -t feature -p 1 -d tk-auth1
# Created: tk-auth2

tk create "Auth: Frontend integration" -t feature -p 1 -d tk-auth2
# Created: tk-auth3

2. Clear Work Order

The stack defines the exact order work should be completed:
tk dep tree tk-auth3
tk-auth3: Auth: Frontend integration [P1] (open)
    └── tk-auth2: Auth: Login endpoint [P1] (open)
        └── tk-auth1: Auth: Base service setup [P1] (open)

3. Coordinated Worktrees

Create worktrees for stack issues that share .tickets/:
# Create worktree for the ready root issue
tk worktree ready --issues tk-auth1

Stack Commands

tk provides a complete set of subcommands for managing stacks:
CommandDescription
tk stacks or tk stacks listList all detected stacks
tk stacks show <id>Show detailed stack info
tk stacks validate <id>Check if stack is ready to merge
tk stacks merge <id>Fast-forward merge all branches
tk stacks worktree <id>Create worktree for stack development

Detecting Stacks

View All Stacks

tk stacks
tk stacks list
tk stacks ls  # alias
Options:
  • --all — Include stacks with closed issues
  • --ready — Show only stacks where all issues are ready
Sample output:
2 stack(s) detected:

○ stack-1 [3 issues] tk-auth1 → tk-auth2 → tk-auth3
  Chain: tk-auth1 → tk-auth2 → tk-auth3
○ stack-2 [2 issues] tk-data1 → tk-data2
  Chain: tk-data1 → tk-data2

Show Stack Details

tk stacks show stack-1
tk stacks show tk-auth1  # By root issue ID
Sample output:
Stack: stack-1

  Status: ready
  Depth:  3 issues
  Root:   tk-auth1
  Tip:    tk-auth3

  Chain:
      (root) tk-auth1 - Auth: Base service setup
             tk-auth2 - Auth: Login endpoint
      (tip)  tk-auth3 - Auth: Frontend integration

JSON Output

For programmatic access:
tk stacks -f json
tk stacks show stack-1 -f json
[
  {
    "id": "stack-1",
    "issues": ["tk-auth1", "tk-auth2", "tk-auth3"],
    "root": "tk-auth1",
    "tip": "tk-auth3",
    "is_ready": true,
    "depth": 3
  }
]

Stack Properties

PropertyDescription
idUnique identifier (e.g., “stack-1”)
rootFirst issue in chain (no blockers)
tipLast issue in chain (no dependents)
issuesOrdered list from root to tip
depthNumber of issues in stack
is_readyWhether the root can be started

Working with Stacks

Start at the Root

Only the root issue is “ready” since others are blocked:
# Find ready work in the stack
tk ready

# Start the root
tk claim tk-auth1

Progress Through the Stack

As you complete each issue, the next becomes unblocked:
# Complete the root
tk resolve tk-auth1
# 🎉 tk-auth2 is now ready!

# Move to the next
tk claim tk-auth2

View Stack Progress

tk stacks
After resolving tk-auth1:
📚 Detected 1 Dependency Stack(s):

  stack-1 ready (2 issues)
    Root: tk-auth2  Tip: tk-auth3
    Chain: tk-auth2 → tk-auth3
The stack shrinks as you complete issues. When only one issue remains, it’s no longer considered a stack.

Stacks vs Branches

Not all dependency chains form stacks:

Linear Chain = Stack

Each issue has one parent and one child. This is a stack.
A has multiple dependents. This is not a stack.
C has multiple dependencies. This is not a stack.

Validating Stacks

Before merging, validate that a stack is ready:
tk stacks validate stack-1
Validation checks:
  • All non-tip issues in the stack are closed
  • Tip issue has no external blockers (outside the stack)
  • All issues exist and are parseable
Sample output (valid):
✓ Stack Validation: stack-1

  PASS Stack is ready for merge!
  All 3 issues are in valid state for merging.

  Issues:
    ✓ tk-auth1 [closed] (root) - Auth: Base service setup
    ✓ tk-auth2 [closed] - Auth: Login endpoint
    ✓ tk-auth3 [open] (tip) - Auth: Frontend integration
Sample output (invalid):
✗ Stack Validation: stack-1

  FAIL Stack is NOT ready for merge.

  Issues:
    ✓ tk-auth1 [closed] (root) - Auth: Base service setup
    ✗ tk-auth2 [open] - Auth: Login endpoint
      → expected closed but is open
    ✓ tk-auth3 [open] (tip) - Auth: Frontend integration

  Fix To fix:
    - Close these issues: tk-auth2
Use tk stacks validate in CI to gate stack merges. Exit code 0 = valid, 1 = invalid.

Merging Stacks

Once validated, merge all branches in a stack with one command:
tk stacks merge stack-1
Options:
  • --dry-run — Preview merge without making changes
  • --yes — Skip confirmation prompt
Process:
  1. Validates the stack (same as tk stacks validate)
  2. Merges branches in dependency order (root → tip)
  3. Closes all issues in the stack
  4. Reports merge results
This command modifies git branches. Always use --dry-run first to preview changes.

Stack Worktrees

Create a dedicated worktree for working on a stack:
tk stacks worktree stack-1
Features:
  • Creates worktree with the stack’s tip branch
  • Symlinks .tickets/ for shared issue tracking
  • Places worktree in ~/.tickets/worktrees/<repo>/<stack-id>
Manage worktrees:
# List existing stack worktrees
tk stacks worktree --list

# Remove a stack worktree
tk stacks worktree --remove stack-1

Git Worktree Integration

Stacks work seamlessly with git worktrees:

1. Configure Worktree Location

tk config set workflow.worktree_base "../wt"

2. Create Worktrees for Stack Development

# Create worktree for a specific stack
tk stacks worktree stack-1

# Or create worktrees for ready issues
tk worktree ready --issues tk-auth1

3. Use Hooks for Automation

Configure hooks in .tickets/config.yaml:
hooks:
  on-claim:
    worktree: "git worktree add {{ worktree_base }}/{{ id | short }} -b {{ id }}"
    editor: "cursor {{ worktree_base }}/{{ id | short }}"

Worktree Variables

Available template variables:
  • {{ worktree_base }} - Base directory from config
  • {{ worktree_path }} - Full path to worktree
  • {{ id | short }} - Issue ID without prefix (e.g., “auth1”)

Best Practices

Aim for 3-5 issues per stack. Longer stacks increase merge risk.
Always complete the root before moving to dependent issues.
Each stack issue should be independently reviewable.
Name issues to show their position: “Auth: Base”, “Auth: API”, “Auth: UI”

Future Enhancements

Planned stack features:
  • Stack navigation: tk stacks navigate to move between issues in a stack
  • Stack rebase: tk stacks rebase to rebase entire stacks onto main
  • Stack create: tk stacks create to easily build new dependency chains
  • Bisection: Isolate failures in O(log n) CI runs

Next Steps