Start with the release boundary

Release notes describe a set of changes that users can identify as one release. Before writing, establish which commits or changes are included, the version label, and whether the build has actually shipped. A commit in the history does not prove that its code reached users. A change may have been reverted, gated, delayed, or excluded from the release artifact.

Benchlight's Release Notes Assembler accepts commit subjects that you paste and groups recognized Conventional Commit types into draft sections. It does not read a repository, inspect tags, determine what shipped, or retrieve issue context. Treat the output as an outline built from the supplied lines, then verify every entry against the release contents.

Translate implementation words into reader outcomes

Commit subjects are written for a development workflow. Release notes are often read by users, operators, or other teams who need to know what changed for them. A line such as “refactor(cache): replace map storage” may be accurate but may not help a user decide whether to update a configuration or expect a different result. Look for the observable effect and explain it in the language of the audience.

Do not invent that effect. Inspect the code, tests, issue, documentation, or release owner’s decision. If the change is an internal refactor with no user-visible effect, it may not belong in user-facing notes. If it changes a default or removes a supported option, explain the compatibility consequence and migration step. If you cannot confirm the effect, ask the change owner or leave the claim out until the evidence is available.

Group by meaning, not just commit type

Conventional Commit types offer a useful first classification, but a release audience may need different categories. “feat” can be a developer-facing capability or a customer-facing feature; “fix” can affect a narrow edge case or a major workflow. A “docs” change might be important if it corrects a required migration procedure. A “chore” may not need a public entry at all.

Keep the raw grouping as an audit trail while editing the public structure. Combine related entries when they describe one outcome, remove duplicate messages, and separate unrelated changes that happen to share a type. Preserve a link to a real issue or pull request when readers need more detail and the destination is accessible to them.

Review risk and required action

For each candidate entry, ask what a reader needs to do. Does the release require a configuration change, data migration, new permission, or restart? Is the change opt-in or enabled by default? Does the change remove an old behavior? Is there a security-relevant note that needs a controlled disclosure process? Do not declare that a vulnerability is fixed or that a release is secure unless the release evidence supports that wording.

Breaking changes deserve a dedicated review. A marker in a commit subject is a useful cue, but the actual compatibility promise and change determine impact. Check supported versions, public APIs, configuration names, file formats, and documented workflows. Provide a migration example only after testing it against the new version. If no migration is required, say why only when that statement is verified.

Use a stable structure

Choose a format readers can scan across versions. Keep a clear release heading, a short introduction when it adds context, and sections for changes that matter to the audience. Keep dates and version identifiers tied to the actual release. Keep a Changelog offers a consistent structure for human-readable change records, while Semantic Versioning defines how version numbers communicate compatibility changes. Neither format can establish that the listed work shipped.

Write entries as complete, specific statements rather than fragments copied from a commit list. Define unfamiliar terms, link to relevant documentation, and avoid promotional adjectives that do not convey evidence. A concise note can still include the affected area, the behavior, and the action. An exhaustive dump of every internal commit is rarely the same thing as a useful summary.

Check completeness against the artifacts

Compare the draft with the actual release tag, merged changes, and shipped build. Check that reverted work is excluded and that gated work is described accurately. Search for migration files, changed environment variables, new permissions, and version constraints that may not be obvious from commit subjects. Confirm that links resolve in the published context.

Ask a reviewer who understands the affected workflow to check factual claims. For a technical release, run the documented examples against the release candidate when feasible. Preserve the source range and checklist so another maintainer can reproduce how the notes were assembled. If tests were not run, do not imply that they passed.

Keep drafts distinct from public claims

The assembler labels its output a draft because commit subjects alone do not establish user impact, release status, or migration risk. Its feature, fix, performance, documentation, and maintenance sections are an initial sort. Unrecognized lines remain visible for manual review, and identical repeated subjects may be collapsed. Inspect the original input if two commits share wording but represent different changes.

The final release note should be shorter than the underlying implementation history while preserving the facts users need. Remove internal details that offer no reader value, but retain consequences that change how someone installs, configures, or uses the product. When an impact cannot be established, record the uncertainty in the internal release review rather than filling it with plausible-sounding copy.

Separate grouping from the decision to publish

Use these invented history lines as a small editorial exercise:

aaaaaaa fix(search): preserve repeated tags
bbbbbbb fix(search): preserve repeated tags
ccccccc feat(export): add spreadsheet mode
Revert spreadsheet mode

The local grouper retains both fix entries because their supplied hashes differ. With no hash, identical subjects are deduplicated case-insensitively. These identity rules reduce exact input repetition; they do not decide whether two commits describe one user-visible fix. The revert line is retained as an uncategorized draft entry. It does not automatically cancel the earlier feature line.

Now assume, only for this fictional exercise, that release review establishes three facts: the two fixes together repair one filter problem, spreadsheet mode was reverted before packaging, and the shipped search behavior was checked. One public note could say that choosing multiple search tags now preserves every selected tag. The spreadsheet feature should not be announced as available in that release. Keep the internal commit mapping so another reviewer can trace why an item was combined or excluded.

Change one assumption and the editorial decision changes. If the fixes were merged but never included in the release artifact, that note belongs in an unreleased draft. If export was merely hidden behind a flag for a limited audience, document the actual availability instead of describing a universal feature. A commit subject supplies none of those deployment facts on its own.

Use version labels only after confirming the project's versioning policy. Semantic Versioning depends on a declared public API and has special rules during major version zero; a feat prefix alone does not prove a particular released version number. This exercise illustrates selection, consolidation, and availability checking. It does not claim that the fictional commits, tests, or release occurred on this website. The final record should pair each published statement with the artifact or decision that supports it.