ReleaseManifest registry.release-manifest@1

Generated at from openvibe-contracts v0.33.0 and openvibe-sdk v0.5.0.

Version
1.1.0
Owner
network
Visibility
public
Status
active
Compatibility
backward
Decision
ADR-016
Schema
https://openvibe.network/contracts/registry/release-manifest.v1.json

What a running web surface is serving (GET /release.json, ADR-016). Open clients compare it on focus and reconnect. A client outside the supported window is prompted and reloads only when that is safe. Since 1.1.0 the manifest can also say which components changed, so a client can apply style and content changes in place, and which contract versions the server still accepts, so a mixed-version population can be checked.

Fields

FieldTypeRequiredDescriptionConstraints
servicestringyes
  • pattern ^[a-z][a-z0-9-]{1,39}$
releasestringyesThe deployed commit (short sha).
  • pattern ^[0-9a-f]{7,40}$
released_atstringyesCommit time of the release.
  • format date-time
booted_atstring
  • format date-time
contracts_versionstring | nullyesopenvibe-contracts version the service runs against.
packagesobjectVersions of the platform packages the page loads (openvibe-shared, openvibe-sdk, ...).
min_client_releasestring | nullyesOldest client release still supported; null while every client in the window is.
mixed_version_window_hoursintegeryes
  • minimum 0
componentsobjectSince 1.1.0. Per-component versions. A client applies a new release in place only when every component that changed is a style, content or server component and the contract ranges still match. Any other change is applied by a reload at a safe moment. The shell component covers every client-facing file that no other component lists.
assetsobjectSince 1.1.0. Asset map: each logical URL path the release serves, mapped to its content-addressed URL. HTML from this release references only these URLs.
schema_generationinteger | nullSince 1.1.0. The database schema generation this release migrates to and runs against; null when the service does not track one.
  • minimum 0
schema_compatible_frominteger | nullSince 1.1.0. The oldest schema generation whose code still runs against this release's schema, because every migration since then only expanded it. Rolling back to a release whose schema_generation is lower is not data-safe.
  • minimum 0
contract_rangesobjectSince 1.1.0. For each contract the service produces (its API, as served to its own pages and clients) or consumes: the version this release speaks and the range of versions it accepts from the other side. A page from release A works against a server on release B when, for every contract A produces, A's version is in B's accepts and B's version is in A's accepts.
metrics_urlstring | nullSince 1.1.0. Same-origin URL where clients POST their update outcome counts (applied, reloaded, deferred, failed); null or absent when the service does not collect them.
  • maxLength 512

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: live-full
{
  "service": "live",
  "release": "047f2069a1b2",
  "released_at": "2026-09-23T18:02:11Z",
  "booted_at": "2026-09-23T18:04:40Z",
  "contracts_version": "0.31.0",
  "packages": {
    "openvibe-shared": "1.5.0",
    "openvibe-sdk": "0.4.0"
  },
  "min_client_release": null,
  "mixed_version_window_hours": 24,
  "components": {
    "styles": {
      "kind": "style",
      "version": "3f9a1c07be21"
    },
    "docs": {
      "kind": "content",
      "version": "a07e44d1c9f0"
    },
    "shell": {
      "kind": "script",
      "version": "c1d2e3f4a5b6"
    },
    "server": {
      "kind": "server",
      "version": "047f2069a1b2"
    }
  },
  "assets": {
    "/css/app.css": {
      "url": "/css/app.css?v=3f9a1c07be21",
      "component": "styles",
      "integrity": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    },
    "/js/app.js": {
      "url": "/js/app.js?v=9b8a7c6d5e4f",
      "component": "shell"
    }
  },
  "schema_generation": 42,
  "schema_compatible_from": 40,
  "contract_ranges": {
    "live.web-api": {
      "version": "1.4.0",
      "accepts": ">=1.0.0 <2.0.0"
    },
    "media.object": {
      "version": "1.0.0",
      "accepts": ">=1.0.0 <2.0.0",
      "role": "consumes"
    }
  },
  "metrics_url": "/release-metrics"
}
Valid: live
{
  "service": "live",
  "release": "8a678c8",
  "released_at": "2026-09-23T01:28:10Z",
  "booted_at": "2026-09-23T01:31:52Z",
  "contracts_version": "0.8.0",
  "packages": {
    "openvibe-shared": "1.0.0",
    "openvibe-sdk": "0.2.2"
  },
  "min_client_release": null,
  "mixed_version_window_hours": 24
}
Rejected: bad-release
{
  "service": "live",
  "release": "main",
  "released_at": "2026-09-23T01:28:10Z",
  "contracts_version": "0.8.0",
  "min_client_release": null,
  "mixed_version_window_hours": 24
}
Rejected: no-window
{
  "service": "live",
  "release": "8a678c8",
  "released_at": "2026-09-23T01:28:10Z",
  "contracts_version": "0.8.0",
  "min_client_release": null
}
Rejected: range-not-normalised
{
  "service": "live",
  "release": "047f2069a1b2",
  "released_at": "2026-09-23T18:02:11Z",
  "contracts_version": "0.31.0",
  "min_client_release": null,
  "mixed_version_window_hours": 24,
  "contract_ranges": {
    "live.web-api": {
      "version": "1.4.0",
      "accepts": "^1.0.0"
    }
  }
}
Rejected: unknown-component-kind
{
  "service": "live",
  "release": "047f2069a1b2",
  "released_at": "2026-09-23T18:02:11Z",
  "contracts_version": "0.31.0",
  "min_client_release": null,
  "mixed_version_window_hours": 24,
  "components": {
    "shell": {
      "kind": "layout",
      "version": "c1d2e3f4a5b6"
    }
  }
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('registry.release-manifest@1', value);   // { valid, errors: [{ path, message }] }