Skip to content

docs(contributing): qualify the branch-naming rule as a convention - #104

Merged
kyle-sexton merged 1 commit into
mainfrom
docs/qualify-branch-naming-convention
Aug 27, 2026
Merged

docs(contributing): qualify the branch-naming rule as a convention#104
kyle-sexton merged 1 commit into
mainfrom
docs/qualify-branch-naming-convention

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Closes #99

Summary

CONTRIBUTING.md Workflow step 1 stated <type>/<description> branch naming as a bare imperative, with nothing enforcing it. #93 and #95 qualified steps 4 and 5 to describe only what is actually gated, which left step 1 as the one unqualified claim in the list. Because this file is the org-wide inherited default, that claim is read by every human contributor and every agent in any repository that has not overridden it.

The issue offered two options: build a branch-name gate (option 1, cross-repo work in ci-workflows and github-iac), or qualify the wording (option 2). This PR takes option 2, and additionally cites the convention that step 1 was paraphrasing.

Fix

Step 1 now reads:

Branch from the default branch, naming it <type>/<short-description> (for example, feat/add-widget) per the org's branch-naming convention. A repository may gate the pattern locally, but no check enforces it by default, so treat it as a convention rather than a requirement.

Three deliberate choices:

The qualifier is hedged, not absolute. An earlier draft of this PR said flatly "no check constrains branch names." That is wrong to assert in a file every non-overriding repository inherits: standards explicitly contemplates a repository gating the pattern locally (below), so the org-wide default cannot promise on any individual repository's behalf. The wording now mirrors the honesty of step 4's "Where the repository enforces this" without implying enforcement that does not currently exist anywhere.

It cites the canonical convention. This is the issue's root cause, not a bonus: #99 was surfaced by a derivability check in which a fresh agent, reading primary sources only, returned could not determine for the org's branch-naming rule. It could not determine it because step 1 restated a convention without naming it. The canonical statement is melodic-software/standards conventions/engineering/naming.md "Branch names: type prefix, then a behavior-naming slug", which defines the grammar, pins the type vocabulary to the eleven Conventional Commits types, and carves out agent/bot prefixes (claude/, codex/, cursor/, copilot/, dependabot/) that must be left as generated. A reader who needs any of that can now get to it.

The placeholder is aligned to that source. <description> becomes <short-description>, matching the canonical grammar exactly. Citing a source while restating it inaccurately would reintroduce the drift this change exists to remove. That is the whole of the secondary change; the example is unchanged.

Why option 2 over option 1

Standards has already classified this rule, and its classification argues against gating rather than for it. naming.md says the type and tool prefixes are "a fixed, exact-match set: deterministic, in the sense enforceability-tiers.md uses the word, so a repo may gate the pattern with a commit hook the same way it gates any other exact-match rule" — permissive, not required. It then rules on the value directly:

Branch name is cosmetic once a PR merges through a squash workflow: the PR title becomes the default-branch history, which is why enforcing the Conventional Commits vocabulary at PR-title time (see ../review/code-quality.md) matters more for history hygiene than the branch name does; the branch grammar exists to keep local development and in-flight PRs legible in the meantime.

This repository already runs that higher-value gate: pr-title.yml, which step 4 documents. Option 1 would add a second gate over the same vocabulary at the point standards calls cosmetic. enforceability-tiers.md supplies the tiebreaker for that kind of proposal: tier classification answers whether a rule can be mechanized, but "whether a candidate is worth mechanizing, given the false-positive rate, the maintenance cost, and how often it actually fires, is a separate decision, and the default answer is 'not yet'." Nothing in #99 offers evidence of the convention being violated, and ci.yml's own header comment records that fork branches may collide on name (which is why concurrency keys on PR number), i.e. head-branch names are already treated as uncontrolled here.

Option 1 remains open on its merits, and standards explicitly leaves the door open for any repository that wants it. Qualifying the prose does not foreclose it; a later gate would simply tighten the new sentence.

Correction to an earlier version of this PR body

The first version of this body claimed that melodic-software/standards contains "no branch-name component, convention doc, or fixture." That was false, and a fresh-context verifier caught it: conventions/engineering/naming.md is exactly such a convention doc. The search that produced the claim listed the standards tree and code-searched for branch, and naming.md was in the results; it was not opened. The claim has been removed and the argument above is rebuilt on what that file actually says, which turns out to support option 2 more directly than the false absence did. Recording the error here rather than quietly rewriting it.

What survives that correction, re-checked: no branch-name gate exists anywhere in the org. Verified across this repository (.github/workflows/ holds only ci.yml, do-not-merge.yml, link-check.yml, pr-issue-linkage.yml, pr-title.yml), ci-workflows (all 38 workflow files plus the .github/actions/ tree; the only head_ref uses are a checkout ref, a dependabot/nuget/ trigger condition, and refs/heads/main run-context guards), and standards (no branch hook in lefthook.yml). A convention exists and is documented; nobody has gated it.

Verification

  • npx markdownlint-cli2@0.23.2 --config .markdownlint-cli2.jsonc CONTRIBUTING.md -> 0 issues.
  • Anchor #branch-names-type-prefix-then-a-behavior-naming-slug derived from the live heading text "## Branch names: type prefix, then a behavior-naming slug" in naming.md.
  • Placeholder and example checked character-for-character against naming.md's <type>/<short-description> grammar.
  • Diff is one line in one file; no links, headings, or list numbering elsewhere changed.
  • Re-read against steps 4 and 5: all three now state their enforcement status explicitly, which was the issue's stated consistency goal.
  • Full ci-status aggregate on this PR.

Related

The org's branch-naming grammar lives in standards'
conventions/engineering/naming.md, which calls the pattern deterministic and
says a repo *may* gate it with a commit hook. None does: no branch-name
check exists in this repository, in ci-workflows, or in standards, and the
org ruleset does not constrain head-branch names. Step 1 stated it as a bare
imperative anyway, while steps 4 and 5 already qualify what they claim, and
the rule was underivable from primary sources because nothing here cited the
convention that defines it.

Closes #99

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton force-pushed the docs/qualify-branch-naming-convention branch from 832f340 to 003d878 Compare August 27, 2026 09:00
@kyle-sexton
kyle-sexton merged commit 8c98919 into main Aug 27, 2026
16 checks passed
@kyle-sexton
kyle-sexton deleted the docs/qualify-branch-naming-convention branch August 27, 2026 10:16
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.

docs(contributing): the branch-naming rule is enforced by nothing and unqualified

1 participant