Compare commits

...

1 Commits

3 changed files with 172 additions and 102 deletions
+31 -87
View File
@@ -1,108 +1,49 @@
--- ---
name: implement-tickets name: implement-tickets
description: "Orchestrate a batch of tickets: plan the briefs, then hand each ticket to its own implementer subagent in its own worktree." description: "Run a planned wave of tickets: one implementer subagent per ticket in its own worktree, then land, merge and close what comes back."
disable-model-invocation: true disable-model-invocation: true
--- ---
# Implement tickets # Implement tickets
You are the **orchestrator**. You write briefs, dispatch, land results, and talk You are the **orchestrator**. You dispatch, land results, and talk to the
to the tracker. You do not write the implementation — every line of ticket code tracker. You do not write the implementation — every line of ticket code is
is written by a `ticket-implementer` subagent in its own git worktree. Reach for written by a `ticket-implementer` subagent in its own git worktree. Reach for the
the editor yourself only for a merge conflict resolution. editor yourself only for a merge conflict resolution.
Ticket source and tracker conventions: `docs/agents/issue-tracker.md`. `tea` usage: skill `gitea`. Ticket source and tracker conventions: `docs/agents/issue-tracker.md`. `tea` usage: skill `gitea`.
## 1. Collect the tickets ## 0. Load the plan
The user's argument is the selector: issue numbers, a label, a parent issue, or Your argument is the batch slug. Read `.scratch/<batch-slug>/plan.md` — it gives
nothing. With nothing, take the open issues labelled `ready-for-agent`. the base branch, the waves, the contracts, and each ticket's brief path and
status. Run the earliest wave that is not landed.
Fetch each with `tea issue <n> --comments`, and read the **whole** body — The briefs are the requirements and they are already approved: read each one you
acceptance criteria and the `Blocked by` line are what the rest of this skill are about to dispatch, but do not rewrite it, and do not fetch the tickets from
runs on. A ticket whose blockers are still open is out of this batch unless a the tracker to second-guess it. A brief that is wrong or thin is a `plan-tickets`
blocker is also in it. problem — say so and stop, rather than patching it here.
## 2. Plan the batch No plan file, or no briefs for the next wave: run `plan-tickets` first. That
skill owns wave membership, contracts, and every brief.
Explore enough of the codebase to write briefs a fresh context can act on: the ## 1. Dispatch the wave
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. Get the plan approved
Present, and stop:
- the wave list, and for each ticket: number, title, one-line brief summary,
the files or areas it will touch, its verification commands
- every cross-ticket contract, verbatim as it will appear in the briefs
- anything you had to assume
Wait for approval. Apply the user's edits to the plan, do not relitigate them.
## 4. Run a wave
Per ticket, before dispatch: Per ticket, before dispatch:
```bash ```bash
git worktree add ../ticket-<n> -b ticket/<n>-<slug> <base> # base = the branch you are on git worktree add ../ticket-<n> -b ticket/<n>-<slug> <base> # base = the plan's base branch, checked out here
cp .env ../ticket-<n>/ 2>/dev/null # gitignored, worktrees do not get it cp .env ../ticket-<n>/ 2>/dev/null # gitignored, worktrees do not get it
tea issue edit <n> --add-assignees <your gitea username> # tea login list has it tea issue edit <n> --add-assignees <your gitea username> # tea login list has it
``` ```
Write the brief to `.scratch/<batch-slug>/t<n>-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.
Then dispatch the whole wave in **one** `task` batch, every item on the Then dispatch the whole wave in **one** `task` batch, every item on the
`ticket-implementer` agent. Each dispatch names: the absolute brief path, the `ticket-implementer` agent. Each dispatch names: the absolute brief path, the
worktree path, the branch, the base ref, and the report path worktree path, the branch, the base ref, and the report path
`.scratch/<batch-slug>/t<n>-report.md`. `.scratch/<batch-slug>/t<n>-report.md`. Mark each ticket `dispatched` in the plan
file.
<brief-template> ## 2. Land the wave
# Ticket #<n> — <title>
**Read first.** `tea issue <n> --comments` for this ticket, then the issue it
refers to — the parent or spec — the same way. The comments carry decisions the
body never got updated with. This brief stays the requirements; those two reads
are the intent behind them.
**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>
## 5. Land the wave
The wave is landed when every ticket in it is closed, reverted, or handed back The wave is landed when every ticket in it is closed, reverted, or handed back
to the user. Per returned ticket: to the user. Per returned ticket:
@@ -120,14 +61,17 @@ clash — both sides green apart, wrong together — goes back to whichever tick
owns the contract, as a re-dispatch with the collision described. owns the contract, as a re-dispatch with the collision described.
Then `tea comment <n> "<the report summary>"`, `tea issue close <n>`, and Then `tea comment <n> "<the report summary>"`, `tea issue close <n>`, and
`git worktree remove ../ticket-<n>`. Keep the report file. `git worktree remove ../ticket-<n>`. Keep the report file, and mark the ticket
`landed` or `handed back` in the plan file.
Only once the whole wave is landed does the next wave start — its briefs may ## 3. Hand back or close the batch
need what this one changed.
## 6. Close the batch Waves left in the plan: stop and say which wave is next. Its briefs are written
by `plan-tickets` against the base you just changed — that is why they were not
written up front, and why you do not write them.
Run the full suite once on the merged base, and report: a line per ticket with Last wave landed: run the full suite once on the merged base, and report a line
its status, commits, and open concerns, plus anything still assigned or open on per ticket with its status, commits, and open concerns, plus anything still
the tracker. A red suite after every ticket went green is an interaction bug — assigned or open on the tracker. A red suite after every ticket went green is an
diagnose it, name the two tickets, and fix it or hand it back with both named. interaction bug — diagnose it, name the two tickets, and fix it or hand it back
with both named.
+125
View File
@@ -0,0 +1,125 @@
---
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/<batch-slug>/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 <n> --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 `<batch-slug>` — short, from what the batch is about — and write
`.scratch/<batch-slug>/plan.md`. It is the handoff: the runner is a fresh context
that reads this and nothing of your reasoning.
<plan-template>
# Batch <batch-slug>
**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.
</plan-template>
Then write a brief per ticket in the next wave to
`.scratch/<batch-slug>/t<n>-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.
<brief-template>
# Ticket #<n> — <title>
**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`.
+16 -15
View File
@@ -24,34 +24,35 @@ Your branch is already checked out there. Never `git checkout`, `git switch`,
## Order of work ## Order of work
1. Read the brief file. It is the single source of requirements — use its exact 1. Read the brief file. It is the only statement of requirements you get — use
values verbatim. its exact values verbatim, and read nothing from the tracker. The
2. Read the ticket and the issue it refers to, as the brief's **Read first** orchestrator has already read the ticket, its comments and its parent spec,
section names them: `tea issue <n> --comments` for each. The ticket's and folded every live decision into the brief; the threads themselves also
comments and its parent carry the intent and the decisions behind the brief. hold reversed and rejected ones you cannot tell apart from here.
Read no other ticket and no other brief. 2. Read `AGENTS.md` in the worktree, plus the nested `AGENTS.md` for the area
3. Read `AGENTS.md` in the worktree, plus the nested `AGENTS.md` for the area
you touch. Its invariants bind you: security rules, design system, comment you touch. Its invariants bind you: security rules, design system, comment
policy. policy.
4. Ask before writing code if requirements, acceptance criteria, approach, or 3. Ask before writing code if requirements, acceptance criteria, approach, or
dependencies are unclear. Asking is free; guessing is not. dependencies are unclear. Asking is free; guessing is not.
5. Implement exactly what the brief specifies. At each TDD seam the brief names, 4. Implement exactly what the brief specifies. At each TDD seam the brief names,
run the `tdd` skill and follow its red → green loop. run the `tdd` skill and follow its red → green loop.
Follow the patterns already in the codebase; improve what you touch, Follow the patterns already in the codebase; improve what you touch,
restructure nothing outside the ticket. restructure nothing outside the ticket.
6. Verify. Focused tests while iterating, the brief's full verification commands 5. Verify. Focused tests while iterating, the brief's full verification commands
once at the end. Test output must be pristine. once at the end. Test output must be pristine.
7. Commit to your branch. Reference the ticket number in the subject. 6. Commit to your branch. Reference the ticket number in the subject.
8. Review (below), fix, re-verify, commit the fixes. 7. Review (below), fix, re-verify, commit the fixes.
9. Write the report file, then return the status contract. 8. Write the report file, then return the status contract.
## Review ## Review
After your first green commit, run the **`code-review`** skill over After your first green commit, run the **`code-review`** skill over
`<base ref>...HEAD` in the worktree, with two changes to how it dispatches: `<base ref>...HEAD` in the worktree, with two changes to how it dispatches:
use the **`cr-spec`** agent for the Spec axis and **`cr-standards`** for the use the **`cr-spec`** agent for the Spec axis and **`cr-standards`** for the
Standards axis, both in one batch, and give the Spec axis your brief file plus Standards axis, both in one batch, and hand the Spec axis your brief file as the
the ticket body as the spec. spec plus the ticket number from the brief's title, telling it to read the
ticket itself (`tea issue <n> --comments`). The tracker check belongs in that
read-only context, not in yours.
Fix every Critical and Important finding, then re-run the tests that cover the Fix every Critical and Important finding, then re-run the tests that cover the
amended code. Two fix rounds maximum: anything still open after that goes in the amended code. Two fix rounds maximum: anything still open after that goes in the