ModManifest mods.mod-manifest@1
Generated at from
openvibe-contracts v0.114.0 and
openvibe-sdk v0.35.1.
- Version
- 1.1.0
- Owner
- contracts
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-013
- Schema
https://openvibe.network/contracts/mods/mod-manifest.v1.json
A mod as the platform knows it (ADR-013): who publishes it, which runtime runs it, which capabilities it asks for and the resources it may use. Requested capabilities are only a request: the install's approved subset is the grant, and trust tiers are install metadata that never change a grant check. The runtime-specific payload (a data pack, a script bundle) is not part of the manifest. 1.1.0 (openvibe-contracts v0.34.0) adds the optional permissions.readGrants and writeGrants, billingHooks and dependencies (ADR-013 amendment of 2026-09-24); every 1.0.0 manifest stays valid.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
id | string | yes | Stable mod id; its principal subject is mod:<id>. |
|
name | string | yes |
| |
version | string | yes | Semantic version of this release. |
|
description | string |
| ||
publisher | identity.subject-ref | yes | Who publishes the mod (a user or an app subject). | |
target | string | yes | Where the mod runs: <service>.<surface>, e.g. games.browser, games.source, live.overlay. |
|
runtime | string | yes | Runtime adapter and its major version, e.g. games-content@1 (declarative data pack) or source-quickjs@1. |
|
permissions | object | yes |
| |
permissions.capabilities | array of string | yes | Capability ids the mod asks for (3+ segments). The target runtime binds only those it implements, and only once granted. |
|
permissions.events | array of string | Event types the mod wants delivered to it. |
| |
permissions.modules | array of string | User-module namespaces the mod wants to read or write (a trailing .* names a family). A namespace listed here may be read and written; readGrants and writeGrants (1.1.0) say which. |
| |
permissions.mediaNamespaces | array of string | Media namespaces the mod wants to read or write. A namespace listed here may be read and written; readGrants and writeGrants (1.1.0) say which. |
| |
permissions.readGrants | object | 1.1.0: namespaces the mod may only read. A namespace that is only here is read-only. The install's approved subset is still the grant. |
| |
permissions.readGrants.modules | array of string | User-module namespaces (a trailing .* names a family). |
| |
permissions.readGrants.mediaNamespaces | array of string | Media namespaces. |
| |
permissions.writeGrants | object | 1.1.0: namespaces the mod may read and write. A write needs the namespace here, or in the older modules and mediaNamespaces lists, which mean read and write. |
| |
permissions.writeGrants.modules | array of string | User-module namespaces (a trailing .* names a family). |
| |
permissions.writeGrants.mediaNamespaces | array of string | Media namespaces. |
| |
resources | object | yes | The budget the mod asks for. Runtimes meter it; the sandbox that enforces it lives in OpenVibe.Host (Stage C). |
|
resources.cpuMs | number | yes | CPU milliseconds per tick (game runtimes) or per request. |
|
resources.memoryMb | integer | yes |
| |
resources.storageMb | integer | yes |
| |
resources.outboundHosts | array of string | Hosts the mod may reach over the network. Empty or absent = none. |
| |
assets | media.media-ref | Assets the mod ships, as Media object references. |
| |
compatibility | object | yes |
| |
compatibility.runtime | string | yes | Semver range of the runtime this release works with, e.g. ">=1.0.0 <2.0.0". |
|
compatibility.contracts | string | Semver range of openvibe-contracts releases it was built against. |
| |
homepage | string |
| ||
billingHooks | array of object | 1.1.0: how the mod takes part in money, only through Billing and VIP primitives (ADR-013 amendment, ADR-012). entitlement: the mod checks that the person holds this entitlement (billing.entitlement.check or vip.entitlement.check, granted like any other capability). checkout: the mod sends the person to the platform's own checkout for this plan (vip.membership.checkout or a Billing intent). A mod never takes payment, sees payment details or holds a balance. Prices live in Billing and VIP, never in the manifest. |
| |
billingHooks[].kind | enum | yes |
| |
billingHooks[].key | string | yes | The entitlement or plan key as Billing and VIP name it, e.g. vip.plan:pln_01jab… (lowercase, the form search.index-document@1 acl.entitlements uses). |
|
billingHooks[].description | string | What it unlocks or sells, shown at install. |
| |
dependencies | array of object | 1.1.0: other mods this release needs. A runtime refuses to enable the mod while a required dependency is not installed, not enabled or outside its range. An optional one is used only when present. |
| |
dependencies[].id | string | yes |
| |
dependencies[].version | string | yes | Semver range of the dependency's releases this release works with, e.g. ">=1.2.0 <2.0.0". |
|
dependencies[].optional | boolean |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: market-stall-1.1
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "Market Stall",
"version": "1.2.0",
"description": "A members-only stall that reads the player's profile summary and keeps its own notes.",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"permissions": {
"capabilities": [
"games.prop.place",
"vip.perk.list"
],
"readGrants": {
"modules": [
"games.progress.summary"
],
"mediaNamespaces": [
"games.maps"
]
},
"writeGrants": {
"modules": [
"games.market_stall.*"
]
}
},
"resources": {
"cpuMs": 2,
"memoryMb": 16,
"storageMb": 5
},
"compatibility": {
"runtime": ">=1.0.0 <2.0.0",
"contracts": ">=0.34.0 <1.0.0"
},
"billingHooks": [
{
"kind": "entitlement",
"key": "vip.plan:pln_01jabcdefghjkmnpqrstvwxyz2",
"description": "Opens the stall for the creator's VIP members."
},
{
"kind": "checkout",
"key": "vip.plan:pln_01jabcdefghjkmnpqrstvwxyz2"
}
],
"dependencies": [
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ0",
"version": ">=1.0.0 <2.0.0"
},
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ3",
"version": "^0.3.0",
"optional": true
}
]
}Valid: town-square
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ0",
"name": "Town Square",
"version": "1.0.0",
"description": "A public workbench and a greeting.",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"permissions": {
"capabilities": [
"games.world.announce",
"games.prop.place"
]
},
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0 <2.0.0"
}
}Rejected: capabilities-in-write-grants
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": [],
"writeGrants": {
"capabilities": [
"games.prop.place"
]
}
}
}Rejected: dependency-not-a-mod-id
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": []
},
"dependencies": [
{
"id": "town-square",
"version": ">=1.0.0"
}
]
}Rejected: dependency-without-range
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": []
},
"dependencies": [
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ0"
}
]
}Rejected: empty-read-grants
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": [],
"readGrants": {}
}
}Rejected: hook-kind-price
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": []
},
"billingHooks": [
{
"kind": "price",
"key": "vip.plan:pln_01jabcdefghjkmnpqrstvwxyz2"
}
]
}Rejected: hook-with-price
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ1",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
},
"permissions": {
"capabilities": []
},
"billingHooks": [
{
"kind": "checkout",
"key": "vip.plan:pln_01jabcdefghjkmnpqrstvwxyz2",
"amount_cents": 499
}
]
}Rejected: no-permissions
{
"id": "mod_01JABCDEFGHJKMNPQRSTVWXYZ0",
"name": "X",
"version": "1.0.0",
"publisher": {
"type": "user",
"id": "usr_01JABCDEFGHJKMNPQRSTVWXYZ0"
},
"target": "games.browser",
"runtime": "games-content@1",
"resources": {
"cpuMs": 1,
"memoryMb": 0,
"storageMb": 0
},
"compatibility": {
"runtime": ">=1.0.0"
}
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('mods.mod-manifest@1', value); // { valid, errors: [{ path, message }] }