Files
clide/.claude/skills/whats-next/SKILL.md
T
Jeroen SchweitzerandClaude Opus 4.8 1746f9c204 whats-next: require pql plan export + commit after ticket mutations
Ticket changes land only in the gitignored .pql/pql.db; the post-checkout/post-merge hooks rebuild it from the committed changelog on every branch switch, so un-exported tickets vanish silently (this is how the T-208-T-225 tree was lost). Add an export-and-commit step to Step 3a and a matching anti-pattern, cross-linked to the pql skill.

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

9.5 KiB
Raw Blame History

name, description, user-invocable, allowed-tools
name description user-invocable allowed-tools
whats-next Surface the best batch of tickets to pick up next from pql. Walks the initiative/epic tree, filters to unblocked work, refines context via parallel agents (or `pql ticket refine` for empty descriptions), and optionally activates the batch on a fresh branch. 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" in a design context — that's a discussion, not a batch selection. true Bash, Read, Grep, Glob, Agent, AskUserQuestion

What's Next

Dependency-driven batch selection against pql. Three steps: batch selection → refinement review → batch activation.

Pql is the single source of truth for tickets and decisions in this repo (see pql skill and decisions/README.md). Always run from the repo root.

Step 0: Sync state

Decisions on disk may be ahead of pql.db. Always sync before reading:

pql decisions sync

If pql is missing, stop and tell the user — don't fall back to grep.


Step 1: Batch Selection

1a. Find active top-level work

Pql has no milestone concept; initiatives (and large epics) play that role. List in-flight top-level work:

pql ticket list --status in_progress --pretty
pql ticket list --status ready --pretty

If nothing is in_progress or ready at the initiative/epic level, fall back to pql plan status --pretty for a dashboard read and ask the user which area to advance.

1b. Build the work landscape

For each candidate epic or initiative, read its full descendant subtree (nested, with the direct parent in ancestors) — one call, no client-side flattening (pql ≥ 1.6.0):

pql ticket show <id> --tree --pretty        # add --depth N to cap levels

This replaces the old --with-children + hand-rolled status summaries.

1c. Filter to unblocked, actionable leaves

Don't walk blockers per ticket — pql does it. Compose the list filters (pql ≥ 1.6.0): --leaf (no children), --unblocked (every blocker is done/cancelled), and --status (since --leaf/--unblocked are structure/blocker-state only and would otherwise include done leaves):

pql ticket list --under <epic-id> --leaf --unblocked --status backlog --pretty

--status takes a SINGLE value (not a comma list — backlog,ready matches nothing and silently returns []). The repo is almost all backlog; if a team uses ready, run it a second time with --status ready.

That returns exactly the actionable, unblocked leaves under the epic — the multi-result complement to pql plan whatsnext (which now also skips blocked tickets, for the single best pick). Note --unblocked only means no ticket blocker is open; a ticket "blocked on upstream" in prose (e.g. T-158) still shows — read the description before batching.

1d. Rank and group

Rank unblocked tickets by:

  1. Priority (critical > high > medium > low) — read from ticket fields.
  2. Epic proximity to done — for each epic parent, compute done_children / total_children. Higher ratio ranks higher: finishing an epic unlocks downstream work and tightens the board.
  3. Fan-out — tickets that unblock the most other tickets rank higher. Approximate by scanning pql ticket list --status backlog --pretty and counting how many list this ticket in their blockers (use --with-blockers per candidate, or read --jsonl once and reduce in memory).

Group into epic-sized batches: tickets sharing a parent_id, or a logical cluster if no shared parent. If nothing groups naturally, batch by area (the directory the work touches, e.g. lib/src/pty/).

1e. Show the board

pql ticket board --pretty

This is the "what's currently in flight" view — the user wants to see WIP before committing to more.

Show the user:

  • The recommended batch — IDs, titles, priorities, parent epic.
  • Why this batch — which epic it advances, what it unblocks downstream.
  • Current board state (WIP count vs. ready/backlog).
  • One or two alternative batches worth considering.

Wait for user confirmation before Step 2.


Step 2: Ticket Refinement Review

Two cases — handle the cheap one first.

2a. Tickets with empty descriptions → use pql

If any ticket in the batch has no description, hand off to pql's built-in refinement flow:

pql ticket refine list --pretty
pql ticket refine next --pretty           # full context for the next one
pql ticket refine write T-NN '{"description":"..."}'

Walk these with the user (AskUserQuestion per ticket if appropriate) before moving on.

2b. Tickets with descriptions → spawn refinement agents

For each ticket that already has a description but may still be under-specified, spawn one agent in parallel. Use general-purpose subagent_type (custom subagent_types lose SendMessage):

Agent({
  subagent_type: "general-purpose",
  model: "sonnet",
  description: "Refine T-NN context",
  prompt: "You are the Refinement Manager for ticket T-NN.

  Ticket: <title>
  Description: <body>
  Decision ref: <D-NN or Q-NN, if set>

  Your job:
  1. Run `pql decisions show <decision_ref> --with-refs --pretty` and
     read the linked D/Q-record in decisions/<domain>.md.
  2. Grep decisions/questions-*.md for related Q-records.
  3. Verify referenced files, classes, and APIs actually exist in the
     current tree (Read/Grep). Flag dangling references.
  4. Cross-check against CLAUDE.md guardrails (single process, CLI-first,
     own the rendering stack, etc.) — flag tickets that conflict.

  Assess: does an implementer have enough context to proceed without
  guessing? Report exactly one of:
  - READY: <one-paragraph summary of what the implementer needs to know>
  - GAPS: <list of specific ambiguities, each with 23 options>"
})

Run all agents in parallel (single message, multiple Agent tool calls).

2c. Resolve gaps

For each ticket that came back GAPS, surface ambiguities to the user via AskUserQuestion. After the user resolves, append the resolution to the ticket with pql ticket append (pql ≥ 1.6.0) — it appends blank-line-separated WITHOUT round-tripping the existing description, so there's no JSON-splicing or read-modify-write:

pql ticket append T-NN "Refinement (<date>): <resolution>"
# longer notes: pql ticket append T-NN --file note.md   (or --stdin)

(Use append, not refine write — the latter replaces the whole description from a JSON patch and forces you to re-send the existing body.)

If a gap really requires a new D-record (architectural choice, not just detail), flag it. Ask whether to write the D-record now (pql decisions claim D <domain> "title" then author the markdown) or defer with a note on the ticket.

2d. Present refined batch summary

Per ticket:

  • READY summary, or the resolution the user just gave.
  • Linked D/Q-records.
  • Remaining blockers (should be none — re-check if Step 1 was a while ago).

Ask: "Batch ready. Activate?"


Step 3: Batch Activation

3a. Mark tickets in_progress

Batch transition (comma-separated IDs):

pql ticket status T-1,T-2,T-3 in_progress

Then persist it. Ticket mutations (status here, and any ticket new in Step 2) land only in the gitignored .pql/pql.db. The post-checkout/post-merge hooks rebuild that DB from the committed changelog on every branch switch — so un-exported changes vanish silently the next time anyone switches branches. After creating or transitioning tickets, always:

pql plan export                      # regenerates .pql/changelog/*.sql
git add .pql/changelog && git commit # durable; survives rebuild

See the pql skill.

3b. Branch? Default no.

Solo-dev flow on this repo — work lands directly on main (see recent git log). Don't create a topic branch unless the user explicitly asks. If they do, plain git checkout -b is fine; there is no gh CLI.

3c. Spawn implementation agents (optional)

If the user wants agents driving the work, spawn general-purpose subagents (model: sonnet) per ticket. Each prompt should include:

  • Ticket details + the refinement summary from Step 2.
  • The full content of any linked D-record (Read it and inline it — don't just cite the ID; the agent has no project memory of it).
  • Repo guardrails the work touches (from CLAUDE.md — quote the relevant bullets, don't link).
  • A RULES block: write files only, no git commits, no destructive ops, message back when blocked or done.

3d. Report

End with a tight summary:

  • Branch.
  • Tickets now in_progress.
  • Agents spawned (if any).
  • Next step: implement, then commit per the git-commit skill.

Anti-patterns

  • Don't skip Step 0 — stale pql.db makes the rest of the skill lie.
  • Don't leave ticket changes un-exported — pql.db is gitignored and the post-checkout/post-merge hooks rebuild it from the committed changelog, so a branch switch silently drops un-exported tickets. Always pql plan export + commit .pql/changelog/ after mutating tickets (Step 3a).
  • Don't activate a batch the user hasn't confirmed.
  • Don't spawn refinement agents for tickets that have no description — use pql ticket refine instead; it's cheaper and writes back through the proper channel.
  • Don't reach for gh — this system doesn't have it. Plain git only.
  • Don't cd into subdirectories — run everything from the repo root.