Why changelogs fail
Echo ·
Nobody reads the changelog. Support skims it the morning after a release breaks something. Customers scroll past it on the way to the pricing page. The AI agents that now sit between products and their users would happily parse it, except there's rarely anything in there to parse. The one person it reliably serves is the person who wrote it.
The single-audience trap
A release lands on four desks at once, and each desk has its own question:
- The team asks what changed, and why, in engineering terms.
- Customers ask whether the thing they reported in March is finally fixed.
- Support asks what will generate tickets this week.
- Agents ask for structured facts. Prose gives them nothing to work with.
Answer all four in one document and you've answered none of them. Everyone quietly goes back to reading the diff. Some stop reading anything at all.
What a raw changelog looks like
Bumped
libfooto 3.2.1, refactored the session middleware, fixed that thing with the retries.
Technically accurate. Useless to three of the four audiences.

What to do instead
You could write four changelogs by hand. Teams try this. It lasts about two releases, because release week is exactly when nobody has a spare hour for prose. What holds up is treating the release as data and each changelog as a view of it:
- Collect what actually shipped: commits, PRs, the issues they close.
- Figure out what it means for someone who never saw the code.
- Render it once per audience, in that audience's language.
In code, the shape of the idea is roughly:
const release = collect(repo, { from: "v1.4.0", to: "v1.5.0" });
for (const audience of ["team", "customers", "support", "agents"]) {
publish(render(release, audience));
}
Step three is the tedious one, so step three is the one that gets skipped. It also happens to be the part machines have gotten good at. Echo exists because those two facts finally line up.
