Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f3ede8d6a |
@@ -1,108 +1,49 @@
|
||||
---
|
||||
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
|
||||
---
|
||||
|
||||
# Implement tickets
|
||||
|
||||
You are the **orchestrator**. You write briefs, dispatch, land results, and talk
|
||||
to the tracker. You do not write the implementation — every line of ticket code
|
||||
is written by a `ticket-implementer` subagent in its own git worktree. Reach for
|
||||
the editor yourself only for a merge conflict resolution.
|
||||
You are the **orchestrator**. You dispatch, land results, and talk to the
|
||||
tracker. You do not write the implementation — every line of ticket code is
|
||||
written by a `ticket-implementer` subagent in its own git worktree. Reach for the
|
||||
editor yourself only for a merge conflict resolution.
|
||||
|
||||
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
|
||||
nothing. With nothing, take the open issues labelled `ready-for-agent`.
|
||||
Your argument is the batch slug. Read `.scratch/<batch-slug>/plan.md` — it gives
|
||||
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 —
|
||||
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.
|
||||
The briefs are the requirements and they are already approved: read each one you
|
||||
are about to dispatch, but do not rewrite it, and do not fetch the tickets from
|
||||
the tracker to second-guess it. A brief that is wrong or thin is a `plan-tickets`
|
||||
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
|
||||
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
|
||||
## 1. Dispatch the wave
|
||||
|
||||
Per ticket, before dispatch:
|
||||
|
||||
```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
|
||||
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
|
||||
`ticket-implementer` agent. Each dispatch names: the absolute brief path, the
|
||||
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>
|
||||
|
||||
# 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
|
||||
## 2. Land the wave
|
||||
|
||||
The wave is landed when every ticket in it is closed, reverted, or handed back
|
||||
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.
|
||||
|
||||
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
|
||||
need what this one changed.
|
||||
## 3. Hand back or close the batch
|
||||
|
||||
## 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
|
||||
its status, commits, and open concerns, plus anything still assigned or open on
|
||||
the tracker. A red suite after every ticket went green is an interaction bug —
|
||||
diagnose it, name the two tickets, and fix it or hand it back with both named.
|
||||
Last wave landed: run the full suite once on the merged base, and report a line
|
||||
per ticket with its status, commits, and open concerns, plus anything still
|
||||
assigned or open on the tracker. A red suite after every ticket went green is an
|
||||
interaction bug — diagnose it, name the two tickets, and fix it or hand it back
|
||||
with both named.
|
||||
|
||||
@@ -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`.
|
||||
@@ -24,34 +24,35 @@ Your branch is already checked out there. Never `git checkout`, `git switch`,
|
||||
|
||||
## Order of work
|
||||
|
||||
1. Read the brief file. It is the single source of requirements — use its exact
|
||||
values verbatim.
|
||||
2. Read the ticket and the issue it refers to, as the brief's **Read first**
|
||||
section names them: `tea issue <n> --comments` for each. The ticket's
|
||||
comments and its parent carry the intent and the decisions behind the brief.
|
||||
Read no other ticket and no other brief.
|
||||
3. Read `AGENTS.md` in the worktree, plus the nested `AGENTS.md` for the area
|
||||
1. Read the brief file. It is the only statement of requirements you get — use
|
||||
its exact values verbatim, and read nothing from the tracker. The
|
||||
orchestrator has already read the ticket, its comments and its parent spec,
|
||||
and folded every live decision into the brief; the threads themselves also
|
||||
hold reversed and rejected ones you cannot tell apart from here.
|
||||
2. 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
|
||||
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.
|
||||
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.
|
||||
Follow the patterns already in the codebase; improve what you touch,
|
||||
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.
|
||||
7. Commit to your branch. Reference the ticket number in the subject.
|
||||
8. Review (below), fix, re-verify, commit the fixes.
|
||||
9. Write the report file, then return the status contract.
|
||||
6. Commit to your branch. Reference the ticket number in the subject.
|
||||
7. Review (below), fix, re-verify, commit the fixes.
|
||||
8. Write the report file, then return the status contract.
|
||||
|
||||
## Review
|
||||
|
||||
After your first green commit, run the **`code-review`** skill over
|
||||
`<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
|
||||
Standards axis, both in one batch, and give the Spec axis your brief file plus
|
||||
the ticket body as the spec.
|
||||
Standards axis, both in one batch, and hand the Spec axis your brief file as the
|
||||
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
|
||||
amended code. Two fix rounds maximum: anything still open after that goes in the
|
||||
|
||||
Reference in New Issue
Block a user