Workflow overview¶
A small, opinionated issue tracker that lives in your repo and runs through
seven commands. The same commands work whether tickets are Markdown files
committed to the repo (filesystem backend) or GitHub issues (github
backend) — the choice lives in config.yaml, and every command delegates the
actual reads, writes, and stage transitions to the ticket-engine
skill.
The two bundles are functionally identical; only the invocation syntax
differs. Every page on this site uses the Claude Code form (/ticket:new) in
prose — use this table to translate:
| Step | Claude Code | Codex | Antigravity · Gemini CLI · Copilot |
|---|---|---|---|
| Bootstrap | /ticket:init |
$ticket-init |
/ticket-init |
| Create | /ticket:new |
$ticket-new |
/ticket-new |
| Refine inbox | /ticket:refine |
$ticket-refine |
/ticket-refine |
| Implement | /ticket:pick |
$ticket-pick |
/ticket-pick |
| Verify | /ticket:review |
$ticket-review |
/ticket-review |
| Send back | /ticket:reject |
$ticket-reject |
/ticket-reject |
| Ship | /ticket:close |
$ticket-close |
/ticket-close |
Stages and roles¶
Tickets move through configurable stages — e.g. inbox → backlog →
in-progress → review → done. Commands don't hard-code stage names; they
resolve roles (inbox, pickable, in_progress, review, terminal)
against whatever stages your config.yaml defines. pickable, in_progress,
and terminal are required; inbox and review are optional, and their
presence changes which commands are available and where flows exit:
- No
inboxrole →/ticket:refineis unavailable;/ticket:newalways commits straight to backlog (no "save as inbox" option). - No
reviewrole →/ticket:pickends directly inin_progressinstead of handing off to review;/ticket:rejectis unavailable;/ticket:closecloses fromin_progress.
stateDiagram-v2
[*] --> inbox: /ticket:new (save)
inbox --> backlog: /ticket:refine
[*] --> backlog: /ticket:new (full)
backlog --> in_progress: /ticket:pick
in_progress --> review: pick completes
review --> done: /ticket:close
review --> in_progress: /ticket:reject
in_progress --> done: /ticket:close (no review stage)
done --> [*]
The seven commands¶
| Command | What it does | Details |
|---|---|---|
/ticket:init |
Bootstrap a project: write config.yaml, create stage folders or labels, set up research agents, lay down a starter ticket template. One-time. |
→ |
/ticket:new |
Create one ticket — or a dependency-ordered slate — through a gated flow that reconciles intent with the assistant's understanding before anything commits. | → |
/ticket:refine |
Resume a captured inbox entry: promote to backlog, fold into another ticket, or close as wontfix. | → |
/ticket:pick |
Claim a backlog ticket and implement it through a bounded plan → implement → verify → evaluate loop, ending at review (or done, if no review stage). | → |
/ticket:review |
Print a read-only verification guide for a ticket in review. | → |
/ticket:reject |
Send a ticket that failed verification back to in-progress, with the reason recorded. | → |
/ticket:close |
Close a ticket as shipped, trusting you've already verified the work. | → |
Shared conventions¶
- Every command loads and validates
config.yamlfirst, via theticket-engineskill. If no config exists, the command stops and tells you to run/ticket:init. - Every user-facing decision point is an explicit gate — the
AskUserQuestiontool, with 2-4 concrete options and a recommended default first. Nothing destructive happens between gates. - Ticket data lives native, not in frontmatter, on GitHub. On the
filesystem backend, ticket files keep self-describing YAML frontmatter,
while graph data (
depends_on,related,milestone) lives in a machine-owned ledger (.ledger.yaml) beside the stage folders. On the GitHub backend, issues carry no frontmatter at all — dependencies are native issue dependencies, the claim clock is the assignment event, priority/effort/risk live as Project board fields (or labels), andtypemaps to native org issue types where available. - Optional GitHub Project (v2) board linkage.
/ticket:initcan link a project; from then on every ticket is added to it on creation with itsStatusfield synced to the workflow stage. The issue itself stays the source of truth for stage — a failed board update never blocks a transition.
Aligned by design¶
Ticket creation treats shared understanding as a first-class goal. After
analyzing the relevant code (and dispatching your research
agents), /ticket:new runs an
alignment-grilling pass — walking the decision tree branch by branch,
answering what it can from the codebase and asking you only the questions
that genuinely change scope, type, acceptance criteria, or size. Every answer
(and every silent default) is recorded in a ## Decisions & assumptions
section on the ticket, so whoever picks it up later sees the same reconciled
view you signed off on.