ticket-worker

Garbage in, garbage out.
Your AI is only as good as your tickets.

Every failed generation, every "that's not quite right," every wasted API call traces back to the same problem: you gave the AI garbage input and expected magic.

Here's what we figured out
The insight

Good input, good output. It's always been this simple.

The problem isn't AI capability. Claude can write code, analyze systems, generate tests. The models are good enough.

The problem is you're skipping the hard part: figuring out exactly what you want.

A vague prompt produces vague output. A well-structured ticket with clear acceptance criteria? That produces code you can actually ship.

The foundation

Documentation for machines, not humans.

Every time an AI works on your code, it wastes tokens exploring. What if it already knew your patterns, your gotchas, your architecture? That's .llm-docs/—documentation optimized for LLMs, not us silly humans.

See how it works →
idea
/create-ticket
ticket-worker
PR

Two phases. Thinking, then doing.

Phase 1

Structure the work

Claude Code /create-ticket

Before any code gets written, Claude helps you think through what you actually need. It asks the questions you'd skip. It finds the edge cases. It creates a ticket worth executing.

$ claude /create-ticket
What problem are you solving?
Who's affected?
What does "done" look like?
# Creates GitHub issue with
# acceptance criteria, labels,
# dependencies, sub-issues
Phase 2

Execute autonomously

ticket-worker

Point it at your backlog. It reads the ticket, writes the code, runs your tests, opens a PR. No babysitting. No "can you try again." It just works through the queue.

$ ticket-worker
Loading tickets...
Starting: Add CSV export #47
Running tests... passed
PR opened: #48
Next: Fix auth timeout #49
What you get

PRs that actually get merged

Because the input was right, the output is right.

CI runs locally first

Parses your GitHub Actions workflows and runs the same checks before opening a PR. If it fails locally, it fixes it—or doesn't waste your time with a broken PR.

Acceptance criteria verified

Before opening a PR, it reviews each acceptance criterion and confirms it was actually met. No more "done" that isn't done.

Stacks on in-review work

Blocked by a PR that's still in review? It branches from that PR and keeps going. No waiting for merges.

Commits on failure

When something breaks, it commits the work-in-progress with full context. You can see exactly what was done and resume from there.

Continuous mode

Runs all night. Merges approved PRs automatically, pulls latest main, moves to the next ticket. Wake up to a cleared backlog.

Gets smarter over time

Accumulates context from completed work and updates your .llm-docs/ after each ticket. The more it does, the better it gets.

01

The bottleneck was never AI capability. It's always been clarity of intent.

02

Thinking and doing are different modes. Trying to do both at once is why one-shotting fails.

03

Automation without structure is just faster chaos. Process isn't overhead. It's leverage.

Why this exists

I kept blaming the AI.

"It doesn't understand the codebase." "It missed the edge case." "It's not quite right."

Then I looked at my tickets. Really looked. And realized: I'd never actually said what I wanted. I'd been writing for developers who'd fill in the gaps, ask questions, course-correct as they went. AI doesn't do that. It follows instructions.

After twenty years of shipping software, I finally saw the job split in two:

Thinking stays human. Not just the what and why—but evaluating the approach, catching bad assumptions before execution, knowing when to redirect. That's judgment.
Typing goes to AI. The code, the tests, the commits. Precise execution of clear instructions.

ticket-worker is built for this split. You think. You evaluate. AI executes.

— Robert Beene

Get started

Three commands

Select a ticket. Press enter. Review the PR when it's ready.

$ pip install ticket-worker
$ cd your-repo
$ ticket-worker
Python 3.12+ / Uses your Anthropic account via Claude Code