Skip to content

Adopt a changelog-fragment workflow to stop CHANGELOG.md being a merge-conflict hotspot #230

Description

@dgenio

Summary

Replace the "every PR hand-edits the top of a single CHANGELOG.md" rule with a
news-fragment workflow (one small file per change, assembled at release time), so
concurrent PRs stop colliding on the same lines of one monolithic file.

Why this matters

The workflow docs make a CHANGELOG.md edit mandatory for every feature/fix PR
(AGENTS.md:98, docs/agent-context/workflows.md:34 and the Definition of Done at
workflows.md:42). Every such PR appends to the same ## [Unreleased] block at the
top of a ~40 KB file (CHANGELOG.md:7 onward). When more than one branch is in flight —
which is the normal state here, given the parallel claude/*-triage-* branches — they
edit the same lines and conflict. This is not hypothetical:

  • e124153fix: resolve CHANGELOG.md merge conflict with main
  • fa0a040merge: resolve CHANGELOG.md conflict with main

The conflict resolution then forces Merge branch 'main' into <feature> reconciliation
merges (e7852e8, 820ce18), adding rebase/rework churn that is otherwise avoidable.

Current evidence

  • 59 commits touch CHANGELOG.md (git log --oneline -- CHANGELOG.md | wc -l).
  • Two commits exist solely to resolve CHANGELOG.md conflicts (above).
  • CHANGELOG.md:7 is a single shared ## [Unreleased] section that every PR appends to.
  • The update is mandated for all feature/fix PRs, so the collision is structural, not occasional.

Proposed implementation

  1. Adopt a fragment tool — towncrier, scriv, or changie. Each PR adds a small file
    under e.g. changelog.d/<issue-or-slug>.<type>.md instead of editing CHANGELOG.md.
  2. Add a release step (Makefile target + a line in RELEASE.md) that assembles fragments
    into CHANGELOG.md and clears changelog.d/.
  3. Update AGENTS.md, docs/agent-context/workflows.md, and CONTRIBUTING.md to require a
    fragment rather than a CHANGELOG.md edit.
  4. Optional, complementary: add a tiny CI check that a PR touching src/ also adds a
    changelog fragment, so the Definition-of-Done item is machine-enforced instead of relying
    on human/Copilot review.

AI-agent execution notes

  • Inspect first: CHANGELOG.md, RELEASE.md, Makefile, AGENTS.md Workflow section,
    docs/agent-context/workflows.md.
  • Keep the existing Keep-a-Changelog section headers (Added/Changed/Fixed/Security)
    so generated output matches today's format.
  • Fragment filenames must be conflict-free by construction (one file per change); do not
    reintroduce a shared file.

Acceptance criteria

  • A new PR can record its changelog entry without editing CHANGELOG.md.
  • Two simultaneous PRs adding entries do not conflict.
  • The release process documents how fragments are compiled into CHANGELOG.md.
  • AGENTS.md / workflows.md / CONTRIBUTING.md describe the fragment workflow.

Test plan

Create two throwaway branches that each add a fragment; confirm they merge without conflict.
Run the assembly step and confirm CHANGELOG.md renders identically to a hand-written entry.

Documentation plan

Update AGENTS.md Workflow, docs/agent-context/workflows.md (Definition of done + update
triggers), CONTRIBUTING.md, and RELEASE.md. Add a CHANGELOG/Changed (tooling) entry.

Migration and compatibility notes

Existing ## [Unreleased] content stays as-is; the fragment workflow applies to new changes.
No public-API impact.

Risks and tradeoffs

Adds a dev-time tool/convention to learn. The payoff is eliminating a recurring, predictable
conflict class. Keep the tool config minimal and document the one command contributors run.

Suggested labels

contributor-experience, reliability, documentation

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions