5.8 KiB
PR#73: An Approval Survives a Rebase
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
The Problem
Gitea dismisses an approval when new commits arrive (dismiss_stale_approvals).
A rebase onto main, or a merge of main into the branch, thus costs a new human approval,
although the change of the PR stays the same.
werkator PR#137 needed three approvals of the same change in this way.
Non-Goals
- No carry-over of an approval that a human dismissed by hand or revoked with "request changes".
- No check that the merged
mainstill fits the change semantically; the CI (werkator) stays required for that. - No calibration of the Jev thresholds for corrections; this PR uses those of
[path_judge].
The Scenarios
Feature: an approval survives a rebase
Scenario#73.01: a rebase keeps the approval
So that a rebase onto main costs no new human approval.
- Given a human approved the head A of a PR
- When the PR is rebased onto a newer
mainwithout a conflict - Then werkrevisor approves the new head without Jev and without a model call
- And its reason names the approval of A
Verified by
Scenario#73.02: a small correction after a merge keeps the approval
So that a resolved merge conflict needs no human when Jev rates it as harmless.
- Given a human approved the head A of a PR
- And the new head has a changed block that A did not have
- And Jev rates that block below the thresholds of
[path_judge] - When werkrevisor reviews the new head
- Then it approves without a model call
Verified by
Scenario#73.03: a risky correction gets a review of the correction only
So that approved changes do not block the PR again.
- Given a human approved the head A of a PR
- And Jev rates a new block as risky
- When werkrevisor reviews the new head
- Then the model gets only the files with new blocks
- And a finding on the lines of an approved block is a hint
Verified by
- test_carry_over.CarryOverTest.test_a_risky_correction_gets_a_review
- test_carry_over.CarryOverTest.test_a_finding_on_approved_lines_is_a_hint
- test_carry_over.ChangeKindTest.test_the_kind_comes_from_the_files_outside_the_approval
Scenario#73.04: an approval dismissed by hand is not carried over
So that a human can take back an approval.
- Given a human dismissed the approval by hand
- When werkrevisor reviews the new head
- Then the model reviews every changed file
Verified by
Scenario#73.05: a dropped approved change is not carried over
So that a check that the PR added cannot disappear unnoticed in a rebase.
- Given a human approved the head A of a PR
- When a rebase drops a changed block of A
- Then the next review gives the model every changed file
- And a hint names the number of missing blocks
Verified by
Scenario#73.06: blocks approved by werkrevisor do not block again
So that a rebase after a GREEN review brings no new blocking findings on unchanged lines.
- Given werkrevisor approved the head A of a PR as GREEN
- When werkrevisor reviews the rebased head
- Then a finding on a block of A is a hint
Verified by
The Solution
- Every result comment gets a hidden marker with a fingerprint per changed block: the path, the removed and the added lines, without line numbers and without context.
- A review looks for the newest approval of a head other than the current one: a human approval that Gitea dismissed automatically, or a GREEN approval of werkrevisor itself. The fingerprints come from the result comment of werkrevisor for that head.
- After a human approval, files with approved blocks only are left out of Jev and the model, like mechanical files. Without new blocks, werkrevisor approves; with new blocks, Jev judges their files first.
- A finding of the model on approved lines only is a hint.
- The change kind, which the model checks, comes from the files outside the approval.
[gate] carry_over_approvals = falseswitches the carry-over of human approvals off.- The README explains it under "Approval after a rebase"; the decision diagram shows both shortcuts.
- Version 0.32.0.
Open Questions
- Can werkrevisor compare the approved head with the new one through the Gitea API?
Not directly: the compare route with
.diffanswers 404 for a private repository, even with a token. So each review keeps the fingerprints of its own head in its result comment. - How does werkrevisor tell an approval dismissed by a push from one dismissed by hand?
Gitea's timeline has a
dismiss_reviewevent; after a push its text is "New commits pushed, approval review dismissed automatically", by hand it is the text of the human.
Additional Changes
- The Werkbaum gets the plan
#werkregie.pwa: the Werkregie frontend becomes a PWA; this PR does not implement it.
Follow-up PRs
- Calibrate the Jev thresholds for corrections on real rebases, e.g. werkator PR#137, see
#gate.carry.calibrate.