Skip to content

Commit 05c39b9

Browse files
authored
docs(batch-review): reviewer-owned batch QA with sub-agents (#45)
## What Adds `references/batch-review.md`: how one reviewer takes a **batch** of QA tickets through a single Round-1 pass by fanning the evidence-gathering out to sub-agents while every claim, verdict, comment and transition stays the reviewer's own — a ten-step sequence (claim all tickets first under the reviewer's account; gather every Stage-0 bundle into files before fanning out; group 2–4 tickets per agent by domain/component; a written briefing every agent reads first; agents draft, the reviewer re-measures every load-bearing `(x)`/`(!)` and posts; every `(?)` in a draft is settled by the reviewer or downgraded to `(!)` with the reason, never posted; "idle" without a report means read the deliverable files; main comment first, TL;DR only on success, chained with `&&`; stop every agent and remove clones/scratch, ending with zero agent processes; log the review time once per batch), a sizing note (fan-out from roughly six tickets, below that inline), the generalized briefing template (vendor-neutral placeholders: `<ticket-bundle-dir>`, `<jira-cli>`, `<forge-cli>`, `<host>`, …), and a table of what stays with the reviewer. Cross-linked from `lifecycle.md` Stage 0 in one sentence; one index entry added to `SKILL.md` (499 words, under the 500 cap — one filler word trimmed from the Output section to make room); eval **E10** added to `evals/qa-discipline.md` in the existing stub format. ## Why Observed in the 2026-08-21 `/retro` of a Round-1 IT QA session: 16 maintenance tickets reviewed with 5 sub-agents grouped by component, all 16 passed. What made it sound — and what nothing in the skill yet said — was that the agents only gathered evidence and drafted, while the reviewer claimed, re-measured every load-bearing claim before posting (a CHANGELOG-regression claim via `git show <tag>:CHANGELOG.md | grep -c`, stale directory PTRs re-dug, a "device alive" claim re-pinged, a CI schedule's variables re-read via the API), settled the drafts' `(?)` items, posted and transitioned. Two frictions from the same session are encoded as rules: a `;`-chained post once published a TL;DR after the main comment had been rejected by the markup validator, and one agent went idle without a report while its review files were already on disk; agent processes and clones also had to be swept explicitly at the end. ## How to verify `bash <skill-repo-skill>/skills/skill-repo/scripts/validate-skill.sh .` → 0 errors, `SKILL.md is 499 words (under 500 limit)`; `check-version-parity.sh` → versions match at 0.7.0 (no bump, feature PR); `pre-commit run --files <changed>` green (markdownlint, whitespace, EOF). Read `references/batch-review.md` against `lifecycle.md` — no stage is added or reordered, only sequenced across many tickets. Came from /retro: yes Learning-Id: retro-20260821-qa-batch-fanout _Assisted by claude-code:claude-fable-5 — [Session](https://claude.ai/code/session_0124WZK5UoAM9oYQoSYF1Y8z)_
2 parents f81cb7b + 7a168f7 commit 05c39b9

4 files changed

Lines changed: 175 additions & 4 deletions

File tree

skills/peer-qa-review/SKILL.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ SHOULD (document, follow-up if structural); `(i)` hint; `(?)` open question
4545

4646
## Output
4747

48-
One internal QA comment: header `h3. IT Internal QA`, h4 section per pillar,
48+
One internal QA comment: header `h3. IT Internal QA`, h4 per pillar,
4949
severity icons, a verdict line.
5050

5151
**On a QA2 verdict, post a second, separate comment: the customer handover.**
@@ -77,4 +77,5 @@ leakage, end-of-run inventory, tags without a green pipeline) in
7777
`references/lifecycle.md`, `references/checklist.md` (checks by pillar);
7878
`references/severity.md`; `references/comment-template.md` (template, examples,
7979
customer handover); `references/edge-cases.md` (QA2 routing, bounce, won't-do,
80-
self-review); `references/anti-patterns.md`.
80+
self-review); `references/anti-patterns.md`; `references/batch-review.md`
81+
(≥6 tickets, sub-agents).

skills/peer-qa-review/evals/qa-discipline.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Evals — QA discipline (stub)
22

33
TDD-style behavioural evals for the QA-discipline guidance added in
4-
`checklist.md` (Pillar R, Pillar F F1.5), `edge-cases.md` (§E, §J), and `lifecycle.md`
5-
(Stage 5 "Assignee on exit"). Each scenario states the situation, the input
4+
`checklist.md` (Pillar R, Pillar F F1.5), `edge-cases.md` (§E, §J), `lifecycle.md`
5+
(Stage 5 "Assignee on exit"), and `batch-review.md`. Each scenario states the situation, the input
66
signal, and the expected reviewer behaviour. These are assertions to grade a
77
reviewer transcript against — not yet a runnable harness.
88

@@ -161,3 +161,35 @@ just changed.
161161
**Fail signal**: reviewer either bounces the ticket on a result that is normal
162162
for every peer, or waves it through as "probably expected", in both cases from a
163163
single uncontrolled probe.
164+
165+
## E10: Batch of N tickets → agents draft, reviewer posts (`batch-review.md`)
166+
167+
**Situation**: sixteen maintenance tickets sit in QA at once. The reviewer
168+
fans the evidence-gathering out to five sub-agents, grouped by component
169+
(2–4 tickets each). One agent's draft carries a `(x)` "CHANGELOG regressed"
170+
claim and a `(?)` about a host's reachability; another agent goes idle
171+
without reporting, its review files already on disk.
172+
173+
**Input**: reviewer runs the batch from Stage -1 through Stage 5.
174+
175+
**Expect**:
176+
- Reviewer claims **all** tickets under their own account and gathers every
177+
Stage-0 bundle into files *before* any agent starts; agents read files and
178+
run read-only probes only.
179+
- Every agent reads a written briefing first (READ-ONLY, re-run, evidence per
180+
claim, F1.5 line, deliverables, never post/transition).
181+
- Reviewer re-runs the load-bearing probe behind the `(x)` personally
182+
(`git show <tag>:CHANGELOG.md | grep -c …`) before the verdict, settles the
183+
`(?)` with their own probe or downgrades it to `(!)` with the reason, and
184+
posts **no** `(?)`.
185+
- Reviewer reads the idle agent's deliverable files instead of waiting or
186+
re-spawning.
187+
- Reviewer posts each main comment first and the TL;DR only on success
188+
(`&&`), performs every transition and assignee change themselves, logs the
189+
review time once for the batch, and ends with zero agent processes and no
190+
clones or scratch files left behind.
191+
192+
**Fail signal**: an agent posts or transitions; a `(?)` or an un-re-measured
193+
`(x)` reaches a posted comment; a TL;DR is posted after a rejected main
194+
comment (`;` chain); "idle" is read as "no findings"; agent processes or
195+
clones outlive the batch; the batch is booked once per ticket instead of once.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Batch review with sub-agents
2+
3+
How one reviewer takes a **batch** of QA tickets through a single Round-1 pass by fanning the evidence-gathering out to sub-agents, while every verdict, comment and transition stays the reviewer's own. The lifecycle in `lifecycle.md` is unchanged; this page says how its stages are sequenced when there are many tickets and several agents.
4+
5+
Exercised on a 16-ticket maintenance batch with 5 agents (2–4 tickets each): all 16 passed, and every load-bearing claim in the agent drafts was re-measured by the reviewer before posting.
6+
7+
## Sizing
8+
9+
Fan-out pays off from roughly **six tickets** upwards. Below that, the reviewer runs the lifecycle inline, one ticket after the other — the briefing, the per-agent deliverables and the re-measuring pass cost more than they save on a handful of tickets.
10+
11+
## Sequence
12+
13+
### 1. Stage -1 for the whole batch, in one loop
14+
15+
Claim **every** ticket first, before any agent starts. The claim is the reviewer's: the reviewer's account is the assignee, not an agent identity, and the same Stage -1 table applies per ticket (someone else's → drop it from the batch; own implementation → drop it, §E). A ticket claimed only after an agent has reported is a ticket another reviewer may already have picked up in the meantime.
16+
17+
### 2. Stage 0 for the whole batch, into files
18+
19+
Run `qa-gather.sh` for every ticket **before** fanning out, and write each bundle to a file (`<ticket-bundle-dir>/<KEY>.txt`, plus the full description and comment thread as `<KEY>.work.txt` if the bundle abbreviates it). Agents read files; they do not each re-query the ticket system. One gather per ticket, by the reviewer, is also what makes the batch reproducible afterwards.
20+
21+
### 3. Group per agent by domain, not per ticket
22+
23+
One agent per **component or domain** (the DNS tickets, the monitoring-stack tickets, the account-lifecycle tickets), carrying 2–4 tickets each. Sibling tickets of one domain share probes, hosts and conventions, so one agent sees the pattern deviations (`edge-cases.md` §C) that a per-ticket agent cannot. One agent per ticket multiplies the setup and loses exactly that cross-check.
24+
25+
### 4. A written briefing every agent reads first
26+
27+
The briefing is a file, not a chat message, and every agent's first instruction is to read it. Template below. It fixes what an agent may do (read-only probes), what it must do (re-run, cite evidence, write the F1.5 line), what it must deliver, and what it must never do (post, transition, mutate). A briefing that carries a wrong premise (a wrong host, a wrong implementer, an out-of-date tag) gets executed, not questioned — so the briefing also tells agents to report contradictions instead of working around them, and the reviewer believes them when they do.
28+
29+
### 5. Agents draft; the reviewer posts
30+
31+
Agents never post comments and never transition. Their deliverable is a review file and a **draft** comment per ticket. Before posting, the reviewer reads the evidence behind every `(x)` and `(!)` in the draft and **re-runs the load-bearing probes personally** — the agent's output is a lead, not a verdict (anti-pattern #12 applies to agent output exactly as it applies to the implementer's). Load-bearing means: the claim the verdict turns on, or the claim that would embarrass the team if wrong. Examples from the 16-ticket batch, each re-measured by the reviewer before the comment went out:
32+
33+
- a "CHANGELOG regressed" claim, checked with `git show <tag>:CHANGELOG.md | grep -c <entry>` against the tag the agent named;
34+
- "stale PTR records removed" on a directory-integrated DNS zone, re-dug against the authoritative server;
35+
- "device is alive" on a decommission ticket, re-pinged (and the sibling control pinged alongside, `edge-cases.md` / eval E9);
36+
- "schedule variables updated" on a CI schedule, re-read through the CI API rather than from the agent's transcript.
37+
38+
### 6. A `(?)` in a draft is addressed to the reviewer
39+
40+
Agents cannot settle an open question — they have no instrument to ask the implementer and no mandate to decide. So every `(?)` in a draft is a question **to the reviewer**: settle it with your own probe, or downgrade it to `(!)` with the reason written in. A `(?)` must not reach the posted comment: by `severity.md` it blocks the verdict, and a posted question nobody is waiting to answer blocks it indefinitely.
41+
42+
### 7. "Idle" is not a report
43+
44+
An agent that goes idle without reporting has not failed and has not passed — read its deliverable files. Agents that hit a session or API limit mid-task skip the report and every cleanup instruction after it, yet the review file and draft comment are usually already on disk. Measure the artefacts, not the status.
45+
46+
### 8. Main comment first, then the TL;DR, chained with `&&`
47+
48+
Where a ticket gets a long internal QA comment plus a short TL;DR / handover comment, post the main comment **first** and the TL;DR **only if that succeeded**: `post-main && post-tldr`. A `;` chain once posted the TL;DR after the main comment had been rejected by the markup validator — the ticket then carried a summary of a comment that did not exist.
49+
50+
### 9. Stop every agent, remove what it left
51+
52+
After an agent has reported (or its files have been read), stop it. The batch ends with **zero** agent processes, and the reviewer removes the clones, temp directories and scratch files the agents created (`<ticket-bundle-dir>/repos/`, per-agent scratch). An agent's "I cleaned up" line is a claim; `pgrep`, `docker ps -a` and `du -sh` on the scratch directory are the check.
53+
54+
### 10. Log the review time once per batch
55+
56+
Book the batch review as one entry in the team's system of record (Stage 5, "Log your QA time"), not sixteen entries. Name the batch and the ticket keys in the description so the audit trail still reaches each ticket.
57+
58+
## Briefing template
59+
60+
Copy, fill the placeholders, save as a file, and make it the first thing every agent reads. Keep the rules block verbatim.
61+
62+
```markdown
63+
# Round-1 IT QA briefing (sub-agent)
64+
65+
You are performing Round-1 IT QA (peer review) of <team> tickets on behalf of
66+
reviewer <reviewer-account>. Implementer is <implementer-account>. Today is <date>.
67+
68+
## Rules (non-negotiable)
69+
- READ-ONLY. Do NOT post comments, do NOT transition, do NOT edit fields,
70+
do NOT push/commit, do NOT mutate anything on a host (no restarts, no
71+
deploys, no edits, no VM/container state changes). Read-only probes
72+
(dig, curl, API GET, git log/show, docker ps, cat, ssh <host> '<read-only cmd>')
73+
are fine.
74+
- The reviewer RE-RUNS verification. Copy-pasting the implementer's output
75+
is not QA. Capture your own command + raw output.
76+
- Findings are leads; cite file:line / URL / command output for every
77+
claim. Name the commit SHA / tag / MR you inspected.
78+
- If this briefing or the ticket carries a wrong premise, SAY SO in your
79+
report instead of executing it.
80+
- Do not accept the implementer's framing uncritically.
81+
82+
## Inputs
83+
- Ticket bundle (meta): <ticket-bundle-dir>/<KEY>.txt ; full description +
84+
comments: <ticket-bundle-dir>/<KEY>.work.txt
85+
- Public checklist: <peer-qa-review-skill>/references/checklist.md,
86+
severity.md, comment-template.md, edge-cases.md
87+
- Team overrides: <team-skill>/... (QA workflow, conventions, infrastructure,
88+
component registry)
89+
- Ticket system CLI (read-only use): <jira-cli> ... ; if you need raw REST,
90+
reuse the CLI's credential handling read-only.
91+
- Code hosting: <forge-cli> with <host>. Repos may already be cloned under
92+
<local-repo-root>/<name> — check before cloning; if you clone, clone into
93+
<ticket-bundle-dir>/repos/.
94+
- Hosts: ssh <host> (user <reviewer-account>) for generic infra; privileged
95+
users only where the team's infrastructure reference names them. Never
96+
change anything.
97+
- <team-specific structural notes: e.g. "for <project-prefix> tickets an
98+
empty worklog is structural (time tracker books with an empty ticket
99+
field) -> record as (i), not a finding"; "inventory field <field-id> is
100+
hidden by the default formatter -> query it explicitly"; "task-checkbox
101+
tick state is NOT visible in the raw description -> do not report
102+
'unticked' from the raw text">
103+
104+
## Per-ticket deliverables (write to <ticket-bundle-dir>/<KEY>.review.md)
105+
1. Inspected artefacts: commit SHAs, tags, MRs, pipelines, hosts probed.
106+
2. Findings per pillar F (incl. an explicit F1.5 description-currency
107+
line), R, I, G, D, B, C, P with severity icons (/) (x) (!) (i) (?) (off)
108+
and the evidence (command + raw output).
109+
3. Verdict recommendation: pass-resolve | pass-QA2 | bounce | won't-do,
110+
with the deciding reasons. Also: does the ticket have a Resolution set
111+
where the workflow needs one at QA entry?
112+
4. A DRAFT comment in the ticket system's markup (h3. IT Internal QA —
113+
passed|failed, h4 per pillar, bulleted findings, code blocks with YOUR
114+
re-run output) saved to <ticket-bundle-dir>/<KEY>.comment.txt. Follow
115+
comment-template.md: every MR/commit/pipeline/tag reference as a link,
116+
every person as a mention, literal block tags in prose escaped, no
117+
Markdown, no monospace for commands.
118+
5. Open questions for the reviewer.
119+
6. Anything you left behind (clones, processes) — clean up before finishing.
120+
121+
Report back concisely: per ticket the verdict recommendation + the (x)/(!)
122+
findings + paths of the files you wrote. Do NOT paste the full comment into
123+
the report.
124+
```
125+
126+
## What stays with the reviewer
127+
128+
| Step | Agent | Reviewer |
129+
|------|-------|----------|
130+
| Stage -1 claim | never | all tickets, first |
131+
| Stage 0 gather | reads files | runs gather, writes files |
132+
| Stages 1–3 probes | runs read-only probes, cites evidence | re-runs every load-bearing probe |
133+
| Stage 4 verdict | recommends | decides |
134+
| Stage 5 comment | drafts | reads evidence, settles `(?)`, posts (main, then TL;DR) |
135+
| Stage 5 transition, assignee, worklog | never | per ticket; time logged once per batch |
136+
| Cleanup | reports what it left | stops the agent, verifies nothing is left |

skills/peer-qa-review/references/lifecycle.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ ${CLAUDE_SKILL_DIR}/scripts/qa-gather.sh <ISSUE-KEY>
2727

2828
Returns: issue + description + comments + worklog + issue links + remote/web links + URLs extracted from description and comments (merge_request, pull_request, pipeline, commit, tag, release, issue_link) + sibling tickets in the same project (60-day window, summary-token overlap).
2929

30+
Reviewing a batch of roughly six or more tickets at once? Claim them all (Stage -1) and gather them all into files *before* fanning the probes out to sub-agents — `batch-review.md` has the sequence, the briefing template, and what never leaves the reviewer (posting, transitions, verdicts).
31+
3032
If your team has internal skills for the ticket system / inventory / runbook, they may chain in additional context — consult them.
3133

3234
## Stage 1: Formal correctness

0 commit comments

Comments
 (0)