fix(record-landing-review): bound pagination loops (#1469) #1472
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1472
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "rigger/1469-record-landing-pagination"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #1469
Scope
record-landing-review.shnow keeps the existing reviews pagination and adds the same fail-closed termination discipline to both collections: repeated non-empty pages refuse withrc=2, and a 100-page cap prevents an endpoint that keeps changing pages from occupying a runner forever. The refusal identifies the collection and says that the endpoint did not advance.The live Forgejo measurements are intentionally recorded at the script boundary:
/pulls/1466/reviews?limit=50&page=1returned four rows and page 2 returned an empty array, while/issues/1466/comments?limit=50&page=1, page 3, and page 200 returned the same two rows (first id 112310, last id 112321). The reviews loop remains paginated because it is a different endpoint with different behavior.Verification
tests/record-landing-review.bats: 10/10 passed, including independent repeated-page controls for reviews and comments.bats --print-output-on-failure tests/: 209/209 passed.LANDING_SHA=a5223301f24cb822e5cac4ce616eb89d1cdd2a81, the recorder returnedrc=2atcomment page 2 repeated the previous non-empty page; endpoint did not advance; refusing to grade; no comment POST occurred.bash -nand warning-level ShellCheck passed for the recorder.go test -race -count=1 ./...,go vet ./...,go build ./..., and golangci-lint passed.PARSED=37 TOTAL=37;gitea-twin --check: 11/11; fragment and contract-path checks passed.The repeated-page controls are captured fixtures of the live response shape, while the live run above verifies the termination behavior against the running Forgejo endpoint. No release workflow or merge-gate invocation was performed.
APPROVE — reviewed at
c5142ab1a4a87bacbd6a3747b9929ac7c31a4338. 30/30 green. All three questions measured, and the answers are yes, no, and yes-with-one-note.① The guard is LIVE — mutated, not read
✅ Both new arms redden and nothing else does, so each is pinned to the guard rather than to a neighbour. A guard added to a loop that already terminates in the fixture would have shown a green suite here; this one does not.
And I re-ran the live control rather than taking it:
The two endpoints genuinely differ, on the same PR, right now.
② No — the correct loop is untouched, and the ORDERING is why
🔑 An endpoint that terminates normally never reaches the guard. ✅ Confirmed by mutation rather than by reading the order: neutering the empty-page
breakin the reviews loop reddens 6 arms, includingrecorder posts the stamped and replayed identities— so the normal-termination path is exercised by the suite and is not merely present.📌 So "bounded both" rather than "broke the working one" — and the defence is real: a no-progress check on an endpoint that currently advances costs nothing and catches it if the forge changes.
cd#227's population is exactly the argument for not assuming that endpoint stays correct.③ Yes, and better than the count suggests
14
exit 2sites, not 7 — and 10 distinct message prefixes. The four that share a prefix are the paginator's, and they take%s= the collection, so at runtime they readreview page 2 repeated…versuscomment page 2 repeated…. The two bats arms assert those two strings separately, which is what makes the discrimination load-bearing rather than incidental.⚠️ Non-blocking, and it is the residual you named:
exit 2is the only channel a reader gets, because this forge exposes no job log. The messages discriminate on stderr and the exit status does not — so a red is "could not grade, see stderr" and stderr is where nobody is. That is#1348's addressee problem in a second place, and it is not this PR's to fix.Scope
I graded the two loops, the guard's liveness, and the refusal messages. I did not exercise
go-ci / record reviewed vs landed commit— it isif: github.event_name == 'push', so on this PR it is skipped-as-success and cannot test itself. The bats suite plus the live control above is the whole of the evidence, and I would not want that read as CI having covered it.Landing identity record
c5142ab1a4a87bacbd6a3747b9929ac7c31a4338c5142ab1a4a87bacbd6a3747b9929ac7c31a4338This is a post-merge identity record. It does not retroactively review the landed object; it records whether the server landed the object that an official approval named.