Skip to content
Musher Docs

Publishing

Manifest schema, version lifecycle, OCI integration, and yank semantics for bundle versions.

Publish Requirements

To publish a bundle version, two conditions must be met:

  1. At least one asset — you'll receive an error if the bundle has no assets. Add at least one asset to your musher.yaml before publishing.
  2. Unique version string — you'll receive an error if that version already exists for this bundle. Bump the version in your musher.yaml to publish a new release.

Publishing freezes the manifest and creates an immutable version record. If an OCI registry is configured, assets are also pushed to the registry.

Manifest Schema

Top-Level Object

FieldTypeRequiredDescription
namespacestringYesNamespace that owns the bundle
bundle_slugstringYesBundle slug at publish time
versionstringYesPublished version string
assetsarray<object>YesSnapshot of every asset in the published version

Asset Entry

Each item in the assets array has the following shape:

FieldTypeRequiredDescription
asset_idstringYesUUID of the asset (used for download)
logical_pathstringYesBundle-relative path, e.g. prompts/review.md
asset_typestringYesAsset classification label
content_sha256stringYesSHA-256 hash of the asset content
size_bytesintegerYesByte length of the asset content at publish time

Manifest Example

Manifest JSON
{
  "namespace": "acme",
  "bundle_slug": "code-review",
  "version": "1.2.0",
  "assets": [
    {
      "asset_id": "550e8400-e29b-41d4-a716-446655440000",
      "logical_path": "prompts/review.md",
      "asset_type": "prompt",
      "content_sha256": "9e8c4b9f1b8d6d52f1c4dd9ab8f6b0fd...",
      "size_bytes": 2048
    },
    {
      "asset_id": "a4b1ac0c-a0db-4ea5-a7d8-c6b4ff4b8c2f",
      "logical_path": "agents/reviewer.yaml",
      "asset_type": "agent_spec",
      "content_sha256": "4f31d7a3fd6f0fca0d66ef7dd3c738fc...",
      "size_bytes": 1187
    }
  ]
}

API Responses

The manifest data appears in two response shapes depending on the endpoint.

The version detail endpoint returns the full manifest with namespace, slug, and version at the top level:

json
{
  "namespace": "acme",
  "bundleSlug": "code-review",
  "version": "1.2.0",
  "assets": [
    {
      "assetId": "550e8400-e29b-41d4-a716-446655440000",
      "logicalPath": "prompts/review.md",
      "assetType": "prompt",
      "contentSha256": "9e8c4b9f...",
      "sizeBytes": 2048
    }
  ]
}

Each asset includes assetId, logicalPath, assetType, contentSha256, and sizeBytes.

OCI Integration

When a registry is configured, the publish flow pushes bundle assets to an OCI-compatible registry using the ORAS protocol.

Media Types

Media TypePurpose
application/vnd.musher.bundle.v1.assetIndividual asset file layer
application/vnd.musher.bundle.v1.configConfig blob with asset metadata (paths, types, hashes)

Reference Format

OCI references follow the pattern {registry}/{namespace}/{bundle_slug}:{version}.

Error Handling

ScenarioHTTP StatusWhat to Do
Registry authentication failed503 Service UnavailableRe-authenticate with musher login or check your API key
Registry unreachable (connection timeout, DNS failure)503 Service UnavailableCheck your network connection and retry; run musher doctor to diagnose
Other push failures500 Internal Server ErrorRetry the publish; if the error persists, contact support

Version States

A published version has exactly one allowed state transition:

published ──yank──▶ yanked ──unyank──▶ published

Yank Semantics

Yanking soft-withdraws a published version from resolution:

  • The version's state changes to yanked, and the reason, timestamp, and actor are recorded.
  • Yanked versions are excluded from resolve queries but remain accessible via the detail endpoint for audit purposes.
  • Idempotent — yanking an already-yanked version is a no-op.
  • Reversible — use musher unyank to restore a yanked version.
  • Audit trail preserved — you can always see what was withdrawn, by whom, when, and why.