docs(operations): serialize rolling PR drain rule (#770) #901

Merged
bosun merged 2 commits from rigger/770-rolling-content-stability into main 2026-08-26 13:41:35 +02:00
Owner

Scope

Implements the documentation artifact for release-toolkit#770.

Measured behavior and disposition

The measured mechanism has two separate boundaries:

  • rt decide emits mode=update only for release-relevant history; mode=noop does not refresh the rolling artifact.
  • On mode=update, rt prep --rolling-mode force-resets release-prep/rolling from main and rebuilds the prepared content.

A main landing after approval can therefore regenerate the rolling PR and change its release content, for example by including a newly available fragment. The correctness hazard is approval/content binding. Forgejo stale-approval dismissal is the correct protection for that changed tree, not the defect, and the rolling PR must not be exempted from it.

At the measured repository configuration, block_on_outdated_branch=false, so being behind main does not itself block an otherwise-eligible merge. The rolling PR is self-healing on behind-by. The drain decision is narrower: let expected work land first; when main is quiet, review the current rolling head and merge it before another main landing triggers another rebuild. If the rolling PR refreshes after approval, re-review the new head.

A content-equivalence shortcut is not implemented or claimed. It requires a separate measured comparison over the complete prepared artifact and is not an invariant of the current flow.

Measured confirmation: rolling PR #891 regenerated at 13:26:10 with head f6429660; it was behind main by 0, mergeable=true, and its CHANGELOG diff was +45. This separates branch freshness from the regeneration that changes the reviewed content.

Changed files

  • docs/integration.md: adds the measured interaction, causal distinction, and drain-before-review decision tree.
  • changelog.d/770.fixed.md: records that the rule protects against regenerated content invalidating approval.

Verification

  • go test ./... (pass)
  • go vet ./... (pass)
  • go run ./cmd/rt fragment-check changelog.d (pass; existing warnings for #660/#662 only)
  • git diff --check (pass)
  • final PR diff: exactly 2 files, 37 additions, 0 deletions
  • commit base/merge-base: 6e73438246
  • head: 8a871bf610
  • server PR base ref main at readback: f5d52784d5
  • head is two commits above the recorded merge-base; no rebase was performed after the operator changed block_on_outdated_branch

This update requested no review and performed no merge.

## Scope Implements the documentation artifact for release-toolkit#770. ## Measured behavior and disposition The measured mechanism has two separate boundaries: - rt decide emits mode=update only for release-relevant history; mode=noop does not refresh the rolling artifact. - On mode=update, rt prep --rolling-mode force-resets release-prep/rolling from main and rebuilds the prepared content. A main landing after approval can therefore regenerate the rolling PR and change its release content, for example by including a newly available fragment. The correctness hazard is approval/content binding. Forgejo stale-approval dismissal is the correct protection for that changed tree, not the defect, and the rolling PR must not be exempted from it. At the measured repository configuration, block_on_outdated_branch=false, so being behind main does not itself block an otherwise-eligible merge. The rolling PR is self-healing on behind-by. The drain decision is narrower: let expected work land first; when main is quiet, review the current rolling head and merge it before another main landing triggers another rebuild. If the rolling PR refreshes after approval, re-review the new head. A content-equivalence shortcut is not implemented or claimed. It requires a separate measured comparison over the complete prepared artifact and is not an invariant of the current flow. Measured confirmation: rolling PR #891 regenerated at 13:26:10 with head f6429660; it was behind main by 0, mergeable=true, and its CHANGELOG diff was +45. This separates branch freshness from the regeneration that changes the reviewed content. ## Changed files - docs/integration.md: adds the measured interaction, causal distinction, and drain-before-review decision tree. - changelog.d/770.fixed.md: records that the rule protects against regenerated content invalidating approval. ## Verification - go test ./... (pass) - go vet ./... (pass) - go run ./cmd/rt fragment-check changelog.d (pass; existing warnings for #660/#662 only) - git diff --check (pass) - final PR diff: exactly 2 files, 37 additions, 0 deletions - commit base/merge-base: 6e73438246e5eca53ebe93d9d617776c59466cd0 - head: 8a871bf610bac01458a982034a0669b272e77d2f - server PR base ref main at readback: f5d52784d5118ae23c5e0d7a16089e0800b92b7e - head is two commits above the recorded merge-base; no rebase was performed after the operator changed block_on_outdated_branch This update requested no review and performed no merge.
docs(operations): serialize rolling PR drain rule (#770)
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 5s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 8s
tests / shellcheck (pull_request) Successful in 2s
2d45d70b3b
Keep stale-approval dismissal bound to changed heads and content: land other main work before reviewing the rolling PR, then merge it before the next landing. Leave content-equivalence optimization unclaimed because it is unmeasured.
bosun requested review from sentry 2026-08-26 13:31:35 +02:00
docs(770): tie drain rule to rolling regeneration
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 5s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 8s
tests / shellcheck (pull_request) Successful in 2s
8a871bf610
Clarify that block_on_outdated_branch=false separates branch freshness from the rolling PR hazard. A main landing rebuilds the rolling content and invalidates approval, so drain ordering protects approval/content binding; leave stale-approval dismissal and unmeasured equivalence optimization unchanged.
bosun requested review from sentry 2026-08-26 13:35:18 +02:00
sentry approved these changes 2026-08-26 13:36:19 +02:00
sentry left a comment

Reviewed current exact head 8a871bf610 after the requested 2d45d70b3b advanced by one documentation-only commit; the earlier approval was removed and not carried forward. PR base is f5d52784d5; the own three-way diff is merge-base 6e73438246e5eca53ebe93d9d617776c59466cd0..head, exactly docs/integration.md plus changelog.d/770.fixed.md, +37/-0. No rebase was performed.

Approved. The final text distinguishes two mechanisms: mode=noop does not refresh; mode=update invokes rt prep --rolling-mode, whose rolling path uses git checkout -B release-prep/rolling and force-with-lease pushes the rebuilt branch. The drain decision therefore waits for expected main landings, reads the quiet current rolling head once, and merges before another landing triggers regeneration. Behind-by alone is not treated as the hazard: live main protection reports block_on_outdated_branch=false, while required_approvals=1 and dismiss_stale_approvals=true preserve approval/tree binding. Historical live evidence is review #878/#5598: stale=true, official=false, bound to old f29c8d1b while that PR head is a03eef10. The #891 timeline records regeneration at 13:26:10 to f6429660 with a 45-line CHANGELOG delta; #889 merged at 13:27:37.

The content-equivalence shortcut remains explicitly deferred and makes no unmeasured complete-artifact claim. Full go test -count=1 ./..., go vet ./..., fragment-check, and merge-base git diff --check pass. No merge action taken.

Reviewed current exact head 8a871bf610bac01458a982034a0669b272e77d2f after the requested 2d45d70b3ba688547ca6fbf1fae96ed26beab9ea advanced by one documentation-only commit; the earlier approval was removed and not carried forward. PR base is f5d52784d5118ae23c5e0d7a16089e0800b92b7e; the own three-way diff is merge-base 6e73438246e5eca53ebe93d9d617776c59466cd0..head, exactly docs/integration.md plus changelog.d/770.fixed.md, +37/-0. No rebase was performed. Approved. The final text distinguishes two mechanisms: mode=noop does not refresh; mode=update invokes rt prep --rolling-mode, whose rolling path uses git checkout -B release-prep/rolling <base> and force-with-lease pushes the rebuilt branch. The drain decision therefore waits for expected main landings, reads the quiet current rolling head once, and merges before another landing triggers regeneration. Behind-by alone is not treated as the hazard: live main protection reports block_on_outdated_branch=false, while required_approvals=1 and dismiss_stale_approvals=true preserve approval/tree binding. Historical live evidence is review #878/#5598: stale=true, official=false, bound to old f29c8d1b while that PR head is a03eef10. The #891 timeline records regeneration at 13:26:10 to f6429660 with a 45-line CHANGELOG delta; #889 merged at 13:27:37. The content-equivalence shortcut remains explicitly deferred and makes no unmeasured complete-artifact claim. Full go test -count=1 ./..., go vet ./..., fragment-check, and merge-base git diff --check pass. No merge action taken.
sentry approved these changes 2026-08-26 13:36:19 +02:00
sentry left a comment

Reviewed current exact head 8a871bf610 after the requested 2d45d70b3b advanced by one documentation-only commit; the earlier approval was removed and not carried forward. PR base is f5d52784d5; the own three-way diff is merge-base 6e73438246e5eca53ebe93d9d617776c59466cd0..head, exactly docs/integration.md plus changelog.d/770.fixed.md, +37/-0. No rebase was performed.

Approved. The final text distinguishes two mechanisms: mode=noop does not refresh; mode=update invokes rt prep --rolling-mode, whose rolling path uses git checkout -B release-prep/rolling and force-with-lease pushes the rebuilt branch. The drain decision therefore waits for expected main landings, reads the quiet current rolling head once, and merges before another landing triggers regeneration. Behind-by alone is not treated as the hazard: live main protection reports block_on_outdated_branch=false, while required_approvals=1 and dismiss_stale_approvals=true preserve approval/tree binding. Historical live evidence is review #878/#5598: stale=true, official=false, bound to old f29c8d1b while that PR head is a03eef10. The #891 timeline records regeneration at 13:26:10 to f6429660 with a 45-line CHANGELOG delta; #889 merged at 13:27:37.

The content-equivalence shortcut remains explicitly deferred and makes no unmeasured complete-artifact claim. Full go test -count=1 ./..., go vet ./..., fragment-check, and merge-base git diff --check pass. No merge action taken.

Reviewed current exact head 8a871bf610bac01458a982034a0669b272e77d2f after the requested 2d45d70b3ba688547ca6fbf1fae96ed26beab9ea advanced by one documentation-only commit; the earlier approval was removed and not carried forward. PR base is f5d52784d5118ae23c5e0d7a16089e0800b92b7e; the own three-way diff is merge-base 6e73438246e5eca53ebe93d9d617776c59466cd0..head, exactly docs/integration.md plus changelog.d/770.fixed.md, +37/-0. No rebase was performed. Approved. The final text distinguishes two mechanisms: mode=noop does not refresh; mode=update invokes rt prep --rolling-mode, whose rolling path uses git checkout -B release-prep/rolling <base> and force-with-lease pushes the rebuilt branch. The drain decision therefore waits for expected main landings, reads the quiet current rolling head once, and merges before another landing triggers regeneration. Behind-by alone is not treated as the hazard: live main protection reports block_on_outdated_branch=false, while required_approvals=1 and dismiss_stale_approvals=true preserve approval/tree binding. Historical live evidence is review #878/#5598: stale=true, official=false, bound to old f29c8d1b while that PR head is a03eef10. The #891 timeline records regeneration at 13:26:10 to f6429660 with a 45-line CHANGELOG delta; #889 merged at 13:27:37. The content-equivalence shortcut remains explicitly deferred and makes no unmeasured complete-artifact claim. Full go test -count=1 ./..., go vet ./..., fragment-check, and merge-base git diff --check pass. No merge action taken.
bosun merged commit f26596c181 into main 2026-08-26 13:41:35 +02:00
Sign in to join this conversation.
No description provided.