PR #28's final review (review 1394). Neither item can be reached from either workflow today, so the PR merged without them. Each is a small hardening of scripts/release-v1.sh.
1. push_leased can move v1 backwards when called directly
release-v1.sh push <A> <B> with v1 = B, where B is already ahead of A, moves v1 back to A. The reviewer reproduced this. Neither workflow can reach it, because sweep-check only sets needed=true when v1 does not cover the tip, and merge mode's own pre-check exits first. It still contradicts the script header's "never backwards", which should hold for the script, not only for its current callers.
Fix: in push_leased, return 0 (a green skip) when covers "$sha" "$expect" is true, before the first push.
2. An annotated v1 wedges both writers red
The lease compares against the tag object's SHA, but fetch_v1 returns the peeled commit (refs/tags/v1^{commit}), so every push is rejected and reported as "not a lost lease". This fails safe, and the live v1 is lightweight. It matters if #27's annotated-tag idea is ever adopted.
Fix: lease against the tag ref's own value (git ls-remote origin refs/tags/v1), and keep using the peeled commit for ancestry checks.
Acceptance criteria
release-v1-selftest.sh gains a scenario for each item, and each fails against the current script.
The header's "never backwards" holds for any direct invocation.
An annotated v1 either releases correctly or fails with a message naming the annotation, not "not a lost lease".
## Found by
PR #28's final review (review 1394). Neither item can be reached from either workflow today, so the PR merged without them. Each is a small hardening of `scripts/release-v1.sh`.
## 1. `push_leased` can move `v1` backwards when called directly
`release-v1.sh push <A> <B>` with `v1` = B, where B is already ahead of A, moves `v1` back to A. The reviewer reproduced this. Neither workflow can reach it, because `sweep-check` only sets `needed=true` when `v1` does not cover the tip, and merge mode's own pre-check exits first. It still contradicts the script header's "never backwards", which should hold for the script, not only for its current callers.
**Fix:** in `push_leased`, return 0 (a green skip) when `covers "$sha" "$expect"` is true, before the first push.
## 2. An annotated `v1` wedges both writers red
The lease compares against the tag object's SHA, but `fetch_v1` returns the peeled commit (`refs/tags/v1^{commit}`), so every push is rejected and reported as "not a lost lease". This fails safe, and the live `v1` is lightweight. It matters if #27's annotated-tag idea is ever adopted.
**Fix:** lease against the tag ref's own value (`git ls-remote origin refs/tags/v1`), and keep using the peeled commit for ancestry checks.
## Acceptance criteria
1. `release-v1-selftest.sh` gains a scenario for each item, and each fails against the current script.
2. The header's "never backwards" holds for any direct invocation.
3. An annotated `v1` either releases correctly or fails with a message naming the annotation, not "not a lost lease".
claude
added the bug label 2026-09-22 23:13:24 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by
PR #28's final review (review 1394). Neither item can be reached from either workflow today, so the PR merged without them. Each is a small hardening of
scripts/release-v1.sh.1.
push_leasedcan movev1backwards when called directlyrelease-v1.sh push <A> <B>withv1= B, where B is already ahead of A, movesv1back to A. The reviewer reproduced this. Neither workflow can reach it, becausesweep-checkonly setsneeded=truewhenv1does not cover the tip, and merge mode's own pre-check exits first. It still contradicts the script header's "never backwards", which should hold for the script, not only for its current callers.Fix: in
push_leased, return 0 (a green skip) whencovers "$sha" "$expect"is true, before the first push.2. An annotated
v1wedges both writers redThe lease compares against the tag object's SHA, but
fetch_v1returns the peeled commit (refs/tags/v1^{commit}), so every push is rejected and reported as "not a lost lease". This fails safe, and the livev1is lightweight. It matters if #27's annotated-tag idea is ever adopted.Fix: lease against the tag ref's own value (
git ls-remote origin refs/tags/v1), and keep using the peeled commit for ancestry checks.Acceptance criteria
release-v1-selftest.shgains a scenario for each item, and each fails against the current script.v1either releases correctly or fails with a message naming the annotation, not "not a lost lease".