Reference for writing and reviewing CHANGELOG entries in the hoist-core library CHANGELOG.md.
Library vs. Application changelogs: This guide applies to hoist-core and other Hoist library packages. Hoist application changelogs have different formatting requirements β see the Application Changelogs section at the end of this document.
Every major version entry should use this structure. Minor/patch releases use whichever sections apply.
## {VERSION} - {YYYY-MM-DD}
### π₯ Breaking Changes (upgrade difficulty: {RATING})
See [`docs/upgrade-notes/v{NN}-upgrade-notes.md`](docs/upgrade-notes/v{NN}-upgrade-notes.md) for
detailed, step-by-step upgrade instructions with before/after code examples.
* {Required change 1}
* {Required change 2}
* {Sub-detail if needed}
* ...
### π New Features
* {Feature description}
### π Bug Fixes
* {Fix description}
### βοΈ Technical
* {Internal change description}
### π€ AI Docs + Tooling
* {AI docs/tooling change description}
### π Libraries
* {Library} `{old} β {new}`Use these emoji-prefixed headers consistently:
| Section | Header | When to Include |
|---|---|---|
| Breaking Changes | ### π₯ Breaking Changes |
Required app changes exist |
| New Features | ### π New Features |
New capabilities added |
| Bug Fixes | ### π Bug Fixes |
Bugs fixed |
| Technical | ### βοΈ Technical |
Internal changes worth noting |
| AI Docs + Tooling | ### π€ AI Docs + Tooling |
AI assistant docs, MCP server, CLI tools |
| Libraries | ### π Libraries |
Major dependency version bumps |
- Past tense, action-driven for descriptions: "Enhanced", "Fixed", "Added", "Improved", "Removed", "Refactored"
- Imperative for developer instructions: "Update", "Adjust", "Remove", "Migrate"
- Avoid starting bullets with "New" (prefer "Added"), "Support for" (prefer "Added support for"), or present tense verbs like "Fix", "Allow", "Enable"
Good:
* Enhanced `JSONClient` exception handling to capture raw string messages.
* Added support for `bcc` and `markImportant` in `EmailService.sendEmail`.
* Fixed regression with `LdapObject` subclasses not fully populating properties.Bad:
* New support for bcc in EmailService (use "Added", not "New support for")
* Fix to regression in LdapObject (use "Fixed regression", not "Fix to")
* Allow improved editing of Views (use "Enabled" or "Added", not "Allow")Every major version with breaking changes MUST include all of the following. Do not skip or reorder these requirements:
- Difficulty rating in the header β append
(upgrade difficulty: {RATING})to the section header. See Difficulty Ratings below for the rating scale. - Upgrade notes link as a standalone sentence β immediately after the header (before any
bullets), include a sentence linking to the upgrade notes file. This is not a bullet point β
it is a standalone paragraph. Use this exact format:
See [`docs/upgrade-notes/v{NN}-upgrade-notes.md`](docs/upgrade-notes/v{NN}-upgrade-notes.md) for detailed, step-by-step upgrade instructions with before/after code examples.
- List every required app-level change as a separate bullet
- Be specific β name exact classes, methods, and config keys
- Link to relevant framework upgrade guides (e.g. Grails, Spring Boot) when applicable
Each bullet should be concise (1-2 lines). The upgrade notes file handles expanded detail with before/after code examples.
When upgrade notes exist for a major version, include a difficulty rating:
### π₯ Breaking Changes (upgrade difficulty: π TRIVIAL)
### π₯ Breaking Changes (upgrade difficulty: π’ LOW - {brief description})
### π₯ Breaking Changes (upgrade difficulty: π MEDIUM - {brief description})
### π₯ Breaking Changes (upgrade difficulty: π΄ HIGH - {brief description})List major dependency version changes with backtick-wrapped versions:
### π Libraries
* Grails `6.2.3 β 7.0`
* Groovy `3.0.23 β 4.0`
* Spring Boot `2.7 β 3.5`Use abbreviated versions where the minor/patch isn't significant (e.g. 7.0 not 7.0.5).
- Positive tone: Favor words like "Enhanced", "Improved", "Streamlined" where accurate. Concisely note why a change is an improvement when not obvious from context (e.g. "Improved shutdown handling β ensures full cleanup if Hazelcast terminates unexpectedly"). Accuracy always takes precedence β bug fixes should be reported clearly as such.
- Conciseness: This is a changelog, not a guide. One bullet = one change, 1-3 lines max. Upgrade notes provide granular detail when needed; keep changelog entries brief and scannable.
- Specificity: Name classes, methods, and config keys in backticks.
- Completeness: Changes that modify behavior, APIs, or configuration in ways developers need to know about should be accounted for. Trivial changes (formatting, internal refactors with no behavioral impact, tooling updates) do not need to be included.
- No duplication: Don't repeat the same change across sections. Pick the most relevant section.
- Punctuation: End each bullet with a period.
- Plain ASCII punctuation: Use a single hyphen (
-) for in-sentence breaks. Do not use em dashes (β), en dashes (β), or double hyphens (--). The CHANGELOG is grep'd, parsed, and viewed across many tools where Unicode dashes cause encoding friction with no rendering benefit. This is stricter than the general coding-conventions rule, which allows em dashes in narrative markdown.
Hoist application changelogs (e.g. in app repos that depend on io.xh:hoist-core) follow
different formatting rules than the library changelog described above. Application changelogs are
parsed at runtime by a Hoist release notes feature that displays them within the app UI.
Do NOT hard-wrap list items in application changelogs. Each bullet point must be a single unwrapped line β the release notes parser treats line breaks within a list item as separate entries. Let the viewing tool handle display wrapping.
All other conventions (section headers, voice/tense, backtick-wrapped specificity) apply to both library and application changelogs.