modelvet release policy and procedure
August 4, 2026 ยท View on GitHub
This document is the versioning contract embedders rely on and the checklist a release actually follows. The ABI rules here are permanent; the procedure evolves.
Versioning policy
modelvet uses semantic versioning. The version lives in one place,
include/modelvet.h (MVET_VERSION_MAJOR/MINOR/PATCH); the
amalgamation banner, the CLI, make dist, and the Python binding all
derive from it.
Permanent ABI, regardless of version:
- Violation-code numbers are append-only. A
MVET_V_*value is never renumbered and never reused. A check that is retired leaves a hole in the numbering. New codes append inside their group gaps or in new groups. A consumer may persist numeric codes forever. - The report struct layout is stable.
mvet_report_tis fixed-width fields only; an all-zero report reads as fail-closed REJECT. - Status and verdict values are stable.
MVET_OK = 0,MVET_ERR_ARG = -1,MVET_ERR_ARENA = -2,MVET_VERDICT_REJECT = 0,MVET_VERDICT_ACCEPT = 1. - CLI exit codes are stable. 0 verified ACCEPT, 1 verified REJECT,
2 no verdict. JSON report fields are append-only: existing fields keep
their names, types, and order; new fields append before
version.
Pre-1.0 rules (current):
- MINOR releases may add public API, add violation codes, and change cap DEFAULTS. The arena bounds move with cap defaults; the closed-form formulas are the contract, not the numeric values.
- Pre-1.0 signature or behavior changes to existing public API are permitted only deliberately, with a CHANGELOG entry and a migration note. There is no silent breakage tier.
- PATCH releases change no public API and no default cap.
Post-1.0, MAJOR gates any signature or behavior break of existing public API; everything above still holds.
Verdict-strictness changes are behavior: a release that makes the validator stricter (new REJECT on previously accepted shapes) or looser documents each change in the CHANGELOG with its violation code and rationale, the way "policy" codes are marked in the public header.
Release artifacts
modelvet-X.Y.Z.tar.gz: reproducible tarball frommake distholding the amalgamatedmodelvet.c+modelvet.h, LICENSE, README.md, CHANGELOG.md, INTEGRATION.md, and themodelvet.1man page. Built with pinned timestamps (SOURCE_DATE_EPOCH, default 0), sorted entries, and numeric zero ownership: the same tree produces the same bytes.modelvet-X.Y.Z.tar.gz.sha256: emitted bymake dist.modelvet-X.Y.Z.tar.gz.sig(or.asc): detached signature, made by the release manager with the same key that signs the tag. 0.1.0 used an SSH signature (ssh-keygen -Y sign -n file); a GPG detached signature is equally acceptable. The release notes must state which, plus the verification command.
Release procedure
-
Verify the tree on the full matrix (both compilers):
make clean && make check CC=gcc make clean && make check CC=clang make test-profile-64k CC=clang make test-no-assert CC=clang make clean && make test CC=clang \ EXTRA_CFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=all" make fuzz && ./build/smoke_fuzz -runs=100000 make check-ggml GGML_DIR=/path/to/pinned/llama.cpp make check-python -
Bump the version in
include/modelvet.h, finish the CHANGELOG section (date it), and land that change through CI. -
Confirm branch protection: the corpus, parity, and gate jobs must be required status checks so the release commit cannot bypass them.
-
Build and sign (SSH shown, as used for 0.1.0; GPG works the same way with
gpg --detach-sign --armor):make dist ssh-keygen -Y sign -f ~/.ssh/<key> -n file \ build/dist/modelvet-X.Y.Z.tar.gz -
Tag and publish:
git tag -s vX.Y.Z -m "modelvet X.Y.Z" git push origin vX.Y.Z gh release create vX.Y.Z build/dist/modelvet-X.Y.Z.tar.gz \ build/dist/modelvet-X.Y.Z.tar.gz.sha256 \ build/dist/modelvet-X.Y.Z.tar.gz.asc \ --title "modelvet X.Y.Z" --notes-file <notes> -
Python package:
make python-vendor, then build and upload the sdist frombindings/python/(reserves the PyPI name at first release). -
Post-release: reserve/confirm the npm name, update integration consumers, and open the next CHANGELOG section.
Steps 4-7 require the release manager's keys and registry accounts; they are never performed by automation or an agent session.