0.2.4 - 2026-08-10
Release Notes
Added
- The contract can now express "version-tracked but never published". An explicitly-set empty
targets: []is honored as authoritative — the normalizer no longer force-expands it into a default
crates.io/cargo-publishtarget. An omittedtargetskey still expands to the ecosystem default
as before (the distinction is explicit-empty vs absent). This lets a private/internal project be
version-tracked and changelogged without any registry publish target. - Multi-distribution (monorepo) support.
Contractnow carriesdistributions: Vec<Distribution>
with a per-packagepackageassociation key, so a monorepo can declare several independently
distributed binaries (each with its own gh-releases/installers/tap). A single baredistribution:
block still parses unchanged (deserialized as a one-element list); a pluraldistributions:list is
also accepted. The release engine remains single-distribution and fails loud on adistributions
length > 1 (per-distribution engine support tracked inper-distribution-release).
Changed
- BREAKING (canonical wire shape):
schema_versionbumped1→2. The canonical-JSON key
distributionwas renamed todistributions(now always an array), and every distribution carries a
packagefield. ossctl still reads v1 documents (a singulardistribution:mapping) and
translates them into the v2 canonical shape. Downstream/oss-*members that read the normalized
contract should key ondistributions. - The normalizer now hard-errors on inconsistent Homebrew configuration (previously silent). A
homebrew-registry target or ahomebrewinstaller with nohomebrew_tapdestination, a
double-publish collision (installer and target both producing a formula), and a
registry/adapter mismatch (registry: homebrewrequires thehomebrew-tapadapter) are now rejected
at validate time with a clear error, instead of failing later at release time. This can reject some
previously-accepted contracts — intended. - The engine's Homebrew tap-write preserves hand-maintained formulas. A formula is fully
regenerated only when it carries anossctl-generated ownership marker; a hand-maintained formula
(no marker) is updated surgically (only theurl/sha256lines) or refused, never clobbered. ossctl's
own generated formula carries the marker, so its own tap keeps the simple full-render path. - An empty
extra_fieldsmap is now omitted from canonical JSON (not emitted as"extra_fields": {}),
symmetrically for the top-levelContractand the nestedDistribution(skip_serializing_if). A
populatedextra_fieldsserializes exactly as before. Noschema_versionchange from this alone, but
the release-planSEAL_VERSIONbumped4→5(the sealed pre-image of an empty-extra_fields
contract changed). Combined with the monorepo change above,SEAL_VERSIONis5andschema_version
is2in this release.
Fixed
- The generated crates-publish CI workflow now auto-fires. It triggers on the version-tag
push
instead ofrelease: published— GitHub does not emit areleaseevent for a Release created by the
defaultGITHUB_TOKEN(as cargo-dist does), so the old trigger never ran and crates.io was published
only via manual dispatch.workflow_dispatchis retained as a manual fallback. release resumeno longer demands--allow-unverifiedwhen the publish phase was never reached.
A run that failed in the build phase (before any publish could have happened) now resumes directly;
the genuinely-unsafe cases (publish reached but no receipt;Published × Unknown) still require the
flag.release abandon --reasonaccepts a reason that starts with--(previously rejected as an
unknown flag by the argument parser).- Normalizer diagnostics JSON-encode user-controlled keys, so a contract key containing quotes,
newlines, or control characters can no longer forge or corrupt diagnostic/JSONL log lines.
Install ossctl 0.2.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/jarimustonen/ossctl/releases/download/v0.2.4/ossctl-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/jarimustonen/ossctl/releases/download/v0.2.4/ossctl-installer.ps1 | iex"Download ossctl 0.2.4
| File | Platform | Checksum |
|---|---|---|
| ossctl-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| ossctl-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| ossctl-aarch64-unknown-linux-musl.tar.xz | ARM64 MUSL Linux | checksum |
| ossctl-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo jarimustonen/ossctlYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>