Metadata-Version: 2.5
Name: ticketwright
Version: 4.7.0
Summary: Ticket-driven analysis for Claude Code and other coding agents: prior work recalled, every result re-run and signed off, and a self-maintaining ticket index. Stdlib-only.
Project-URL: Homepage, https://github.com/kyle-chalmers/ticketwright
Project-URL: Repository, https://github.com/kyle-chalmers/ticketwright
Project-URL: Documentation, https://github.com/kyle-chalmers/ticketwright/blob/main/docs/README.md
Project-URL: Changelog, https://github.com/kyle-chalmers/ticketwright/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/kyle-chalmers/ticketwright/issues
Project-URL: Security, https://github.com/kyle-chalmers/ticketwright/blob/main/SECURITY.md
Author: Kyle Chalmers
License: MIT
License-File: LICENSE
Keywords: analytics,claude-code,jira,linear,qc,recall,snowflake,ticket-index,tickets,workflow
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: build>=1; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: twine>=5; extra == 'dev'
Description-Content-Type: text/markdown

<!-- markdownlint-disable MD033 MD041 -->
![Ticketwright: the Claude Code plugin for ticket-driven analysis. Prior work recalled, every result reviewed, nothing sent without your go-ahead. A KC AI Labs project.](https://raw.githubusercontent.com/kyle-chalmers/ticketwright/main/docs/images/banner.png)

<div align="center">

[Get started](#get-started) · [Try it](#try-it) · [Skills](#the-skills) · [Safety](#safety-rails) · [Data and network](#data-and-network) · [Docs](docs/README.md) · [Changelog](CHANGELOG.md)

[![CI](https://github.com/kyle-chalmers/ticketwright/actions/workflows/ci.yml/badge.svg)](https://github.com/kyle-chalmers/ticketwright/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/ticketwright?label=pypi&color=c4ff00&labelColor=030303)](https://pypi.org/project/ticketwright/) [![Claude Code plugin](https://img.shields.io/badge/Claude%20Code-plugin-c4ff00?labelColor=030303)](#get-started) [![Python 3.9+, stdlib only](https://img.shields.io/badge/python-3.9%2B%20%C2%B7%20stdlib%20only-c4ff00?labelColor=030303)](pyproject.toml) [![License: MIT](https://img.shields.io/badge/license-MIT-c4ff00?labelColor=030303)](LICENSE)

</div>

![A rendered walkthrough of one ticket in a Claude Code chat. /ticket opens TEST-130, ranks bob's TEST-118 as the closest prior work, writes the plan and waits for approval. /build runs the plan. /review walks the validation pyramid (dialect lint, counts and duplicates, reconciliation, an independent re-run) to the person's sign-off and an APPROVE. /ship shows its delivery plan and stops until the person says go ahead, then files the ticket into the team index.](https://raw.githubusercontent.com/kyle-chalmers/ticketwright/main/docs/images/demo.gif)

<sub>A rendered walkthrough drawn from the skills' own wording, not a screen recording.</sub>

**Ticketwright is a Claude Code plugin for teams whose work product is an answer.** Every ticket
follows the same five phases, every result is re-run and signed off before it ships, and every
finished ticket is filed where the next person or agent can find it.

> **Quick start.** Open your coding agent (Claude Code, Codex, Cursor and others) in your team's
> ticket repo and say:
>
> *"Read the install prompt in github.com/kyle-chalmers/ticketwright and follow it."*
>
> Prefer typing the steps? See [Get started](#get-started).

## Mission

**Ticketwright empowers a team to do a high volume of analysis without letting quality slide, on whatever tools they already use.**

## Vision

**Any new or experienced member can pick up any analysis and be productive the same day, because the team's past work is written down and organized, and AI can trace it.**

**This is for you if:**

- ✅ you're an analytics, BI, ops or reporting team closing many tickets a week
- ✅ you want every number re-run and signed off before it leaves
- ✅ you want past work to surface when a similar ticket arrives
- ✅ you want to keep your tracker, warehouse, chat and drive
- ❌ you ship software features, or want an agent that posts on its own

## What it builds: a team brain

Every ticket lands in one folder with its business context, written assumptions, QC verdict and
deliverables. An auto-maintained catalog (`tickets/INDEX.md`) and object map (`tickets/OBJECTS.md`)
make that history searchable by people and agents, so `/ticket` opens new work with the closest
prior work ranked. Details: [docs/how-it-works.md](docs/how-it-works.md).

![How /ticket finds prior work. Each past ticket folder becomes a card: the model writes the summary, tags and links, and a scan finds the tables in the SQL. Plain code scores the new ticket, TEST-130, against every card: a shared table scores 4 (rarer tables count more), a shared tag 3, a link between the two tickets 5, and each shared word 1, up to 6. Recency only breaks ties. Here bob's TEST-118 ranks first at 9.0 (a shared table, a shared tag and 2 words), ahead of alice's TEST-127 at 4.0 and bob's TEST-94 at 1.0, so the verdict is strong. The model reads the top 2 to 4 and writes the reuse brief, and you approve the plan. When the match is weak or missing, you choose whether to search older tickets in your tracker; they are scored the same way and labeled as having no folder or QC record here. That branch is drawn as if asked for, since a strong match like this one never offers it. Once shipped, TEST-130 becomes a card too.](https://raw.githubusercontent.com/kyle-chalmers/ticketwright/main/docs/images/recall.png)

## The lifecycle is the map

![The Ticketwright lifecycle. The team brain (tickets/, INDEX.md, OBJECTS.md) feeds the closest prior work into five phases: 1 Open the work (/ticket), 2 Do the work (/build), 3 Quality-check (/review), 4 Deliver (/ship) and 5 Announce (/ship). You approve the plan, sign off the numbers, and say go ahead before anything is sent. Each shipped ticket is filed back into the brain with its assumptions and QC verdict. Hooks ask first before destructive warehouse SQL, a push with no approving review, or a raw transcript being committed or backed up.](https://raw.githubusercontent.com/kyle-chalmers/ticketwright/main/docs/images/lifecycle.png)

Quality checking has no slot of its own: `/review` borrows the warehouse to re-run your queries,
then a person signs off. Skills speak to tool slots, never to a vendor, so swapping a tool is one
config line and one adapter file:

![Skills (/ticket, /build, /review, /ship) call verbs such as fetch_ticket, query, backup, draft and commit. stack.yaml names which tool fills each slot, adapters map each verb to the tool's real command, and your tools do the work: tracker, warehouse, chat, docs, meetings and git.](https://raw.githubusercontent.com/kyle-chalmers/ticketwright/main/docs/images/tool-slots.png)

| Tool slot | Works with |
|---|---|
| Tracker | Jira (`acli` optional), Azure DevOps, Linear, Asana, Monday, GitHub Issues, or none (`id_mode: slug`) |
| Warehouse | Snowflake, BigQuery, Databricks, Postgres, Redshift, Synapse, or none |
| Chat | Slack, Teams, Gmail, Outlook |
| Docs | Google Drive, SharePoint, or Dropbox/S3/Box through rclone |
| Meetings | Zoom, Fireflies, Granola, Teams, Notion (optional) |
| Git | GitHub, GitLab, Azure Repos |

Another tool is [one more adapter file](adapters/README.md).
Desktop-sync backup needs one local step: [docs/drive-mount.md](docs/drive-mount.md).

## Try it

Plain requests work too:

```text
/ticketwright:ticket TEST-130
    Open the ticket, load its context and the closest prior work, write the plan, wait for my OK.

/ticketwright:ticket --recall --object RETURNS
    Which past tickets touched the RETURNS table, and what can I reuse?

/ticketwright:review --deep
    Re-check this ticket's numbers with one independent reviewer per validation layer.

/ticketwright:ship
    Show me exactly what will be sent and where, then wait for "go ahead".

What did we learn last time someone measured late orders by region?
```

## The skills

```
/ticket <id>        opens or resumes the ticket, auto-loads its context + closest prior work,
                    writes the plan (and the spec when the plan calls for one), and waits for
                    your approval before anything is built ↓
/build              starts on your approval (subagents build the bigger tickets), runs /review,
                    asks before /ship, and replans with you when the review finds the plan was wrong
/review [--deep]    the independent QC pass /build runs for you: re-runs queries, walks the validation
                    pyramid → APPROVE / REQUEST-CHANGES; run it directly to re-check or go --deep
                    …and at the top of that pyramid, opens the deliverables in YOUR apps and waits
/ship [--go]        PR → merge (asks first) → backup → comment → chat draft, a HARD HALT before anything
                    external; warns, waits for a typed `ship unreviewed`, and records it when no
                    review verdict is on file
/setup              configure once, or onboard a teammate
/refresh            rebuild the catalog
/skillify           turn a recurring workflow into its own skill
```

On a plugin install, prefix each one: `/ticketwright:ticket`.

## What a working repo looks like

`/setup` writes the top half; the `tickets/` half grows as the team works.

```
your-repo/
├── AGENTS.md                  # team rules, read by people and agents alike
├── CLAUDE.md                  # one line: @AGENTS.md
├── bin/tw                     # launcher that finds the installed kit
├── .claude/config/
│   ├── stack.yaml             # which tool fills each slot, plus team policies
│   └── connections.local.yaml # your machine only (gitignored)
├── people/
│   ├── alice.yaml             # one file per teammate: identities, viewer, voice
│   └── bob.yaml
├── documentation/             # the domain knowledge pack
└── tickets/
    ├── INDEX.md               # every owner's tickets in one catalog      (auto)
    ├── OBJECTS.md             # table or view -> tickets that touched it  (auto)
    ├── graph/  objects/       # Obsidian nodes for tickets and tables     (auto)
    ├── bob/
    │   └── TEST-118/          # returns baseline, shipped last month
    └── alice/
        ├── TEST-127/          # shipped
        └── TEST-130/          # in progress, builds on bob's TEST-118
            ├── README.md              /ticket   business context, every assumption
            ├── plan.md                /ticket   the plan you approved
            ├── specs/                 /ticket   the spec, when the plan calls for one
            ├── source_materials/      /ticket   attachments, curated meeting notes
            ├── exploratory_analysis/  /build    scratch queries, kept for the record
            ├── final_deliverables/    /build    01_returns_by_region_1284rows.sql + .csv
            ├── qc_queries/            /build    numbered checks, then /review's verdict
            └── delivery-plan.yaml     /ship     who received it, and where
```

Alice's TEST-130 cites Bob's TEST-118, so her reviewer can trace the numbers back to his.

## Install with your coding agent

<details>
<summary><b>Show the install prompt</b></summary>

```text
Install Ticketwright (https://github.com/kyle-chalmers/ticketwright) for me at the
project level: for this repo only, never at the user level or with --global. Confirm
with me before installing anything, ask me each setup question yourself and wait for
my answer (never answer one for me), and show me the file list before committing.

1. Work in the git repo where my team keeps its ticket work. Ask me which folder if
   unsure; if it is new, create it and run `git init`. Run every command below from
   its root.

2. If you are Claude Code: run
   `claude plugin marketplace add https://github.com/kyle-chalmers/ticketwright.git --scope project`
   and then `claude plugin install ticketwright@ticketwright --scope project`. Both
   record the plugin in this repo's .claude/settings.json, not my user settings. If
   either fails, run `python3 ~/.claude/plugins/marketplaces/ticketwright/bin/plugin_doctor.py`
   (on disk once the marketplace is added) and follow its fixes in order. Then tell me
   to run `/reload-plugins` (or fully quit and relaunch the app; a new chat is not a
   restart), then `/ticketwright:setup`, or `/ticketwright:setup --teammate` if the
   repo already has .claude/config/stack.yaml. Stop there; setup does the rest.

3. Any other agent: with Python 3.9 or newer, run `pip install ticketwright`, then
   `ticketwright init`, then `ticketwright install --runtime <name>`, where <name> is
   codex-cli, cursor, opencode, cline, devin or antigravity. Tell me plainly that
   /setup runs only in Claude Code, so here the config is written by hand. If the repo
   has no .claude/config/stack.yaml, offer to draft it with me from
   .claude/config/stack.schema.md and the closest .claude/config/stack.example.*.yaml,
   asking me which tool fills each slot, then check it with
   `bash bin/verify_stack.sh .claude/config/stack.yaml --dry-run`.

Rules: never ask me for a password, token or key in chat; I sign in to each tool
myself. While installing, run no warehouse SQL and post nothing to my tracker or chat.
```

</details>

## Get started

Install project-scoped, from the root of your ticket repo, so the whole team runs one version:

```bash
claude plugin marketplace add https://github.com/kyle-chalmers/ticketwright.git --scope project
claude plugin install ticketwright@ticketwright --scope project
```

Run `/reload-plugins` (or fully quit the app), then `/ticketwright:setup`, which interviews you
before writing anything. Step by step: [docs/getting-started.md](docs/getting-started.md).
Upgrading: [uninstall, install, relaunch](docs/troubleshooting.md#upgrading).

### Other coding agents

From PyPI, for Codex, Cursor, OpenCode, Cline, Devin and Antigravity:

```bash
pip install ticketwright
ticketwright init                         # copy the kit into this repo
ticketwright install --runtime codex-cli  # write the skills where your agent reads them
```

`/setup` runs only in Claude Code, so elsewhere you write the config yourself, and the guards are proven only in Claude Code. Details:
[docs/runtimes.md](docs/runtimes.md) and
[installing without the plugin](docs/getting-started.md#installing-without-the-plugin).

## Safety rails

- Destructive warehouse SQL run through a CLI asks first, even hidden in a `-f` file; verifiably
  read-only SQL runs without a prompt.
- `/ship` stops before any external post and shows exactly what it will send.
- Pushing deliverables with no approving review on file asks first.
- Committing or backing up a raw meeting transcript asks first.

Hooks fail open, never loosen your own deny rules, and see shell commands only, so SQL sent
through an MCP tool falls under that tool's permissions. All of them:
[docs/how-it-works.md](docs/how-it-works.md#hooks-in-full).

## Data and network

No telemetry, and no service of its own: Ticketwright's own code makes no network calls.
Installing fetches it from GitHub or PyPI; everything else goes through tools you configured,
under your own sign-in.

- **Your coding agent.** What the skills read (ticket text, query results, notes, team docs you link) goes to your
  agent's model provider under your account's terms, as does the ticket text
  `ticketwright enrich` sends to the model command you configure, and up to three older tracker
  tickets it summarizes.
- **Your tools, named in `stack.yaml`.** `/ticket` reads the ticket and, on your yes, searches
  your tracker's older tickets. `/build` and `/review` query the warehouse; `/ship` backs up,
  comments, drafts the chat message (sent only on "send it") and opens and merges a pull request.
- **Local reads.** Hooks read the repo, any `-f` SQL file a command names, your viewer and people
  config, and Claude Code's `installed_plugins.json`. They write nothing outside the repo.
- **Committed by default:** ticket folders, deliverable CSVs and voice profiles. Raw transcripts
  and `*.private.csv` files are not.

Full statement: [PRIVACY.md](PRIVACY.md).

## See it as a graph (Obsidian)

The index also writes `tickets/graph/` and `tickets/objects/`: open the repo as an Obsidian vault
to see which tickets touched which tables ([docs/obsidian.md](docs/obsidian.md)).

## Learn more

- [docs/README.md](docs/README.md): every doc, grouped by what you're trying to do
- [docs/how-it-works.md](docs/how-it-works.md): the lifecycle, voice profiles, every hook
- [docs/architecture.md](docs/architecture.md): adapters, the verb contract, adding a tool
- [docs/obsidian.md](docs/obsidian.md) and [docs/drive-mount.md](docs/drive-mount.md)
- [CONTRIBUTING.md](CONTRIBUTING.md) · [ROADMAP.md](ROADMAP.md) · [CHANGELOG.md](CHANGELOG.md)

## Support and security

Questions and bugs: [SUPPORT.md](SUPPORT.md). Vulnerabilities, privately: [SECURITY.md](SECURITY.md).
Everyone taking part follows the [Code of Conduct](CODE_OF_CONDUCT.md).

## License

MIT, see [`LICENSE`](LICENSE). A [KC AI Labs](https://kclabs.ai) project by Kyle Chalmers, not
affiliated with Anthropic or any vendor named above.
