Skip to content

docs: add the major-line runbook (fixes #2979) - #2997

Open
mfal wants to merge 1 commit into
mainfrom
claude/docs-major-line-runbook-2979
Open

docs: add the major-line runbook (fixes #2979)#2997
mfal wants to merge 1 commit into
mainfrom
claude/docs-major-line-runbook-2979

Conversation

@mfal

@mfal mfal commented Aug 28, 2026

Copy link
Copy Markdown
Member

ADR 0004 §11 says
the next → major cascade uses "the same mechanism" as main → next. That
holds for the design, not for the configuration: every piece of
automation is hardcoded to the two standing lines, so opening 2.x today means
discovering that one broken invariant at a time.

New docs/major-line-runbook.md records what has to happen — the branch and
ruleset (in that order), the guard and workflow edits, the second cascade, the
sync tooling, a verification list for the first PR, and the promotion and
retirement paths. ADR 0004 §11 is expanded in place with the configuration gaps
and points at it; release-workflow.md links it from the model and from Where
to look next
.

Decisions recorded

Decision Value
Branch name 2.x — the routing guard's head-ref exemption already matches it
dist-tag next-majornext is taken, latest is the stable line
preid major2.0.0-major.N, kept separate so the version string stays readable
Publish workflow publish.yml, extended — never a second file (npm's Trusted Publisher binds one workflow filename per package; that is what killed the first two next publishes, #2968)

Found while verifying against the code

Everything in the runbook was checked against the actual workflows and scripts
rather than taken from the issue. Four things the issue does not name:

  • Escalation cross-talk. forward-merge.yml's close_sync_issue() closes
    every open sync-labelled issue matching in:title "Forward-merge blocked",
    so a healthy main → next run would close the major line's escalation while
    its conflict still stands. open_sync_issue() suppresses in the other
    direction, and forward-merge-drift.yml looks up its blocker with
    gh issue list --label sync and no title filter.
  • sync-resolve.cjs is hardcoded to main → next (BRANCH, the fetch and
    merge of origin/main into origin/next, the message, the PR base) — and it
    is the only way out of a conflict, because GitHub does not run the
    .gitattributes merge drivers. It needs --from/--to, which
    /prepare-release already has.
  • The commit-guard.yml if: gates must move into the step, not grow a
    literal branch list: the ruleset requires those four contexts, and a job
    skipped by if: is not a reliable reporter for them. version-contract
    already has the right place (steps.gate).
  • publish.yml is six edits, not one — including the seed formula in
    Version (next line), which computes ${M}.${m+1}.0-next.0, a minor
    prerelease. The major line needs ${M+1}.0.0-major.0 and --preid major.

Two details worth calling out

  • The ruleset deliberately does not require the coverage context.
    coverage.yml triggers on pull_request: branches: [main] only, so on a
    major-line PR the check never reports — and a required context that never
    reports blocks every PR on the line. next's ruleset omits it for the same
    reason.
  • The ruleset must come after the branch: like main's and next's it
    carries a creation rule. And it is not a nicety — the repo allows merge
    commits and squash merges repo-wide, so an unprotected line offers both
    buttons. Verified: chore(sync): resolve forward-merge conflict (main into next) #2969's merge commit e25acaaa5 has a single parent, while
    a27c61b51 and 8b76367f0 have two.

Verification

pnpm format:check and pnpm nx test:links docs green; the release-relevance
classifier reads the change as docs-only → no publish.

fixes #2979

🤖 Generated with Claude Code

ADR 0004 §11 says the `next → major` cascade uses "the same mechanism" as
`main → next`. That holds for the design, not for the configuration: every
piece of automation is hardcoded to the two standing lines, so opening `2.x`
today means discovering that one broken invariant at a time.

The runbook records the four decisions (branch `2.x`, dist-tag `next-major`,
preid `major`, publishing stays in `publish.yml` because npm's Trusted
Publisher binds one workflow filename per package), the ruleset and the order
it has to be created in, every workflow edit with its reason, a verification
list for the first PR, and the promotion and retirement paths.

Verified against the code, which turned up four things the issue did not name:

- `forward-merge.yml`'s `close_sync_issue()` closes EVERY open `sync`-labelled
  issue matching `in:title "Forward-merge blocked"`, so a healthy `main → next`
  run would close the major line's escalation while its conflict still stands.
  `open_sync_issue()` suppresses in the other direction, and
  `forward-merge-drift.yml` looks up its blocker with no title filter at all.
- `sync-resolve.cjs` is hardcoded to `main → next`, and it is the only way out
  of a conflict — GitHub does not run the merge drivers.
- The two `commit-guard.yml` `if:` gates must move into the step rather than
  grow a literal branch list: the ruleset requires those contexts, and a job
  skipped by `if:` is not a reliable reporter for them.
- `publish.yml` is six edits, not one — including the seed formula in
  `Version (next line)`, which computes a MINOR prerelease.

The `coverage` context is deliberately excluded from the ruleset: `coverage.yml`
triggers on PRs to `main` only, and a required context that never reports blocks
every PR on the line. `next`'s ruleset omits it for the same reason.

§11 is expanded in place with the configuration gaps and points at the runbook;
`release-workflow.md` links it from the model and from "Where to look next".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mfal
mfal requested a review from a team August 28, 2026 10:00
@mfal mfal self-assigned this Aug 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for ./packages/components/

Status Category Percentage Covered / Total
🔵 Lines 76% 627 / 825
🔵 Statements 75.91% 643 / 847
🔵 Functions 77.95% 145 / 186
🔵 Branches 66.66% 298 / 447
File CoverageNo changed files found.
Generated in workflow #6393 for commit 6db2aff by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-2997.docs.review.flow-components.de
storybook pr-2997.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-2997
  • storybook: ghcr.io/mittwald/flow/storybook:pr-2997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document what opening a new major line requires

1 participant