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:
@@ -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`.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user