@erclx/aitk 3.11.0 → 3.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-address-review/SKILL.md +10 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-poll.md +4 -1
- package/claude/skills/claude-orchestrate/scripts/poll.sh +59 -13
- package/claude/skills/claude-pr-review/REQUIREMENT.md +3 -0
- package/claude/skills/claude-pr-review/SKILL.md +24 -4
- package/package.json +1 -1
- package/standards/pr.md +3 -3
|
@@ -194,3 +194,13 @@ Rebased PR #<number> onto origin/main. <N> files resolved by hand, <N> rebuilt b
|
|
|
194
194
|
```
|
|
195
195
|
|
|
196
196
|
Do not merge. Hand back to the orchestrator for re-review.
|
|
197
|
+
|
|
198
|
+
## Post-review findings
|
|
199
|
+
|
|
200
|
+
Not everything worth reaching the reviewing session surfaces inside the numbered flow above. A worker that settled a risk, filed a follow-up, or found something else worth reporting after Step 7 already closed the review posts it directly rather than waiting on a review pass that has nothing left to trigger it. Write the body the way Step 6 writes a reply: load `write-human` for voice, follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for the banned words, and run the `${CLAUDE_SKILL_DIR}/../../standards/publish.md` scan before posting.
|
|
201
|
+
|
|
202
|
+
Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered. `claude-pr-review` states the full heading set this belongs to and routes it the same as a response: `claude-orchestrate`'s poll picks it up and sends the reviewing session back for a pass. Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
gh pr comment <number> --body-file .claude/.tmp/address-review/reply-<number>.md
|
|
206
|
+
```
|
|
@@ -36,6 +36,7 @@ Poll GitHub for pull request movement by running <POLL_SCRIPT>, then act on what
|
|
|
36
36
|
- SEEN: report it and stop. A pass already covers that head, whether it arrived out of band or before the poll first saw the pull request, so no review follows.
|
|
37
37
|
- STALLED: read the last pass and report what it carried. The pass has sat open for hours with nothing following it, so a worker mid-task is already ruled out and the dispatch either never went out or the session holding it is gone. Confirm and re-send it under the dispatch rule below, whatever grades the pass carried. Do not re-run a review to correct the heading, since a pass on an unchanged head with no response behind it stops by design.
|
|
38
38
|
- CONFLICT: report it and stop. The branch owner rebases, not this session.
|
|
39
|
+
- UNMATCHED: report it and stop. A comment posted under a heading outside the known set reaches nobody automatically, so a person decides whether to answer it by hand or the set needs a sixth heading.
|
|
39
40
|
- GONE: report it, then sweep the board by invoking the aitk:claude-orchestrate skill and following its queue-refill sweep.
|
|
40
41
|
- A line starting `poll:`: report it verbatim and treat that pull request as unread this run. It is a failed query, not a state.
|
|
41
42
|
- Nothing changed: say exactly "No movement." and nothing else.
|
|
@@ -51,7 +52,9 @@ The script exits non-zero and classifies nothing when the open pull request list
|
|
|
51
52
|
|
|
52
53
|
The baseline lives at `.claude/.tmp/pr-poll/baseline.txt` under the main worktree root and is per-machine. A first run against a board already in flight reports each open pull request once before it settles.
|
|
53
54
|
|
|
54
|
-
The
|
|
55
|
+
The five review headings the script matches are written by `claude-pr-review` and `claude-address-review`, and the whole set is stated once in the first. A project that posts its reviews under different headings edits the jq filters in the script to match, or every pull request reads as never reviewed.
|
|
56
|
+
|
|
57
|
+
`UNMATCHED` is what a heading outside the five reaches, carried the same way `RESPONSE` is: a rising count against the baseline is what is new to this script, and the message names the heading so a person can tell whether to answer it by hand or add it to the set. It fires on a tracked pull request only, since a first sighting reports `SEEN` or `OPENED` and takes whatever count already sits on the thread as its starting baseline rather than flagging history the poll never watched.
|
|
55
58
|
|
|
56
59
|
`RESPONSE` is qualified by recency as well as by count, so it means a reply the last pass has not already answered rather than one this script has not seen before. A worker answers a finding and the reviewing session posts its close-out seconds later, which is the ordinary handback rather than a race, so a count on its own reported the answered thread on the next run and the re-review it routed to stopped at its own guard. The state now fires when the newest reply is stamped later than the last pass, and on a pull request carrying no pass at all, which is a worker talking to nobody and worth the turn. A reply landing inside the same second as the pass is dropped, matching the comparison `claude-pr-review` makes on the same two fields.
|
|
57
60
|
|
|
@@ -32,16 +32,19 @@ if [ -z "$BASE_REF" ]; then
|
|
|
32
32
|
fi
|
|
33
33
|
BASE_BRANCH="${BASE_REF#origin/}"
|
|
34
34
|
|
|
35
|
-
# These
|
|
36
|
-
# writes `## Review` and `## Review closed`, and
|
|
37
|
-
#
|
|
35
|
+
# These five strings are owned elsewhere and pinned here. `claude-pr-review`
|
|
36
|
+
# writes `## Review` and `## Review closed`, and states the full five-heading
|
|
37
|
+
# set once, beside the threshold it already states once. `claude-address-review`
|
|
38
|
+
# writes `## Review response`, `## Rebase`, and `## Post-review findings`, the
|
|
39
|
+
# last for a finding a worker produces after a close-out rather than in answer
|
|
40
|
+
# to one already on the thread. All three surfaces ship separately, so a
|
|
38
41
|
# heading added in either skill breaks a test here that no check reaches across.
|
|
39
42
|
#
|
|
40
|
-
# Both families match on the first line alone so the
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
43
|
+
# Both families match on the first line alone so the tests stay symmetric. The
|
|
44
|
+
# reply family carries `## Rebase` and `## Post-review findings` beside
|
|
45
|
+
# `## Review response` because neither answers a comment already on the thread,
|
|
46
|
+
# which is why both were kept outside the `## Review` family rather than folded
|
|
47
|
+
# into it.
|
|
45
48
|
JQ_LAST_REVIEWED_HEAD='
|
|
46
49
|
[ .reviews[]
|
|
47
50
|
| select((.body // "") | split("\n")[0] | rtrimstr("\r")
|
|
@@ -55,13 +58,37 @@ JQ_LAST_REVIEWED_HEAD='
|
|
|
55
58
|
JQ_REPLY_STATE='
|
|
56
59
|
[ .comments[]
|
|
57
60
|
| select((.body // "") | split("\n")[0] | rtrimstr("\r")
|
|
58
|
-
| . == "## Review response" or . == "## Rebase"
|
|
61
|
+
| . == "## Review response" or . == "## Rebase"
|
|
62
|
+
or . == "## Post-review findings")
|
|
59
63
|
] as $replies
|
|
60
64
|
| ($replies | length | tostring)
|
|
61
65
|
+ " "
|
|
62
66
|
+ ([ $replies[] | .createdAt // empty | fromdateiso8601 | floor ]
|
|
63
67
|
| max // 0 | tostring)
|
|
64
68
|
'
|
|
69
|
+
# A comment matching neither family above is the gap this filter exists to
|
|
70
|
+
# surface rather than absorb: a worker inventing a sixth heading used to reach
|
|
71
|
+
# this script as silence, indistinguishable from no comment at all. The count
|
|
72
|
+
# is read the same way the reply count is, a rising value against the baseline
|
|
73
|
+
# being new to this script, and the newest heading's text rides along for the
|
|
74
|
+
# report. It carries its spaces intact rather than encoded, since it is the
|
|
75
|
+
# last field on both sides of the pipe: `${unmatched_state#* }` below strips
|
|
76
|
+
# only the first space, and `read -r` further down hands its last named
|
|
77
|
+
# variable the rest of the line whole. Neither reads a heading's own spaces
|
|
78
|
+
# as a field separator, so a heading round-trips verbatim into the report a
|
|
79
|
+
# person reads when deciding whether to answer it by hand.
|
|
80
|
+
JQ_UNMATCHED_STATE='
|
|
81
|
+
[ .comments[]
|
|
82
|
+
| (.body // "") | split("\n")[0] | rtrimstr("\r")
|
|
83
|
+
| select(startswith("## "))
|
|
84
|
+
| select(. != "## Review" and . != "## Review closed"
|
|
85
|
+
and . != "## Review response" and . != "## Rebase"
|
|
86
|
+
and . != "## Post-review findings")
|
|
87
|
+
] as $unclassified
|
|
88
|
+
| ($unclassified | length | tostring)
|
|
89
|
+
+ " "
|
|
90
|
+
+ (($unclassified | last) // "none")
|
|
91
|
+
'
|
|
65
92
|
|
|
66
93
|
# `claude-pr-review` states the threshold and posts `## Review` exactly when a
|
|
67
94
|
# pass carries a finding, so the heading of the last review is what says whether
|
|
@@ -176,6 +203,11 @@ snapshot() {
|
|
|
176
203
|
# Three space-separated fields, so the line below carries them as its own
|
|
177
204
|
# sixth, seventh, and eighth rather than needing a split.
|
|
178
205
|
review_state=$(jq -r "$JQ_LAST_REVIEW_STATE" <<<"$payload")
|
|
206
|
+
# Split the same way as the reply state, carried as the line's tenth and
|
|
207
|
+
# eleventh fields.
|
|
208
|
+
unmatched_state=$(jq -r "$JQ_UNMATCHED_STATE" <<<"$payload")
|
|
209
|
+
unmatched_count=${unmatched_state%% *}
|
|
210
|
+
unmatched_heading=${unmatched_state#* }
|
|
179
211
|
|
|
180
212
|
# `gh pr view --json mergeable` reports UNKNOWN until GitHub finishes
|
|
181
213
|
# computing it, which is exactly when a poll asks. merge-tree answers
|
|
@@ -194,7 +226,7 @@ snapshot() {
|
|
|
194
226
|
merges=conflict
|
|
195
227
|
fi
|
|
196
228
|
|
|
197
|
-
echo "$n $head ${prior:-none} $resp $merges $review_state $reply_at"
|
|
229
|
+
echo "$n $head ${prior:-none} $resp $merges $review_state $reply_at $unmatched_count $unmatched_heading"
|
|
198
230
|
done
|
|
199
231
|
}
|
|
200
232
|
|
|
@@ -211,7 +243,7 @@ CHANGED=0
|
|
|
211
243
|
# would fire on every later run and the board would never read "No movement."
|
|
212
244
|
FINAL=""
|
|
213
245
|
|
|
214
|
-
while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
246
|
+
while read -r n head prior resp merges heading age pass_at reply_at unmatched_count unmatched_heading; do
|
|
215
247
|
[ -z "$n" ] && continue
|
|
216
248
|
state=$heading
|
|
217
249
|
old=$(grep "^$n " "$STATE" || true)
|
|
@@ -229,7 +261,7 @@ while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
|
229
261
|
echo "OPENED #$n at ${head:0:7}, $merges against $BASE_BRANCH"
|
|
230
262
|
fi
|
|
231
263
|
CHANGED=1
|
|
232
|
-
FINAL+="$n $head $prior $resp $merges $state $
|
|
264
|
+
FINAL+="$n $head $prior $resp $merges $state $unmatched_count"$'\n'
|
|
233
265
|
continue
|
|
234
266
|
fi
|
|
235
267
|
old_head=$(echo "$old" | cut -d' ' -f2)
|
|
@@ -240,6 +272,7 @@ while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
|
240
272
|
# age decides the rest, so the first run after an upgrade needs no history and
|
|
241
273
|
# classifies a thread already past the threshold rather than waiting a run.
|
|
242
274
|
old_heading=$(echo "$old" | cut -d' ' -f6)
|
|
275
|
+
old_unmatched=$(echo "$old" | cut -d' ' -f7)
|
|
243
276
|
|
|
244
277
|
# A conflict arrives from the base moving, not from the branch, so it is
|
|
245
278
|
# reported on the transition rather than only when the head changes.
|
|
@@ -248,6 +281,19 @@ while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
|
248
281
|
CHANGED=1
|
|
249
282
|
fi
|
|
250
283
|
|
|
284
|
+
# A rising count is what is new to this script, the same test RESPONSE
|
|
285
|
+
# below runs against the reply family. It fires on a tracked pull request
|
|
286
|
+
# only: a first sighting reports SEEN or OPENED and takes whatever count
|
|
287
|
+
# already sits on the thread as its starting baseline rather than flagging
|
|
288
|
+
# history retroactively. A carried line supplies neither, since
|
|
289
|
+
# carry_forward re-echoes the shorter baseline shape rather than a full
|
|
290
|
+
# snapshot line, so both sides default to zero the way old_unmatched
|
|
291
|
+
# already does.
|
|
292
|
+
if [ "${unmatched_count:-0}" -gt "${old_unmatched:-0}" ]; then
|
|
293
|
+
echo "UNMATCHED #$n posted under '$unmatched_heading'"
|
|
294
|
+
CHANGED=1
|
|
295
|
+
fi
|
|
296
|
+
|
|
251
297
|
if [ "$head" != "$old_head" ]; then
|
|
252
298
|
if [ "$prior" = "none" ]; then
|
|
253
299
|
echo "MOVED #$n -> ${head:0:7}, never reviewed"
|
|
@@ -312,7 +358,7 @@ while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
|
312
358
|
# re-enters next run and STALLED oscillates instead of reporting once.
|
|
313
359
|
state=reported
|
|
314
360
|
fi
|
|
315
|
-
FINAL+="$n $head $prior $resp $merges $state"$'\n'
|
|
361
|
+
FINAL+="$n $head $prior $resp $merges $state $unmatched_count"$'\n'
|
|
316
362
|
done <<<"$NEW"
|
|
317
363
|
|
|
318
364
|
while read -r n _rest; do
|
|
@@ -11,6 +11,8 @@ Without this skill, a pull request is reviewed only by the session that wrote it
|
|
|
11
11
|
|
|
12
12
|
A finding also stops being true by argument rather than by a fix. A worker naming the plan question that already declined it, or a constraint the pass could not see, settles it in the exchange that carried the answer, and the pass that accepts the argument drops the finding from its next body. A reader then sees a finding raised once and never mentioned again, which is indistinguishable from one everyone forgot.
|
|
13
13
|
|
|
14
|
+
A request written under `## For the reviewer` also reached no reader. The authoring standard names it as what the reviewing session should confirm, and nothing on this side read the section by that name, so a branch author's question sat in the body until this skill answered it.
|
|
15
|
+
|
|
14
16
|
## Must
|
|
15
17
|
|
|
16
18
|
- Post until the review closes. A first pass opens against the whole change, and each later pass checks whether the prior findings landed.
|
|
@@ -22,6 +24,7 @@ A finding also stops being true by argument rather than by a fix. A worker namin
|
|
|
22
24
|
- State a withdrawal or a regrade on the thread with the fact that settled it, since a finding dropped in silence reads the same as one nobody answered
|
|
23
25
|
- Key the body file on the pull request number and the head commit, and on the response it answers once the head repeats, so no two passes overwrite each other
|
|
24
26
|
- Scan the comment for banned characters and internal phase labels before posting, since a finding phrased against a phase label reaches a reader with no task board
|
|
27
|
+
- Answer a `## For the reviewer` bullet in the body, bounded to the section itself rather than the Summary or the Technical Context around it, so the independent vantage stays clear of the author's framing
|
|
25
28
|
|
|
26
29
|
## Must not
|
|
27
30
|
|
|
@@ -15,7 +15,7 @@ review against the whole change, and every later pass reads only the commits
|
|
|
15
15
|
added since. The heading reports state rather than pass number: a pass carrying
|
|
16
16
|
anything owed takes `## Review`, and `## Review closed` covers a pass carrying
|
|
17
17
|
none, so the most recent comment's heading reports whether any work is owed.
|
|
18
|
-
Owed is a finding at any severity
|
|
18
|
+
Owed is a finding at any severity, a Testing question, or a reviewer request nobody has answered, defined once at Step 4. Every pass is this skill, and which one it is gets detected from
|
|
19
19
|
the thread rather than named by the caller.
|
|
20
20
|
|
|
21
21
|
## Guards
|
|
@@ -89,6 +89,10 @@ Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/
|
|
|
89
89
|
|
|
90
90
|
Ask rather than grade. Whether a human is genuinely required is a reading the branch author may hold a reason this session cannot see, so the question carries no severity and enters no count. What it does carry is the heading and the dispatch, on the rule Step 4 states, because a question the author never receives corrects nothing and the author is the only party who can answer it. Answering it closes it, and the answer may be that the requirement holds.
|
|
91
91
|
|
|
92
|
+
Read `## For the reviewer` the same way, bounded to the bullets under that heading rather than the Summary or the Technical Context around it. Those two carry the author's argument for the change, and reading them while judging it is most of what an independent pass exists to avoid, so the read stops at the section itself.
|
|
93
|
+
|
|
94
|
+
Answer each bullet in the body, on the same terms as a Testing question: no severity, no count. A request nobody can answer stays owed under the heading and dispatch Step 4 states, keeping the thread open exactly as an unanswered Testing box does. One the pass does answer carries no further weight, since the answer is discharged in the same comment that carries it.
|
|
95
|
+
|
|
92
96
|
Apply the high-signal filter: flag only what will cause incorrect behavior, break a documented rule, or mislead a downstream feature. If uncertain, do not flag.
|
|
93
97
|
|
|
94
98
|
A later pass applies the same axes to the delta, and adds one check the first pass cannot make: did each prior finding land, and did the fix regress anything it touched. Findings of its own are normal findings, stated at the same severity and counted the same way. That count is one of the two things Step 4 reads to pick the heading, so a pass raising a finding of its own is not a close-out at any severity.
|
|
@@ -160,7 +164,17 @@ A Testing box the Step 3 check raised goes in a `**Testing**` block placed after
|
|
|
160
164
|
|
|
161
165
|
Keep it to the boxes the check raised. Restating a box whose stated requirement holds teaches the branch author to skip the block.
|
|
162
166
|
|
|
163
|
-
|
|
167
|
+
Every `## For the reviewer` bullet Step 3 read goes in a `**For the reviewer**` block placed after the Testing block, one bullet per request, each followed by its answer or, where the pass could not answer it, by what would settle it. It carries no severity and enters no count.
|
|
168
|
+
|
|
169
|
+
An unanswered bullet is owed the same way an unanswered Testing box is, so a pass carrying one takes `## Review` and the full body rather than either ✅ line. A bullet the pass answered is not owed, since the answer is discharged in the same comment that carries it. A pass still posting a numeric summary line, because a finding, a Testing question, or an unanswered bullet already forces one, says so there as `plus N reviewer request(s)`. The all-answered close-out below carries the block in place of that line and needs no addition to it.
|
|
170
|
+
|
|
171
|
+
```markdown
|
|
172
|
+
**For the reviewer**
|
|
173
|
+
|
|
174
|
+
- Confirm the 401 and 403 split reads correctly for the public API. Confirmed — `AuthService.authenticate()` returns 401 for an expired token and 403 for a missing scope, and both paths are covered under `## Testing`.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The threshold is stated here and nowhere else, and every other surface acting on it cites this skill rather than restating the grades. One rule governs both the heading and the dispatch: a pass carrying anything owed takes `## Review` and owes a dispatch to the session holding the branch, and a pass carrying nothing at all takes `## Review closed` and owes none. Owed covers a finding at any severity, a Testing question, and a reviewer request nobody has answered alike, which is what keeps the two halves from separating. Sending that dispatch is `claude-orchestrate`'s step rather than this one, which posts and stops. Post the open heading whether it is the first pass or the fourth. A pull request thread then reads as `## Review`, the worker's answer under `## Review response` from `claude-address-review`, another `## Review` while anything stays open, and `## Review closed` when nothing does.
|
|
164
178
|
|
|
165
179
|
Keying either half on the grade was measured wrong: across 8 findings on one archived pass, 3 were posted as minor and 2 of those were defects a worker fixed rather than recorded, so a floor at should-fix loses real fixes to a grade that runs low. Splitting the two halves so the dispatch fired lower than the heading was the other candidate, and it left a thread reading closed while work was owed on it. The Testing question was first written to sit outside both, which is that same split reached from the other side, and it left the one party who could answer the question with no route to it.
|
|
166
180
|
|
|
@@ -170,7 +184,9 @@ A minor the dispatched worker declines is what needs a surface that survives the
|
|
|
170
184
|
|
|
171
185
|
Read the state off the most recent review comment rather than off the presence of a closed one. A close-out does not close the pull request, so a commit pushed after it gets its own pass, and that pass reopens the review under `## Review` when it raises a finding of any grade.
|
|
172
186
|
|
|
173
|
-
Both of this skill's headings anchor as a section distinct from human threads.
|
|
187
|
+
Both of this skill's headings anchor as a section distinct from human threads, and neither invents beyond what the whole set already states. That set is five headings across two families, stated here once so `claude-orchestrate`'s poll and every reply-posting skill cite it rather than carry a copy. The review family, `## Review` and `## Review closed`, belongs to this skill alone, and the reply family, `## Review response`, `## Rebase`, and `## Post-review findings`, belongs to `claude-address-review`.
|
|
188
|
+
|
|
189
|
+
The first reply heading answers a finding this skill posted, the second reports a stale branch resolved without one, and the third carries a finding a worker produces after a close-out rather than in answer to one already on the thread, since a finding produced late is still a finding. A comment posted under a heading outside these five reaches the poll as unclassified rather than as silence, so an invented sixth heading is a gap the next run reports instead of one it repeats. Do not append the PR number, which GitHub already renders above the comment.
|
|
174
190
|
|
|
175
191
|
Name the scope in every summary line after the first pass, since a reader cannot otherwise tell a narrow read from a full one. When the fallback in Step 2 fired, replace the commit count with `Re-reviewed the full change, the prior pass's commit is no longer on the branch`.
|
|
176
192
|
|
|
@@ -190,7 +206,7 @@ gh pr review <number> --comment --body-file .claude/.tmp/pr-review/body-<number>
|
|
|
190
206
|
|
|
191
207
|
A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. On a first pass, post `✅ No findings. Reviewed against project docs and the board.` On a later pass, post `✅ Prior findings addressed. Re-reviewed <short-sha>, N commits since the prior pass.`
|
|
192
208
|
|
|
193
|
-
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. A pass carrying only Testing questions takes the same route for the same reason. Keep whichever scope sentence the pass owes on the summary line:
|
|
209
|
+
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. A pass carrying only Testing questions, or only an unanswered reviewer request, takes the same route for the same reason. Keep whichever scope sentence the pass owes on the summary line:
|
|
194
210
|
|
|
195
211
|
```markdown
|
|
196
212
|
## Review
|
|
@@ -206,6 +222,8 @@ A pass carrying only minors is an ordinary finding-carrying pass, so it takes th
|
|
|
206
222
|
|
|
207
223
|
A pass that closed by withdrawing a finding rather than by reading its fix takes neither ✅ line, per the withdrawal rule in Step 3. Both claim a fix landed, and the second names it, so posting either over a withdrawal credits work nobody did on the one comment a reader treats as the verdict. Write the withdrawal and the fact that settled it in place of the canned line, keeping the heading and the footer.
|
|
208
224
|
|
|
225
|
+
A pass whose only content is a `## For the reviewer` block with every bullet answered, and that owes nothing else, takes the same shape: `## Review closed`, the block in place of the canned line, and the footer. The heading reports what the branch author still owes rather than what the pass did, and an answer discharged in the same comment owes nothing back.
|
|
226
|
+
|
|
209
227
|
Post a close-out even when there is nothing to report. A review left with no closing comment reads as one nobody answered.
|
|
210
228
|
|
|
211
229
|
## Step 5: output
|
|
@@ -216,4 +234,6 @@ X critical, Y should-fix, Z minor. Posted to PR #<number>.
|
|
|
216
234
|
|
|
217
235
|
Add `N Testing question(s) raised.` to that line when the Step 3 check raised any. The counts cover findings alone, so a pass whose only output was a question otherwise reports as silent to the session that drove it. That session is not who the question is addressed to, which is what the dispatch covers.
|
|
218
236
|
|
|
237
|
+
Add `N reviewer request(s) answered.` to that line when the PR body carried a `## For the reviewer` section. The counts and the Testing question line both cover something else, so a pass that only answered a request otherwise reports as silent too.
|
|
238
|
+
|
|
219
239
|
Report the merge decision as a plain recommendation in chat (merge, or address findings first). Do not merge.
|
package/package.json
CHANGED
package/standards/pr.md
CHANGED
|
@@ -43,7 +43,7 @@ Does not govern:
|
|
|
43
43
|
- `## Testing` (optional): specify exact commands or test cases run
|
|
44
44
|
- Omit Testing for docs, config, or trivial sync changes
|
|
45
45
|
- Use checkboxes, never prose. See Testing discipline for which box gets ticked.
|
|
46
|
-
- `## For the reviewer` (optional): what the
|
|
46
|
+
- `## For the reviewer` (optional): what the reviewing session should confirm, one bullet per request
|
|
47
47
|
- Visuals: include only when they clarify architecture, UI, or complex logic flows
|
|
48
48
|
|
|
49
49
|
## Testing discipline
|
|
@@ -88,7 +88,7 @@ Does not govern:
|
|
|
88
88
|
|
|
89
89
|
## For the reviewer
|
|
90
90
|
|
|
91
|
-
- <What the
|
|
91
|
+
- <What the reviewing session should confirm>
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
### Correct
|
|
@@ -134,5 +134,5 @@ This PR updates the authentication system to be more robust. # "This PR" opener
|
|
|
134
134
|
|
|
135
135
|
- Tested manually # no specific command or case
|
|
136
136
|
- [ ] `npm run test:auth` # unchecked box for a check the agent can run
|
|
137
|
-
- [ ]
|
|
137
|
+
- [ ] The reviewing session confirms the error split reads correctly # a reviewer request, belongs under `## For the reviewer`
|
|
138
138
|
```
|