--- name: plan-tickets description: "Plan a batch of tickets and write the briefs for its next wave: read the tracker, decide waves and contracts, get the plan approved." disable-model-invocation: true --- # Plan tickets You produce the two artifacts the `implement-tickets` skill runs on: a **plan file** and one **brief** per ticket in the next wave. You write no ticket code and create no worktrees — that is the runner's half. Ticket source and tracker conventions: `docs/agents/issue-tracker.md`. `tea` usage: skill `gitea`. Called twice in a batch's life, at least: once to open it, then again after each wave lands, because a later wave's briefs may need what the last one changed. On a re-entry, read the existing `.scratch//plan.md` first and plan only the next unlanded wave — the waves and contracts already approved there stand unless the landed wave proved one wrong. ## 1. Collect the tickets The user's argument is the selector: issue numbers, a label, a parent issue, or nothing. With nothing, take the open issues labelled `ready-for-agent`. Fetch each with `tea issue --comments`, and read the **whole** body — acceptance criteria and the `Blocked by` line are what the rest of this skill runs on. A ticket whose blockers are still open is out of this batch unless a blocker is also in it. Read the issue each ticket refers to, its parent or spec, the same way: nothing on the implementation path reads the tracker after you — only `cr-spec` does, at review time — so a decision that lives in a comment reaches the implementer only if you carry it into the brief. ## 2. Plan the batch Explore enough of the codebase to write briefs a fresh context can act on: the files each ticket lands in, the patterns it must follow, the `AGENTS.md` invariants it touches. Then decide three things: - **Waves.** Blocking edges set the order; tickets with no open blocker inside the batch share a wave. Cap each wave at **3** concurrent tickets unless the user set another width. - **Contracts.** Two tickets in one wave that meet at a function signature, a JSON shape, a table column, or a token name: you decide the shape now and write the identical wording into both briefs. A contract left for the subagents to negotiate is a merge conflict you scheduled. - **Splits.** A ticket too big for one fresh context window goes into the wave as two briefs, or back to the user. ## 3. Write the artifacts Pick a `` — short, from what the batch is about — and write `.scratch//plan.md`. It is the handoff: the runner is a fresh context that reads this and nothing of your reasoning. # Batch **Base branch.** The branch every worktree forks from and merges back into. **Waves.** A table: wave number, ticket number, title, brief path, and status — `planned` | `dispatched` | `landed` | `handed back`. Every ticket in the batch, including waves not briefed yet. **Contracts.** Each cross-ticket contract verbatim, naming both ticket numbers. **Assumptions.** What you had to assume, and what the user corrected at approval. Then write a brief per ticket in the next wave to `.scratch//t-brief.md`, using the template below, in the ubiquitous language of `CONTEXT.md` — a brief that says "scrape" where the domain says Poll hands the subagent the wrong model of the system. # Ticket # — **Decisions.** Whatever the ticket's comments or its parent spec settled that the body never got updated with, restated verbatim. The implementer reads this brief and the code, never the tracker — a decision missing here is lost to it, and a stale comment thread is not a source you want a fresh context guessing from. Omit only when the ticket has no comments. **Goal.** The end-to-end behaviour this ticket makes work, from the user's side. **Acceptance criteria.** Verbatim from the ticket. **Contract.** The exact shared signatures / shapes / names this ticket must implement or consume, and which sibling ticket is on the other end. Omit when the ticket touches nothing shared. **Where it lands.** The files and packages, and the existing pattern to follow in each. **Binding invariants.** The `AGENTS.md` rules this change can break — name them. **TDD seams.** Where a test comes first — run the `tdd` skill at each one and follow its red → green loop. Or "none — verify after". **Verify.** The exact commands, e.g. `cd backend && go test ./...`, `node --test userscript/test/logic.test.js`. **Out of scope.** What not to touch, especially a sibling ticket's files. </brief-template> ## 4. Get the plan approved Present, and stop: - the wave list, and for each ticket in the next wave: number, title, one-line brief summary, the files or areas it will touch, its verification commands - every cross-ticket contract, verbatim as it appears in the briefs - anything you had to assume Wait for approval. Apply the user's edits to the plan, do not relitigate them — into the files, not just the reply, or the runner never sees them. Then hand off: name the batch slug and the wave, and stop. Running the wave is `implement-tickets`.