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

FieldTypeRequiredDescriptionConstraints
idstringyesStable mod id; its principal subject is mod:<id>.
  • pattern ^mod_[0-9A-HJKMNP-TV-Z]{26}$
namestringyes
  • minLength 1
  • maxLength 80
versionstringyesSemantic version of this release.
  • pattern ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?$
descriptionstring
  • maxLength 1000
publisheridentity.subject-refyesWho publishes the mod (a user or an app subject).
targetstringyesWhere the mod runs: <service>.<surface>, e.g. games.browser, games.source, live.overlay.
  • pattern ^[a-z][a-z0-9-]{1,39}\.[a-z][a-z0-9-]{1,39}$
runtimestringyesRuntime adapter and its major version, e.g. games-content@1 (declarative data pack) or source-quickjs@1.
  • pattern ^[a-z][a-z0-9-]{1,39}@[1-9][0-9]{0,3}$
permissionsobjectyes
  • no other fields
permissions.capabilitiesarray of stringyesCapability ids the mod asks for (3+ segments). The target runtime binds only those it implements, and only once granted.
  • maxItems 64
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+){2,}$
permissions.eventsarray of stringEvent types the mod wants delivered to it.
  • maxItems 64
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+){2,}$
permissions.modulesarray of stringUser-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.
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*(\.\*)?$
permissions.mediaNamespacesarray of stringMedia 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.
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_-]*(\.[a-z0-9_-]+)*$
permissions.readGrantsobject1.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.
  • no other fields
permissions.readGrants.modulesarray of stringUser-module namespaces (a trailing .* names a family).
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*(\.\*)?$
permissions.readGrants.mediaNamespacesarray of stringMedia namespaces.
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_-]*(\.[a-z0-9_-]+)*$
permissions.writeGrantsobject1.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.
  • no other fields
permissions.writeGrants.modulesarray of stringUser-module namespaces (a trailing .* names a family).
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*(\.\*)?$
permissions.writeGrants.mediaNamespacesarray of stringMedia namespaces.
  • maxItems 32
  • unique items
  • items: pattern ^[a-z][a-z0-9_-]*(\.[a-z0-9_-]+)*$
resourcesobjectyesThe budget the mod asks for. Runtimes meter it; the sandbox that enforces it lives in OpenVibe.Host (Stage C).
  • no other fields
resources.cpuMsnumberyesCPU milliseconds per tick (game runtimes) or per request.
  • minimum 0
  • maximum 1000
resources.memoryMbintegeryes
  • minimum 0
  • maximum 4096
resources.storageMbintegeryes
  • minimum 0
  • maximum 102400
resources.outboundHostsarray of stringHosts the mod may reach over the network. Empty or absent = none.
  • maxItems 32
  • unique items
  • items: pattern ^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$
assetsmedia.media-refAssets the mod ships, as Media object references.
  • maxItems 256
compatibilityobjectyes
  • no other fields
compatibility.runtimestringyesSemver range of the runtime this release works with, e.g. ">=1.0.0 <2.0.0".
  • minLength 1
  • maxLength 100
compatibility.contractsstringSemver range of openvibe-contracts releases it was built against.
  • minLength 1
  • maxLength 100
homepagestring
  • pattern ^https://[^\s]{1,2000}$
billingHooksarray of object1.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.
  • maxItems 32
  • items: no other fields
billingHooks[].kindenumyes
  • one of "entitlement", "checkout"
billingHooks[].keystringyesThe 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).
  • pattern ^[a-z][a-z0-9_.:-]{0,127}$
billingHooks[].descriptionstringWhat it unlocks or sells, shown at install.
  • minLength 1
  • maxLength 200
dependenciesarray of object1.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.
  • maxItems 32
  • unique items
  • items: no other fields
dependencies[].idstringyes
  • pattern ^mod_[0-9A-HJKMNP-TV-Z]{26}$
dependencies[].versionstringyesSemver range of the dependency's releases this release works with, e.g. ">=1.2.0 <2.0.0".
  • minLength 1
  • maxLength 100
dependencies[].optionalboolean
  • default false

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 }] }