> ## 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.

# ticket-rs: A Git-Native, Graph-Aware Issue Tracker for the Agentic Development Era

> Dependency-aware issue tracking for the agentic coding era. Git-backed, graph-powered, zero daemons.

<Frame>
  <div style={{ display: 'flex', alignItems: 'center', gap: '16px', padding: '16px' }}>
    <img src="https://avatars.githubusercontent.com/u/61203850?v=4" alt="Henrik Albihn" style={{ width: '64px', height: '64px', borderRadius: '50%' }} />

    <div>
      <div style={{ fontWeight: 600, fontSize: '16px' }}>Henrik Albihn</div>
      <div style={{ color: '#666', fontSize: '14px' }}>Creator of ticket-rs</div>

      <div style={{ display: 'flex', gap: '12px', marginTop: '8px' }}>
        <a href="https://github.com/henrikalbihn" style={{ color: '#666' }}>GitHub</a>
        <a href="https://bsky.app/profile/henrik.sh" style={{ color: '#666' }}>Bsky</a>
      </div>
    </div>
  </div>
</Frame>

***

## 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–13 MB static binary (per target) 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:

```markdown theme={null}
---
status: open
type: feature
priority: 1
deps: [tk-abc123, tk-def456]
labels: [backend, auth]
estimated_minutes: 1440
---

# 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)$ where each vertex $v \in V$ is an issue and each directed edge $(u, v) \in E$ means issue $u$ must be completed before issue $v$ can begin.

```mermaid theme={null}
flowchart TB
    OAUTH["OAuth Setup\n<b>PageRank: 0.42 · Blocks 5</b>"]
    GH["GitHub OAuth"]
    GOOG["Google OAuth"]
    SSO["SSO Config"]
    SESSION["Session Mgmt"]
    MIDDLEWARE["API Auth Middleware"]

    OAUTH --> GH
    OAUTH --> GOOG
    OAUTH --> SSO
    GH --> SESSION
    GOOG --> SESSION
    SSO --> SESSION
    SESSION --> MIDDLEWARE

    style OAUTH fill:#d62922,stroke:#a92215,stroke-width:3px,color:#fff
    style GH fill:#cce5ff,stroke:#004085,stroke-width:2px,color:#1a1a2e
    style GOOG fill:#cce5ff,stroke:#004085,stroke-width:2px,color:#1a1a2e
    style SSO fill:#cce5ff,stroke:#004085,stroke-width:2px,color:#1a1a2e
    style SESSION fill:#fff3cd,stroke:#856404,stroke-width:2px,color:#1a1a2e
    style MIDDLEWARE fill:#e2e3e5,stroke:#6c757d,stroke-width:1px,color:#1a1a2e
```

*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)$ to each node via power iteration:

$$
r(v) = \frac{1 - d}{|V|} + d \sum_{u \in \text{In}(v)} \frac{r(u)}{|\text{Out}(u)|}
$$

where $d = 0.85$ is the damping factor, $\text{In}(v)$ is the set of issues that depend on $v$ (i.e., $v$ blocks them), and $\text{Out}(u)$ is the set of issues that $u$ 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)$ are surfaced by `tk priority`.

#### Betweenness Centrality

For each issue $v$, betweenness centrality is defined as:

$$
C_B(v) = \sum_{s \neq v \neq t} \frac{\sigma_{st}(v)}{\sigma_{st}}
$$

where $\sigma_{st}$ is the total number of shortest paths from issue $s$ to issue $t$, and $\sigma_{st}(v)$ is the number of those paths that pass through $v$. Issues with high $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|)$ via topological order dynamic programming:

$$
\text{dist}(v) = \max_{u \in \text{In}(v)} \left( \text{dist}(u) + w(u, v) \right)
$$

where $w(u, v)$ is the estimated duration of issue $u$. The critical path length is $\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 $B_1, B_2, \ldots, B_k$ such that all issues within a batch $B_i$ have their dependencies satisfied by issues in $\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.

```mermaid theme={null}
flowchart LR
    subgraph B1["Batch 1 — start immediately"]
        A["tk-001\nDatabase schema"]
        B["tk-002\nCI/CD setup"]
        C["tk-003\nDesign mockups"]
    end
    subgraph B2["Batch 2 — after Batch 1"]
        D["tk-004\nAPI endpoints"]
        E["tk-005\nUI components"]
    end
    subgraph B3["Batch 3 — after Batch 2"]
        F["tk-006\nIntegration tests"]
    end
    subgraph B4["Batch 4 — after Batch 3"]
        G["tk-007\nDeploy"]
    end

    A --> D
    C --> E
    D --> F
    E --> F
    F --> G

    style A fill:#d4edda,stroke:#28a745,color:#1a1a2e
    style B fill:#d4edda,stroke:#28a745,color:#1a1a2e
    style C fill:#d4edda,stroke:#28a745,color:#1a1a2e
    style D fill:#cce5ff,stroke:#004085,color:#1a1a2e
    style E fill:#cce5ff,stroke:#004085,color:#1a1a2e
    style F fill:#fff3cd,stroke:#856404,color:#1a1a2e
    style G fill:#f8d7da,stroke:#dc3545,color:#1a1a2e
```

*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 across a 500-issue repository, and under 10ms on a small (\~68-issue) one. An intelligent filesystem mtime-based cache—invalidated automatically on file create, delete, or modify—returns single-issue queries (`tk ready`, `tk show`) in under 5ms on cache hits. Cold computation (cache fully rebuilt before each invocation) completes in under 20ms even at 500-issue scale.

{/* Generated: 2026-02-12T06:29:39.402263+00:00*/}

| Implementation                           | Median Time | Speedup     |
| ---------------------------------------- | ----------- | ----------- |
| **ticket-rs** (Rust CLI (tk))            | **9.0ms**   | 6.2x faster |
| kardianos/ticket (Go trie YAML)          | 9.7ms       | 5.8x faster |
| nwiizo/vibe-ticket (Rust (archived))     | 16.2ms      | 3.5x faster |
| **ticket-py** (Python bindings via PyO3) | **24.3ms**  | 2.3x faster |
| wedow/ticket (Bash)                      | 35.1ms      | 1.6x faster |
| steveyegge/beads (Go daemon)             | 55.9ms      | 1.0x faster |
| steveyegge/beads (Go direct)             | 58.8ms      | 1.1x slower |

<Info>
  Benchmarks run with 500 tickets, 30 iterations.
  Data source: [benchmark-data.json](https://github.com/ticket-rs/ticket/blob/main/web/src/data/benchmark-data.json)
</Info>

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

<CardGroup cols={2}>
  <Card title="No Daemon" icon="ban">
    Every invocation reads `.tickets/`, computes, writes output, and exits. No background process persists.
  </Card>

  <Card title="No Database" icon="database">
    Storage is plain files. No schema migrations are ever required.
  </Card>

  <Card title="Stateless" icon="rotate">
    Commands are pure functions of the `.tickets/` directory state.
  </Card>

  <Card title="Cross-Platform" icon="globe">
    Native binaries for macOS (Apple Silicon + Intel), Linux (x86\_64 + ARM64), and Windows (x86\_64).
  </Card>
</CardGroup>

***

## 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.

<Info>
  **`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.
</Info>

**`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.

***

## Comparison to Related Work

### Design Lineage

`ticket-rs` sits at the end of a clear intellectual lineage:

```mermaid theme={null}
flowchart LR
    A["Erlang Ticket System\n1985 — Peter Högfeldt\nPlain text + CVS\nOne command: newticket"]
    B["Beads\n2025 — Steve Yegge\nSQLite + git\nAI-native CLI"]
    C["wedow/ticket\n2025\nMarkdown + YAML\nNo daemons"]
    D["ticket-rs\n2026 — this work\nMarkdown + YAML\n+ Graph analytics"]

    A -->|"MVP design\nprinciples"| C
    A -->|"git-backed\ninspiration"| B
    B -->|"AI-native\nconcept"| D
    C -->|"storage\narchitecture"| D

    style A fill:#e2e3e5,stroke:#6c757d,color:#1a1a2e
    style B fill:#fff3cd,stroke:#856404,color:#1a1a2e
    style C fill:#d4edda,stroke:#28a745,color:#1a1a2e
    style D fill:#d62922,stroke:#a92215,color:#fff
```

**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.

**2025 — 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

| Tool                  | Storage            | Graph analytics | Offline | Token-efficient | Zero daemon |
| --------------------- | ------------------ | --------------- | ------- | --------------- | ----------- |
| Erlang tickets (1985) | Plain text + CVS   | No              | Yes     | Yes             | Yes         |
| GitHub Issues         | Remote DB          | No              | No      | No              | N/A         |
| Linear                | Remote DB          | Partial         | No      | No              | N/A         |
| Jira                  | Remote DB          | No              | No      | No              | N/A         |
| Beads                 | SQLite + git       | Basic           | Yes     | Partial         | No          |
| wedow/ticket          | Markdown files     | No              | Yes     | Yes             | Yes         |
| **ticket-rs**         | **Markdown files** | **Yes**         | **Yes** | **Yes**         | **Yes**     |

***

## Limitations and Future Work

<Warning>
  `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.
</Warning>

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

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