diff --git a/changelog.d/gst-965-finish-review-loop-exception.md b/changelog.d/gst-965-finish-review-loop-exception.md index 7a790b070..ff06e5a17 100644 --- a/changelog.d/gst-965-finish-review-loop-exception.md +++ b/changelog.d/gst-965-finish-review-loop-exception.md @@ -1,7 +1,7 @@ **`gstack-ship-release finish` now accepts the owner's edit after a fix-check instead of asking for another review round (GST-965).** On gbrain #8425, the fix-check found a blocker, the owner's pre-agreed fallback was applied and "then ship" was granted. Finish still classed the edit as behavior and stopped with `insert 5–11.5 → 12–14 → 16`, a third round the R51 cap forbids, so /ship could not get through Step 16 without running its stages by hand. ### Added -- **`finish --review-loop-exception `** (`lib/ship-release.ts`) takes the same record `gstack-ship-receipt write --review-loop-exception` takes. Paths changed since `fix_check.head` that the branch already touched at that commit (narrowed to the record's `fix_check.files` when it lists them) route as `accepted=` on the `ROUTE:` line, a `REVIEW_LOOP_EXCEPTION:` line names them with the owner, date and channel, and the docs stage carries them (`accepted=` in the DOCS line). A path outside that scope, a gate-edited test (with or without `--reviewed-base`) and a file too large for the scoped review still route as behavior. A malformed record, or a `fix_check.head` that is not HEAD or an ancestor of it, stops before the release commit. Without the flag nothing changes. +- **`finish --review-loop-exception `** (`lib/ship-release.ts`) takes the same record `gstack-ship-receipt write --review-loop-exception` takes. Paths changed since `fix_check.head` that the branch already touched at that commit (narrowed to the record's `fix_check.files` when it lists them) route as `accepted=` on the `ROUTE:` line, a `REVIEW_LOOP_EXCEPTION:` line names them with the owner, date and channel, and the docs stage carries them (`accepted=` in the DOCS line). A path outside that scope and a gate-edited test (with or without `--reviewed-base`) still route as behavior, and with `--reviewed-base` so does a file too large for the scoped review. A malformed record, or a `fix_check.head` that is not HEAD or an ancestor of it, stops before the release commit. Without the flag nothing changes. ### Tests - `test/ship-rereview-triggers.test.ts`: an owner fallback edit to a source file and a doc after the fix-check stops without the record and passes Step 16 with it; a new file outside the scope (even when `fix_check.files` lists it), a fix-check head off the branch, a malformed record, an unreadable record file and an empty `fix_check.files` stop; a `fix_check.files` list narrows what is accepted; a test weakened after the fix-check stops with and without `--reviewed-base`. diff --git a/docs/review-policy.md b/docs/review-policy.md index c25d74622..87129195b 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -422,9 +422,9 @@ under `REVIEW_LOOP:`. Step 16 takes the same record: paths the branch touched at `fix_check.head` (narrowed to the record's `fix_check.files` when it lists them) and changed since as `accepted=` in `ROUTE:`, prints them on a `REVIEW_LOOP_EXCEPTION:` line, and carries them -through the docs stage. A path outside that scope, a gate-edited test and a -file too large for the scoped review still route as behavior, and without the -record nothing changes. +through the docs stage. A path outside that scope and a gate-edited test still +route as behavior, with `--reviewed-base` (as /ship passes it) so does a file +too large for the scoped review, and without the record nothing changes. The receipt's summary line prints `passes= blocking_found= deferred=`, which is what a scorecard tracks (target: a median of 1 pass per PR). A