openvibers/openvibe.contracts Commits
v0.72.0: mod principals in Network (roadmap WS-M task 3, ADR-013). mods.grant.manage is active: the owning runtime registers an install's principal mod:<mod_id> (POST /internal/mods, network.mod-install-request@1: the manifest and the subset approved at install, the rest pending), approves or revokes one capability (POST /internal/mods/{id}/grants, network.mod-grant-change@1), revokes the install (POST /internal/mods/{id}/revoke) and reads them (GET /internal/mods[/{id}]). Only the owner or Network staff (staff.games.manage) change a mod. Adds network.mod-principal@1 and the event network.mod.grants_changed@1 (the complete approved set by revision, the change, runtime or staff), which Games consumes.
Changes
@@@ -6,6 +6,13 @@ the notes were in the tag and commit messages (`git tag -n1`).## Unreleased++## 0.72.0 — 2026-09-27++++**Mod principals in Network** (roadmap WS-M task 3, ADR-013).++- `mods.grant.manage` is active. A runtime (OpenVibe.Games) registers an install's principal `mod:<mod_id>` (`POST /internal/mods`, `network.mod-install-request@1`: the manifest, and the subset staff approved at install; the rest stays pending). It then approves or revokes one capability (`POST /internal/mods/{mod_id}/grants`, `network.mod-grant-change@1`) or revokes the install (`POST /internal/mods/{mod_id}/revoke`). It reads them with `GET /internal/mods[/{mod_id}]`. Only the owning runtime or Network staff (`staff.games.manage`) change a mod.++- `network.mod-principal@1`: the principal with requested, approved, pending and revoked capabilities, and a revision.++- `network.mod.grants_changed@1` (internal): after every change, the complete approved set (by revision), the change, and whether the runtime or staff made it. The owning runtime sets its copy to it. Games lists it as consumed.++## 0.71.0 — 2026-09-27**Account export and deletion** (roadmap WS-B task 7, ADR-033).@@@ -2476,6 +2476,46 @@"status": "active","adr": "ADR-033"},++ {++ "id": "network.mod.grants_changed",++ "version": "1.0.0",++ "owner": "network",++ "schema": "events/payloads/network.mod.grants_changed.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-013"++ },++ {++ "id": "network.mod-install-request",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/mod-install-request.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-013"++ },++ {++ "id": "network.mod-grant-change",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/mod-grant-change.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-013"++ },++ {++ "id": "network.mod-principal",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/mod-principal.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-013"++ },{"id": "network.subject.merged","version": "1.0.0",nnew file mode 100644@@@ -0,0 +1,86 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/network.mod.grants_changed.v1.json",++ "title": "NetworkModGrantsChangedPayload",++ "description": "network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.",++ "type": "object",++ "required": [++ "mod_id",++ "owner",++ "status",++ "approved",++ "revision",++ "change",++ "by"++ ],++ "additionalProperties": false,++ "properties": {++ "mod_id": {++ "type": "string",++ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,31}$"++ },++ "status": {++ "enum": [++ "active",++ "revoked"++ ]++ },++ "approved": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "pending": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revision": {++ "type": "integer",++ "minimum": 1++ },++ "change": {++ "type": "object",++ "additionalProperties": false,++ "required": [++ "action"++ ],++ "properties": {++ "action": {++ "enum": [++ "register",++ "approve",++ "revoke",++ "revoke_all"++ ]++ },++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ }++ },++ "by": {++ "enum": [++ "runtime",++ "staff"++ ]++ },++ "reason": {++ "type": "string",++ "maxLength": 500++ }++ }++}nnew file mode 100644@@@ -0,0 +1,32 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-grant-change.v1.json",++ "title": "NetworkModGrantChange",++ "description": "network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).",++ "type": "object",++ "required": [++ "capability",++ "action"++ ],++ "additionalProperties": false,++ "properties": {++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "action": {++ "enum": [++ "approve",++ "revoke"++ ]++ },++ "actor": {++ "type": "string",++ "maxLength": 80++ },++ "reason": {++ "type": "string",++ "maxLength": 500++ }++ }++}nnew file mode 100644@@@ -0,0 +1,32 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-install-request.v1.json",++ "title": "NetworkModInstallRequest",++ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",++ "type": "object",++ "required": [++ "manifest"++ ],++ "additionalProperties": false,++ "properties": {++ "manifest": {++ "type": "object",++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ "approve": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ "actor": {++ "type": "string",++ "maxLength": 80,++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ }++ }++}nnew file mode 100644@@@ -0,0 +1,99 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-principal.v1.json",++ "title": "NetworkModPrincipal",++ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",++ "type": "object",++ "required": [++ "principal",++ "mod_id",++ "owner",++ "runtime",++ "status",++ "requested",++ "approved",++ "pending",++ "revoked",++ "revision",++ "updated_at"++ ],++ "additionalProperties": false,++ "properties": {++ "principal": {++ "type": "string",++ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "mod_id": {++ "type": "string",++ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,31}$",++ "description": "The runtime service that registered it (games)."++ },++ "runtime": {++ "type": "string",++ "maxLength": 60,++ "description": "The manifest's runtime, e.g. games-content@1."++ },++ "name": {++ "type": "string",++ "maxLength": 120++ },++ "version": {++ "type": "string",++ "maxLength": 40++ },++ "status": {++ "enum": [++ "active",++ "revoked"++ ]++ },++ "requested": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "approved": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "pending": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revoked": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revision": {++ "type": "integer",++ "minimum": 1++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1 @@++{"capability":"*","action":"approve"}nnew file mode 100644@@@ -0,0 +1 @@++{"capability":"games.world.announce","action":"approve"}nnew file mode 100644@@@ -0,0 +1 @@++{"approve":[]}nnew file mode 100644@@@ -0,0 +1 @@++{"manifest":{"id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ"},"approve":["games.world.announce"],"actor":"usr_01JAB2C3D4E5F6G7H8J9K0MNPR"}nnew file mode 100644@@@ -0,0 +1 @@++{"principal":"app:mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","runtime":"games-content@1","status":"active","requested":[],"approved":[],"pending":[],"revoked":[],"revision":1,"updated_at":"2026-09-27T23:40:00.000Z"}nnew file mode 100644@@@ -0,0 +1 @@++{"principal":"mod:mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","runtime":"games-content@1","name":"Lanterns","version":"1.0.0","status":"active","requested":["games.world.announce","games.prop.place"],"approved":["games.world.announce"],"pending":["games.prop.place"],"revoked":[],"revision":1,"updated_at":"2026-09-27T23:40:00.000Z"}nnew file mode 100644@@@ -0,0 +1 @@++{"mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","status":"active","approved":[],"revision":3,"change":{"action":"delete"},"by":"staff"}nnew file mode 100644@@@ -0,0 +1 @@++{"mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","status":"active","approved":[],"pending":["games.prop.place"],"revision":3,"change":{"action":"revoke","capability":"games.world.announce"},"by":"staff","reason":"spawned items in a safe zone"}@@@ -25752,6 +25752,275 @@}}},++ "network.mod.grants_changed": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/network.mod.grants_changed.v1.json",++ "title": "NetworkModGrantsChangedPayload",++ "description": "network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.",++ "type": "object",++ "required": [++ "mod_id",++ "owner",++ "status",++ "approved",++ "revision",++ "change",++ "by"++ ],++ "additionalProperties": false,++ "properties": {++ "mod_id": {++ "type": "string",++ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,31}$"++ },++ "status": {++ "enum": [++ "active",++ "revoked"++ ]++ },++ "approved": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "pending": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revision": {++ "type": "integer",++ "minimum": 1++ },++ "change": {++ "type": "object",++ "additionalProperties": false,++ "required": [++ "action"++ ],++ "properties": {++ "action": {++ "enum": [++ "register",++ "approve",++ "revoke",++ "revoke_all"++ ]++ },++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ }++ },++ "by": {++ "enum": [++ "runtime",++ "staff"++ ]++ },++ "reason": {++ "type": "string",++ "maxLength": 500++ }++ }++ }++ },++ "network.mod-install-request": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-install-request.v1.json",++ "title": "NetworkModInstallRequest",++ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",++ "type": "object",++ "required": [++ "manifest"++ ],++ "additionalProperties": false,++ "properties": {++ "manifest": {++ "type": "object",++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ "approve": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ "actor": {++ "type": "string",++ "maxLength": 80,++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ }++ }++ }++ },++ "network.mod-grant-change": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-grant-change.v1.json",++ "title": "NetworkModGrantChange",++ "description": "network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).",++ "type": "object",++ "required": [++ "capability",++ "action"++ ],++ "additionalProperties": false,++ "properties": {++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "action": {++ "enum": [++ "approve",++ "revoke"++ ]++ },++ "actor": {++ "type": "string",++ "maxLength": 80++ },++ "reason": {++ "type": "string",++ "maxLength": 500++ }++ }++ }++ },++ "network.mod-principal": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/mod-principal.v1.json",++ "title": "NetworkModPrincipal",++ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",++ "type": "object",++ "required": [++ "principal",++ "mod_id",++ "owner",++ "runtime",++ "status",++ "requested",++ "approved",++ "pending",++ "revoked",++ "revision",++ "updated_at"++ ],++ "additionalProperties": false,++ "properties": {++ "principal": {++ "type": "string",++ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "mod_id": {++ "type": "string",++ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,31}$",++ "description": "The runtime service that registered it (games)."++ },++ "runtime": {++ "type": "string",++ "maxLength": 60,++ "description": "The manifest's runtime, e.g. games-content@1."++ },++ "name": {++ "type": "string",++ "maxLength": 120++ },++ "version": {++ "type": "string",++ "maxLength": 40++ },++ "status": {++ "enum": [++ "active",++ "revoked"++ ]++ },++ "requested": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "approved": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "pending": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revoked": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revision": {++ "type": "integer",++ "minimum": 1++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },"network.subject.merged": {"version": "1.0.0","owner": "network",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Chat API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Codes API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Coupons API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Deals API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Events API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -96,8 +96,8 @@"service": "network","name": "OpenVibe.Network","origin": "https://openvibe.network",-- "operations": 20,-- "capabilities": 17++ "operations": 25,++ "capabilities": 18},{"service": "news",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Live API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Media API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Network API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -965,6 +965,376 @@}}},++ "/internal/mods": {++ "get": {++ "operationId": "get_internal_mods",++ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",++ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "tags": [++ "mods.grant"++ ],++ "x-openvibe-capabilities": [++ "mods.grant.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "network-admin",++ "security": [++ {++ "openvibeToken": [++ "mods.grant.manage"++ ]++ }++ ],++ "x-openvibe-input": {++ "$ref": "#/components/schemas/network.mod-install-request.v1"++ },++ "parameters": [++ {++ "name": "manifest",++ "in": "query",++ "required": true,++ "schema": {++ "type": "object",++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ {++ "name": "approve",++ "in": "query",++ "required": false,++ "schema": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ {++ "name": "actor",++ "in": "query",++ "required": false,++ "schema": {++ "type": "string",++ "maxLength": 80,++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ },++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-principal.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ },++ "post": {++ "operationId": "post_internal_mods",++ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",++ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "tags": [++ "mods.grant"++ ],++ "x-openvibe-capabilities": [++ "mods.grant.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "network-admin",++ "security": [++ {++ "openvibeToken": [++ "mods.grant.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-install-request.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-principal.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/internal/mods/{mod_id}": {++ "get": {++ "operationId": "get_internal_mods_mod_id",++ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",++ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "tags": [++ "mods.grant"++ ],++ "x-openvibe-capabilities": [++ "mods.grant.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "network-admin",++ "security": [++ {++ "openvibeToken": [++ "mods.grant.manage"++ ]++ }++ ],++ "x-openvibe-input": {++ "$ref": "#/components/schemas/network.mod-install-request.v1"++ },++ "parameters": [++ {++ "name": "mod_id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ },++ {++ "name": "manifest",++ "in": "query",++ "required": true,++ "schema": {++ "type": "object",++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ {++ "name": "approve",++ "in": "query",++ "required": false,++ "schema": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ {++ "name": "actor",++ "in": "query",++ "required": false,++ "schema": {++ "type": "string",++ "maxLength": 80,++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ },++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-principal.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/internal/mods/{mod_id}/grants": {++ "post": {++ "operationId": "post_internal_mods_mod_id_grants",++ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",++ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "tags": [++ "mods.grant"++ ],++ "x-openvibe-capabilities": [++ "mods.grant.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "network-admin",++ "security": [++ {++ "openvibeToken": [++ "mods.grant.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-install-request.v1"++ }++ }++ }++ },++ "parameters": [++ {++ "name": "mod_id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-principal.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/internal/mods/{mod_id}/revoke": {++ "post": {++ "operationId": "post_internal_mods_mod_id_revoke",++ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",++ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "tags": [++ "mods.grant"++ ],++ "x-openvibe-capabilities": [++ "mods.grant.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "network-admin",++ "security": [++ {++ "openvibeToken": [++ "mods.grant.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-install-request.v1"++ }++ }++ }++ },++ "parameters": [++ {++ "name": "mod_id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.mod-principal.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },"/internal/modules/{namespace}/{subject}": {"get": {"operationId": "get_internal_modules_namespace_subject",@@@ -2164,6 +2534,133 @@}}},++ "network.mod-install-request.v1": {++ "title": "NetworkModInstallRequest",++ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",++ "type": "object",++ "required": [++ "manifest"++ ],++ "additionalProperties": false,++ "properties": {++ "manifest": {++ "type": "object",++ "description": "The mod's manifest, mods.mod-manifest@1."++ },++ "approve": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ },++ "description": "Approved at install; each must be requested by the manifest."++ },++ "actor": {++ "type": "string",++ "maxLength": 80,++ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."++ }++ }++ },++ "network.mod-principal.v1": {++ "title": "NetworkModPrincipal",++ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",++ "type": "object",++ "required": [++ "principal",++ "mod_id",++ "owner",++ "runtime",++ "status",++ "requested",++ "approved",++ "pending",++ "revoked",++ "revision",++ "updated_at"++ ],++ "additionalProperties": false,++ "properties": {++ "principal": {++ "type": "string",++ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "mod_id": {++ "type": "string",++ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,31}$",++ "description": "The runtime service that registered it (games)."++ },++ "runtime": {++ "type": "string",++ "maxLength": 60,++ "description": "The manifest's runtime, e.g. games-content@1."++ },++ "name": {++ "type": "string",++ "maxLength": 120++ },++ "version": {++ "type": "string",++ "maxLength": 40++ },++ "status": {++ "enum": [++ "active",++ "revoked"++ ]++ },++ "requested": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "approved": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "pending": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revoked": {++ "type": "array",++ "maxItems": 64,++ "uniqueItems": true,++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"++ }++ },++ "revision": {++ "type": "integer",++ "minimum": 1++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ },"network.module-write-request.v1": {"title": "NetworkModuleWriteRequest","description": "network.module-write-request@1: the request of network.modules.write on OpenVibe.Network. PUT /internal/modules/:namespace/:subject: { data } — the record's new value, validated against the namespace's schema; If-Match names the revision read (412 if it moved). DELETE /internal/modules/:namespace/:subject (204) takes no body. The answer to PUT is modules.module-record@1.",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.News API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenRe.Stream API",-- "version": "0.71.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Search API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Sources API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tips API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Trade API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.VIP API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.71.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.72.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -28804,6 +28804,101 @@ export interface NetworkAccountDataReceipt {replaced: boolean;}++/** [email protected] (owner: network) */++/**++ * network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.++ */++export interface NetworkModGrantsChangedPayload {++ mod_id: string;++ owner: string;++ status: "active" | "revoked";++ /**++ * @maxItems 64++ */++ approved: string[];++ /**++ * @maxItems 64++ */++ pending?: string[];++ revision: number;++ change: {++ action: "register" | "approve" | "revoke" | "revoke_all";++ capability?: string;++ };++ by: "runtime" | "staff";++ reason?: string;++}++++/** [email protected] (owner: network) */++/**++ * network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.++ */++export interface NetworkModInstallRequest {++ /**++ * The mod's manifest, mods.mod-manifest@1.++ */++ manifest: {};++ /**++ * Approved at install; each must be requested by the manifest.++ *++ * @maxItems 64++ */++ approve?: string[];++ /**++ * Who installed it at the runtime (a subject or 'games'), for the audit row.++ */++ actor?: string;++}++++/** [email protected] (owner: network) */++/**++ * network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).++ */++export interface NetworkModGrantChange {++ capability: string;++ action: "approve" | "revoke";++ actor?: string;++ reason?: string;++}++++/** [email protected] (owner: network) */++/**++ * network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.++ */++export interface NetworkModPrincipal {++ principal: string;++ mod_id: string;++ /**++ * The runtime service that registered it (games).++ */++ owner: string;++ /**++ * The manifest's runtime, e.g. games-content@1.++ */++ runtime: string;++ name?: string;++ version?: string;++ status: "active" | "revoked";++ /**++ * @maxItems 64++ */++ requested: string[];++ /**++ * @maxItems 64++ */++ approved: string[];++ /**++ * @maxItems 64++ */++ pending: string[];++ /**++ * @maxItems 64++ */++ revoked: string[];++ revision: number;++ updated_at: string;++}++/** [email protected] (owner: network) *//*** network.subject.merged v1 (OpenVibe.Network; roadmap WS-B task 5, ADR-029). Two accounts became one: `from`, the folded-in subject, is now an alias of `into`, the survivor, which keeps its subject, username, profile and settings. Network has already moved what it owns (linked providers, sessions, OAuth grants, developer projects, OpenCoins and user modules) in the transaction that writes this event to its outbox. Every service that stores subjects repoints its own rows from `from` to `into` in its own transaction and keeps no copy under `from`; a row it cannot move (a unique conflict, such as both accounts following the same channel) keeps the survivor's row and drops the other, as a counted, logged outcome. Until a service has applied it, its rows stay under `from`, which still resolves to `into` through Network's aliases. Apply once per merge_id. Envelope: subject { type: user, id: <into> }, visibility internal, actor the person who merged (or the staff member, for an account-recovery merge).@@@ -2,13 +2,26 @@"id": "mods.grant.manage","version": "1.0","owner": "network",-- "status": "planned",++ "status": "active","visibility": "first-party",-- "description": "Planned (ADR-013, grants in Network): create the `mod` principal (mod:mod_<ULID>) for an install and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants are checked like any other principal's. Until Network implements it, each runtime keeps the approved subset itself (OpenVibe.Games: mod_grants).",-- "inputSchema": "mods.mod-manifest@1",-- "permissions": ["network:grants:admin"],-- "resourceConstraints": ["none"],++ "description": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",++ "inputSchema": "network.mod-install-request@1",++ "permissions": [++ "network:grants:admin"++ ],++ "resourceConstraints": [++ "owner"++ ],"quotaClass": "network-admin",-- "events": [],-- "implementedBy": []++ "events": [++ "network.mod.grants_changed"++ ],++ "implementedBy": [++ "POST /internal/mods",++ "GET /internal/mods",++ "GET /internal/mods/:mod_id",++ "POST /internal/mods/:mod_id/grants",++ "POST /internal/mods/:mod_id/revoke"++ ],++ "outputSchema": "network.mod-principal@1"}@@@ -49,6 +49,7 @@"eventsConsumed": ["network.account.deleted","network.account.export_requested",++ "network.mod.grants_changed","network.user.token_valid_after"],"namespacesOwned": [@@@ -54,6 +54,8 @@"network.status.incident"],"eventsProduced": [++ "network.account.deleted",++ "network.account.export_requested","network.app.created","network.app.revoked","network.block.changed",@@@ -61,13 +63,12 @@"network.credential.rotated","network.follow.created","network.follow.deleted",-- "network.subject.merged",-- "network.account.export_requested",-- "network.account.deleted","network.grant.changed",++ "network.mod.grants_changed","network.module.updated","network.notification.created","network.principal_grant.changed",++ "network.subject.merged","network.user.token_valid_after","network.user.updated"],@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.71.0",++ "version": "0.72.0","description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.","main": "index.js","types": "generated/typescript/index.d.ts",
@@ -6,6 +6,13 @@ the notes were in the tag and commit messages (`git tag -n1`).
@@ -6,6 +6,13 @@ the notes were in the tag and commit messages (`git tag -n1`).
## Unreleased
## Unreleased
+## 0.72.0 — 2026-09-27
+
+**Mod principals in Network** (roadmap WS-M task 3, ADR-013).
+- `mods.grant.manage` is active. A runtime (OpenVibe.Games) registers an install's principal `mod:<mod_id>` (`POST /internal/mods`, `network.mod-install-request@1`: the manifest, and the subset staff approved at install; the rest stays pending). It then approves or revokes one capability (`POST /internal/mods/{mod_id}/grants`, `network.mod-grant-change@1`) or revokes the install (`POST /internal/mods/{mod_id}/revoke`). It reads them with `GET /internal/mods[/{mod_id}]`. Only the owning runtime or Network staff (`staff.games.manage`) change a mod.
+- `network.mod-principal@1`: the principal with requested, approved, pending and revoked capabilities, and a revision.
+- `network.mod.grants_changed@1` (internal): after every change, the complete approved set (by revision), the change, and whether the runtime or staff made it. The owning runtime sets its copy to it. Games lists it as consumed.
+
## 0.71.0 — 2026-09-27
## 0.71.0 — 2026-09-27
**Account export and deletion** (roadmap WS-B task 7, ADR-033).
**Account export and deletion** (roadmap WS-B task 7, ADR-033).
@@ -2476,6 +2476,46 @@
@@ -2476,6 +2476,46 @@
"status": "active",
"status": "active",
"adr": "ADR-033"
"adr": "ADR-033"
},
},
+ {
+ "id": "network.mod.grants_changed",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "events/payloads/network.mod.grants_changed.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-013"
+ },
+ {
+ "id": "network.mod-install-request",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/mod-install-request.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-013"
+ },
+ {
+ "id": "network.mod-grant-change",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/mod-grant-change.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-013"
+ },
+ {
+ "id": "network.mod-principal",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/mod-principal.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-013"
+ },
{
{
"id": "network.subject.merged",
"id": "network.subject.merged",
"version": "1.0.0",
"version": "1.0.0",
new file mode 100644
new file mode 100644
@@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/network.mod.grants_changed.v1.json",
+ "title": "NetworkModGrantsChangedPayload",
+ "description": "network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.",
+ "type": "object",
+ "required": [
+ "mod_id",
+ "owner",
+ "status",
+ "approved",
+ "revision",
+ "change",
+ "by"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "mod_id": {
+ "type": "string",
+ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,31}$"
+ },
+ "status": {
+ "enum": [
+ "active",
+ "revoked"
+ ]
+ },
+ "approved": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "pending": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revision": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "change": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "action"
+ ],
+ "properties": {
+ "action": {
+ "enum": [
+ "register",
+ "approve",
+ "revoke",
+ "revoke_all"
+ ]
+ },
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ }
+ },
+ "by": {
+ "enum": [
+ "runtime",
+ "staff"
+ ]
+ },
+ "reason": {
+ "type": "string",
+ "maxLength": 500
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-grant-change.v1.json",
+ "title": "NetworkModGrantChange",
+ "description": "network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).",
+ "type": "object",
+ "required": [
+ "capability",
+ "action"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "action": {
+ "enum": [
+ "approve",
+ "revoke"
+ ]
+ },
+ "actor": {
+ "type": "string",
+ "maxLength": 80
+ },
+ "reason": {
+ "type": "string",
+ "maxLength": 500
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-install-request.v1.json",
+ "title": "NetworkModInstallRequest",
+ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",
+ "type": "object",
+ "required": [
+ "manifest"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "manifest": {
+ "type": "object",
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ "approve": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ "actor": {
+ "type": "string",
+ "maxLength": 80,
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-principal.v1.json",
+ "title": "NetworkModPrincipal",
+ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",
+ "type": "object",
+ "required": [
+ "principal",
+ "mod_id",
+ "owner",
+ "runtime",
+ "status",
+ "requested",
+ "approved",
+ "pending",
+ "revoked",
+ "revision",
+ "updated_at"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "principal": {
+ "type": "string",
+ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "mod_id": {
+ "type": "string",
+ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,31}$",
+ "description": "The runtime service that registered it (games)."
+ },
+ "runtime": {
+ "type": "string",
+ "maxLength": 60,
+ "description": "The manifest's runtime, e.g. games-content@1."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 120
+ },
+ "version": {
+ "type": "string",
+ "maxLength": 40
+ },
+ "status": {
+ "enum": [
+ "active",
+ "revoked"
+ ]
+ },
+ "requested": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "approved": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "pending": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revoked": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revision": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"capability":"*","action":"approve"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"capability":"games.world.announce","action":"approve"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"approve":[]}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"manifest":{"id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ"},"approve":["games.world.announce"],"actor":"usr_01JAB2C3D4E5F6G7H8J9K0MNPR"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"principal":"app:mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","runtime":"games-content@1","status":"active","requested":[],"approved":[],"pending":[],"revoked":[],"revision":1,"updated_at":"2026-09-27T23:40:00.000Z"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"principal":"mod:mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","runtime":"games-content@1","name":"Lanterns","version":"1.0.0","status":"active","requested":["games.world.announce","games.prop.place"],"approved":["games.world.announce"],"pending":["games.prop.place"],"revoked":[],"revision":1,"updated_at":"2026-09-27T23:40:00.000Z"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","status":"active","approved":[],"revision":3,"change":{"action":"delete"},"by":"staff"}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{"mod_id":"mod_01JAB2C3D4E5F6G7H8J9K0MNPQ","owner":"games","status":"active","approved":[],"pending":["games.prop.place"],"revision":3,"change":{"action":"revoke","capability":"games.world.announce"},"by":"staff","reason":"spawned items in a safe zone"}
@@ -25752,6 +25752,275 @@
@@ -25752,6 +25752,275 @@
}
}
}
}
},
},
+ "network.mod.grants_changed": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/network.mod.grants_changed.v1.json",
+ "title": "NetworkModGrantsChangedPayload",
+ "description": "network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.",
+ "type": "object",
+ "required": [
+ "mod_id",
+ "owner",
+ "status",
+ "approved",
+ "revision",
+ "change",
+ "by"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "mod_id": {
+ "type": "string",
+ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,31}$"
+ },
+ "status": {
+ "enum": [
+ "active",
+ "revoked"
+ ]
+ },
+ "approved": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "pending": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revision": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "change": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "action"
+ ],
+ "properties": {
+ "action": {
+ "enum": [
+ "register",
+ "approve",
+ "revoke",
+ "revoke_all"
+ ]
+ },
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ }
+ },
+ "by": {
+ "enum": [
+ "runtime",
+ "staff"
+ ]
+ },
+ "reason": {
+ "type": "string",
+ "maxLength": 500
+ }
+ }
+ }
+ },
+ "network.mod-install-request": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-install-request.v1.json",
+ "title": "NetworkModInstallRequest",
+ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",
+ "type": "object",
+ "required": [
+ "manifest"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "manifest": {
+ "type": "object",
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ "approve": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ "actor": {
+ "type": "string",
+ "maxLength": 80,
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ }
+ }
+ }
+ },
+ "network.mod-grant-change": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-grant-change.v1.json",
+ "title": "NetworkModGrantChange",
+ "description": "network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).",
+ "type": "object",
+ "required": [
+ "capability",
+ "action"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "action": {
+ "enum": [
+ "approve",
+ "revoke"
+ ]
+ },
+ "actor": {
+ "type": "string",
+ "maxLength": 80
+ },
+ "reason": {
+ "type": "string",
+ "maxLength": 500
+ }
+ }
+ }
+ },
+ "network.mod-principal": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/mod-principal.v1.json",
+ "title": "NetworkModPrincipal",
+ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",
+ "type": "object",
+ "required": [
+ "principal",
+ "mod_id",
+ "owner",
+ "runtime",
+ "status",
+ "requested",
+ "approved",
+ "pending",
+ "revoked",
+ "revision",
+ "updated_at"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "principal": {
+ "type": "string",
+ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "mod_id": {
+ "type": "string",
+ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,31}$",
+ "description": "The runtime service that registered it (games)."
+ },
+ "runtime": {
+ "type": "string",
+ "maxLength": 60,
+ "description": "The manifest's runtime, e.g. games-content@1."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 120
+ },
+ "version": {
+ "type": "string",
+ "maxLength": 40
+ },
+ "status": {
+ "enum": [
+ "active",
+ "revoked"
+ ]
+ },
+ "requested": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "approved": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "pending": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revoked": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revision": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
"network.subject.merged": {
"network.subject.merged": {
"version": "1.0.0",
"version": "1.0.0",
"owner": "network",
"owner": "network",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.AI API",
"title": "OpenVibe.AI API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Billing API",
"title": "OpenVibe.Billing API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Blog API",
"title": "OpenVibe.Blog API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Chat API",
"title": "OpenVibe.Chat API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Codes API",
"title": "OpenVibe.Codes API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Community API",
"title": "OpenVibe.Community API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Coupons API",
"title": "OpenVibe.Coupons API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Deals API",
"title": "OpenVibe.Deals API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Events API",
"title": "OpenVibe.Events API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Games API",
"title": "OpenVibe.Games API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Host API",
"title": "OpenVibe.Host API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -96,8 +96,8 @@
@@ -96,8 +96,8 @@
"service": "network",
"service": "network",
"name": "OpenVibe.Network",
"name": "OpenVibe.Network",
"origin": "https://openvibe.network",
"origin": "https://openvibe.network",
- "operations": 20,
- "capabilities": 17
+ "operations": 25,
+ "capabilities": 18
},
},
{
{
"service": "news",
"service": "news",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Live API",
"title": "OpenVibe.Live API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Media API",
"title": "OpenVibe.Media API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Network API",
"title": "OpenVibe.Network API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -965,6 +965,376 @@
@@ -965,6 +965,376 @@
}
}
}
}
},
},
+ "/internal/mods": {
+ "get": {
+ "operationId": "get_internal_mods",
+ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",
+ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "tags": [
+ "mods.grant"
+ ],
+ "x-openvibe-capabilities": [
+ "mods.grant.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "network-admin",
+ "security": [
+ {
+ "openvibeToken": [
+ "mods.grant.manage"
+ ]
+ }
+ ],
+ "x-openvibe-input": {
+ "$ref": "#/components/schemas/network.mod-install-request.v1"
+ },
+ "parameters": [
+ {
+ "name": "manifest",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "object",
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ {
+ "name": "approve",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ {
+ "name": "actor",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "maxLength": 80,
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ },
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-principal.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "operationId": "post_internal_mods",
+ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",
+ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "tags": [
+ "mods.grant"
+ ],
+ "x-openvibe-capabilities": [
+ "mods.grant.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "network-admin",
+ "security": [
+ {
+ "openvibeToken": [
+ "mods.grant.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-install-request.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-principal.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/internal/mods/{mod_id}": {
+ "get": {
+ "operationId": "get_internal_mods_mod_id",
+ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",
+ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "tags": [
+ "mods.grant"
+ ],
+ "x-openvibe-capabilities": [
+ "mods.grant.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "network-admin",
+ "security": [
+ {
+ "openvibeToken": [
+ "mods.grant.manage"
+ ]
+ }
+ ],
+ "x-openvibe-input": {
+ "$ref": "#/components/schemas/network.mod-install-request.v1"
+ },
+ "parameters": [
+ {
+ "name": "mod_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "manifest",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "object",
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ {
+ "name": "approve",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ {
+ "name": "actor",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "maxLength": 80,
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ },
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-principal.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/internal/mods/{mod_id}/grants": {
+ "post": {
+ "operationId": "post_internal_mods_mod_id_grants",
+ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",
+ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "tags": [
+ "mods.grant"
+ ],
+ "x-openvibe-capabilities": [
+ "mods.grant.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "network-admin",
+ "security": [
+ {
+ "openvibeToken": [
+ "mods.grant.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-install-request.v1"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "mod_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-principal.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/internal/mods/{mod_id}/revoke": {
+ "post": {
+ "operationId": "post_internal_mods_mod_id_revoke",
+ "summary": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's.",
+ "description": "**mods.grant.manage** (first-party): Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "tags": [
+ "mods.grant"
+ ],
+ "x-openvibe-capabilities": [
+ "mods.grant.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "network-admin",
+ "security": [
+ {
+ "openvibeToken": [
+ "mods.grant.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-install-request.v1"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "mod_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.mod-principal.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/internal/modules/{namespace}/{subject}": {
"/internal/modules/{namespace}/{subject}": {
"get": {
"get": {
"operationId": "get_internal_modules_namespace_subject",
"operationId": "get_internal_modules_namespace_subject",
@@ -2164,6 +2534,133 @@
@@ -2164,6 +2534,133 @@
}
}
}
}
},
},
+ "network.mod-install-request.v1": {
+ "title": "NetworkModInstallRequest",
+ "description": "network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.",
+ "type": "object",
+ "required": [
+ "manifest"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "manifest": {
+ "type": "object",
+ "description": "The mod's manifest, mods.mod-manifest@1."
+ },
+ "approve": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ },
+ "description": "Approved at install; each must be requested by the manifest."
+ },
+ "actor": {
+ "type": "string",
+ "maxLength": 80,
+ "description": "Who installed it at the runtime (a subject or 'games'), for the audit row."
+ }
+ }
+ },
+ "network.mod-principal.v1": {
+ "title": "NetworkModPrincipal",
+ "description": "network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.",
+ "type": "object",
+ "required": [
+ "principal",
+ "mod_id",
+ "owner",
+ "runtime",
+ "status",
+ "requested",
+ "approved",
+ "pending",
+ "revoked",
+ "revision",
+ "updated_at"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "principal": {
+ "type": "string",
+ "pattern": "^mod:mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "mod_id": {
+ "type": "string",
+ "pattern": "^mod_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,31}$",
+ "description": "The runtime service that registered it (games)."
+ },
+ "runtime": {
+ "type": "string",
+ "maxLength": 60,
+ "description": "The manifest's runtime, e.g. games-content@1."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 120
+ },
+ "version": {
+ "type": "string",
+ "maxLength": 40
+ },
+ "status": {
+ "enum": [
+ "active",
+ "revoked"
+ ]
+ },
+ "requested": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "approved": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "pending": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revoked": {
+ "type": "array",
+ "maxItems": 64,
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+){2,}$"
+ }
+ },
+ "revision": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
"network.module-write-request.v1": {
"network.module-write-request.v1": {
"title": "NetworkModuleWriteRequest",
"title": "NetworkModuleWriteRequest",
"description": "network.module-write-request@1: the request of network.modules.write on OpenVibe.Network. PUT /internal/modules/:namespace/:subject: { data } — the record's new value, validated against the namespace's schema; If-Match names the revision read (412 if it moved). DELETE /internal/modules/:namespace/:subject (204) takes no body. The answer to PUT is modules.module-record@1.",
"description": "network.module-write-request@1: the request of network.modules.write on OpenVibe.Network. PUT /internal/modules/:namespace/:subject: { data } — the record's new value, validated against the namespace's schema; If-Match names the revision read (412 if it moved). DELETE /internal/modules/:namespace/:subject (204) takes no body. The answer to PUT is modules.module-record@1.",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.News API",
"title": "OpenVibe.News API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenRe.Stream API",
"title": "OpenRe.Stream API",
- "version": "0.71.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Reviews API",
"title": "OpenVibe.Reviews API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Search API",
"title": "OpenVibe.Search API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Sources API",
"title": "OpenVibe.Sources API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tips API",
"title": "OpenVibe.Tips API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tools API",
"title": "OpenVibe.Tools API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Trade API",
"title": "OpenVibe.Trade API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.VIP API",
"title": "OpenVibe.VIP API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Wiki API",
"title": "OpenVibe.Wiki API",
- "version": "0.71.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.71.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.72.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.72.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -28804,6 +28804,101 @@ export interface NetworkAccountDataReceipt {
@@ -28804,6 +28804,101 @@ export interface NetworkAccountDataReceipt {
replaced: boolean;
replaced: boolean;
}
}
+/** [email protected] (owner: network) */
+/**
+ * network.mod.grants_changed v1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod principal's grants changed: registered, a capability approved or revoked, or the whole install revoked. `approved` is the complete approved set after the change, so the owning runtime sets its copy to it (idempotent by revision: an older revision changes nothing). `by` says whether the owning runtime or Network staff made the change; a runtime applies both.
+ */
+export interface NetworkModGrantsChangedPayload {
+ mod_id: string;
+ owner: string;
+ status: "active" | "revoked";
+ /**
+ * @maxItems 64
+ */
+ approved: string[];
+ /**
+ * @maxItems 64
+ */
+ pending?: string[];
+ revision: number;
+ change: {
+ action: "register" | "approve" | "revoke" | "revoke_all";
+ capability?: string;
+ };
+ by: "runtime" | "staff";
+ reason?: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * network.mod-install-request@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a runtime (OpenVibe.Games) registers an install's mod principal, POST /internal/mods with capability mods.grant.manage. The manifest (mods.mod-manifest@1) names the requested capabilities; `approve` is the subset staff approved at install, and the rest stays pending. The runtime that registers a mod is its owner: only it (or Network staff) changes its grants. Registering the same mod again answers the existing principal.
+ */
+export interface NetworkModInstallRequest {
+ /**
+ * The mod's manifest, mods.mod-manifest@1.
+ */
+ manifest: {};
+ /**
+ * Approved at install; each must be requested by the manifest.
+ *
+ * @maxItems 64
+ */
+ approve?: string[];
+ /**
+ * Who installed it at the runtime (a subject or 'games'), for the audit row.
+ */
+ actor?: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * network.mod-grant-change@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): approve or revoke one requested capability of a mod principal, POST /internal/mods/{mod_id}/grants (the owning runtime, mods.grant.manage) or POST /api/admin/mods/{mod_id}/grants (staff.games.manage, with a reason).
+ */
+export interface NetworkModGrantChange {
+ capability: string;
+ action: "approve" | "revoke";
+ actor?: string;
+ reason?: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * network.mod-principal@1 (OpenVibe.Network; roadmap WS-M task 3, ADR-013): a mod install's principal, `mod:<mod_id>`. Its grants are the approved subset of the capabilities its manifest requests; the rest are pending (never approved) or revoked. A revoked principal (the install ended) has no approved grants and never gets any again. The owning runtime keeps a copy of `approved` for its hot path and follows network.mod.grants_changed.
+ */
+export interface NetworkModPrincipal {
+ principal: string;
+ mod_id: string;
+ /**
+ * The runtime service that registered it (games).
+ */
+ owner: string;
+ /**
+ * The manifest's runtime, e.g. games-content@1.
+ */
+ runtime: string;
+ name?: string;
+ version?: string;
+ status: "active" | "revoked";
+ /**
+ * @maxItems 64
+ */
+ requested: string[];
+ /**
+ * @maxItems 64
+ */
+ approved: string[];
+ /**
+ * @maxItems 64
+ */
+ pending: string[];
+ /**
+ * @maxItems 64
+ */
+ revoked: string[];
+ revision: number;
+ updated_at: string;
+}
+
/** [email protected] (owner: network) */
/** [email protected] (owner: network) */
/**
/**
* network.subject.merged v1 (OpenVibe.Network; roadmap WS-B task 5, ADR-029). Two accounts became one: `from`, the folded-in subject, is now an alias of `into`, the survivor, which keeps its subject, username, profile and settings. Network has already moved what it owns (linked providers, sessions, OAuth grants, developer projects, OpenCoins and user modules) in the transaction that writes this event to its outbox. Every service that stores subjects repoints its own rows from `from` to `into` in its own transaction and keeps no copy under `from`; a row it cannot move (a unique conflict, such as both accounts following the same channel) keeps the survivor's row and drops the other, as a counted, logged outcome. Until a service has applied it, its rows stay under `from`, which still resolves to `into` through Network's aliases. Apply once per merge_id. Envelope: subject { type: user, id: <into> }, visibility internal, actor the person who merged (or the staff member, for an account-recovery merge).
* network.subject.merged v1 (OpenVibe.Network; roadmap WS-B task 5, ADR-029). Two accounts became one: `from`, the folded-in subject, is now an alias of `into`, the survivor, which keeps its subject, username, profile and settings. Network has already moved what it owns (linked providers, sessions, OAuth grants, developer projects, OpenCoins and user modules) in the transaction that writes this event to its outbox. Every service that stores subjects repoints its own rows from `from` to `into` in its own transaction and keeps no copy under `from`; a row it cannot move (a unique conflict, such as both accounts following the same channel) keeps the survivor's row and drops the other, as a counted, logged outcome. Until a service has applied it, its rows stay under `from`, which still resolves to `into` through Network's aliases. Apply once per merge_id. Envelope: subject { type: user, id: <into> }, visibility internal, actor the person who merged (or the staff member, for an account-recovery merge).
@@ -2,13 +2,26 @@
@@ -2,13 +2,26 @@
"id": "mods.grant.manage",
"id": "mods.grant.manage",
"version": "1.0",
"version": "1.0",
"owner": "network",
"owner": "network",
- "status": "planned",
+ "status": "active",
"visibility": "first-party",
"visibility": "first-party",
- "description": "Planned (ADR-013, grants in Network): create the `mod` principal (mod:mod_<ULID>) for an install and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants are checked like any other principal's. Until Network implements it, each runtime keeps the approved subset itself (OpenVibe.Games: mod_grants).",
- "inputSchema": "mods.mod-manifest@1",
- "permissions": ["network:grants:admin"],
- "resourceConstraints": ["none"],
+ "description": "Register a mod install's principal (mod:<mod_id>, ADR-013) and approve or revoke the subset of its manifest's requested capabilities, so a mod's grants live in Network like any other principal's. Only the runtime that registered a mod (its owner) changes it; Network staff (staff.games.manage) can too. Every change is network.mod.grants_changed.",
+ "inputSchema": "network.mod-install-request@1",
+ "permissions": [
+ "network:grants:admin"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
"quotaClass": "network-admin",
"quotaClass": "network-admin",
- "events": [],
- "implementedBy": []
+ "events": [
+ "network.mod.grants_changed"
+ ],
+ "implementedBy": [
+ "POST /internal/mods",
+ "GET /internal/mods",
+ "GET /internal/mods/:mod_id",
+ "POST /internal/mods/:mod_id/grants",
+ "POST /internal/mods/:mod_id/revoke"
+ ],
+ "outputSchema": "network.mod-principal@1"
}
}
@@ -49,6 +49,7 @@
@@ -49,6 +49,7 @@
"eventsConsumed": [
"eventsConsumed": [
"network.account.deleted",
"network.account.deleted",
"network.account.export_requested",
"network.account.export_requested",
+ "network.mod.grants_changed",
"network.user.token_valid_after"
"network.user.token_valid_after"
],
],
"namespacesOwned": [
"namespacesOwned": [
@@ -54,6 +54,8 @@
@@ -54,6 +54,8 @@
"network.status.incident"
"network.status.incident"
],
],
"eventsProduced": [
"eventsProduced": [
+ "network.account.deleted",
+ "network.account.export_requested",
"network.app.created",
"network.app.created",
"network.app.revoked",
"network.app.revoked",
"network.block.changed",
"network.block.changed",
@@ -61,13 +63,12 @@
@@ -61,13 +63,12 @@
"network.credential.rotated",
"network.credential.rotated",
"network.follow.created",
"network.follow.created",
"network.follow.deleted",
"network.follow.deleted",
- "network.subject.merged",
- "network.account.export_requested",
- "network.account.deleted",
"network.grant.changed",
"network.grant.changed",
+ "network.mod.grants_changed",
"network.module.updated",
"network.module.updated",
"network.notification.created",
"network.notification.created",
"network.principal_grant.changed",
"network.principal_grant.changed",
+ "network.subject.merged",
"network.user.token_valid_after",
"network.user.token_valid_after",
"network.user.updated"
"network.user.updated"
],
],
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.71.0",
+ "version": "0.72.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
"types": "generated/typescript/index.d.ts",