Semantic Versioning skill for Codex

Major, minor or patch, decided against the real API. Codex pins down what the public API actually is, classifies each change since the last tag, and proposes the version bump with reasons, including subtle breaks like narrowed TypeScript types, changed defaults and dropped runtimes. It knows 0.x caret rules, pre-release ordering, PEP 440 and Go module paths, runs API-diff tools where they exist, and writes a deprecation policy with warnings in code.

  • Engineering Workflow
  • $semantic-versioning
  • 172 lines
  • 2 files
  • ~1,850 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- semantic-versioning

Installs to ~/.agents/skills/semantic-versioning/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $semantic-versioning, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Decides the correct SemVer 2.0.0 bump for a library, CLI, API or package by classifying every change against the public API - including the edge cases (new required parameters, narrowed types, changed defaults, dropped runtimes, 0.x rules), pre-release identifiers such as 2.0.0-rc.1, npm dist-tags, PEP 440 and Go module /v2 paths - and writes a deprecation policy with warnings and removal windows. Use when asking "is this a breaking change", "major or minor", choosing the next version, publishing a beta, deprecating an API, or checking a diff with cargo-semver-checks or API Extractor.

Use it when

  • You are choosing the next version number for a library or CLI
  • A diff might break consumers and you need a clear answer
  • You need alpha, beta or rc versions that sort correctly
  • Your project has no written deprecation policy

Use something else when

How to check the result

Every commit since the last tag appears in the classification table, and the ecosystem's API-diff tool agrees with the proposed bump or the difference is explained.

The mistake it prevents

Calling a change minor because runtime behaviour is unchanged, when a narrowed type or new required field breaks every consumer's build.

~/.agents/skills/semantic-versioning/SKILL.md

--- name: semantic-versioning description: Decides the correct SemVer 2.0.0 bump for a library, CLI, API or package by classifying every change against the public API - including the edge… license: MIT ---

A version number is a promise to consumers. The bump is right when every consumer who followed your documented public API can take a MINOR or PATCH upgrade without changing their code or behaviour, and when anything that could break them waited for a MAJOR with a deprecation period first.

Define the public API first

SemVer is meaningless until the public surface is written down. Check README, docs, the package exports map, __all__, exported Go identifiers, pub items, OpenAPI spec, CLI flags, config keys, environment variables, file formats, and wire or database schemas that consumers read. If the project has no statement, propose one to the user before deciding a bump.

The decision

Classify each change since the last tag, then take the highest bump:

git log --oneline $(git describe --tags --abbrev=0)..HEAD
git diff $(git describe --tags --abbrev=0)..HEAD --stat
ChangeBump
Bug fix that restores documented behaviourPATCH
Performance improvement, internal refactor, docsPATCH
New function, class, endpoint, optional parameter, CLI flagMINOR
New deprecation warning (old thing still works)MINOR
New optional field in a response or configMINOR
Removing or renaming anything publicMAJOR
New required parameter, field or env varMAJOR
Narrowing an input type or widening an output type (TypeScript, typed APIs)MAJOR
Changing a default value consumers rely onMAJOR
Changing error types or codes consumers catchMAJOR
Dropping a supported runtime, OS or language versionMAJOR (state it in the changelog)
Raising a peer dependency’s major rangeMAJOR
Fixing a bug that consumers demonstrably depend onJudgement: MAJOR if widely relied on, else PATCH with a loud note
Security fix that must break a behaviourShip it; MAJOR if possible, otherwise MINOR or PATCH with explicit advisory

Hyrum’s law means any observable behaviour gets depended on. The table is about the documented contract; use judgement where the observable behaviour is popular.

TypeScript and typed APIs

Type changes break builds even when runtime behaviour is identical:

  • Adding a member to a union in a return type can break exhaustive switch statements: MAJOR unless documented as open.
  • Making an optional property required in an input type: MAJOR.
  • Making an interface property optional in an output type: MAJOR (readers must now handle undefined).
  • Raising the minimum TypeScript version required by your .d.ts: treat as MAJOR, or document a TS support window explicitly.

Before 1.0.0

0.y.z signals an unstable API. Common conventions, which package managers encode:

  • npm caret: ^0.4.2 means >=0.4.2 <0.5.0, so a minor bump in 0.x is treated as breaking.
  • Cargo: 0.4.2 likewise allows only 0.4.x.
  • Treat 0.MINOR as the breaking digit and 0.x.PATCH as fixes and features.

Ship 1.0.0 once real users depend on the package in production. Staying on 0.x for years does not remove the obligation; it only hides it.

Pre-releases and build metadata

2.0.0-alpha.1 < 2.0.0-alpha.2 < 2.0.0-beta.1 < 2.0.0-rc.1 < 2.0.0
2.0.0-beta.2 < 2.0.0-beta.11      # numeric identifiers compare numerically
2.0.0+build.5                     # build metadata: ignored for precedence
  • Use dot-separated numeric counters (rc.1, not rc1) so ordering is correct.
  • npm: npm version prerelease --preid rc produces 2.0.0-rc.0, then -rc.1. Publish with npm publish --tag next so latest is untouched (publishing is outward-facing: confirm with the user first).
  • Ranges skip pre-releases unless the range itself names one; consumers opt in deliberately.

Ecosystem rules that override plain SemVer

EcosystemRule
Python (PEP 440)Pre-releases are 2.0.0a1, 2.0.0b2, 2.0.0rc1; post-releases 2.0.0.post1. -rc.1 is normalised, so write the PEP 440 form
Go modulesFrom v2 on, the module path must end in /v2 (module example.com/lib/v2) and imports change; tags are v2.0.0
Rust / CargoCargo treats 0.x minors and any major as incompatible; check with cargo semver-checks
npmpeerDependencies ranges are part of your contract; engines changes are user-visible
REST / GraphQL APIsVersion the contract (URL, header or schema evolution), not the server build; see api-versioning
Apps (not libraries)SemVer adds little; calendar versions or build numbers are fine

Tooling to check a bump

These compare the public API between two versions. Run them in CI on release PRs when the project is a library (installs need network):

  • Rust: cargo semver-checks (compares against the last published crate version).
  • TypeScript: API Extractor (api-extractor run) keeps an API report file under review; @arethetypeswrong/cli checks package exports and types resolution.
  • Go: gorelease (golang.org/x/exp/cmd/gorelease) suggests the next version from API diff.
  • Python: griffe check <package> reports API breakages against a git ref.
  • OpenAPI: oasdiff breaking old.yaml new.yaml.

A clean tool report does not prove behaviour compatibility; it only covers signatures.

Deprecation policy

Write a policy once and follow it every time:

## Deprecation policy
- Deprecations are announced in a MINOR release, never a PATCH.
- Deprecated APIs keep working for at least one further MINOR release and 3 months,
  and are removed only in the next MAJOR.
- Each deprecation emits a runtime warning once per process and names the replacement.
- The changelog lists deprecations under "Deprecated" and removals under "Removed".

Mark deprecations in code so tools surface them:

/** @deprecated Since 3.4.0. Use `createClient({ retries })` instead. Removed in 4.0.0. */
export function createRetryingClient(opts: Options) { /* ... */ }
import warnings

def load_config(path):
    warnings.warn(
        "load_config() is deprecated since 3.4.0; use Config.from_file(). Removal in 4.0.0.",
        DeprecationWarning, stacklevel=2,
    )
    return Config.from_file(path)

Gotchas

  • Bumping MAJOR for every trivial break trains users to ignore majors; batch breaking changes into planned majors with a migration guide.
  • A PATCH that changes behaviour “to match the docs” can still break production users. Search issues and dependents first.
  • Version in code, tag and package metadata must match; derive one from the other (for example setuptools-scm or a release tool) instead of editing three places.
  • Yanked or unpublished versions are never reused. If 2.1.0 was bad, the fix is 2.1.1.

Output

**Last release:** v3.3.1   **Proposed:** v4.0.0 (MAJOR)
| Change | Classification | Why |
|---|---|---|
| Removed `createRetryingClient` | MAJOR | public export removed (deprecated since 3.4.0) |
| New `timeoutMs` option | MINOR | optional, default unchanged |
| Fix off-by-one in pagination | PATCH | restores documented behaviour |
**Tool check:** api-extractor report diff attached; 1 removal, 1 addition
**Migration notes needed:** yes - see changelog draft

Verification

  • Every change since the last tag appears in the classification table.
  • The API-diff tool for the ecosystem agrees with the proposed bump, or the disagreement is explained.
  • Deprecated items carry the version, the replacement and the planned removal version.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Semantic Versioning"
  short_description: "Major, minor or patch, decided against the real API"
  default_prompt: "$semantic-versioning Is this change breaking? Tell me whether the next version is major, minor or patch"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem