Repository navigation
ci(review-coverage): count a Review-Coverage footer only when the pre-push helper could have written it - #2894
Conversation
…hes the helper's grammar A hand-typed footer (`authored=claude @ <sha>; ran=codex,gemini; ...`) crediting a CI bot's review as the gemini leg scored two families and passed enforce mode, because structuredCoverage parses leniently. evaluateCiCoverage now checks the last footer line, read from the unmasked body, against the exact grammar formatReviewCoverage emits; a mismatch is still reported but counts 0 toward enforcement, and the detail names the mismatch and the pr-body-review-need.mjs --write remedy. The vendored reviewGate.mjs is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cj4LC7bsgYR6j8FPPG6EUW Dispatch-Task: harper-review-coverage-strict-footer
…d read families from the masked line A bare `Review-Coverage:` as the last footer fell back to an earlier footer's families and a "prose-only" note; it now reports zero and names the grammar mismatch. Families are read from the masked prose line so a trailing comment cannot rewrite them, while the grammar still checks the raw line. The remedy text no longer assumes a hand edit (a stale helper fails the same way), and the README notes the leg list is mirrored by hand from REVIEW_LEGS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cj4LC7bsgYR6j8FPPG6EUW Dispatch-Task: harper-review-coverage-strict-footer
…ke the masked-suffix test bite Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cj4LC7bsgYR6j8FPPG6EUW Dispatch-Task: harper-review-coverage-strict-footer
There was a problem hiding this comment.
Code Review
This pull request introduces strict grammar validation for the Review-Coverage: footer in the review-coverage CI action. It adds a new coverageFooterProblem helper in evaluateCiCoverage.mjs to parse and validate the footer's segments (such as authored, ran, and rounds) and its trailing SHA pin against the exact format emitted by the helper tool. If a footer is hand-edited or malformed, it now counts as zero toward enforcement. Comprehensive unit tests have been added to ci-review-coverage.test.mjs to verify various well-formed and malformed footer scenarios, and the README has been updated accordingly. There are no review comments to address, and I have no additional feedback to provide.
|
Reviewed; no blockers found. |
cb1kenobi
left a comment
There was a problem hiding this comment.
The CI coverage check now counts a Review-Coverage footer toward enforce mode only when it matches the helper grammar, so a hand-edited double-@ pin scores 0. The last footer still wins, families still come from the masked line, and a grammar mismatch also blocks the easy-complexity waiver. Helper-shaped variants, the observed malformed footer, and the CLI enforce path are tested. No confirmed blockers on the changed lines.
—
Reviewed 4df1292
The
review-coveragecheck now counts aReview-Coverage:footer towardmode: enforceonly when it matches the exact grammar the cross-model-review helper (formatReviewCoveragein skills-internal'sprepush-policy.mjs) writes. A hand-typed or hand-edited footer the helper could not have produced is still reported, but it counts 0, and the check names the mismatch and points atpr-body-review-need.mjs --write.The trigger: a PR carried the hand-written footer
authored=claude @ 5d0901e86b8f; ran=codex,gemini; rounds=4 @ 5d0901e86b8f, which credited a CI bot's review as thegeminileg, and the check passed with 2 families.structuredCoveragein the vendoredreviewGate.mjsparses leniently (split on;/=, strip@…), so any footer that roughly looks right was counted.For the human reviewer
evaluateCiCoverage.mjs), leaving the vendoredreviewGate.mjsbyte-identical with HarperFast/dispatchdispatch/lib/reviewGate.mjs. I followed that. The trade-off is that the dispatch server gate still parses leniently: it counts a hand-edited footer this check now rejects, so the two gates can disagree on the same PR body. Porting the same check todispatch/lib/reviewGate.mjsis the follow-up. Declining it here is cheap to reverse.authored; ran; [adjudicated]; [blocked]; [declined]; rounds; [full], known leg names per segment (ran=accepts only coverage legs, sodomain/conformancethere are rejected), no repeated legs, canonical positive integers, and exactly one trailing@ <12 lowercase hex>pin. The alternative was to check only known keys and the pin, and tolerate unknown legs. Cost of the strict choice: the leg list mirrorsREVIEW_LEGSby hand, so a new review leg must land here before the helper emits it, or compliant PRs naming it go red. The README now says so. Loosening later is a one-line change.pr-body-review-need.mjs --write. It also covers the opposite case: if a current helper wrote the footer, this check's grammar is behind and needs the new value. The alternative was to count the footer and only warn; switching to that is a one-line change.evaluatePrFormat.mjsalready fails a coverage pin that is not the current head (format check), and the coverage README deliberately reports but does not enforce the pin. This check only requires the pin to be well-formed.formatReviewCoverageand 305 real footers (see Verification). Nothing in this repo catches later drift. A generated fixture file, or a parity test on the skills-internal side, would, and is cheap to add later.LEG_FAMILYinreviewGate.mjshas no entry forcursor-kimi/cursor-muse, so both score as thecursorfamily.ran=cursor-composer,cursor-kimicounts 1 where the producer counts 2 (familieskimi,muse). This fails closed (under-count). The fix is two map entries in dispatch's canonical copy, then a re-vendor.Changes
evaluateCiCoverage.mjs: newcoverageFooterProblem(line)returns''for a helper-shaped footer, or a phrase naming the first mismatch.evaluateCiCoverageselects the last live footer as before. It runs the grammar on the unmasked body line (masking would hide a trailing<!-- -->or inline code the helper never writes) and zeroesenforceableon a mismatch. That also blocks theComplexity: easywaiver. Reported families still come fromstructuredCoverage, reading the masked line so a comment suffix cannot rewrite them. A last footer too broken to parse now reports 0 rather than falling back to an earlier footer.README.md: two sentences. Only helper-grammar footers are enforceable. The grammar catches malformed edits, not forgeries, and its leg list must trackREVIEW_LEGS.reviewGate.mjs: unchanged.Verification
Route: not observable end-to-end before merge. The workflow runs from the base checkout (
pull_request_target), so this PR's own check still runs main's evaluator. The evaluator is covered through its real CLI entry point instead.node --test .github/actions/review-coverage/*.test.mjs: 127 pass, 0 fail. New cases inci-review-coverage.test.mjs:ran=none,authored=unknown, adjudicated/blocked/declined,claude(fallback)(reason), with and withoutfull=, with and without<sub>.@footer, out-of-order segments, unknown and non-coverage legs inran=, a missing pin, duplicated@, a short or uppercase pin, an unknown segment, a reasonlessblocked=, a repeated leg or segment,rounds=01, a missingrounds=, an unpaired<sub>, and comment or inline-code suffixes.ci-review-coverage.mjs --mode enforce.Review-Coverage:line from the last 400 HarperFast/harper PR bodies was run throughcoverageFooterProblem. All 305 helper-produced lines pass. The 5 rejected lines are 4 hand-written footers plus one CRLF artifact:@footer. It is open and will go red on its next sync, which is intended.blocked=gemini. The helper has always writtenleg(reason).authored=), so its check does not change.unavailable=and a 9-hex pin.formatReviewCoveragefrom skills-internalorigin/main, run on synthetic receipts (fallback leg, blocked/declined,unknownauthor,full=), produced footers that all pass.npx oxlint --deny-warnings .github/actions/review-coverage/andprettier --checkare clean.git diff main -- .github/actions/review-coverage/reviewGate.mjsis empty.Complexity: medium
🤖 Generated with Claude Code
https://claude.ai/code/session_01Cj4LC7bsgYR6j8FPPG6EUW
— Claude Opus 5.5
Origin — the dispatch brief this PR was written from
Harden the
review-coverageGitHub Action (.github/actions/review-coverage/) so aReview-Coverage:footer counts as enforceable coverage only when it matches the exact grammar the cross-model-review footer helper emits. A hand-typed or hand-edited footer that the helper could not have produced must score as not enforceable (count 0 inmode: enforce), with a report line naming the mismatch and pointing atpr-body-review-need.mjs --write.Acceptance
Tests in .github/actions/review-coverage/ci-review-coverage.test.mjs (or a sibling) covering: every helper-shaped footer variant (ran=none; with adjudicated/blocked/declined; with and without full=; with and without ) is enforceable; the observed malformed footer above, a footer with segments out of order, an unknown leg name in ran=, a missing trailing
@ <sha>, and a duplicated@are NOT enforceable and the report names why. reviewGate.mjs unchanged. README.md in the action updated in one or two sentences to say only helper-grammar footers are enforceable. Follow harper-engineering-guidelines DLC; draft PR.Dispatch: task
harper-review-coverage-strict-footer· queued by kris-session · ran by claude/opus/high · worker kzyp-xps-1Review-Coverage: authored=claude; ran=codex,gemini; adjudicated=domain; declined=cursor-grok,cursor-composer,cursor-kimi,cursor-muse; rounds=3; full=1 @ 4df1292
Human-Review-Need: 3 (decisions: exact-helper-grammar, parity-by-hand, ci-only-strictness) @ 4df1292