Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f3ede8d6a |
@@ -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.
|
||||||
|
|||||||
@@ -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
|
## 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
|
||||||
|
|||||||
Reference in New Issue
Block a user