From 64be2672493d8749217d0dbc2fac060d86d5ccbc Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 6 Jun 2026 12:57:58 +0200 Subject: [PATCH] docs(skills): cut workflow skills over to pql (phase 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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- 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) --- .claude/agents/clerk.md | 2 +- .claude/skills/bug-report/SKILL.md | 4 +- .claude/skills/pr-process/SKILL.md | 9 +- .claude/skills/ticket/SKILL.md | 98 ++++++++----------- .claude/skills/whats-next/SKILL.md | 87 ++++++---------- .claude/skills/workshop-start/IMPROVEMENTS.md | 16 +-- 6 files changed, 89 insertions(+), 127 deletions(-) diff --git a/.claude/agents/clerk.md b/.claude/agents/clerk.md index 72f60af6e..7dd13f831 100644 --- a/.claude/agents/clerk.md +++ b/.claude/agents/clerk.md @@ -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`. diff --git a/.claude/skills/bug-report/SKILL.md b/.claude/skills/bug-report/SKILL.md index 4d06aca63..c176bc354 100644 --- a/.claude/skills/bug-report/SKILL.md +++ b/.claude/skills/bug-report/SKILL.md @@ -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: diff --git a/.claude/skills/pr-process/SKILL.md b/.claude/skills/pr-process/SKILL.md index e34e90f40..85b6f9ef0 100644 --- a/.claude/skills/pr-process/SKILL.md +++ b/.claude/skills/pr-process/SKILL.md @@ -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.. ``` -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 review +pql ticket status T- review ``` Report which tickets were moved to review. Skip tickets that are diff --git a/.claude/skills/ticket/SKILL.md b/.claude/skills/ticket/SKILL.md index ed5f9874d..3be1b7d8c 100644 --- a/.claude/skills/ticket/SKILL.md +++ b/.claude/skills/ticket/SKILL.md @@ -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 ` for an epic's subtree.) -### Create ticket +### Create ```bash -tooling/db/ticket create [--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 diff --git a/.claude/skills/whats-next/SKILL.md b/.claude/skills/whats-next/SKILL.md index e74155cb3..36031151c 100644 --- a/.claude/skills/whats-next/SKILL.md +++ b/.claude/skills/whats-next/SKILL.md @@ -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 diff --git a/.claude/skills/workshop-start/IMPROVEMENTS.md b/.claude/skills/workshop-start/IMPROVEMENTS.md index d36eb25d0..3ba9b1162 100644 --- a/.claude/skills/workshop-start/IMPROVEMENTS.md +++ b/.claude/skills/workshop-start/IMPROVEMENTS.md @@ -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