#2070: SemVer, Changelogs, and the Social Contract of Code

Stop breaking the internet. Learn the exact system developers use to release software without causing chaos.

0:000:00
Episode Details
Episode ID
MWP-2226
Published
Duration
21:05
Audio
Direct link
Pipeline
V5
TTS Engine
chatterbox-regular
Script Writing Agent
Gemini 3 Flash

AI-Generated Content: This podcast is created using AI personas. Please verify any important information independently.

The Hidden Language of Software Releases

When a developer clicks "publish" on a new software update, they aren't just sending code into the void—they are entering a contract. This episode explores the high art of software release management, focusing on three pillars: Semantic Versioning (SemVer), the "Keep a Changelog" philosophy, and Conventional Commits. The core problem these tools solve is "Dependency Hell," a chaotic state where updating one piece of software breaks another. The conversation frames software distribution not just as a technical challenge, but as a communication problem between the creator and the user.

Understanding the Three-Part Number

At the heart of this system is Semantic Versioning, or SemVer. It uses a three-part number: Major.Minor.Patch (e.g., 2.4.1). Each segment has a strict meaning:

  • Major: You increment this when you make incompatible, breaking changes. If this number changes, the user must update their own code.
  • Minor: You increment this when you add new functionality in a backward-compatible manner. It’s safe to upgrade.
  • Patch: You increment this for backward-compatible bug fixes.

This structure acts as a warning system. A change in the first number tells a user to stop and prepare for work; a change in the last two signals a safe, incremental update.

The "Zero" Loophole and Major Bump Anxiety

A significant point of contention in open source is the "zero" version. According to the spec, any version starting with 0.x.x is considered unstable, and the API can change at any time. Large, widely-used projects sometimes stay in this phase for years. This acts as a legal shield, allowing maintainers to make breaking changes without technically violating the SemVer contract. However, once a project hits 1.0.0, the stakes change. There is often "Major bump anxiety" because incrementing the first number admits that you are inconveniencing users with breaking changes. Yet, hiding a breaking change inside a Minor update is considered a betrayal of trust. The best practice is to be honest and bump the Major version frequently if the API is evolving.

Changelogs Are for Humans

A version number tells you that something changed, but not how. This is where the changelog comes in. The "Keep a Changelog" standard insists that a changelog is a curated document for humans, not a raw dump of machine-generated git logs. A proper changelog uses clear sections like Added, Changed, Deprecated, Removed, and Fixed. It tells a story, explaining the why behind changes, not just the what. For solo developers, this can feel like a chore, which leads to the automation layer.

Conventional Commits: Automation Meets Discipline

Conventional Commits provide a standardized format for commit messages (e.g., feat: add new button or fix: resolve login error). This structure allows tools like semantic-release to automatically analyze commit history, determine whether a release is a Major, Minor, or Patch update, bump the version number, and even generate a changelog. This automation enforces developer discipline; knowing that a specific commit type will trigger a public release encourages more thoughtful coding. However, automation has its limits. It can list what changed, but it can't explain the design philosophy—a task best left to a human maintainer who can write a "highlights" section for each release.

Yanking Releases and the Importance of Reproducibility

Mistakes happen. A "yanked" release is a version that has been removed due to a critical bug. The cardinal sin is deleting the release entirely, as this breaks reproducibility—if someone built their system yesterday using that version, their build will fail today if the version is gone. The correct approach is to mark it as "YANKED" in the changelog and immediately release a fixed version. This leaves a clear paper trail, acting as a flight recorder for the software's history.

Security and the Path Forward

Finally, SemVer is crucial for security. It allows package managers to automatically apply patch-level updates—which, by definition, don't break existing code—to fix vulnerabilities. This enables unattended upgrades for critical libraries, a vital defense in an era of constant supply chain attacks.

For developers looking to adopt these practices, the first step is to start an "Unreleased" section at the top of the changelog. By adding to this section as work is completed, the changelog becomes a living document, transforming a stressful pre-release task into a manageable process. Combined with the ISO 8601 date format (YYYY-MM-DD) for unambiguous sorting, these practices build a foundation of trust and clarity in the software ecosystem.

Downloads

Episode Audio

Download the full episode as an MP3 file

Download MP3
Transcript (TXT)

Plain text transcript file

Transcript (PDF)

Formatted PDF with styling

#2070: SemVer, Changelogs, and the Social Contract of Code

Corn
Alright, we have a heavy hitter today. Daniel sent over a prompt that is near and dear to the hearts of every developer who has ever stared at a terminal and wondered why their code suddenly stopped working after a simple update. He wants us to dig into the high art of software release management. We are talking Semantic Versioning, or SemVer, the philosophy of "Keep a Changelog," and the magic of Conventional Commits. Basically, how do we stop the digital world from breaking every time someone hits the "publish" button?
Herman
This is essentially the social contract of the internet, Corn. People think of code as just logic, but software distribution is actually a communication problem. And by the way, for the nerds keeping track, today’s episode is powered by Google Gemini 3 Flash. I am Herman Poppleberry, and I have been waiting for an excuse to nerd out on versioning numbers for a long time.
Corn
I knew you’d be excited. Most people see a version number like two point four point one and think, "Oh, neat, a bigger number." But for you, that’s a manifesto, isn't it? Daniel’s prompt really focuses on the "contract" between the developer and the user. So, let’s start with the basics for those who might just be clicking "update all" on their apps without thinking. What is the SemVer spec actually trying to tell us?
Herman
It is trying to prevent what we call "Dependency Hell." Imagine you are building a house, and you buy a specific type of bolt. Then the bolt manufacturer changes the thread size but keeps the same part number. Your house falls down. SemVer prevents that by using a three-part number: Major, Minor, and Patch. Major is for breaking changes, Minor is for new features that don’t break anything, and Patch is for bug fixes. If you see that first number change, you should be worried. If it’s just the last two, you’re usually safe to upgrade.
Corn
It sounds so simple in theory, but I’ve seen projects that seem to stay on version zero point something for a decade. Looking at you, early Terraform or even some of the big JavaScript libraries. If the "contract" says version one point zero means it's stable, what does it mean when a massive, world-dominating tool refuses to leave the zero phase?
Herman
That is actually a huge point of contention in the open-source world. According to the SemVer dot org spec, version zero point y point z is the "Wild West" phase. The spec literally says that at this stage, the API is unstable and anything can change at any time. When a project like React or Terraform stays in zero-point-X for years despite being used by Fortune five hundred companies, they are essentially using it as a legal shield. They’re saying, "Hey, if we break your entire infrastructure tomorrow, don't complain, we told you we weren't at one point zero yet." It’s a way to bypass the contract.
Corn
It’s like a "get out of jail free" card for developers. But once you hit that one point zero milestone, the stakes change. You can't just move fast and break things anymore. You have to be intentional. Daniel mentioned the "Major bump anxiety." Why are developers so scared of moving from version two to version three?
Herman
Because a Major bump is an admission that you are inconveniencing your users. It means you’ve removed a function, changed a data structure, or altered a requirement in a way that requires the user to rewrite their own code. In a corporate environment, a Major bump in a dependency might mean a week of refactoring for a whole team. But here is the thing: hiding a breaking change inside a Minor update is actually much worse. That’s a betrayal of trust. SemVer argues that you should bump the Major version frequently if your API is evolving. It’s a signal of honesty. It tells the user, "Stop, look at the notes, and prepare for a transition."
Corn
I love that idea of versioning as a signal of honesty. But the number alone doesn't tell the whole story. If I see a jump from version four to version five, I know it's broken, but I don't know how it's broken. That brings us to the second part of Daniel’s prompt: the Changelog. He pointed us toward "Keep a Changelog," which has some pretty spicy opinions on how to talk to users.
Herman
Oh, they are very strict, and rightly so. The number one rule of "Keep a Changelog" is that a changelog is for humans, not machines. You see so many projects that just dump their "git log" into a text file. You open it up and it’s just fifty lines of "fixed typo," "added stuff," "merged branch," and "I hate my life." That is useless to a user. A real changelog needs to be curated. It needs sections like Added, Changed, Deprecated, Removed, and Fixed.
Corn
"Fixed typo" is my favorite entry to see in a public changelog. It really inspires confidence in the codebase. But honestly, who has the time to manually curate these things? If you’re a solo dev or a small team pushing code every day, sitting down to write a beautiful prose summary of your work feels like a chore. Is there a way to bridge that gap between the messy reality of daily coding and the clean, professional changelog Daniel is talking about?
Herman
That is exactly where Conventional Commits come in. This is the "automation" part of the puzzle. Instead of writing random commit messages like "finished the thing," you use a structured format. You start your commit message with a type, like "feat" for a new feature, "fix" for a bug, or you put a little exclamation point or a "BREAKING CHANGE" footer if you’re breaking things. Because the messages are standardized, you can run a script like "semantic-release" that looks at your commit history, decides if you need a Major, Minor, or Patch bump, updates the version number, and generates the changelog for you.
Corn
Wait, so the computer reads my commit messages and then decides how to version my software? That sounds efficient, but also a little dangerous. If I forget that exclamation point on a breaking change, the tool might push a Minor update and break everyone's site. It puts a lot of pressure on the developer to get the commit message right every single time.
Herman
It does, but it enforces a discipline that actually makes you a better developer. If you know that typing "feat!" is going to trigger a Major release, you tend to think twice about whether that change is actually necessary or if you could make it backward-compatible. This structure also helps with what Daniel called "Dependency Hell." If everything in your ecosystem follows these rules, your package manager—like npm or pip—can automatically resolve versions. It can say, "I know version one point five point zero is safe because the dev used the 'feat' tag, not the 'breaking' tag."
Corn
I want to go back to the human element for a second. Daniel mentioned how mature projects like Datasette or SQLite handle this. Simon Willison, who created Datasette, is famous for his release notes. He doesn't just list the features; he explains the why. He might say, "We changed this because we realized users were struggling with the previous syntax." A machine can't write that. Conventional Commits can tell me what changed, but it can’t explain the design philosophy.
Herman
You’ve hit on the "Automation vs. Curation" debate. The best projects use a hybrid approach. They use Conventional Commits to handle the heavy lifting—the version bumping and the basic list of fixes—but then a human maintainer goes in and writes a "highlights" section at the top. Think of it like a movie trailer versus the full credits. The automated part is the credits; the manual part is the trailer that gets people excited about the new version.
Corn
I like that. But what happens when things go horribly wrong? Daniel brought up "Yanked Releases." I’ve been there. You push a version, everything looks great, and then ten minutes later the bug reports start flooding in because you accidentally deleted the database connection string. In the old days, people would just delete the release and pretend it never happened. Why is that a bad idea now?
Herman
Deleting a release is a cardinal sin in modern software because of "reproducibility." If I built a system yesterday using version two point one point zero, and today you delete that version from the internet, my build process will break. I can’t recreate my environment. The "Keep a Changelog" standard says you should mark it as "YANKED" in the notes. You keep the version number there, but you put a big warning sign on it and immediately push a fix in the next version. It’s about leaving a paper trail. It’s the "black box" flight recorder of software.
Corn
It’s basically honesty as a service. Speaking of honesty, let's talk about the "Post-one point zero anxiety" again. I see so many projects that are on version twenty-four or thirty-two. Chrome is on what, version one hundred and something? Does the number lose meaning when it gets that high? Does it stop being a "contract" and just become a timestamp?
Herman
Chrome and Firefox use "Calendar Versioning" or "Rapid Release" cycles, which is a different beast entirely. In those cases, the version number is mostly a marketing tool or a way to track the passage of time. But for a library that other developers use, a high version number is actually a sign of health. It means the project is alive and is willing to break things to move forward. Look at the "Angular" transition years ago. They went from version one—which was called AngularJS—to version two, and it was a complete rewrite. People were furious. But by using a Major version bump, the team was being technically accurate. They were saying, "This is a new world."
Corn
It’s the difference between a "product" version and an "API" version. If I'm using an app, I don't care if it's version ten or version twenty. But if I'm a developer building on top of that app, those numbers are my lifeblood. I’m thinking about the "security" section in the changelog too. Daniel mentioned that as a standard section. In an era of constant supply chain attacks, how does SemVer help with security?
Herman
It’s huge for automated patching. If you have a security vulnerability in version two point four point one, and the fix is in two point four point two, a good package manager can automatically pull that fix because it knows, based on the SemVer contract, that a Patch release won't break your existing code. This allows for "unattended upgrades" of critical security libraries. Without SemVer, you’d have to manually audit every single update to make sure it didn't break your site while trying to save it from hackers.
Corn
That makes total sense. So, if I'm a developer listening to this and I want to start doing things "the right way," what's the first step? Do I just start naming my versions differently, or is there a cultural shift I need to make?
Herman
It starts with the "Unreleased" section. This is a brilliant tip from the "Keep a Changelog" folks. Most people only write the changelog right before they hit "publish." But you should have an "Unreleased" header at the top of your file from day one. Every time you finish a task, you add a bullet point there. Then, when you’re ready to release, you just change that header to the new version number and the date. It turns the changelog from a stressful "end-of-project" task into a living document.
Corn
I love that. It’s like keeping a diary instead of trying to write your memoirs in a single night. And the ISO eight-six-zero-one date format! Daniel mentioned that too. Year-Month-Day. It’s the only logical way to date things. If you write "zero-four-ten-twenty-six," is that April tenth or October fourth? You cause a geopolitical crisis just by trying to date your software.
Herman
Well, I shouldn't say exactly, but you're spot on. ISO eight-six-zero-one is the only format that sorts correctly in a file system and avoids all regional confusion. It’s the small details like that which separate the professional projects from the hobbyist ones. When you see a project with a clean SemVer history, a human-readable changelog in ISO format, and clear breaking change warnings, you know you can trust that code.
Corn
It builds a "reputation" for the developer. We talk a lot about code quality, but the way you release code is often more important than the code itself. You can have the most beautiful, optimized algorithm in the world, but if you distribute it in a way that breaks everyone’s build or confuses your users, nobody is going to use it.
Herman
It's the "user experience" of the developer. We spend so much time on the UX of the app's interface, but the UX of the library is the versioning and documentation. Daniel’s point about Conventional Commits really highlights this. If you use "fix," "feat," and "breaking change," you are providing a clear map for anyone who wants to contribute to your project or use it. It’s about reducing the cognitive load for everyone involved.
Corn
Let’s talk about the "breaking change" convention for a second. In Conventional Commits, you can put an exclamation point after the type, like "feat exclamation point." It’s so aggressive, I love it. It’s like the commit message is screaming at you. "FEATURE! BUT IT WILL BREAK YOUR STUFF!" It’s a very honest way to communicate.
Herman
It is! And there’s a technical reason for it too. Tools that parse these messages look for that exclamation point or the "BREAKING CHANGE" footer to automatically trigger a Major version bump in the build pipeline. This means the developer doesn't even have to remember to change the version number from "two" to "three." The system sees the exclamation point and says, "Okay, this is a Major release, I’m incrementing the first digit." It removes human error from the equation.
Corn
So we’ve got the machine handling the numbers, the developer handling the commit messages, and the human user getting a beautiful, curated changelog at the end. It’s a perfect harmony. But I have to ask, what about the "Patch" releases? Sometimes I see projects that are on version one point zero point five hundred. Is that a sign that they’re just fixing a lot of bugs, or that they’re afraid to add features?
Herman
It usually means they have a very robust CI-CD pipeline—Continuous Integration and Continuous Deployment. If every single bug fix is pushed immediately to the users, you’ll see those Patch numbers climb very fast. It’s actually a sign of a very "active" project. In the old days, you’d wait six months to bundle fifty fixes into a Minor release. Now, we prefer to push them as soon as they’re ready. As long as it’s a true Patch—meaning it doesn't change the API and doesn't add a big new feature—it's zero-risk for the user.
Corn
What about the "Minor" bump? That feels like the "sweet spot" for most users. You get something new, like a "Dark Mode" or a new search filter, but you don't have to change anything on your end. It’s like getting a free gift with your purchase.
Herman
The Minor bump is where the "value" lives. If you see a jump from two point four to two point five, you know there’s something new to play with. But even there, the "Keep a Changelog" rules say you should be careful. Don't just list the feature; mention if anything was deprecated. Deprecation is the "polite warning" of the software world. You’re saying, "Hey, this function still works for now, but we’re going to remove it in the next Major version, so start moving away from it."
Corn
It’s the "graceful exit." I’ve always appreciated when a library tells me six months in advance that they’re going to change something. It gives me time to plan. It’s so much better than waking up on a Monday morning to a broken build because a maintainer decided they didn't like the name of a variable anymore.
Herman
That is the "version promiscuity" problem that SemVer was designed to fix. People used to just "assume" that the next version would work. With SemVer, you don't have to assume. You can set your package manager to "caret versioning," which basically says, "Give me any version that isn't a Major bump." So if I’m on version two point one, the computer will automatically grab two point two or two point nine, but it will never grab version three point zero without my explicit permission.
Corn
It’s like a digital bodyguard for your code. "You can come in if you’re a bug fix, but if you’re a breaking change, you’re not on the list." I think we’ve covered the "what" and the "how," but let’s talk about the "why" one more time. Daniel is very active in open source—GitHub, NPM, Hugging Face. For someone like him, this isn't just about being organized; it’s about community.
Herman
When you follow these standards, you are showing respect for your fellow developers' time. You’re saying, "I value your workflow enough to be disciplined about mine." It also makes it much easier for new contributors to join your project. If they see a clean commit history and a clear release process, they feel more confident that their contributions will be handled professionally. It’s the difference between a messy garage and a world-class laboratory.
Corn
I’m thinking about the "SQLite" example again. That project is legendary for its stability. They have tests that cover every single line of code, but their release notes are also a masterclass in clarity. They’ll explain a one-percent performance improvement in a specific SQL query with absolute precision. That level of detail is what builds a multi-decade legacy.
Herman
And they don't use Git in the traditional way! They use Fossil, which was built specifically to handle their philosophy of versioning. They emphasize the "permanent record" even more than most. But the principles are the same. Whether you’re using Git, Fossil, or Subversion, the "contract" of SemVer and the "communication" of a changelog are universal.
Corn
So, as we wrap up this technical deep dive, what are the practical takeaways for the folks listening at home who might be feeling a little overwhelmed by all these acronyms?
Herman
First, start using Semantic Versioning today. If you have a project, give it a version number and follow the Major point Minor point Patch rule. Second, create a "CHANGELOG dot md" file in your repository and use the "Unreleased" section. Don't just dump your git log; write for a human being. Third, look into Conventional Commits. Even if you don't automate the release process yet, just starting to label your commits as "feat" or "fix" will change the way you think about your code.
Corn
And for the love of all that is holy, use ISO dates. Don't make us guess what month it is. We have enough problems in 2026 without wondering if your software was released in April or October.
Herman
I think the most important takeaway is that versioning is a form of empathy. You are imagining the person on the other side of the screen who is trying to use your work. You are making their life easier by being predictable. In a world of chaotic software, predictability is a superpower.
Corn
That’s a great way to put it. Software as an act of empathy. Who knew a bunch of dots and numbers could be so emotional? This has been a fascinating look at the "hidden" infrastructure of the software world. Thanks to Daniel for the prompt—he really knows how to get us into the weeds on things that actually matter for the "plumbing" of the internet.
Herman
It’s the plumbing that keeps the water running, Corn. Without these versioning contracts, the web would be a much more broken and frustrating place. I’m glad we got to shine a light on the people who take the time to do it right.
Corn
Alright, that's our deep dive into the world of SemVer and changelogs. Before we sign off, a big thanks to our producer, Hilbert Flumingtop, for keeping us on track. And of course, a huge thank you to Modal for providing the GPU credits that power the generation of this show. We literally couldn't do this without them.
Herman
If you found this useful, or if you’re a developer who has a strong opinion on whether version one point zero is a trap, we’d love to hear from you. You can reach us at show at myweirdprompts dot com.
Corn
This has been My Weird Prompts. If you are enjoying the show, a quick review on your podcast app really helps us reach new listeners and keeps the algorithm happy. You can also find us at myweirdprompts dot com for the full archive and our RSS feed.
Herman
Until next time, keep your versions semantic and your changelogs human.
Corn
See ya.

This episode was generated with AI assistance. Hosts Herman and Corn are AI personalities.