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
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
service | string | yes |
| |
release | string | yes | The deployed commit (short sha). |
|
released_at | string | yes | Commit time of the release. |
|
booted_at | string |
| ||
contracts_version | string | null | yes | openvibe-contracts version the service runs against. | |
packages | object | Versions of the platform packages the page loads (openvibe-shared, openvibe-sdk, ...). | ||
min_client_release | string | null | yes | Oldest client release still supported; null while every client in the window is. | |
mixed_version_window_hours | integer | yes |
| |
components | object | Since 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. | ||
assets | object | Since 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_generation | integer | null | Since 1.1.0. The database schema generation this release migrates to and runs against; null when the service does not track one. |
| |
schema_compatible_from | integer | null | Since 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. |
| |
contract_ranges | object | Since 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_url | string | null | Since 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. |
|
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 }] }