Switch the merge style to fast-forward-only and protect main #79

Closed
opened 2026-09-22 15:46:33 +01:00 by cruelacid · 1 comment
Owner

Part of #77. Blocked by the merge-path proof.

Why

There are zero protected branches on this repository. CLAUDE.md's rule —
"A plan is worked in its own worktree, on its own branch, and never committed to
main directly" — is an honour system, and that document records a session
breaking it: three commits of in-progress work straight onto the deployment
trigger, then a completion report that never checked CI. It calls the outcome
"luck rather than method."

main is the deployment trigger. promote moves :stable and every host
adopts within a minute.

What to do

  • DefaultMergeStyle: merge → fast-forward-only. AllowFastForwardOnly
    is already true
    on the repo, so this is a default change, not a capability
    one. It preserves the linear history CLAUDE.md asks for: "a merge commit for
    a one-branch plan reads as noise a year later."
  • Protect main: require a pull request, and require the build and e2e
    checks green before merge.
  • Decide explicitly whether Renovate gets an automerge exemption, or whether its
    PRs are merged by hand. All 15 so far were closed, not merged, and applied
    some other way; that path disappears under protection.

Watch for

Protection must not lock out publish-plugin.mjs or any release automation that
pushes. Check what pushes to main today before turning it on.

Part of #77. Blocked by the merge-path proof. ## Why There are **zero protected branches** on this repository. `CLAUDE.md`'s rule — "A plan is worked in its own worktree, on its own branch, and never committed to `main` directly" — is an honour system, and that document records a session breaking it: three commits of in-progress work straight onto the deployment trigger, then a completion report that never checked CI. It calls the outcome "luck rather than method." `main` is the deployment trigger. `promote` moves `:stable` and every host adopts within a minute. ## What to do - `DefaultMergeStyle`: `merge` → `fast-forward-only`. **`AllowFastForwardOnly` is already `true`** on the repo, so this is a default change, not a capability one. It preserves the linear history `CLAUDE.md` asks for: "a merge commit for a one-branch plan reads as noise a year later." - Protect `main`: require a pull request, and require the `build` and `e2e` checks green before merge. - Decide explicitly whether Renovate gets an automerge exemption, or whether its PRs are merged by hand. All 15 so far were **closed**, not merged, and applied some other way; that path disappears under protection. ## Watch for Protection must not lock out `publish-plugin.mjs` or any release automation that pushes. Check what pushes to `main` today before turning it on.
Author
Owner

Done, on 23 September 2026.

  • Protection on main: enable_push=false, apply_to_admins=true, block_on_outdated_branch=true, required_approvals=0. Required checks: CI / build (pull_request), CI / e2e (pull_request), Release note / release-note (pull_request). The protected_branch row confirms it.
  • Default merge style: fast-forward-only, confirmed in the repo_unit config.
  • Direct push refused: rehearsed on a throwaway branch with an identical rule, where an admin push got "Not allowed to push to protected branch". It wasn't tested on main, because a success there would be a release.
  • Renovate now automerges development dependencies through a PR, with automergeType: pr, platformAutomerge and automergeStrategy: fast-forward, plus a NONE release note (#115). It has no push exemption.
  • Merges through protection: #116, #121 and #122–#125 all merged with POST /pulls/<n>/merge {"Do":"fast-forward-only"}. One caveat for automation: right after main moves, the next merge can return a transient 405 Please try again later, and a retry 5–10 s later succeeds.

The rule was applied at main = ea78644, which is WORKFLOW_EPOCH in scripts/changelog.mjs.

Done, on 23 September 2026. - **Protection on `main`:** `enable_push=false`, `apply_to_admins=true`, `block_on_outdated_branch=true`, `required_approvals=0`. Required checks: `CI / build (pull_request)`, `CI / e2e (pull_request)`, `Release note / release-note (pull_request)`. The `protected_branch` row confirms it. - **Default merge style:** `fast-forward-only`, confirmed in the `repo_unit` config. - **Direct push refused:** rehearsed on a throwaway branch with an identical rule, where an admin push got "Not allowed to push to protected branch". It wasn't tested on `main`, because a success there would be a release. - **Renovate** now automerges development dependencies through a PR, with `automergeType: pr`, `platformAutomerge` and `automergeStrategy: fast-forward`, plus a `NONE` release note (#115). It has no push exemption. - **Merges through protection:** #116, #121 and #122–#125 all merged with `POST /pulls/<n>/merge {"Do":"fast-forward-only"}`. One caveat for automation: right after `main` moves, the next merge can return a transient `405 Please try again later`, and a retry 5–10 s later succeeds. The rule was applied at `main` = `ea78644`, which is `WORKFLOW_EPOCH` in `scripts/changelog.mjs`.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda#79
No description provided.