From 8f4194982e94c957bb9d1fba05116caa5d9df1a6 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 6 Jun 2026 12:52:27 +0200 Subject: [PATCH] docs(meta): rewrite ticket/decision command surface to pql (phase 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites the canonical command reference (.claude/rules/ticket-cli.md) and CLAUDE.md to the pql CLI: `pql ticket`/`pql plan`/`pql decisions` replace `tooling/db/ticket`, `sqlite-query`/`sqlite-exec`, and `tooling/db/decision`. Documents T-NNN ids, the markdown-sourced governance decision tree, the rebuildable changelog-backed pql.db, and labels-as-milestones (phase:4) in place of the removed milestone entity. Maps the old surface accurately: ticket new (positional type+title), show --with-context/--with-blockers, block --by / unblock --from, label add/remove, decisions claim/list/show/validate/sync, plan whatsnext/review/status. Behavioral/command cutover only — the legacy tooling/db/* and SR_DB_PATH stay as the rollback path until Phase 6. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/rules/ticket-cli.md | 111 +++++++++++++++++++++++++----------- CLAUDE.md | 32 ++++++----- 2 files changed, 96 insertions(+), 47 deletions(-) diff --git a/.claude/rules/ticket-cli.md b/.claude/rules/ticket-cli.md index dd8149c19..3a498798e 100644 --- a/.claude/rules/ticket-cli.md +++ b/.claude/rules/ticket-cli.md @@ -1,57 +1,102 @@ -# Ticket CLI +# Ticket & Decision CLI (pql) -**Use `tooling/db/ticket`** for all ticket operations. Never use `sqlite3` directly (crashes in Claude Code). +**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 -`ticket create` uses **positional** arguments for `type` and `title`. There is no `--title` flag. +`pql ticket new` uses **positional** arguments for `type` and `title`. There is no +`--title` flag. ```bash # CORRECT — type and title are positional -tooling/db/ticket create story "My ticket title" --description "Details here" --team server --priority low +pql ticket new story "My ticket title" --description "Details here" --team server --priority low -# WRONG — --title does not exist, gets absorbed into the title string -tooling/db/ticket create story --title "My ticket title" --description "Details here" -# Creates a ticket titled: "--title My ticket title" +# WRONG — --title is absorbed into the title string +pql ticket new story --title "My ticket title" ``` -## Full usage +## Tickets ```bash -# Create -tooling/db/ticket create [--parent N] [--priority P] [--decision D] [--team T] [--description TEXT] -# type: initiative | epic | story | task | bug -# priority: critical | high | medium | low +# 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 -tooling/db/ticket show <id> -tooling/db/ticket list [--milestone N] [--team T] [--status S] +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 -tooling/db/ticket assign <id> <agent> +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 -tooling/db/ticket deps <id> -tooling/db/ticket dep add <blocker_id> <blocked_id> -tooling/db/ticket dep rm <blocker_id> <blocked_id> +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 -# WIP -tooling/db/ticket wip +# Labels (also used as milestones — see below) +pql ticket label T-440 add phase:4 +pql ticket label T-440 remove phase:4 -# Milestones -tooling/db/ticket milestone list [--status S] -tooling/db/ticket milestone create <name> [--description TEXT] [--phase N] -tooling/db/ticket milestone link <ticket_id> <milestone_id> -tooling/db/ticket milestone unlink <ticket_id> <milestone_id> -tooling/db/ticket milestone complete <milestone_id> -tooling/db/ticket milestone show <milestone_id> -tooling/db/ticket milestone dep <blocker_id> <blocked_id> +# 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 + +```bash +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 + +```bash +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) +``` + +## Milestones → labels + +pql has **no milestone entity** (the legacy milestone subsystem was vestigial). Phase +gating is expressed with **labels**: the active phase is `phase:4`. + +```bash +pql ticket list --label phase:4 --unblocked # the kanban "what's ready in this phase" +pql ticket label T-950 add phase:4 # put a ticket in the phase ``` ## Key rules -- **Type and title are positional** — everything else is a flag -- **Quote the title** — always wrap in double quotes to handle spaces -- **Never use `sqlite3` CLI** — it crashes (std::bad_alloc). Use `tooling/db/sqlite-query` or `tooling/db/sqlite-exec` for raw SQL -- **Verify after create** — run `tooling/db/ticket show <id>` to confirm the title is clean -- **Milestones are many-to-many** — a ticket can be linked to multiple milestones via `milestone link` +- **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-NNN`** — `T-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 create** — `pql ticket show <id>` to confirm the title is clean. +- The legacy `tooling/db/*` CLI and `SR_DB_PATH` remain only as a migration rollback path + and are removed once the cutover is stable. diff --git a/CLAUDE.md b/CLAUDE.md index dc19a3179..ac05857b1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,7 +51,7 @@ Development follows a strict cascade. Each phase has a concrete deliverable. **D ## Work Modes ### Kanban mode (default) -Work flows continuously through milestones. `/whats-next` selects the next epic-sized batch from the dependency graph, refines ticket context via parallel Si agents, then activates a worktree. `/pr-process` (from worktree) and `/pr-review` (from main) handle the review cycle through Gitea PR comments. Milestones are many-to-many with tickets, can run in parallel, and can block other milestones. +Work flows continuously through the current phase. `/whats-next` selects the next epic-sized batch from the dependency graph (`pql ticket list --label phase:4 --unblocked`), refines ticket context via parallel Si agents, then activates a worktree. `/pr-process` (from worktree) and `/pr-review` (from main) handle the review cycle through Gitea PR comments. Phase gating is expressed with **labels** (`phase:4`), not a milestone entity — a ticket can carry several labels. ### Pair session Human and Claude work together interactively on a single task. No background agents, no autonomous work. Used for load-bearing architecture changes where the human needs to make judgment calls as the work progresses — not approve a finished result. @@ -74,28 +74,32 @@ Human and Claude work together interactively on a single task. No background age - **Never chain git commands** in a single Bash call (e.g. `git add ... && git commit ...`). Always run `git add` and `git commit` as **separate sequential Bash calls**. - **Stale git lock files:** If a `git` command fails with `index.lock: File exists`, you may remove the lock file at `.git/index.lock` (or `.git/worktrees/<name>/index.lock` if in a worktree). -### Database +### Planning store (pql) -The ticketing database (`settledreach.db`) is accessed via `SR_DB_PATH` env var (set in `.claude/settings.json`). A backup is committed to `docs/backups/settledreach.db.backup` via main only. +Tickets live in `.pql/pql.db`, rebuilt from the **git-tracked** `.pql/changelog/` (no +binary-DB backup ritual). 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 pre-commit hook auto-exports + stages the changelog. ### Before starting work -1. Check active work: `tooling/db/ticket list --status in_progress` -2. Check your ticket: `tooling/db/ticket show <id>` -3. Check dependencies: `tooling/db/ticket deps <id>` +1. Check active work: `pql ticket list --status in_progress` +2. Check your ticket: `pql ticket show T-<id> --with-context` +3. Check dependencies: `pql ticket show T-<id> --with-blockers` 4. Read relevant `governance/**/*.md` decision record(s) referenced in the ticket (`pql decisions show <id>`) 5. Background context: `docs/briefings/{your-name}.md`, `docs/discussions/` ### CLI tools -**Prefer CLI wrappers over raw SQL.** Never use the `sqlite3` CLI — it crashes in Claude Code (std::bad_alloc). Use the wrapper scripts instead. +**Use `pql`** for tickets and decisions. Never use the `sqlite3` CLI — it crashes in Claude Code (std::bad_alloc). | Tool | Command | Full reference | |------|---------|----------------| -| Tickets | `tooling/db/ticket list`, `show`, `create`, `assign` | `/ticket` skill | -| Milestones | `tooling/db/ticket milestone list`, `create`, `link`, `show` | `/ticket` skill | -| SQL queries | `tooling/db/sqlite-query "SELECT ..."` | — | -| SQL writes | `tooling/db/sqlite-exec "UPDATE ..."` | — | -| Decisions | `tooling/db/decision show`, `next`, `claim`, `check-dupes` | — | +| Tickets | `pql ticket list`, `show`, `new`, `status`, `assign`, `label` | `.claude/rules/ticket-cli.md`, `/ticket` skill | +| Planning | `pql plan whatsnext`, `review`, `status`, `board` | `.claude/rules/ticket-cli.md` | +| Decisions | `pql decisions show`, `list`, `claim`, `validate`, `sync` | `.claude/rules/ticket-cli.md` | +| Vault query | `pql query`, `search`, `backlinks`, `related`, `context` | — | + +Phase gating uses **labels** (`phase:4`), not a milestone entity: `pql ticket list --label phase:4 --unblocked`. ### Testing preferences @@ -129,8 +133,8 @@ The implant UI system — all diegetic neural overlay panels — lives at `clien ### File conventions - Decisions: records in `governance/{decisions,questions,rejected}/<domain>.md` (see `governance/README.md`; query via `pql decisions`) - Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected) -- **Claim IDs before writing:** `tooling/db/decision claim D <domain> "title"` — prevents ID collisions across parallel branches +- **Claim IDs before writing:** `pql decisions claim D <domain> "title"` — prevents ID collisions across parallel branches - Diagrams: `.d2` source + `.png` renders in `docs/diagrams/{category}/`. Create or update diagrams via `/d2-diagram` when D-records are added or modified. - Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete - Briefings: one per agent, updated after decision-producing rounds -- Tickets: managed via `tooling/db/ticket` CLI or `/ticket` skill +- Tickets: managed via `pql ticket`/`pql plan` CLI or `/ticket` skill (`T-NNN` ids)