docs(skills): cut workflow skills over to pql (phase 4)

Repoints the kanban workflow skills from tooling/db/* to the pql CLI:

- /whats-next: milestone queries -> `pql ticket list --label phase:4 --unblocked`
  (--unblocked does the dependency walk, collapsing the old milestone + per-ticket
  deps + milestone_deps steps); WIP via `pql ticket list --status in_progress` (pql
  doesn't enforce the limit — warn manually); refinement append via `pql ticket append`;
  activation via `pql ticket status`.
- /ticket: full reference rewritten to `pql ticket`/`pql plan`; milestone subcommands
  -> phase labels; points at .claude/rules/ticket-cli.md.
- /pr-process: step 8 extracts T-NNN (maps bare #NNN -> T-NNN) and calls
  `pql ticket status T-<id> review`.
- /bug-report: bug creation via `pql ticket new bug`.
- clerk: decisions-sync mechanism line -> `pql decisions sync` (factual fix only; the
  agent's review logic stays for the #965 re-enable).
- workshop-start IMPROVEMENTS: the old `decision claim` non-idempotency footgun no
  longer applies — `pql decisions claim` is side-effect-free.

pr-review/git-commit needed only the Phase-1 path repoint (no command refs); the
settledreach.db.backup exclusion in pr-review stays until Phase 6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 12:57:58 +02:00
co-authored by Claude Opus 4.8
parent 8f4194982e
commit 64be267249
6 changed files with 89 additions and 127 deletions
+1 -1
View File
@@ -39,4 +39,4 @@ When spawned manually for an audit:
## Project context
Read `governance/README.md` for the domain index. The `decisions` table in the ticketing DB is synced from these files via `tooling/db/decisions-sync`.
Read `governance/README.md` for the domain index. The `decisions` table in `.pql/pql.db` is synced from these files via `pql decisions sync`.
+2 -2
View File
@@ -166,10 +166,10 @@ nature of the bug:
issues)
Construct the ticket title and description from the report summary and any
investigation findings. Use the ticket CLI:
investigation findings. Use the pql CLI:
```bash
tooling/db/ticket create bug "{title}" --team {team} --description "{description}"
pql ticket new bug "{title}" --team {team} --description "{description}"
```
The description should include:
+5 -4
View File
@@ -328,17 +328,18 @@ Report PR URL when done.
### 8. Update ticket status to review
Scan all commit messages in the PR for ticket references (`#NNN`):
Scan all commit messages in the PR for ticket references. Commits use either the
`T-NNN` convention or the legacy `#NNN` (which is numerically identical — `#440 == T-440`):
```bash
git log --oneline main..<branch>
```
Extract ticket IDs from `#NNN` patterns. For each ticket that is
currently `in_progress`, update it to `review`:
Extract ticket ids from `T-NNN` / `#NNN` patterns (map a bare `#NNN` to `T-NNN`).
For each ticket currently `in_progress`, update it to `review`:
```bash
tooling/db/ticket status <id> review
pql ticket status T-<id> review
```
Report which tickets were moved to review. Skip tickets that are
+41 -57
View File
@@ -1,93 +1,77 @@
---
name: ticket
description: >
Manage project tickets and milestones in the SQLite ticketing database. Use
when the user says "ticket", "create a ticket", "show tickets", "milestone",
or invokes /ticket. Wraps the ticket CLI for structured project management.
Manage project tickets in the pql planning store. Use when the user says
"ticket", "create a ticket", "show tickets", "board", "phase", or invokes
/ticket. Wraps the pql CLI for structured project management.
user-invocable: true
allowed-tools: Bash, Read, Grep, Glob
---
# Ticket Skill
Manage the project ticketing database. Basic usage is in CLAUDE.md's CLI tools
section. This skill covers the full command reference.
Manage tickets via **pql** (`.pql/pql.db`, rebuilt from the git-tracked
`.pql/changelog/`). Ids are `T-NNN` (`T-440 == legacy #440`). Full command reference:
`.claude/rules/ticket-cli.md`.
## Commands
### List tickets (full flags)
### List / browse
```bash
tooling/db/ticket list [--status S] [--priority P] [--epic N] [--milestone N] [--assigned A] [--team T]
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, grouped by status
pql ticket show T-440 [--with-context] [--with-children] [--with-blockers] [--tree]
pql ticket show T-1,T-2,T-3 # batch
```
(pql ticket `list` has no `--type`/`--priority` filter — list and read the JSON, or use
`--under <epic>` for an epic's subtree.)
### Create ticket
### Create
```bash
tooling/db/ticket create <type> <title> [--parent N] [--priority P] [--decision D] [--team T] [--description TEXT]
pql ticket new <type> <title> [--parent T-N] [--priority P] [--decision D-NNN] [--team T] [--description TEXT] [--assign A]
```
Types: `initiative`, `epic`, `story`, `task`, `bug`
Priorities: `critical`, `high`, `medium`, `low`
Types: `initiative`, `epic`, `story`, `task`, `bug`. Priorities: `critical`, `high`, `medium`, `low`.
### Update status
### Update
```bash
tooling/db/ticket status <id> <new_status>
tooling/db/ticket done <id> [<id> ...]
pql ticket status T-440 in_progress # backlog|ready|in_progress|review|done|cancelled (batch with commas)
pql ticket assign T-440 dudley
pql ticket team T-440 server # comma teams allowed: server,client
pql ticket setparent T-9 T-2
pql ticket append T-440 "extra context" # --file PATH / --stdin
pql ticket label T-440 add|remove <label>
```
Statuses: `backlog`, `ready`, `in_progress`, `review`, `done`, `cancelled`
### Assignment
```bash
tooling/db/ticket assign <id> <agent>
tooling/db/ticket unassign <id>
```
### Team assignment
```bash
tooling/db/ticket team <id> <teams>
```
Teams are comma-separated, e.g. `server`, `client`, `server,client`.
### Dependencies
```bash
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
```
### WIP
### Phases (labels, not a milestone entity)
```bash
tooling/db/ticket wip
pql ticket list --label phase:4 --unblocked # ready work in the active phase
pql ticket label T-950 add phase:4
```
### Milestones
### Refinement & planning
```bash
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>
```
### Search and browse
```bash
tooling/db/ticket search <keyword>
tooling/db/ticket epics [--status S]
tooling/db/ticket children <id>
tooling/db/ticket count [--status S]
```
### Batch show
```bash
tooling/db/ticket show --brief <id> [<id>...]
pql ticket refine list # tickets with no description
pql ticket refine next [--skip N]
pql ticket refine write T-5 '{"description":"..."}'
pql plan whatsnext # next ticket to work on
pql plan review # next ticket awaiting review
pql plan status # decision + ticket dashboard / counts
```
## Workflow
1. Decisions from `governance/` domain files become **initiatives**
1. Decisions from `governance/` records become **initiatives**
2. Initiatives break into **epics** (major work areas)
3. Epics break into **stories** (user-facing deliverables)
4. Stories break into **tasks** (concrete work items)
5. **Milestones** group tickets by deliverable (many-to-many via `milestone link`)
6. `/whats-next` selects the next batch from the dependency graph
7. Track history via `ticket_history` table for audit trail
5. **Phase gating** is expressed with labels (`phase:4`), not a milestone entity
6. `/whats-next` selects the next batch via `pql ticket list --label phase:4 --unblocked`
7. Mutations flow to the git-tracked `.pql/changelog/`; the pre-commit hook exports + stages it
+32 -55
View File
@@ -1,7 +1,7 @@
---
name: whats-next
description: >
Analyze the milestone dependency web and surface the best batch of tickets
Analyze the ticket dependency graph and surface the best batch of tickets
to pick up next. Refines ticket context via parallel Si agents before
activation. Use when the user says "what's next", "next batch", "pick up
work", or invokes /whats-next. NOT triggered by "what should we work on"
@@ -17,71 +17,46 @@ batch selection → refinement review → batch activation.
## Step 1: Batch Selection
### 1a. Query active milestones
### 1a. List the ready work in the current phase
pql has **no milestone entity** — phase gating is a label, and the active phase is
`phase:4`. `--unblocked` does the dependency walk for you (returns only tickets whose
blockers are all `done`/`cancelled`), collapsing the old milestone + per-ticket deps
queries into one:
```bash
tooling/db/ticket milestone list --status active
pql ticket list --label phase:4 --unblocked
```
If no active milestones exist, tell the user and stop.
If this is empty, the phase is either complete or fully in progress — tell the user and stop.
### 1b. Build the work landscape
### 1b. Rank and group
For each active milestone, get its tickets:
```bash
tooling/db/ticket milestone show <milestone_id>
```
Collect all tickets across all active milestones. Deduplicate (a ticket
can appear in multiple milestones).
### 1c. Identify unblocked tickets
For each ticket that is `ready` or `backlog`, check its dependencies:
```bash
tooling/db/ticket deps <id>
```
A ticket is **unblocked** if all its blockers are `done` or `cancelled`.
Filter to only unblocked tickets.
### 1d. Check milestone-level blocking
```bash
tooling/db/sqlite-query "SELECT * FROM milestone_deps"
```
If a milestone is blocked by another milestone that is not yet `completed`,
deprioritize its tickets (they're unblocked at the ticket level but the
milestone isn't ready for focus yet). Still show them, but ranked lower.
### 1e. Rank and group
Rank unblocked tickets by:
Rank the unblocked tickets by:
1. **Priority** (critical > high > medium > low)
2. **Milestone proximity** — milestones closest to completion (highest
done/total ratio) get priority. Finishing a milestone unlocks downstream
milestone deps.
3. **Fan-out** — tickets that unblock the most downstream tickets rank
higher (query `ticket_deps` for blocked_id counts per blocker_id)
2. **Fan-out** — tickets that unblock the most downstream work rank higher. pql has no
fan-out field yet; when it matters, gauge it from the dependency graph
(`pql ticket list --under <epic>`, or scan candidates' blockers), or judge by epic
membership.
Group into **epic-sized batches**: tickets sharing the same `parent_id`
(epic), or logically related tickets if no epic parent. If a natural
grouping doesn't exist, batch by milestone.
Group into **epic-sized batches**: tickets sharing the same parent (epic), via
`pql ticket show <epic> --with-children` or `pql ticket list --under <epic>`. If no
natural grouping exists, batch by the readiest related cluster.
### 1f. Show WIP status
### 1c. Show WIP status
```bash
tooling/db/ticket wip
pql ticket list --status in_progress
```
### 1g. Present the recommended batch
The kanban WIP soft-limit is 5; pql does not enforce it — warn if activating the batch
would push in-progress past 5.
### 1d. Present the recommended batch
Show the user:
- The recommended batch (tickets with IDs, titles, priorities, milestones)
- Why this batch (which milestone it advances, what it unblocks)
- The recommended batch (tickets with IDs, titles, priorities, phase label)
- Why this batch (what it advances, what downstream tickets it unblocks)
- Current WIP status
- Any alternative batches worth considering
@@ -141,7 +116,8 @@ via AskUserQuestion:
After the user responds, append the resolution to the ticket description:
```bash
tooling/db/sqlite-exec "UPDATE tickets SET description = description || char(10) || char(10) || '---' || char(10) || 'Refinement: <resolution>' WHERE id = <id>"
pql ticket append T-<id> "---
Refinement: <resolution>"
```
If the user says a gap requires a D-record, flag it and ask whether to
@@ -163,11 +139,12 @@ Ask: "Batch ready. Activate?"
### 3a. Mark tickets in_progress
```bash
tooling/db/ticket status <id> in_progress
pql ticket status T-<id> in_progress
```
For each ticket in the batch. The `status` command will warn if WIP limit
is exceeded.
For each ticket in the batch (batch with commas: `pql ticket status T-1,T-2 in_progress`).
pql does **not** enforce the WIP limit — check it yourself in step 1c and warn if the
batch pushes in-progress past 5.
### 3b. Create topic branch
@@ -68,14 +68,14 @@ simpler designs, internal contradictions, and external design prior-art.
## Wrap-up gotchas (2026-05-31)
- **`decision claim` is NOT idempotent.** Each call burns the next ID and appends a
placeholder. Retrying it (e.g. after misreading an unrelated error) creates a
DUPLICATE record that must be hand-removed before filing. Before re-running claim,
check `decision next D` / grep the domain file. The wrap-up step should claim each
ID exactly once and record it immediately.
- **Read-only documenter can still file**, but the lead must hand it the exact ID(s)
and the "remove any stray placeholder" instruction — the claim/file split is where
duplicate IDs sneak in.
- **`pql decisions claim` is side-effect-free** (it just prints the next available ID).
This fixes the old `tooling/db/decision claim` footgun, which burned an ID and appended
a placeholder on every call — retrying it created duplicate records. With pql, claim is
safe to re-run; the record only exists once you write the `### D-NNN: …` heading into the
governance file. Still claim each ID once and write it immediately so parallel branches
don't pick the same number.
- **Read-only documenter can still file** — the lead hands it the claimed ID(s); the
documenter writes the records into `governance/{decisions,questions,rejected}/<domain>.md`.
- **Background (`run_in_background`) teammates can be slow/unreliable to consume
`shutdown_request`.** At wrap-up, qatux + si (both spawned in background per the
skill's §5 guidance) stayed "active" through multiple shutdown sends, blocking