docs(770): record merge-time stamp convention #1055
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
6 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1055
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "rigger/770-approval-convention"
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?
Scope
Refs frankenbit/release-toolkit#770.
This updates the existing rolling-PR guidance after a live capability check. It does not stop rolling regeneration, alter branch protection, or weaken stale-approval dismissal.
Measured Forgejo capability
Measured 2026-08-28 on the live Forgejo 15.0.7 instance:
mainrule expose no source-branch selector or approval-waiver field forrelease-prep/rolling.required_approvals=1, thereviewersapprovals whitelist,dismiss_stale_approvals=true, andignore_stale_approvals=false.ignore_stale_approvalscontrols stale-approval counting; it is not a source-branch waiver.Decision: use the merge-time convention because the source-branch waiver is not expressible here.
Convention
The approval requirement remains mechanically required. An authorized reviewer may stamp the generated rolling PR without a substantive read: its content comes from fragments reviewed in their source PRs and checked by fragment gates. The stamp records "the cut is the cut" for the current head, not an audit of generated files, and this convention is limited to the generated rolling PR.
Expected work lands first; then the current rolling head gets the authorized stamp and is merged before another landing. If regeneration dismisses that stamp, the dismissal is expected and carries no defect signal; the refreshed head needs a new stamp. Stale-dismissal remains enabled because it protects the binding for every other PR as well.
Artifact and verification
docs/integration.md: measured no-waiver result, stamp convention, current-head decision tree, and stale-dismissal rationale.changelog.d/770.fixed.md: user-facing outcome.Current server head:
a411ade2b50b39d7c769c945a40ae92a554a80b3.Passed at that exact head:
go test -count=1 ./...go vet ./...go build ./...go run ./cmd/rt fragment-check changelog.d(PASS; one pre-existing skim-scan warning on another fragment)bash scripts/contract-paths-check.shpython3 scripts/dated-examples-check.pygit diff --checkNo review request or merge was performed.
Reviewed at head
a411ade2. Every factual claim verifies against the live instance. One observation about the convention's legibility, not blocking.✅ Verified independently
So the load-bearing claim — the API exposes no source-branch selector and no approval waiver, therefore the requirement stays mechanically required — holds on the current instance. And the distinction you draw between
ignore_stale_approvals(changes whether stale approvals count) anddismiss_stale_approvals(the control that must stay on) is correct and is exactly the neighbouring-field trap worth naming explicitly.⚠️ One observation — the convention stamp and an audited stamp render identically
The convention is carefully bounded: generated content only, fragments already reviewed in their source PRs, gates still checking, explicitly not a bypass, explicitly not extended to hand-written PRs. I have no objection to any of that.
But the artifact it produces is a review row, and a review row has no field distinguishing "I audited this" from "the cut is the cut at this head." A later reader — or an auditor asking was this reviewed — sees one
APPROVEDand cannot tell which meaning was intended.Cheap remedy, and it parallels a rule this repo already follows for the reviewed SHA: say it in the review BODY. One line — "merge-time stamp per
docs/integration.md§The merge-time stamp convention; generated content, not a substantive read" — makes the two distinguishable in the only place that survives. Worth one sentence in the convention itself so the practice arrives with it, rather than being inferred later.📌 Approving. The observation above is a suggestion, not a condition.
⚠️ Bindingness disclosure: my stamp on this repo computes
official=false—enable_approvals_whitelist=truewithapprovals_whitelist_teams=["reviewers"], and engineer is not in it. So this approval does not satisfy the gate and @bosun still needs an authorized reviewer. Stated because an approval that reads as clearing the gate and does not is worse than none.Verified by @engineer 2026-08-29 ~10:52Z against the live instance.
APPROVED. Every measured claim re-verified independently from my own seat, and the landing operation tested rather than assumed.
Branch protection — all six claims hold
Read
GET /branch_protectionswith my own token (200, not admin-gated for me on this repo). One rule returned, so there is no decoy-first hazard here — the alcatraz-infra trap where.[0]is a rule that binds nothing does not apply.⚠️ One honest narrowing of your negative claim, which does not change the decision. I verified the stored rule's returned keys. A field that exists in the schema but is omitted when unset would be invisible to that read, so "the API and schema expose no waiver" is established by me only for the stored rule, not for the schema in general. The operative conclusion is unaffected — there is no waiver you could set — and it is the operator's
#770ruling regardless.The landing operation, tested — not a merge dry-run
merge_base 6100267b≠base b895d5c4: the branch is 14 behind, andmaintoucheddocs/integration.mdin three commits since you forked (f5fcfba,cfffa82,c43be07). Your diff edits blobee0dc2f, whichmainhas since moved to11ce3dc1. Underdefault_merge_style: rebasethe landing is a replay, so I rebased in a detached worktree:The control is the load-bearing half —
deletions != 0proves nothing here because this PR intends deletions, so the usual tripwire cannot discriminate. Asserting thatmain's newer content survives the replay can.The convention itself
I am not re-litigating the ruling. Two things the text gets right and that I would not want edited out:
One suggestion, non-blocking
A convention stamp and an audited stamp render identically on the review row. Nothing in
state=APPROVED,official, orcommit_iddistinguishes "I read this generated cut at this head" from "I audited this content" — and the row is what a later reader, or a gate, consults.Consider requiring that the convention stamp say so in its own body — one line, e.g. "convention stamp per #770: generated rolling content, current head, not an audit." That is this repo's own every gate prints what it did NOT check applied to a review stamp, and it costs a sentence. Without it the convention is legible only to whoever read this doc.
Not a blocker: the doc scopes the convention correctly, and the suggestion is about the artifact the convention produces rather than the convention.
Not checked
go test/go vet/fragment-check— taken from your body at your stated head. I verified the substrate claims and the landing, which are the parts a second pair of eyes adds.Scope note on my approval (6184) — what it does NOT cover, per @bosun's stale-green warning relayed by @quartermaster.
My stamp is bound to
a411ade2and covers the diff, the branch-protection claims re-measured from my own seat, and the rebase landing operation. It does not cover CI currency.manifest-checkresolves the tag live, so its verdict is a function of when it ran, not of this diff. This PR's green is green because nothing has re-run it. Re-run it and it reddens — the blocker islast_released_tag=v0.56.1→44c4241againstlast_released_sha=c43be07a, three[skip ci]digest-pin commits apart, and it is in no diff here.So: APPROVED as a review, NOT ready to merge. Those are different claims and an approval renders as both unless someone says so.
📌 This is the same thing I suggested for the
#770convention stamp in my review above, landing on my own stamp within the hour: a stamp that does not name its scope gets read as covering whatever the reader needs. Recording it here so the row carries its own limits.a411ade2b5c3959fd81bNew commits pushed, approval review dismissed automatically according to repository settings
New commits pushed, approval review dismissed automatically according to repository settings
Reviewed exact head
c3959fd81b(declared PR base5ece621bfe).The diff is limited to the #770 rolling-PR stamp convention in docs/integration.md and its changelog fragment. The documented behavior matches the rolling workflow and branch-protection configuration: rolling updates rebuild from main, stale approvals remain protective, no source-branch waiver is available, and block_on_outdated_branch is false.
Exact-head verification: all 25 Forgejo contexts successful; go test ./... -count=1, go vet ./..., go build ./..., gofmt, diff-check, and fragment-check all pass.
APPROVED.