Scrydon
SDKsPacks & Authoring SDK

Pack Versioning

How pack versions flow from your repository through the catalog to what actually runs — semver rules, the release checklist, version pins, update policies, breaking-change detection, and SDK compatibility.

This page is the end-to-end picture of pack versioning: what a version is, every place it must be declared when you release one, and what the platform does with it — from catalog sync to the moment a workflow executes your integration's code.

The version model

Three layers carry a version, and they serve different purposes:

LayerDeclared inPurpose
Pack versionpack.jsonpackage.version, and the source's catalog index (scrydon.yamlversion)Identifies a catalog row. The catalog keeps one row per (packId, version) — releasing 1.2.0 adds a row; the 1.1.0 row stays.
Content-entry versionpack.jsoncontents[].version and each subdir manifest (e.g. integration-acme/manifest.jsonversion)Per-kind version inside the pack. For integrations it must match the version compiled into the artifact.
Artifact versionInside the built bundle (defineVendor({ version }) for integrations)What the platform registers and what update comparisons use. The install verifies it matches the content entry — a mismatch rejects the install.

All versions are semver (MAJOR.MINOR.PATCH, pre-release suffixes like 2.0.0-beta.1 sort below the release). The platform compares versions numerically — 1.10.0 is newer than 1.9.0.

Old versions never disappear on their own. Catalog rows for previous versions stay live (they power rollback and the "Other live catalog versions" list). Everything that decides what is current — the marketplace, the Packs page, the runtime — selects the highest-semver live version, honoring any version pin (below). You never need to delete old rows for a new release to take effect.

Releasing a new version — the checklist

A release only propagates when every layer moves together. Forgetting one is the most common publishing mistake — in particular the catalog index: the sync reconciler compares index versions, so a bumped pack.json behind an unchanged scrydon.yaml entry is silently skipped on every sync.

For integrations: defineVendor({ version: "1.2.0" }) (or your build's equivalent), then rebuild the artifact — bunx @scrydon/sdk-authoring integrations build produces dist/{vendorId}-1.2.0.bundle.tar.gz.

The subdir manifest (integration-*/manifest.jsonversion) and the matching contents[] entry in pack.json must declare the same version as the artifact. The install verifies artifact identity against the catalog entry and rejects mismatches.

pack.jsonpackage.version. Convention: the pack version moves at least as fast as its fastest-moving content entry.

For Git/OCI pack sources: the scrydon.yaml entry for your pack (version:) must be bumped to the new version. This is the field the reconciler keys on — without it, nothing else you changed is ever picked up.

If your repo commits built output (the recommended layout), rebuild dist/ and run your verify gate so dist/ matches src/. Push/publish; the platform syncs the source on its interval (default every 5 minutes) or immediately via Refresh on the source in Settings → Platform → Packs.

Pick the right bump

BumpUse whenPlatform behavior
Patch (1.1.11.1.2)Bug fixes, no surface changesEligible for auto_patch and auto_minor policies
Minor (1.1.x1.2.0)New tools, new optional inputs, new capabilitiesEligible for auto_minor
Major (1.x2.0.0)Anything breaking: removed/renamed tools, new required inputs, changed input/output types, auth-mode changesAlways manual; the update review shows a breaking warning

The platform verifies your choice rather than trusting it — see breaking-change detection.

What happens after a release lands

A new version arriving in the catalog is deliberately inert:

  1. The sync adds a catalog row for the new version (and, for integration content, stores the artifact). Nothing about what runs has changed yet.
  2. Every installed integration is pinned to the version it was installed at. The pin — not the newest row — decides which version the marketplace lists, which manifest tools/blocks resolve from, and which code executes in the sandbox.
  3. The new version surfaces as Update available on the Packs page and as an Update badge on the integration's marketplace card.
  4. The pin moves in exactly two ways:
    • Manually — an admin clicks Update pack after the impact review. In-flight workflow runs finish on the version they started with; new runs use the new version.
    • Automatically — connections that opted in via an update policy:
PolicyAuto-applies
manual (default)Nothing — updates wait for the Packs page
auto_patchPatch bumps with no detected breaking changes
auto_minorPatch + minor bumps with no detected breaking changes

Major bumps and any update with detected breaking changes always wait for manual review (the connection shows update blocked: breaking_diff until an admin reviews it).

Breaking-change detection and semver honesty

When an update is available, the platform diffs the installed and target manifests and classifies the changes:

ChangeClassification
Tool, product, or block removed or renamedBreaking
New required input field; existing field removed or type changedBreaking
Output field removed or type changedBreaking
Auth mode changed (e.g. apiKey → OAuth)Breaking
New tool/product, new optional input, description changesCompatible

The findings appear in the update review on the Packs page, next to the list of affected workflows. Two warning levels:

  • Potentially breaking (amber) — a major bump, or breaking findings correctly shipped as a major.
  • Breaking changes in a non-major update (red) — the diff found breaking changes but you shipped a minor or patch. Auto-update policies refuse it, and admins see the stronger warning. Don't do this — re-release as a major.

SDK contract compatibility

Integration artifacts are compiled against a specific generation of the platform↔bundle runtime contract (the shape of ctx.auth, the dispatch protocol). The SDK stamps this contract version into your manifest automatically at build time — you never declare it by hand.

  • The platform supports the current and the immediately previous generation; previous-generation bundles run through an automatic compatibility translation.
  • A bundle built against an unsupported generation is refused at install (integration_contract_incompatible) and at run time (BUNDLE_CONTRACT_INCOMPATIBLE) with a message naming the versions involved. Both mean the same thing: rebuild and republish with a current @scrydon/sdk-authoring release (a patch release of your pack is enough).

Practical rule: rebuild your packs with a current SDK whenever you cut a release, and you will never be more than one generation behind.

Rolling back

Because old catalog rows and old installed versions are retained, an admin can roll an integration back to any previous version from the version management surface — the pin moves backwards and in-flight runs drain first, the same mechanics as an upgrade. Rollback never requires re-publishing anything from your side.

Exceptions by content kind

  • Process flows always track the latest live catalog version — they have no pinned installed version and no update action.
  • Ontologies, KB domains, workflows, data sources are versioned per install; the Packs page shows their per-kind install state.
On this page

On this page