Repository navigation
review-pr: settle earlier findings on a re-review; name skill and model on the card - #2183
Conversation
Code metrics gate: PASSEDJudged: the 8 files this change touches. Files it does not touch never fail it; anything found there is listed under Outside this change for information.
17 findings in files this change does not touchOutside this change (informational): 17
Thresholds and sources: |
c03be87 to
86da0ee
Compare
ZhengGong-amd
left a comment
There was a problem hiding this comment.
The goal (re-reviews that continue from earlier cards, a named skill and model, a way to measure) is right. The route adds mechanisms the repo already covers, and several of them fail silently. Please rework it as one PR along these lines.
-
Re-review reuses what exists; drop the second card parser.
- Earlier cards from the author, writers and the bot are already in
comments.txt(fetch.shtrusted filter).prior.txtre-parses them withscripts/review_pr_cards.py, whilepr-review-publish.shparses the same card contract in shell. That is two owners for one contract. - Replace with an instruction in
SKILL.md/references/re-review.md: read the latest card incomments.txt, settle each finding FIXED / HOLDS / MOVED inprior_verdicts.txt, keep HOLDS under its key. Make thepublish.shgate a shell check using the same strict matchingpublish.shalready applies to the card. - Delete the
prioranddeltasubcommands,prior.txt,deltafiles.txt,delta.txtand thegh comparelogic.re-review.mditself says the delta "never limits what is read", so it only reorders reading. - Sync the text that still contradicts this:
SKILL.mdStep 7 and thecomments.txtrow ("do not repeat a point already made"), Step 1b (re-review.md adds HOLDS/MOVED rules, Step 1b does not), thepublish.shheader comment, and the Output contract for the new card fields.
- Earlier cards from the author, writers and the bot are already in
-
Roundis not what the skill says it is.prior_textsetsround = len(cards) + 1, which counts every trusted card, including re-runs on the same head and local reviews. The "round 3: ask the author to reconsider the approach" rule can fire with no author change. RemoveRound, or define it as pushes that changed a patch. -
Silent failures to remove.
fetch.shwritesSkill: unknown/Model: unknownand nothing enforces them, so cards can ship without the version the PR exists to record. Fail the fetch or reject the card.gh api compare ... || truereports any API failure as "not an ancestor (rebased?)", while the nextmerge_base_commitcall has no guard. Let it fail visibly.grep -q '^card [0-9]' "$WORK/prior.txt" 2>/dev/nullinpublish.shskips the gate when its input is missing, andPrior: .+accepts any text.- A card the parser does not recognise turns the whole feature off (round 1, no gate) with no message.
_prior()silently drops malformed items; the evalscorejob is green with no replay results (continue-on-errorplusmkdir -p results).
-
Delete
scripts/review_pr_stats.pyand its tests. Nothing in the repo consumes it; its numbers are already in the description. Also drop fields nothing reads outside tests:Finding.missed_at,Finding.verified,Card.review_round,Card.prior,Card.deferred,Card.base,Card.title. -
The eval part does not measure what it claims; reconsider it before keeping it.
- Positive cases come from the
rules.md"Seen in" PRs (#1564, #1444, #1497, #1567, #1563, #1526). The replayed agent reads the currentrules.md, which already describes each bug, so the replay checks whether the agent finds the answer written in the skill, not whether the skill finds problems. - The agent runs unrestricted with a read token, and
fetch.shonly cuts its own artifacts, so later comments on the merged PR are reachable. - 7 positive cases at 1 replay each cannot separate a skill change from model variance.
- If kept: pick cases that are not quoted in
rules.md, say how later information is excluded, size the repeats, and reusepr-review.ymlviaworkflow_callinstead of copying its checkout/node/gh/merge-base steps. Drop--json, the agreement metric and theload_casesvalidation for a repo-owned file.
- Positive cases come from the
-
Tests.
- Remove: the stats tests,
len(cases) >= 10, the malformed-case tests, thematrixexact-stringstartswithtest. - Add: tests for the new
publish.shgate and forpr-review-run.sh(the description says both were only checked by hand; the eval workflow has never run). The[result]line test uses a hand-written line while the real one comes from the jq inpr-review-run.sh; nothing ties them together.
- Remove: the stats tests,
Per AGENTS.md: "Simplify by removing a mechanism", "Trust the caller" and "Finish the replacement" (owners: pr-review-publish.sh and comments.txt for card handling; pr-review.yml for the review job). Please update the description to match the reduced diff.
Two cards that disagree about one head can come from different versions of the skill or from different models, and nothing on a card says which: none of the 125 cards on the last 100 merged pull requests (#2028..#2174) does. fetch.sh now writes skill.txt: the tree hash of .claude/skills/review-pr at HEAD, +dirty with uncommitted edits, and the model the environment names. It stops when git cannot name the tree, rather than let a card ship without the version. The card's Checked line carries Skill and Model; a local run names the model its system prompt gives when the environment names none. pr-review-publish.sh applies the bot's verdict only when the card names exactly the skill and the model skill.txt recorded for the run, with a clean tree and a known model, and the CI contract asks for that. SKILL.md stays within its 350-line budget: the CI failure classification, read only before ci.txt or mergeable is quoted, moves unchanged to references/ci.md. Co-authored-by: Cursor <cursoragent@cursor.com>
86da0ee to
6b124c4
Compare
|
Reworked along these lines; the PR is now two commits and no production Python.
|
A re-review reads the earlier cards in comments.txt as prose: a finding fixed since can vanish without a word, one that still holds can come back under a new name, and nothing tells the author which. On #2045 a second review of the head the author's own card had passed found a defect the author then fixed, and nothing on that card said the first one had missed it. references/re-review.md, read whenever comments.txt holds an earlier card for the PR, has the review decide each finding of the latest card first, FIXED, HOLDS or MOVED, into prior_verdicts.txt, and then review the whole diff as a first review does. A finding that holds goes back under its key, opening `held since <sha>`; a new finding on code the earlier card's head already had says `(missed at <sha>)`; a class that comes back after the author changed the code names the cause the findings share. A defect in several places is one finding listing every place. The card's Checked line adds Prior, `C1 fixed, T2 holds` or `none`, written only on a re-review. comments.txt heads each entry with its time: its three lists are written one after another, so their order does not say which card came last. pr-review-publish.sh applies the bot's verdict on such a PR only when prior_verdicts.txt is one well-formed line per finding, the card's Prior lists it key for key, and every HOLDS or MOVED key is back among the numbered findings (a clean card beside Prior: C1 holds would otherwise dismiss the bot's earlier request-changes review). The CI contract asks for both. Any `## PR #<n>` heading in comments.txt counts as an earlier card: earlier cards include ones people posted from local runs, and a stricter match would switch the check off unseen. The check fails closed when comments.txt is missing, and a card naming a Prior on a PR with no earlier card is refused. Skill hashes accept the 12-to-40 hex digits `git rev-parse --short=12` can emit. SKILL.md stays within its 350-line budget: two pairs of artifact rows share a row each. Co-authored-by: Cursor <cursoragent@cursor.com>
6b124c4 to
91a6004
Compare
Description: what and why
review-pr reviews every push of a pull request from scratch. The earlier cards sit in
comments.txtas prose, so a finding fixed since can vanish without a word, one that still holds can come back under a new name, and two cards on one head can disagree with neither saying why. Nothing on a card says which version of the skill or which model wrote it: none of the 125 cards on the last 100 merged PRs (refactor(kb_store): move derive_kernel_names into kb_store.identity.kernel_names #2028..Document which roles the agent backend governs and how deepseek joins the Forge relay #2174) does. On fix(report): count dispatches, kernel outcomes and critic passes once each #2045 a second review of the head the author's own clean card had passed found a defect the author then fixed, and nothing marked it as a miss.Two commits; please use Rebase and merge:
Checked:line namesSkill:(the tree hash of.claude/skills/review-pr,+dirtywith local edits) andModel:, whichfetch.shrecords inskill.txt;fetch.shstops when git cannot name the tree.pr-review-publish.shapplies the bot's verdict only when the card names exactly this run's skill and model, with a clean tree and a known model. The CI failure classification moves unchanged toreferences/ci.md, soSKILL.mdstays within its 350-line budget.comments.txtholds an earlier card, the review first decides each finding of the latest card,FIXED,HOLDSorMOVED, intoprior_verdicts.txt, then reviews the whole diff as a first review does (references/re-review.md). A finding that holds keeps its key and saysheld since <sha>; a new finding on code the earlier card already passed says(missed at <sha>); a class that comes back after the author changed the code names the cause the findings share. The card'sChecked:line addsPrior: C1 fixed, T2 holds, orPrior: none.pr-review-publish.shapplies no verdict to such a PR when the review left noprior_verdicts.txt, the card'sPriordoes not list it key for key, or aHOLDS/MOVEDkey is missing from the numbered findings (a clean card besidePrior: C1 holdswould otherwise dismiss the bot's earlier request-changes review).comments.txtnow heads each entry with its time, so the latest card can be told apart.Linked issue(s): none
Tests: added/updated? commands run? (what to test; if a test was replaced, where its assertions live now):
scripts/tests/test_pr_review_publish.py,pr-review-publish.shagainst a stubgh. A card naming this run's skill and model gets its verdict; an unknown model, a dirty or another skill, or a missingskill.txtgets none. A first review beside another PR's card and a re-review that settles the earlier card (fixed; holds and fixed; moved on the card; none) get their verdict. A re-review with noprior_verdicts.txt, a malformed line,nonebeside findings, aPriorthat disagrees or is missing, aHOLDS/MOVEDkey dropped from a clean card, aPrioron a PR with no earlier card, or a review that left nocomments.txtgets none.scripts/tests/test_review_pr_fetch.pygainsskill.txt, the stop outside a git checkout, and the timedcomments.txtheaders.ruff check .,ruff format --check .,check_broad_suppress.py src scripts,check_cli_references.py,pytest scripts/tests(816 passed, 2 skipped, neither in these files),code_metrics.py --base-ref origin/main(passed). Theruffpre-commit hook fails onmainthe same way (--force-excludepassed twice), so ruff ran directly. After the self-review fix:pytest scripts/tests/test_pr_review_publish.py scripts/tests/test_review_pr_fetch.py(30 passed), andruff check .andruff format --check .with the pinned ruff 0.16.2.Size/complexity triggers crossed: split, or why the shape is right: none; no production Python changes, and most of the added lines are the two test files.
If this simplifies or refactors: which mechanism was removed, which contract was preserved, and the tests that show it: the CI failure classification moves verbatim from
SKILL.mdtoreferences/ci.md; nothing else moves.Observable effect: what an operator will now see, and what the old behaviour cost them (if none, why the change is unobservable):
Checked: ... | Ran: ... | Skill: <sha> | Model: <name> | Base: ... | Head: ....Prior: C1 fixed, T2 holds), keeps a finding that still holds under its key withheld since <sha>, and marks one an earlier card missed(missed at <sha>)instead of presenting it as new.Breaking changes: yes/no (details if yes): no. The stricter publish checks apply to the bot's cards, whose CI contract now asks for
Skill,Modeland, on a re-review,Prior; local runs work as before. An earlier card is recognised by its## PR #<n>heading alone, so older cards count.PR addresses single concern: yes/no (details if no): yes. Re-reviews that account for the earlier card; naming the skill and the model is what makes two cards comparable.
Root cause is upstream (Magpie/TraceLens/GEAK/IntelliKit/AgentKernelArena), ticket filed: n/a