Definition & Overview
Semantic Versioning (Semver) is a versioning standard that uses a three-part MAJOR.MINOR.PATCH format to communicate the scope and compatibility impact of changes. As defined by semver.org: MAJOR version increments indicate backward-incompatible API changes, MINOR version increments indicate backward-compatible feature additions, and PATCH version increments indicate backward-compatible bug fixes. Pre-release versions and build metadata are appended as additional labels (e.g., 1.0.0-rc.1+build.42).
Semver's value lies in making version numbers meaningful rather than arbitrary. When a dependency updates from 1.3.2 to 1.4.0, consumers know that new features were added but no breaking changes were introduced. An update from 1.4.0 to 2.0.0 signals breaking changes that require migration effort. This semantic communication enables automated dependency management -- tools like Mix, npm, and Cargo can safely apply MINOR and PATCH updates while flagging MAJOR updates for manual review.
The Prismatic Platform follows semver strictly across all its components: the platform version itself (currently 8.0.0), individual umbrella application versions, AIAD component versions, policy versions, and documentation versions. The CLAUDE.md file tracks the platform version (currently 8.0.0, Generation 19), and each umbrella application's mix.exs declares its version following semver conventions.
Technical Deep Dive
Elixir's Mix build system integrates semver natively. Dependency specifications in mix.exs use semver-compatible version constraints: ~> (pessimistic, allows MINOR and PATCH updates), >= (minimum version), and exact version pinning.
defmodule PrismaticPlatform.MixProject do
use Mix.Project
@version "8.0.0"
def project do
[
app: :prismatic_platform,
version: @version,
elixir: "~> 1.19",
deps: deps()
]
end
defp deps do
[
# Pessimistic constraint: allows 1.7.x updates, blocks 1.8.0
{:phoenix, "~> 1.7.14"},
# Allows any 3.x version
{:phoenix_live_view, "~> 1.0"},
# Exact version pin (for stability-critical dependencies)
{:ecto, "3.12.5"},
# Minimum version
{:jason, ">= 1.4.0"}
]
end
end
Version comparison and constraint checking in Elixir uses the Version module, which implements full semver parsing including pre-release labels and build metadata.
defmodule PrismaticQuality.VersionChecker do
@moduledoc """
Validates version consistency across umbrella applications
and checks dependency version constraints.
"""
@spec check_platform_version() :: {:ok, Version.t()} | {:error, term()}
def check_platform_version do
case Version.parse("8.0.0") do
{:ok, version} ->
{:ok, version}
:error ->
{:error, :invalid_version}
end
end
@spec compatible?(String.t(), String.t()) :: boolean()
def compatible?(version_string, requirement_string) do
case Version.parse(version_string) do
{:ok, version} ->
requirement = Version.parse_requirement!(requirement_string)
Version.match?(version, requirement)
:error ->
false
end
end
@spec check_umbrella_consistency() :: {:ok, map()} | {:error, [map()]}
def check_umbrella_consistency do
apps = discover_umbrella_apps()
inconsistencies =
apps
|> Enum.flat_map(fn {app, version} ->
check_app_deps(app, version)
end)
case inconsistencies do
[] -> {:ok, %{apps: length(apps), all_consistent: true}}
issues -> {:error, issues}
end
end
@spec bump(String.t(), :major | :minor | :patch) :: {:ok, String.t()}
def bump(version_string, level) do
{:ok, version} = Version.parse(version_string)
new_version =
case level do
:major -> %{version | major: version.major + 1, minor: 0, patch: 0}
:minor -> %{version | minor: version.minor + 1, patch: 0}
:patch -> %{version | patch: version.patch + 1}
end
{:ok, Version.to_string(new_version)}
end
defp discover_umbrella_apps do
Path.wildcard("apps/*/mix.exs")
|> Enum.map(fn mix_file ->
app_dir = Path.dirname(mix_file)
app_name = Path.basename(app_dir) |> String.to_atom()
version = extract_version(mix_file)
{app_name, version}
end)
end
defp extract_version(mix_file) do
content = File.read!(mix_file)
case Regex.run(~r/version:\s*"([^"]+)"/, content) do
[_, version] -> version
_ -> "0.0.0"
end
end
defp check_app_deps(_app, _version) do
# Check internal dependency version constraints
[]
end
endArchitecture & Implementation
The Prismatic Platform's version management spans multiple dimensions. The platform version (8.0.0) represents the overall release. Individual umbrella applications maintain their own version numbers that increment independently based on their specific changes. AIAD components (agents, commands, policies) include version metadata in their YAML frontmatter.
The CI/CD pipeline validates version consistency: it verifies that committed changes are reflected in appropriate version bumps, that dependency constraints remain satisfiable, and that the changelog is updated for version changes. The pre-commit hook includes a version check phase that warns when source changes are committed without corresponding version bumps.
Version information is embedded in runtime metadata, enabling the health check endpoint and monitoring dashboard to report exact version numbers for debugging and deployment verification.
Usage in Prismatic Platform
Version management is integrated into the development workflow through Mix tasks and CI checks. The platform tracks versions across all 115 umbrella applications.
# Check current platform version
# mix version
# Check all umbrella app versions
# mix version --all
# Bump version
# mix version.bump patch # 8.0.0 -> 8.0.1
# mix version.bump minor # 8.0.0 -> 8.1.0
# mix version.bump major # 8.0.0 -> 9.0.0
# Verify version consistency
# mix quality.version_check
The Hex package manager, used for Elixir dependency distribution, requires semver compliance for all published packages. The platform's four OSS packages (SDK, Plugin Kit, Security, UI) follow strict semver with automated version validation in the release pipeline.
Cross-References
- Schema Migration - Database changes coordinated with version bumps
- Quality Floor - Quality standards versioned alongside the platform
- Placeholder - Forbidden patterns tracked by version
- Runtime - Version information available at runtime for diagnostics
- Self-Registration - Registered components carrying version metadata
Created by Tomas Korcak (korczis) | GitHub