Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ticket-rs.io/llms.txt

Use this file to discover all available pages before exploring further.

Henrik Albihn
Henrik Albihn
Creator of ticket-rs

Summary

ticket-rs (invoked as tk) is a command-line issue tracker that stores issues as Markdown files with YAML frontmatter inside a repository’s .tickets/ directory. By treating issues as first-class version-controlled artifacts, tk provides dependency-aware project management through graph algorithms (PageRank, betweenness centrality, critical path analysis, topological sort) with no database, no daemon processes, and no network requirements. The tool is designed to serve both human developers and AI coding agents working in agentic development workflows, where minimal token overhead and direct filesystem access are essential constraints.

Statement of Need

The minimal viable issue tracker was built in 1985 by Peter Högfeldt for the Erlang project. It had one command—newticket—and stored each ticket as a plain text file in ${HOME}/tickets/. Status was tracked as a field in the file; timestamps came for free from the version control system. Joe Armstrong’s retrospective essay on this design articulates the core principle: a minimal viable program does exactly one thing, stores its state in the simplest possible format, and delegates everything else—history, diffing, collaboration—to existing infrastructure. That 1985 design remains the right architecture. wedow/ticket explicitly revived it for the AI era: Markdown files with YAML frontmatter in .tickets/, no daemons, no databases, version-controlled alongside code. ticket-rs is a direct descendant of this lineage—a modernized, AI-native extension that adds the one capability the original design intentionally deferred: algorithmic priority inference from the structure of the issue graph itself. Contemporary issue trackers have gone the opposite direction. GitHub Issues, Jira, Linear, and Asana are web applications optimized for human-readable dashboards. They store data in remote databases, require network connectivity, impose API rate limits, return verbose JSON payloads expensive in LLM context windows, and treat project backlogs as flat ordered lists. None of these design choices are suited to the emerging class of AI coding agents (Claude Code, Cursor, Copilot, Windsurf, Cline, Goose) that autonomously plan and execute multi-step software tasks. The shift toward agentic software development creates a new set of requirements for project management infrastructure:
  1. Local-first access — Agents running in sandboxed or offline environments need to read and write issues without external API calls.
  2. Token efficiency — Agent context windows are finite. CLI output that fits a sprint’s worth of priorities into ~500 tokens is categorically different from a 50-field JSON response object.
  3. Structural awareness — A flat list obscures the dependency graph that governs execution order. Agents need to know which issues block others and what they can safely parallelize. Agents also need semantic search to locate relevant issues without loading the entire backlog.
  4. Version-controlled provenance — Issues should carry the same history, branching, and merge semantics as the code they describe.
ticket-rs is designed to satisfy all four requirements. It compiles to a single ~9 MB static binary with zero runtime dependencies, operates entirely on files in .tickets/, and exposes graph-theoretic commands (tk priority, tk insights, tk ready, tk plan) whose output is deliberately minimal for agentic consumption.

Design and Implementation

Storage Model

Each issue is a Markdown file with a YAML frontmatter block:
---
status: open
type: feature
priority: 1
deps: [tk-abc123, tk-def456]
labels: [backend, auth]
estimate: 3d
---

# Add OAuth2 authentication

Implement Google and GitHub OAuth login flows.
Files live in .tickets/ within the repository root:
  • git clone transfers the complete issue history with no additional setup
  • git log -- .tickets/tk-abc123.md shows the full change history of a single issue
  • Issues branch and merge alongside feature branches
  • Standard text tooling (grep, sed, awk, jq --format json) works without any intermediate API layer

Dependency Graph Model

Issues form a directed acyclic graph (DAG) G=(V,E)G = (V, E) where each vertex vVv \in V is an issue and each directed edge (u,v)E(u, v) \in E means issue uu must be completed before issue vv can begin. Figure 1: Dependency DAG for a representative OAuth feature rollout. The root node (red, high PageRank) blocks three parallel branches (blue) that converge on Session Management (yellow, high betweenness centrality) before the final integration step (gray). ticket-rs reads the deps field from each issue’s YAML frontmatter to construct this graph at command invocation time, with no persistent index required for small-to-medium repositories.

Graph Analytics

ticket-rs applies four classical graph algorithms to the issue DAG:

PageRank

The standard PageRank formulation assigns a score r(v)r(v) to each node via power iteration: r(v)=1dV+duIn(v)r(u)Out(u)r(v) = \frac{1 - d}{|V|} + d \sum_{u \in \text{In}(v)} \frac{r(u)}{|\text{Out}(u)|} where d=0.85d = 0.85 is the damping factor, In(v)\text{In}(v) is the set of issues that depend on vv (i.e., vv blocks them), and Out(u)\text{Out}(u) is the set of issues that uu depends on. In the web-link analogy, a page is important if many important pages link to it; here, an issue is important if many important issues are blocked by it. Issues with high r(v)r(v) are surfaced by tk priority.

Betweenness Centrality

For each issue vv, betweenness centrality is defined as: CB(v)=svtσst(v)σstC_B(v) = \sum_{s \neq v \neq t} \frac{\sigma_{st}(v)}{\sigma_{st}} where σst\sigma_{st} is the total number of shortest paths from issue ss to issue tt, and σst(v)\sigma_{st}(v) is the number of those paths that pass through vv. Issues with high CB(v)C_B(v) are architectural bottlenecks—delays cascade across many independent work streams. tk insights --centrality reports these scores.

Critical Path

The critical path is the longest path in the DAG, computed in O(V+E)O(|V| + |E|) via topological order dynamic programming: dist(v)=maxuIn(v)(dist(u)+w(u,v))\text{dist}(v) = \max_{u \in \text{In}(v)} \left( \text{dist}(u) + w(u, v) \right) where w(u,v)w(u, v) is the estimated duration of issue uu. The critical path length is maxvVdist(v)\max_{v \in V} \text{dist}(v) and represents the minimum project duration under unlimited parallelism. tk insights --critical-path reports this chain.

Parallel Execution Planning

tk plan applies Kahn’s topological sort to partition open issues into sequential batches B1,B2,,BkB_1, B_2, \ldots, B_k such that all issues within a batch BiB_i have their dependencies satisfied by issues in j<iBj\bigcup_{j < i} B_j. Issues within the same batch are dependency-free with respect to one another and may be executed concurrently—by multiple developers or by multiple AI agents running in parallel worktrees. Figure 2: tk plan output — topological batching maximizes parallelism across agents or developers.

Triage Synthesis

tk triage combines all four analyses into a single structured report whose full output fits in approximately 500 tokens. It includes a project health score (A–F), a top recommendation with rationale, quick-win candidates, and a ranked list of blockers. This compact representation is designed to be injected directly into an LLM context without consuming a significant fraction of the available window.

Performance

Written in Rust, tk completes all analytics commands in under 25ms on cached data. An intelligent filesystem mtime-based cache—invalidated automatically on file create, delete, or modify—returns results in under 10ms on cache hits. Cold computation on a repository of ~68 issues completes in under 900ms.
ImplementationMedian TimeSpeedup
ticket-rs (Rust CLI (tk))9.0ms6.2x faster
kardianos/ticket (Go trie YAML)9.7ms5.8x faster
nwiizo/vibe-ticket (Rust (archived))16.2ms3.5x faster
ticket-py (Python bindings via PyO3)24.3ms2.3x faster
wedow/ticket (Bash)35.1ms1.6x faster
steveyegge/beads (Go daemon)55.9ms1.0x faster
steveyegge/beads (Go direct)58.8ms1.1x slower
Benchmarks run with 500 tickets, 30 iterations. Data source: benchmark-data.json
The absence of garbage collection pauses and the use of efficient adjacency-list representations contribute to predictable, sub-second latency suitable for interactive and agentic use alike.

Architecture Properties

No Daemon

Every invocation reads .tickets/, computes, writes output, and exits. No background process persists.

No Database

Storage is plain files. No schema migrations are ever required.

Stateless

Commands are pure functions of the .tickets/ directory state.

Cross-Platform

Native binaries for macOS (Apple Silicon + Intel), Linux (x86_64 + ARM64), and Windows (x86_64).

AI Agent Integration

ticket-rs ships integration guides and MCP (Model Context Protocol) server configurations for Claude Code, Cursor, Windsurf, Cline, Goose, GitHub Copilot, JetBrains AI, Gemini Code Assist, OpenAI Codex, and Zed. The MCP server exposes tk commands as typed tools that agents can invoke with structured parameters and receive minimal, machine-parseable responses. The Python SDK (pip install ticket-rs) and npm bindings provide idiomatic interfaces for agents written in those ecosystems, backed by the same native Rust binary via PyO3 and napi-rs respectively. Bidirectional sync with GitHub Issues and Linear allows teams to maintain the local-first tk workflow while surfacing issues in the external trackers their stakeholders rely on.
tk prime is a dedicated command for AI agent session initialization. It outputs a compact, structured project state—ready issues, top PageRank recommendation, parallel execution tracks, and critical path depth—designed to be injected as context at the start of a Claude Code or Cursor session. This operationalizes the context engineering pattern: giving the agent a structured graph state rather than a raw list at every iteration.
tk stacks detects linear dependency chains (Graphite-style stacks) within the DAG and exposes validate, merge, and worktree subcommands for coordinated incremental development and merge-queue workflows. ticket-rs also provides full-text retrieval via BM25 search (tk search), similarity search (tk similar), and duplicate detection (tk duplicates) to help teams manage issue quality as backlogs grow.

Design Lineage

ticket-rs sits at the end of a clear intellectual lineage: 1985 — The Erlang Ticket System: Peter Högfeldt’s original design for the Erlang project. One command (newticket), one plain text file per ticket, status as a structured field, timestamps delegated to version control. Armstrong’s retrospective identifies this as a minimal viable program: the smallest design that solves the problem, where removing any single feature would render it useless, and adding any feature would be unnecessary. 2024 — Beads (Steve Yegge): The most widely adopted git-native issue tracker. Pioneered the concept of AI-native issue tracking with a tight terminal-first CLI and git-backed storage. Introduced the core insight—later carried into this lineage—that AI agents need structured, queryable memory to coordinate multi-step work. Uses SQLite for richer querying capability; ticket-rs provides a tk migrate-beads command for smooth migration. 2025 — wedow/ticket: A direct revival of the Armstrong MVP design for the AI era. Explicitly cites the MVP essay as its inspiration. Tickets are Markdown files with YAML frontmatter in .tickets/; the only additions over the 1985 design are dependency tracking and AI-agent-friendly output. No daemons, no databases. 2026 — ticket-rs (this work): Extends wedow/ticket with the one capability the minimal design intentionally omits—algorithmic priority inference from the dependency graph. Rust performance, graph analytics (PageRank, betweenness centrality, critical path), parallel execution planning, MCP integrations, and AI-native session context (tk prime) are layered on top of an identical storage model. The storage format is deliberately preserved across this lineage. A ticket file from wedow/ticket is valid ticket-rs input.

Feature Comparison

ToolStorageGraph analyticsOfflineToken-efficientZero daemon
Erlang tickets (1985)Plain text + CVSNoYesYesYes
GitHub IssuesRemote DBNoNoNoN/A
LinearRemote DBPartialNoNoN/A
JiraRemote DBNoNoNoN/A
BeadsSQLite + gitBasicYesPartialNo
wedow/ticketMarkdown filesNoYesYesYes
ticket-rsMarkdown filesYesYesYesYes

Limitations and Future Work

ticket-rs is optimized for repositories with up to approximately 10,000 issues. Above this threshold, file-system enumeration and in-memory graph construction impose latency that may degrade the interactive experience. Persistent index caching is planned to address this.
Real-time collaborative editing across team members is not supported; the intended synchronization mechanism is standard git push/git pull. Teams requiring live multi-user updates should evaluate whether a hybrid approach—tk locally with external tracker sync—meets their needs. Future work includes:
  • Weighted dependency edges (partial blocking)
  • Time-phased critical path with calendar-aware scheduling
  • Language server protocol integration for in-editor issue navigation
  • Cross-repository dependency tracking in monorepos

Acknowledgements

The authors thank Joe Armstrong and Peter Högfeldt for the 1985 Erlang ticket system and Armstrong’s essay on minimal viable programs, which established the design principles this work extends. We thank Steve Yegge for Beads, which proved the viability of git-backed AI-native issue tracking as a concept and established the community of practice this work builds on. We thank the wedow/ticket project for the Markdown + YAML frontmatter storage architecture that ticket-rs directly inherits. The graph analytics design was further inspired by the beads_viewer project by Dicklesworthstone. We also thank the Rust community for the ecosystem of crates that make high-performance CLI tooling tractable, and the developers of Claude Code, Cursor, and the broader agentic coding toolchain whose workflows motivated this design.

References

KeyCitation
Armstrong 2014Joe Armstrong. Minimal Viable Programs. Blog post, June 2014. joearms.github.io/published/2014-06-25-minimal-viable-program.html
Page et al. 1999Lawrence Page, Sergey Brin, Rajeev Motwani, Terry Winograd. The PageRank Citation Ranking: Bringing Order to the Web. Stanford InfoLab Technical Report 1999-66.
Brandes 2001Ulrik Brandes. A Faster Algorithm for Betweenness Centrality. Journal of Mathematical Sociology, 25(2):163–177, 2001.
Kahn 1962Arthur B. Kahn. Topological Sorting of Large Networks. Communications of the ACM, 5(11):558–562, 1962.
Yegge 2024Steve Yegge. Beads. github.com/steveyegge/beads
wedow 2025wedow contributors. ticket. github.com/wedow/ticket
Dicklesworthstone 2024Dicklesworthstone. beads_viewer. github.com/Dicklesworthstone/beads_viewer