Skip to main content
Henrik Albihn
Henrik Albihn
Creator of ticket-rs

The List Delusion

Open your issue tracker right now. What do you see? A list. Sorted by date, maybe by priority. Columns on a kanban board. Rows in a spreadsheet. Everything laid out flat, one item after another. Here’s the problem: your work isn’t flat. Issue #47 can’t start until #31 and #38 are both done. Issue #12 is blocking four other issues downstream. Issue #89 looks low-priority, but it’s the single bottleneck holding up your entire release. You can’t see any of that in a list. Every issue tracker I’ve used—JIRA, Linear, Asana, GitHub Issues—presents your backlog as a one-dimensional sequence. They let you sort and filter, maybe drag cards between columns. But the actual structure of your work—the dependency relationships that determine what can ship and when—is invisible. You’re navigating a graph with a tool designed for lists.

Your Work Is a DAG

In computer science, a directed acyclic graph (DAG) is a graph with directed edges and no cycles. It’s the natural data structure for task dependencies: issue A blocks issue B, B blocks C, but C can never block A (that’s a cycle, a deadlock). Your backlog is a DAG whether you model it as one or not. The dependencies exist in reality even if your tooling ignores them. Consider a typical feature rollout: That changes your entire execution strategy.

Three Things Your List Can’t Tell You

1. Which issue actually matters most

Most teams sort by priority: P0, P1, P2. But priority is a local property: how important this issue seems in isolation. What you want is a global property: how much total work does this issue unblock? A P2 bug that blocks five downstream features is more urgent than a P0 polish task that blocks nothing. Lists can’t express this. Graphs can.

2. Where your real bottleneck is

You have 30 open issues. Three developers. Where do you assign them? A list says: pick the top three by priority. A graph says: find the issues that sit on the most dependency paths. Those are your bottlenecks—clear them, and the entire project accelerates. In graph theory, this is called betweenness centrality. It measures how often a node appears on shortest paths between other nodes. High betweenness = high leverage.

3. What determines your actual ship date

Your ship date isn’t determined by the total number of issues. It’s determined by the critical path—the longest chain of sequential dependencies in your DAG. If your critical path is 8 issues deep, that’s your minimum timeline regardless of how many developers you throw at the other 22. Adding parallelism helps, but only for work that’s off the critical path.
This is the insight behind CPM (Critical Path Method), developed at DuPont in the 1950s for managing construction projects. Seven decades later, most software teams still don’t use it.

PageRank for Your Backlog

Here’s where it gets interesting. Google’s original insight was that the importance of a web page is determined by the structure of links pointing to it, not the page itself. A page linked by many important pages is itself important. The algorithm that captures this is PageRank. The same logic applies to issue dependencies. An issue that blocks many important issues is itself important, even if no one manually flagged it as P0. The importance propagates through the dependency graph, just like link authority propagates through the web graph.

Traditional Priority

Input: Human judgment (P0/P1/P2)Problem: Doesn’t account for dependency structure. A P2 blocking five P0s stays P2.Result: Teams work on locally optimal tasks while globally critical work stalls.

Graph-Derived Priority

Input: Dependency structure + statusAlgorithm: PageRank over the dependency DAG, weighted by blocking relationships.Result: Issues that unblock the most downstream work rise to the top.
This isn’t a metaphor. ticket-rs applies a PageRank-style scoring algorithm to your dependency graph—issues that block more downstream work score higher.

From Theory to tk triage

I built ticket-rs to make this practical. Issues are stored as markdown files with YAML frontmatter. Dependencies are explicit: deps: [tk-31, tk-38]. The CLI runs graph algorithms over this structure and returns ranked recommendations.
$ tk triage

📊 Project Health: 72/100
━━━━━━━━━━━━━━━━━━━━━━━━━━

🎯 Top Recommendations:
  1. tk-38 [P2] "Set up OAuth config"
 Unblocks 4 downstream issues (PageRank: 0.34)
  2. tk-12 [P1] "Fix connection pooling"
 Critical path bottleneck (betweenness: 0.67)
  3. tk-89 [P3] "Add retry logic"
 Quick win: no blockers, unblocks tk-90

 Quick Wins (ready now, high impact):
 tk-41 "Update error messages" 0 deps, unblocks tk-55

🔴 Blockers to Clear:
 tk-31 blocks 3 issues, in_progress 4 days

📈 Critical Path: tk-38 tk-44 tk-51 tk-67 (4 hops)
The tk-38 OAuth config issue is P2 by human judgment but the most important thing to work on by graph analysis. Without the graph, a developer would reasonably skip it in favor of the P1. With the graph, the priority inversion is obvious.

Why This Matters More with Coding Agents

This distinction matters more when AI agents are doing the work. Claude Code, Cursor, Windsurf, Codex — they all need to know what to build next. An agent working from a flat list picks the top item and runs. If that item is blocked by something else, the work either fails or can’t be integrated. Tokens spent, nothing to show for it. An agent working from a dependency graph knows:
  • What’s ready — issues with no open blockers
  • What to prioritize — issues that maximize downstream unblocking
  • What to parallelize — independent branches that can run concurrently
# What an AI agent sees at session start
$ tk prime

Ready issues: tk-41, tk-38, tk-55
Top recommendation: tk-38 (PageRank: 0.34, unblocks 4)
Parallel tracks: [tk-41, tk-55] can run alongside tk-38
Critical path depth: 4
This is context engineering. The graph gives the agent structured project state instead of a flat list and a prayer.
tk triage runs PageRank, betweenness centrality, critical path, and ready detection in under 25ms. For comparison, a typical cloud API call takes 500ms-2s. In an agentic loop where every tool call adds latency, that 25-100x difference compounds fast.

The Uncomfortable Math

Here’s a thought experiment. Suppose you have 50 open issues and a team of 3 developers (or 3 parallel AI agents). Your list-based approach says: sort by priority, assign top 3, repeat. But your dependency graph has:
  • 12 issues that are currently blocked
  • 8 issues that are ready but low-impact (leaf nodes)
  • 3 issues that each unblock 4+ downstream tasks
  • 1 critical path of depth 7
The list approach might assign developers to three P0 issues—two of which are blocked and one of which is a leaf node. Net progress toward ship date: minimal. The graph approach assigns developers to the three high-betweenness issues first, then the critical path entry point. Net progress: maximum unblocking, critical path shortened. Over a week of sprints, the graph-aware team ships. The list-driven team is still clearing blockers they should have prioritized on day one. The math is straightforward. It’s the predictable consequence of optimizing a local objective (individual issue priority) versus a global one (dependency-weighted impact).

Getting Started

# Install
curl -fsSL https://ticket-rs.io/install.sh | sh

# Initialize
tk init

# Create issues with dependencies
tk create "Set up database schema" -t task -p 1
tk create "Build API endpoints" -t task -p 1
tk create "Implement auth" -t feature -p 0
tk dep add tk-2 tk-1   # API depends on schema
tk dep add tk-3 tk-1   # Auth depends on schema

# See the graph in action
tk triage              # Full analysis
tk next                # Single top recommendation
tk ready               # What's unblocked right now
tk plan                # Parallel execution plan

So What?

My background is in machine learning. Finding structure in messy data is what I do. Turns out, most of us ignore the structure sitting right in front of us—in our own backlogs. Your issues have dependencies. Those dependencies form a graph. And that graph tells you what to work on next, where your bottlenecks are, and what determines your ship date. You don’t need a PhD to use PageRank. You need a dependency graph and a tool that knows what to do with it. Run tk triage once. If the top recommendation surprises you—if it shows you something you weren’t prioritizing—that’s the gap between list-thinking and graph-thinking. That gap is where the interesting work happens.