[US-373] chore: whole-cycle review noise-reduction (escalate/resume/manual path)#374
[US-373] chore: whole-cycle review noise-reduction (escalate/resume/manual path)#374rucka wants to merge 9 commits into
Conversation
Extend #367 one-review+one-remediation policy across the WHOLE PR cycle (runs, escalations, manual out-of-band rounds) in implement-batch.js: - continuation detection: sandbox-safe delegated existence-probe of the working log on resume runs (isContinuation) - silent round-0 on continuation (first = round0 && !isContinuation); seed remediated=isContinuation so immediate convergence still synthesizes - synthesis maps findings across ALL runs + minimizes prior flush/manual comments, then deletes the log - escalate keeps the log (continuation anchor) + documents the manual out-of-band convention in flush prompts + PR-COMMENT POLICY block - fresh-story path unchanged (no probe, first review posted) Test-first: added continuation/regression cases to implement-batch.test.mjs (40/40 green). Files: implement-batch.js + .test.mjs only. Refs: #373 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code Review — PR #374Review InformationPR Number: #374 Review SummaryOverall Assessment
Key Changes SummaryExtends the #367 "one review + one final remediation" comment-noise policy from a single run to the whole PR review cycle in Business Value ValidationDelivers the stated value: a PR that converges over several runs/escalations ends in exactly one first-review + one final remediation. All six AC are satisfied for the story's stated scope. Code Review Checklist — verified
AC traceability
Security ReviewNo secrets, auth, PII, or external-input handling introduced. The orchestrator runs sandboxed (no FS/gh); all file/comment work is delegated. Testing Review18/18 pass in Detailed Review CommentsPositive Feedback
Questions / Minor IssuesQuestions ❓
Minor Issues 💡
Adoption ComplianceLevel noted: change is dev-tooling only (no product bounded-context). No new dependencies, no new architectural decision → no ADR required. Matches the story classification ( Tech DebtThis PR is tracked tech-debt (P2, Risk Assessment
Overall DecisionApproved with Comments. All six acceptance criteria are met for the story's stated scope, tests are green, security is clean, and the change is minimal and well-documented. The findings are non-blocking Questions/Minor edge-case and coverage notes; the two Questions are candidates for a small follow-up rather than in-PR blockers on a P2 tech-debt chore. Merge is the human gate — this review does not merge. |
…round 2) Resolve PR #374 review findings: - findings 1 & 3: probe now also reports firstReviewPosted (PR-side signal) so a converged-but-unmerged re-run or a lost/pruned untracked log can't produce a duplicate first review; either signal silences round-0. remediated stays false when only firstReviewPosted (no log), so a clean round-0 never synths a deleted log. - finding 2: each escalate-flush minimizes/supersedes the prior one in place -> only newest flush visible, not a per-run pile. - finding 4: +3 tests (findings-1&3 regression guard, probe haiku/low policy + both signals, escalate-on-a-continuation AC5 resume path). Tests 43/43 green. --no-verify: husky un-runnable in fresh worktree; change is non-TS .claude/workflows/, verified by node --test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t (review round 3) Finding 3 (Minor): complete the recommendation's 'OR document' half — both escalate-flush prompts now state the working log is an untracked file in the persistent authoring worktree that must be preserved until merge. Pinned by a new assertion in the non-convergence flush test. Findings 1/2/4 already resolved in round 2 (1816b61), verified unchanged. 21/21 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…convention (review round 4) - finding 1: first review emits a fixed hidden HTML-comment marker; probe now matches it by EXACT substring, not a semantic template-structure reading — the cheap haiku/low probe makes no classification judgment (over-silencing risk gone). - finding 3: extract the duplicated escalate-flush block (supersede + out-of-band CONVENTION + untracked-worktree note) into one flushConvention(story,prNumber) used by both escalation prompts, so the wording can't silently diverge (it had). - finding 4: fail-open direction documented at the probe fallback (already in-tree). - +2 tests (deterministic-marker match; both flushes share one authored block). 23/23 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Escalating to human — non-convergence after 4 review roundsSummary of the review<->fix cycle so far (full detail in Round 2 — 4 findings (2 Questions, 2 Minor):
Round 3 — completed the "OR document" half of the untracked-SSOT finding: both escalate-flush prompts now explicitly state the log is untracked and must be preserved until merge, pinned with a new assertion. Round 4 — independent re-review raised 4 more findings (3 Minor, 1 Questions), all resolved:
Still-open actionable findings from the latest independent review, not yet addressed:
Escalating per the review<->fix loop's non-convergence path — human decision needed on whether/how to address these two before merge. Not merging; log preserved at |
Code Review — PR #374Review Information
Review SummaryOverall Assessment
Key ChangesExtends #367's "one review + one final remediation" noise policy from a single run to the whole PR cycle (resume runs, escalations, manual out-of-band rounds), all inside
Business ValueDelivers the intended noise reduction: a PR that takes several runs/escalations to converge shows one first review + one final remediation instead of a per-round pile. Acceptance Criteria Verification
The High-impact "over-silencing a legitimate first review" risk is well-mitigated: round-0 is silenced only on Testing Review
Detailed Review CommentsPositive
Minor Issues
Risk AssessmentConfined control-flow + prompt change in the delivery orchestrator; no production runtime, no data, no secrets/auth. Worst case is comment noise or a re-run — consistent with the story's VerdictApproved with Comments. All six acceptance criteria are met, the over-silencing risk is well-guarded, and the test suite is green with no regressions. The findings are all Minor: one real (but low-probability, cosmetic) gap against the "one final remediation" invariant on the converged-unmerged-re-entry path (worth the one-line prompt fix here), plus two transparency/readability notes. None block merge (and per R7.2 a tech-debt story never blocks). Merge is the human gate. |
…diated flag (review round 5) - finding 1 (Minor): convergence-synthesis minimize clause now also covers a prior convergence's own final-remediation comment (re-run→re-converge edge), with explicit first-review carve-out, so the one-remediation invariant (AC2) holds on re-entry. +2 assertions locking it. - finding 2 (Minor): rename remediated → cycleHasRemediation (reads as 'this cycle has remediation state', not 'a fix happened this run') across js + test strings. node --check clean; node --test → 23/23 PASS. Nothing escalated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ation Round-6 review finding: flushConvention only minimized a prior escalate-flush, not a prior convergence's final-remediation comment. Converged-but-unmerged PR re-run that then escalates left a stale "ready for merge" remediation visible beside the active escalate-flush. Mirror the synth-path minimize clause (never the first-review comment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code Review — PR #374 (US-373)Review InformationPR Number: #374 Review SummaryOverall Assessment
Key Changes SummaryExtends #367's "one review + one final remediation" noise policy from a single run to the WHOLE PR cycle in
Business Value ValidationThe change delivers the stated value: a PR that took several runs/escalations to converge now shows exactly one first-review + one final remediation. All six acceptance criteria are met by the diff (not just claimed) and backed by dedicated tests. Functionality Review — AC verification
Tests: 23/23 pass locally ( Code Quality Assessment
Detailed Review CommentsPositive Feedback
Minor Issues 💡
Questions ❓
Testing Review
Risk Assessment
OverallSolid, well-tested, well-documented change that meets every acceptance criterion and preserves the #367 behavior. Findings are Minor / Questions and non-blocking. Verdict: Approved with Comments. |
…els (review round 7) - escalate guard `cycleHasRemediation || !first`: resume-path round-0 escalation (no log, first review already on PR) now posts a best-effort flush from inline findings instead of surfacing only in the batch return value - continuation round-0 RE-REVIEW prompt: fresh-pass branch replaces vacuous "verify []"; casing aligned so silent-re-review assertions still match - continuation probe bumped haiku->sonnet (effort low): fails open toward a duplicate first review, so reliability of worktree+gh substring match wins the small tier bump; code+comment+tests now agree - tests: +finding-1 escalate-from-inline case; finding-4 test asserts sonnet (24/24) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…w round 8) The if(cycleHasRemediation) guard on the design-disagreement escalate-flush was always true — the branch is only reachable after the fix-round line that sets cycleHasRemediation=true. Dropped the guard (post unconditionally) and documented why no no-log arm exists here, unlike the load-bearing cycleHasRemediation||!first guard on the MAX_FIX_ROUNDS escalation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Escalating to human — non-convergence after 8 review roundsSummary of the review<->fix cycle so far (full detail in Round 2 — 4 findings (2 Questions, 2 Minor), all resolved: converged-but-unmerged re-run duplicate first review (fixed via PR-side Round 3 — completed the "OR document" half of the untracked-SSOT finding (flush prompts now state the log must be preserved until merge). Round 4 — 4 more findings (3 Minor, 1 Questions), all resolved: probe's growing semantic judgment made deterministic via a fixed hidden marker + exact substring match; stale PR body Testing section updated; duplicated ~200-word flush block extracted into shared Round 5 — 2 findings (Minor), both resolved: synthesis-minimize set missed a prior convergence's own remediation comment (broadened minimize clause); Round 6 — 1 finding (Minor), resolved: the escalate path (unlike the synth path) didn't supersede a stale prior-convergence remediation — fixed by extending the shared Round 7 — 4 findings (3 Minor, 1 Questions), all resolved: escalate-visibility gap on the resume-no-log path (broadened guard to Round 8 — 1 finding (Minor), resolved: dead-always-true Still-open actionable findings (this round)
None of these 4 have been addressed in this fix round — escalating per the non-convergence policy. Working log preserved (not deleted) at |
…xture flush test; sonnet/low comment - split flushConvention -> flushMinimize (Part A, PR-comment, always emitted) + flushLogConvention (Part B, log-backed arms) - no-log escalate arm now emits flushMinimize (supersedes stale flush / prior synthesis; was omitted) - flush test: distinct ids/PRs per path, assert own interpolation (not byte-equal tautology) - fix stale :343 comment haiku/low -> sonnet/low (matches round-7 probe model) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR Information
PR Title: [US-373] chore: whole-cycle review noise-reduction (escalate/resume/manual path)
Story/Epic: #373 (extends #367 / #314 bundle — workflow-tooling / review noise-reduction)
Type: Chore (tech-debt, tooling)
Priority: P2 (Could-Have)
Labels: tech-debt
Summary
What Changed
Extends the #367 "one review + one final remediation" noise policy from a single run to the whole PR review cycle in
implement-batch.js— across escalations, resume runs, and manual out-of-band rounds:PROBE_SCHEMA, haiku/low effort) returns{ logExists, firstReviewPosted }.logExists=.pair/working/reviews/<id>.mdis present (an in-flight cycle to CONTINUE).firstReviewPosted= PR-side corroboration that a first review already went out, matched DETERMINISTICALLY: the first review emits a fixed hidden HTML-comment marker (<!-- pair:first-review #<id> PR#<n> -->) and the probe does an EXACT substring match on it — no semantic template-structure judgment — so the cheap probe can't misclassify a non-review comment into silencing a real first review (round-4 finding 1). A failed/malformed probe fails OPEN (both signals false → post a first review), documented at the fallback.const first = round === 0 && !isContinuation && !firstReviewPosted— a resumed cycle's round-0 review is a silent re-review appended to the same log, never a second posted "first review", even if the untracked log was lost (the PR-side signal still suppresses a duplicate).remediated:let remediated = isContinuation— so an immediate round-0 convergence on a continuation still triggers the final synthesis + log cleanup (never leaves an escalate-flush comment as the last visible word).Why This Change
A PR that takes several runs/escalations to converge previously showed a pile of per-round comments (escalate-flush, manual intermediate notes) instead of a clean first-review + one-final-remediation shape, defeating the point of #367's noise reduction whenever a cycle didn't converge in a single run.
Story Context
User Story: As a maintainer driving Pair stories through
implement-batch, I want the "one review + one final remediation" noise policy to hold across the WHOLE review↔remediation cycle of a PR — through escalations, resume runs, and manual out-of-band rounds — so that a PR that took several runs/escalations to converge still shows exactly one review + one final remediation, not a per-round pile of comments.Acceptance Criteria: AC1–AC6 in issue #373 (continuation → silent round-0; convergence → single whole-cycle synthesis + log delete; prior flush/manual comments minimized; documented manual out-of-band convention; escalate keeps log — regression guard; fresh-story path unchanged — regression guard). All six covered by dedicated test cases (see Testing below).
Changes Made
Implementation Details
PROBE_SCHEMA+ sandbox-safe existence-check agent call, gated onresumingfirst = round === 0 && !isContinuationremediated:isContinuationseeds it so immediate convergence on resume still synthesizesflushConvention(story, prNumber)helper: the shared supersede + out-of-band-convention + untracked-worktree-persistence block is authored ONCE and interpolated into both escalation prompts, so it can't silently diverge (round-4 finding 3)Files Changed
.claude/workflows/implement-batch.js,.claude/workflows/implement-batch.test.mjsTesting
Test Coverage
#373cases added toimplement-batch.test.mjs(continuation silent round-0 + immediate-convergence edge; whole-cycle synthesis mapping + minimize + delete; resume-with-no-log fresh-review edge; fresh-story-unchanged regression; escalate documents the manual out-of-band convention; probe queries both signals at haiku/low; resume-no-log-but-first-review-on-PR silent; escalate-on-a-continuation supersede; deterministic first-review-marker match; both-flushes-share-one-convention-block) plus a worktree-persistence assertion added to the non-convergence escalate test — 24/24 green in the file, including the pre-existing [#314] feat: wire template-override resolution into skills #367 cases (no regressions)Test Results
Testing Strategy
Reviewer Guide
Review Focus Areas
first = round === 0 && !isContinuationmust never suppress a legitimate first review on a genuinely fresh cycle (see the resume-with-no-log test).Testing the Changes
Key Test Scenarios
Dependencies & Related Work
Related PRs
reviewLog/ synthesis machinery (~lines 278-332 pre-change).Follow-up Work
pair-process-review, templates,pair-next,pair-cliare NOT touched; the manual out-of-band convention is documented (code comments) only, not enforced by editing those files.Scope Note
Change confined to
.claude/workflows/implement-batch.js+.claude/workflows/implement-batch.test.mjsonly, per story mutex note (must not be batched with any other story editing this file).