From c8d52b2e58163f12701d072fc04ee06ef9cc7a31 Mon Sep 17 00:00:00 2001 From: Sal Date: Sun, 16 Aug 2026 21:03:52 +0100 Subject: [PATCH] fix(settings): set squash-merge default message to blank on z-shell/.github squash_merge_commit_message=COMMIT_MESSAGES (GitHub's default) aggregates every squashed commit's message, trailers included, into the merge commit whenever --body is omitted -- the actual mechanism behind the Co-authored-by trailer that reappeared on both #516 and #517 in one day. A pre-merge commit-lint check cannot catch this: the trailer is synthesized into a commit that does not exist until merge time. Sets squash_merge_commit_title=PR_TITLE and squash_merge_commit_message=BLANK via the repos API so there is nothing to synthesize a trailer from, regardless of --body. Adds the setting and its rationale to decisions/0013-repository-settings-baseline.md. Org-wide audit/rollout tracked in #518. --- .../0013-repository-settings-baseline.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/decisions/0013-repository-settings-baseline.md b/decisions/0013-repository-settings-baseline.md index f40f31125..aa74de2d2 100644 --- a/decisions/0013-repository-settings-baseline.md +++ b/decisions/0013-repository-settings-baseline.md @@ -89,6 +89,7 @@ recommended for this class. | Linear history | - | S | S | S | | Signed commits | S | S | S | S | | Copilot code review | R | R | S | R | +| Squash merge default message: title only, no body | R | R | R | R | Rationale for the differences: @@ -112,6 +113,31 @@ Rationale for the differences: (trunk-only classes 3-4), so linear history stays recommended there. - **Copilot code review** is required wherever a change reaches users or other repositories without a second human necessarily reading it. +- **Squash merge default message** is required uniformly, unlike the other + rows, because it isn't a class-scaled risk — it's a plain repository API + setting (`squash_merge_commit_title`/`squash_merge_commit_message`), not a + ruleset rule, and it fails the same way regardless of class. When + `squash_merge_commit_message` is `COMMIT_MESSAGES` (GitHub's default), + squashing a PR without an explicit `--body` aggregates every squashed + commit's full message — trailers included — into the merge commit, which + reliably reintroduces `Co-authored-by` even when no individual commit + carried one (`runbooks/branch-protection.md`'s "Squash-merge trailers" + section documents the same mechanism for `next` → `main` promotions). This + is not a theoretical risk: it hit the ADR-0016 acceptance PR + ([z-shell/.github#516](https://github.com/z-shell/.github/pull/516)) and, + within the same day, the PR that added org-wide commit-trailer CI + enforcement itself + ([z-shell/.github#517](https://github.com/z-shell/.github/pull/517)) — a + lint check on pre-merge commits structurally cannot catch this, since + GitHub synthesizes the trailer into a commit that doesn't exist until + merge time. Setting `squash_merge_commit_title=PR_TITLE` and + `squash_merge_commit_message=BLANK` (`gh api -X PATCH repos// +--field squash_merge_commit_title=PR_TITLE --field +squash_merge_commit_message=BLANK`) removes the default body entirely, so + there is nothing to synthesize a trailer from regardless of whether a + human remembers `--body`. Applied to `z-shell/.github` itself + 2026-08-16; auditing and applying it to the rest of the org is open + follow-up, not covered by this change. ### Expressed as rulesets, not classic protection