Releases only happen from a green master — CI (.github/workflows/ci.yml) runs the same
checks listed here, so a red anywhere means stop.
-
Sync the payload from the kit source of truth and verify:
uv run --project scripts scripts/sync_kit.py --kit <delivery-standard>/kit uv run --project scripts scripts/sync_kit.py --kit <delivery-standard>/kit --check
-
Run the suite — everything, including the golden-repo compose test and the payload completeness tripwire:
uv run --project scripts pytest scripts/tests -q
If the kit legitimately changed the installed tree, regenerate the snapshot (
GOLDEN_REGEN=1 uv run --project scripts pytest scripts/tests/test_golden_repo.py -q), review the diff, and commit it deliberately. -
Bump the version in
.claude-plugin/plugin.jsonAND.claude-plugin/marketplace.json(they must match). Semver: new capability = minor, fixes only = patch. -
Write the CHANGELOG entry —
CHANGELOG.md, newest first, factual and short.Steps 3 and 4 are enforced by
scripts/tests/test_release_manifest_agreement.py: the two manifests must agree on version and name, the version must be semver, and it must be the newest release heading in the CHANGELOG. This exists because 1.1.0 bumpedplugin.jsonalone — git then auto-mergedmarketplace.jsonto the previous version with no conflict and no failing test, which would have published a release the marketplace never offered. -
Commit (
feat:/fix:/chore:as appropriate), push, and wait for CI green. -
Tag and push the tag:
git tag -a vX.Y.Z -m "X.Y.Z — <one-line summary>" git push origin vX.Y.ZTags exist from
v0.4.0onward; every release gets one — it is how an engagement can say which harness version it runs (see also.claude/harness-manifest.jsonin installed repos, which records the version at install time, and/sdlc-upgradeto move repos forward).