Files
settled-reach/.claude/rules/ticket-cli.md
T
jpmschweitzerandClaude Opus 4.8 a46946e2ac docs(meta): read the pql skill before non-trivial planning-store ops
settled-reach is always a pql repo, so make the rule repo-canonical (CLAUDE.md +
ticket-cli.md): routine ticket/decision CLI is covered by the rules, but the
load-bearing model lives only in the pql skill — changelog is write-through (never
git-restore it), `export` doesn't replicate ticket_idmap, post-checkout rebuilds
pql.db from the changelog, so cross-branch planning moves must re-create via
`pql ticket`, not changelog surgery. Back up pql.db before risky ops.

The clide-side equivalent (read the clide skill when running inside clide) is an
editor choice, not a repo property — it belongs in a clide-owned SessionStart hook,
not here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 08:15:23 +02:00

6.3 KiB

Ticket & Decision CLI (pql)

Use pql for all ticket and decision operations. Tickets live in .pql/pql.db (rebuildable from the git-tracked .pql/changelog/); decisions are markdown-sourced under governance/{decisions,questions,rejected}/ and synced into the same DB.

Ticket ids are T-NNN (T-440 == legacy #440). The legacy tooling/db/ticket

  • sqlite-query/sqlite-exec path is retired — do not use it, and never invoke the sqlite3 CLI (it crashes in Claude Code).

Positional arguments — not flags

pql ticket new uses positional arguments for type and title. There is no --title flag.

# CORRECT — type and title are positional
pql ticket new story "My ticket title" --description "Details here" --team server --priority low

# WRONG — --title is absorbed into the title string
pql ticket new story --title "My ticket title"

Tickets

# Create  (type: initiative|epic|story|task|bug ; priority: critical|high|medium|low)
pql ticket new <type> <title> [--parent T-N] [--priority P] [--decision D-NNN] [--team T] [--description TEXT] [--assign agent] [--id-only]

# Read
pql ticket show T-440 [--with-context] [--with-children] [--with-blockers] [--tree] [--depth N]
pql ticket list [--status S] [--team T] [--label L] [--assigned A] [--decision D-NNN] \
                [--unblocked] [--leaf] [--under T-N]
pql ticket board [--team T]                 # kanban view

# Update
pql ticket status T-440 in_progress         # backlog|ready|in_progress|review|done|cancelled
pql ticket assign T-440 dudley
pql ticket team   T-440 server
pql ticket setparent T-9 T-2                 # (clear with no parent arg)
pql ticket append T-440 "extra context"      # also --file PATH / --stdin

# Dependencies
pql ticket show T-440 --with-blockers         # what blocks this
pql ticket block   T-7 --by T-440             # T-440 blocks T-7
pql ticket unblock T-7 --from T-440           # remove that edge

# Labels  (action is add | rm)
pql ticket label T-440 add needs-refinement
pql ticket label T-440 rm  needs-refinement

# Refinement (tickets with no description are "unrefined")
pql ticket refine list
pql ticket refine next [--skip N]
pql ticket refine write T-5 '{"description":"..."}'

Most subcommands batch with comma-separated ids: pql ticket status T-1,T-2,T-3 done.

Planning dashboard

pql plan status        # decision counts, open questions, ticket summary
pql plan whatsnext     # next ticket to work on
pql plan review        # next ticket awaiting review
pql plan export        # flush ticket mutations to .pql/changelog/ (--stage to git-add)
pql plan import        # replay changelog into pql.db (post-merge)
pql plan rebuild       # drop + replay changelog from scratch (post-checkout/rewrite)

Decisions

pql decisions claim D <domain> "title"   # next free id, no side effects (D | Q | R)
pql decisions list [--type confirmed|question|rejected] [--domain X]
pql decisions show D-010 [--with-tickets]
pql decisions read D-238                   # full markdown body
pql decisions refs D-010                    # cross-references
pql decisions sync                          # parse governance/*.md -> pql.db
pql decisions validate                      # malformed-record gate (pre-commit)

Phases → the cascade hierarchy (no milestone entity)

pql has no milestone entity (the legacy one was vestigial). Phase gating is the ticket hierarchy: the initiative T-745 (Development Cascade) holds the six phases as epics; a ticket is in a phase by being parented under that phase epic — self-maintaining, no label to apply or forget. The active phase is the phase epic with status in_progress (sequential per D-166 → the lowest-numbered non-done phase epic; currently T-750, Phase 4).

pql ticket list --under T-750 --unblocked        # the kanban "what's ready in this phase"
pql ticket setparent T-990 T-750                  # put a ticket in the phase (re-parent)
pql ticket show T-745 --tree                      # the whole cascade

Key rules

  • Type and title are positional on pql ticket new — everything else is a flag.
  • Quote the title — wrap in double quotes to handle spaces.
  • Ids are T-NNNT-N == legacy #N. PR numbers (PR #138) are a separate namespace.
  • Don't hand-edit .pql/pql.db — it's rebuildable. Mutations go through pql ticket …; the pre-commit hook exports + stages .pql/changelog/ automatically.
  • Verify after createpql ticket show <id> to confirm the title is clean.
  • The legacy tooling/db/{ticket,decision,sqlite-*} CLI, SR_DB_PATH, and the committed settledreach.db backup were removed in Phase 6 of the migration. The live settledreach.db file (gitignored, repo-parent) is left on disk as a cold rollback only.

Changelog & planning-store safety (read the pql skill first)

Routine ticket/decision CLI is covered above. For anything non-routine — hand-touching .pql/changelog/, moving planning across branches, or recovering a broken store — load the pql skill (Skill(pql)) before acting. The load-bearing model is not obvious and is easy to corrupt:

  • The changelog is write-through, not a cache. pql ticket/pql decisions mutations write .pql/changelog/ synchronously. Never git restore, git checkout --, or hand-edit the changelog to "reset" it — you are deleting real data, and it is the git-tracked source of truth (pql.db is gitignored and rebuilt from it).
  • pql plan export does NOT replicate ticket_idmap (only tickets/deps/labels/history). So once you discard write-through rows, export cannot regenerate the human T-NNNrecord_id mapping — a rebuild then loses or reassigns ids.
  • post-checkout/post-rewrite rebuild pql.db from the target branch's changelog (pql plan rebuild). So a branch switch is governed by the changelog, not the live DB — uncommitted DB-only mutations are dropped on switch.
  • Therefore: move planning across branches by re-creating via pql ticket (write-through repopulates everything, idmap included), not by copying/restoring changelog files.
  • Back up .pql/pql.db before any risky planning-store operation (cp .pql/pql.db /tmp/pql_backup.db) and verify with a pql plan rebuild + pql ticket show <id> after.