openvibers/openvibe.contracts Commits

0.268.0: bot.machine.watch_link, so an owner's agent can ask for a link that shows the desk it works on (#277)

OP OpenVibers committed 12 days ago · e6054fcdc4 · 63 files, +507 −91

* 0.268.0: bot.machine.watch_link, so an owner's agent can ask for a link that shows the desk it works on (plan L55)

A watch link is the owner's own link to a desk on their own machine: the page needs no sign-in, may sit in a
frame inside a chat, and lives for minutes rather than days. Bot guards it with a capability of its own, because
bot.computer.control deliberately leaves the live screen out and bot.machine.manage is the network's hub alone.

- the capability bot.machine.watch_link (first-party, sensitive): only the owner's own agent may make one, and
  the machine must be the one the named person owns
- bot.watch-link-request@1 (the desk, the minutes, and whether the mouse and keyboard come along) and
  bot.watch-link-result@1 (the link and when it ends), with valid and invalid fixtures
- bot serves the capability

* bot.watch-link-request@1: the desk is an agent's, never the owner's screen

Review: the request named main (the owner's own screen) as a desk and as the default. An agent's watch link is for
the desk it works on, so desk is required and is private or desk-<name>; fixtures for main and for no desk refused.

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 75fdf7e8..ab02a49d 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -1,5 +1,16 @@
# Changelog
++## 0.268.0 — 2026-11-01
++
++- **`bot.machine.watch_link`** (active, first-party, sensitive; plan L55): the owner's agent (OpenVibe.Actor) asks Bot
++ for a link that shows the desk it works on (the private desk or its own `desk-<name>`, never the owner's own screen),
++ live, inside a chat turn. `POST /api/v1/machines/:id/watch-links`
++ (`bot.watch-link-request@1`, answered by `bot.watch-link-result@1`) makes one for the machine the named person owns —
++ never another person's — and it lives for 5 to 240 minutes. The page needs no sign-in (the token is the credential),
++ may sit in a frame on openvibe.chat or openvibe.actor, and carries the mouse and keyboard only when the caller asks
++ for it. Only the owner's agent may make one: the capability alone would let any service that holds it name any
++ person.
++
## 0.267.0 — 2026-11-01
- `today.reminder.write` (active, first-party; plan L48): a first-party service sets, lists, snoozes, stops and removes a
ddiff --git a/contracts/bot/watch-link-request.v1.json b/contracts/bot/watch-link-request.v1.json
nnew file mode 100644
iindex 00000000..370e8575
---- /dev/null
++++ b/contracts/bot/watch-link-request.v1.json
@@@ -0,0 +1,31 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/bot/watch-link-request.v1.json",
++ "title": "BotWatchLinkRequest",
++ "description": "bot.watch-link-request@1: the watch link an agent asks for on a person's own machine (plan L55). The desk is one an agent works on — the private desk or an agent task's own desk (desk-<name>), never the owner's own screen — and the link lives for minutes, not days.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": ["desk"],
++ "properties": {
++ "desk": {
++ "type": "string",
++ "pattern": "^(private|desk-[a-z0-9][a-z0-9-]{0,23})$",
++ "description": "The desk the link shows: private, or the agent task's desk-<name>. The owner's own screen (main) is never an agent's to link."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too, at the level the owner set on the machine. Absent: they may only watch."
++ },
++ "minutes": {
++ "type": "integer",
++ "minimum": 5,
++ "maximum": 240,
++ "description": "How long the link lives. Absent: 60 minutes."
++ },
++ "label": {
++ "type": "string",
++ "maxLength": 80,
++ "description": "Where the owner put the link (\"the chat\")."
++ }
++ }
++}
ddiff --git a/contracts/bot/watch-link-result.v1.json b/contracts/bot/watch-link-result.v1.json
nnew file mode 100644
iindex 00000000..4eb19aa4
---- /dev/null
++++ b/contracts/bot/watch-link-result.v1.json
@@@ -0,0 +1,36 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/bot/watch-link-result.v1.json",
++ "title": "BotWatchLinkResult",
++ "description": "bot.watch-link-result@1: the watch link itself (plan L55): the page that shows the desk, and when it ends. The link is the machine owner's own, so the page needs no sign-in.",
++ "type": "object",
++ "required": [
++ "url",
++ "expires_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "url": {
++ "type": "string",
++ "format": "uri",
++ "description": "The page that shows the desk: https://openvibe.bot/screen/<token>."
++ },
++ "expires_at": {
++ "type": "string",
++ "format": "date-time",
++ "description": "When the link ends."
++ },
++ "desk": {
++ "type": "string",
++ "description": "The desk the link shows."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too."
++ },
++ "share_id": {
++ "type": "string",
++ "description": "Bot's id for the link."
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex 16c8e5a2..c5e3e8f5 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -7826,6 +7826,24 @@
"status": "active",
"adr": "ADR-043"
},
++ {
++ "id": "bot.watch-link-request",
++ "version": "1.0.0",
++ "owner": "bot",
++ "schema": "bot/watch-link-request.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "bot.watch-link-result",
++ "version": "1.0.0",
++ "owner": "bot",
++ "schema": "bot/watch-link-result.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
{
"id": "common.action-item",
"version": "1.0.0",
ddiff --git a/fixtures/bot.watch-link-request/invalid/bad-desk.json b/fixtures/bot.watch-link-request/invalid/bad-desk.json
nnew file mode 100644
iindex 00000000..1558aede
---- /dev/null
++++ b/fixtures/bot.watch-link-request/invalid/bad-desk.json
@@@ -0,0 +1,3 @@
++{
++ "desk": "desk-../x"
++}
ddiff --git a/fixtures/bot.watch-link-request/invalid/no-desk.json b/fixtures/bot.watch-link-request/invalid/no-desk.json
nnew file mode 100644
iindex 00000000..20a22c1e
---- /dev/null
++++ b/fixtures/bot.watch-link-request/invalid/no-desk.json
@@@ -0,0 +1,3 @@
++{
++ "minutes": 30
++}
ddiff --git a/fixtures/bot.watch-link-request/invalid/owners-screen.json b/fixtures/bot.watch-link-request/invalid/owners-screen.json
nnew file mode 100644
iindex 00000000..9605e44d
---- /dev/null
++++ b/fixtures/bot.watch-link-request/invalid/owners-screen.json
@@@ -0,0 +1,4 @@
++{
++ "desk": "main",
++ "minutes": 30
++}
ddiff --git a/fixtures/bot.watch-link-request/invalid/too-short.json b/fixtures/bot.watch-link-request/invalid/too-short.json
nnew file mode 100644
iindex 00000000..49e86b30
---- /dev/null
++++ b/fixtures/bot.watch-link-request/invalid/too-short.json
@@@ -0,0 +1,3 @@
++{
++ "minutes": 2
++}
ddiff --git a/fixtures/bot.watch-link-request/valid/task-desk.json b/fixtures/bot.watch-link-request/valid/task-desk.json
nnew file mode 100644
iindex 00000000..959d3840
---- /dev/null
++++ b/fixtures/bot.watch-link-request/valid/task-desk.json
@@@ -0,0 +1,4 @@
++{
++ "desk": "desk-task-a",
++ "minutes": 30
++}
ddiff --git a/fixtures/bot.watch-link-request/valid/watch-only.json b/fixtures/bot.watch-link-request/valid/watch-only.json
nnew file mode 100644
iindex 00000000..9cd6766e
---- /dev/null
++++ b/fixtures/bot.watch-link-request/valid/watch-only.json
@@@ -0,0 +1,3 @@
++{
++ "desk": "desk-research"
++}
ddiff --git a/fixtures/bot.watch-link-request/valid/with-control.json b/fixtures/bot.watch-link-request/valid/with-control.json
nnew file mode 100644
iindex 00000000..2f6c1b2c
---- /dev/null
++++ b/fixtures/bot.watch-link-request/valid/with-control.json
@@@ -0,0 +1,6 @@
++{
++ "desk": "private",
++ "control": true,
++ "minutes": 60,
++ "label": "the chat"
++}
ddiff --git a/fixtures/bot.watch-link-result/invalid/missing-url.json b/fixtures/bot.watch-link-result/invalid/missing-url.json
nnew file mode 100644
iindex 00000000..4c73d0a0
---- /dev/null
++++ b/fixtures/bot.watch-link-result/invalid/missing-url.json
@@@ -0,0 +1,3 @@
++{
++ "expires_at": "2026-11-01T12:30:00.000Z"
++}
ddiff --git a/fixtures/bot.watch-link-result/valid/link.json b/fixtures/bot.watch-link-result/valid/link.json
nnew file mode 100644
iindex 00000000..844139b0
---- /dev/null
++++ b/fixtures/bot.watch-link-result/valid/link.json
@@@ -0,0 +1,7 @@
++{
++ "url": "https://openvibe.bot/screen/abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGH",
++ "expires_at": "2026-11-01T12:30:00.000Z",
++ "desk": "desk-task-a",
++ "control": false,
++ "share_id": "shr_01JAB2C3D4E5F6G7H8J9K0MNPS"
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex b4f69fba..25a8d61b 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -88395,6 +88395,85 @@
}
}
},
++ "bot.watch-link-request": {
++ "version": "1.0.0",
++ "owner": "bot",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/bot/watch-link-request.v1.json",
++ "title": "BotWatchLinkRequest",
++ "description": "bot.watch-link-request@1: the watch link an agent asks for on a person's own machine (plan L55). The desk is one an agent works on — the private desk or an agent task's own desk (desk-<name>), never the owner's own screen — and the link lives for minutes, not days.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "desk"
++ ],
++ "properties": {
++ "desk": {
++ "type": "string",
++ "pattern": "^(private|desk-[a-z0-9][a-z0-9-]{0,23})$",
++ "description": "The desk the link shows: private, or the agent task's desk-<name>. The owner's own screen (main) is never an agent's to link."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too, at the level the owner set on the machine. Absent: they may only watch."
++ },
++ "minutes": {
++ "type": "integer",
++ "minimum": 5,
++ "maximum": 240,
++ "description": "How long the link lives. Absent: 60 minutes."
++ },
++ "label": {
++ "type": "string",
++ "maxLength": 80,
++ "description": "Where the owner put the link (\"the chat\")."
++ }
++ }
++ }
++ },
++ "bot.watch-link-result": {
++ "version": "1.0.0",
++ "owner": "bot",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/bot/watch-link-result.v1.json",
++ "title": "BotWatchLinkResult",
++ "description": "bot.watch-link-result@1: the watch link itself (plan L55): the page that shows the desk, and when it ends. The link is the machine owner's own, so the page needs no sign-in.",
++ "type": "object",
++ "required": [
++ "url",
++ "expires_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "url": {
++ "type": "string",
++ "format": "uri",
++ "description": "The page that shows the desk: https://openvibe.bot/screen/<token>."
++ },
++ "expires_at": {
++ "type": "string",
++ "format": "date-time",
++ "description": "When the link ends."
++ },
++ "desk": {
++ "type": "string",
++ "description": "The desk the link shows."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too."
++ },
++ "share_id": {
++ "type": "string",
++ "description": "Bot's id for the link."
++ }
++ }
++ }
++ },
"common.action-item": {
"version": "1.0.0",
"owner": "contracts",
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex 41309113..e99baae5 100644
---- a/generated/openapi/actor.json
++++ b/generated/openapi/actor.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Actor API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex cd8cd975..7359b148 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/bench.json b/generated/openapi/bench.json
iindex c3c4c915..b362ef75 100644
---- a/generated/openapi/bench.json
++++ b/generated/openapi/bench.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bench API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex f804c7b7..cdc9fe31 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex 8a06aec0..31856759 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/bot.json b/generated/openapi/bot.json
iindex b11d4b37..b91b2ab6 100644
---- a/generated/openapi/bot.json
++++ b/generated/openapi/bot.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bot API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
@@@ -1120,6 +1120,72 @@
}
}
},
++ "/api/v1/machines/{id}/watch-links": {
++ "post": {
++ "operationId": "post_api_v1_machines_id_watch_links",
++ "summary": "A watch link to a person's own machine desk (plan L55): the owner's agent (OpenVibe.Actor) asks Bot for a link that shows the desk it works on (the private desk or its own desk-<name>, never the owner",
++ "description": "**bot.machine.watch_link** (first-party): A watch link to a person's own machine desk (plan L55): the owner's agent (OpenVibe.Actor) asks Bot for a link that shows the desk it works on (the private desk or its own desk-<name>, never the owner's own screen), live, inside a chat turn. POST /api/v1/machines/:id/watch-links (bot.watch-link-request@1, answered by bot.watch-link-result@1) makes one for the machine the named person owns — never another person's (404) — and it lives for 5 to 240 minutes. The page needs no sign-in (the token is the credential), may sit in a frame on openvibe.chat or openvibe.actor, and carries the mouse and keyboard only when the caller asks for it. Only the owner's agent may make one: the capability alone would let any service that holds it name any person.",
++ "tags": [
++ "bot.machine"
++ ],
++ "x-openvibe-capabilities": [
++ "bot.machine.watch_link"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "bot-machine",
++ "security": [
++ {
++ "openvibeToken": [
++ "bot.machine.watch_link"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/bot.watch-link-request.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/bot.watch-link-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/resources": {
"get": {
"operationId": "get_api_v1_resources",
@@@ -3220,6 +3286,71 @@
}
}
},
++ "bot.watch-link-request.v1": {
++ "title": "BotWatchLinkRequest",
++ "description": "bot.watch-link-request@1: the watch link an agent asks for on a person's own machine (plan L55). The desk is one an agent works on — the private desk or an agent task's own desk (desk-<name>), never the owner's own screen — and the link lives for minutes, not days.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "desk"
++ ],
++ "properties": {
++ "desk": {
++ "type": "string",
++ "pattern": "^(private|desk-[a-z0-9][a-z0-9-]{0,23})$",
++ "description": "The desk the link shows: private, or the agent task's desk-<name>. The owner's own screen (main) is never an agent's to link."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too, at the level the owner set on the machine. Absent: they may only watch."
++ },
++ "minutes": {
++ "type": "integer",
++ "minimum": 5,
++ "maximum": 240,
++ "description": "How long the link lives. Absent: 60 minutes."
++ },
++ "label": {
++ "type": "string",
++ "maxLength": 80,
++ "description": "Where the owner put the link (\"the chat\")."
++ }
++ }
++ },
++ "bot.watch-link-result.v1": {
++ "title": "BotWatchLinkResult",
++ "description": "bot.watch-link-result@1: the watch link itself (plan L55): the page that shows the desk, and when it ends. The link is the machine owner's own, so the page needs no sign-in.",
++ "type": "object",
++ "required": [
++ "url",
++ "expires_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "url": {
++ "type": "string",
++ "format": "uri",
++ "description": "The page that shows the desk: https://openvibe.bot/screen/<token>."
++ },
++ "expires_at": {
++ "type": "string",
++ "format": "date-time",
++ "description": "When the link ends."
++ },
++ "desk": {
++ "type": "string",
++ "description": "The desk the link shows."
++ },
++ "control": {
++ "type": "boolean",
++ "description": "true: the holders may use the mouse and keyboard too."
++ },
++ "share_id": {
++ "type": "string",
++ "description": "Bot's id for the link."
++ }
++ }
++ },
"common.owned-resource-control-request.v1": {
"title": "OwnedResourceControlRequest",
"description": "common.owned-resource-control-request@1 (ADR-048 amendment 2026-10-15, step 8 phase 2): one control operation on a person-owned resource. Robots, chat rooms, restream definitions and pastes belong to a person, not to a project, so they carry no OVRN and the project-scoped common.resource-control-request@1 cannot name them. OpenVibe.Services sends this to the owning authority's POST /api/v1/resources/control (the same route, told apart by `owned`), acting for the person in on_behalf_of. owned names the resource by its index summary's kind and id. owner is the person it belongs to: the authority refuses unless its own record says the same (Services also offers actions only on the viewer's own resources). A sensitive action (deleting, physical control) asked by an agent is refused with confirmation_required until the owner approves, as for project resources. idempotency_key makes a retry safe: the authority answers a repeated key from the same caller with the first result, and refuses the key reused with another request. Answered with common.resource-control-result@1 (without resource: there is no OVRN). The actions each authority takes are in its <service>.resource.control capability; any other action is refused unsupported.",
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex 7d445b14..98ebd26e 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 86250d18..77d313c3 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex 55ee8527..8d8d3fd7 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex 4e45f11a..2e141ced 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex 4ccf2a90..44811b04 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/domains.json b/generated/openapi/domains.json
iindex 0ae89016..4d74a808 100644
---- a/generated/openapi/domains.json
++++ b/generated/openapi/domains.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Domains API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex c35c47e9..fa57c9c6 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/food.json b/generated/openapi/food.json
iindex 5810e355..8ec51b39 100644
---- a/generated/openapi/food.json
++++ b/generated/openapi/food.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Food API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex 86c4f532..3a449dbe 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex 71f42232..1b87c672 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex ba2de9b7..6a25ffa6 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -40,8 +40,8 @@
"service": "bot",
"name": "OpenVibe.Bot",
"origin": "https://openvibe.bot",
-- "operations": 30,
-- "capabilities": 10
++ "operations": 31,
++ "capabilities": 11
},
{
"service": "chat",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 1bd1db11..81047c8b 100644
---- a/generated/openapi/inventory.json
++++ b/generated/openapi/inventory.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Inventory API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 7508f83a..677c0691 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/media-hub.json b/generated/openapi/media-hub.json
iindex 45ea430a..ea3f97fc 100644
---- a/generated/openapi/media-hub.json
++++ b/generated/openapi/media-hub.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.MediaHub API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex 409233cd..e1682460 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 733d2fae..0253017f 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex f127e59e..e2275dcd 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex f354e55a..31173135 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRestream API",
-- "version": "0.267.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/play.json b/generated/openapi/play.json
iindex de49e9df..0084f176 100644
---- a/generated/openapi/play.json
++++ b/generated/openapi/play.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Play API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/quest.json b/generated/openapi/quest.json
iindex a159b966..9ead4bb2 100644
---- a/generated/openapi/quest.json
++++ b/generated/openapi/quest.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Quest API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/report.json b/generated/openapi/report.json
iindex 6e1c9fe5..06378eac 100644
---- a/generated/openapi/report.json
++++ b/generated/openapi/report.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Report API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex bf224169..1c5b0f65 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/run.json b/generated/openapi/run.json
iindex 999e76f1..dc19ffb1 100644
---- a/generated/openapi/run.json
++++ b/generated/openapi/run.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Run API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 932d96a7..f83e8018 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/services.json b/generated/openapi/services.json
iindex ccfa302f..bc356cc7 100644
---- a/generated/openapi/services.json
++++ b/generated/openapi/services.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Services API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 68c6fa36..8ae56483 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/space.json b/generated/openapi/space.json
iindex 45cc87f4..1a0fc8b6 100644
---- a/generated/openapi/space.json
++++ b/generated/openapi/space.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Space API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex 94f8f45e..6e0970b9 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/today.json b/generated/openapi/today.json
iindex 47d84fcf..36c34fbf 100644
---- a/generated/openapi/today.json
++++ b/generated/openapi/today.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Today API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex d67dcf06..9e8613bf 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex bc056127..30e6d5b3 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex 0cc41284..8a479192 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/vision.json b/generated/openapi/vision.json
iindex f6fa5e0f..e2648b70 100644
---- a/generated/openapi/vision.json
++++ b/generated/openapi/vision.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Vision API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/watch.json b/generated/openapi/watch.json
iindex ffa504f5..caca2cd1 100644
---- a/generated/openapi/watch.json
++++ b/generated/openapi/watch.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Watch API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex f996f68d..46f18d75 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/work.json b/generated/openapi/work.json
iindex cf63adb2..27e237c8 100644
---- a/generated/openapi/work.json
++++ b/generated/openapi/work.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Work API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/openapi/zone.json b/generated/openapi/zone.json
iindex 3c31c47d..02f01180 100644
---- a/generated/openapi/zone.json
++++ b/generated/openapi/zone.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Zone API",
-- "version": "0.267.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.267.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.268.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.268.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"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex de55c765..e219c25d 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -264213,6 +264213,56 @@ export interface BotDeskLeaseCreateRequest {
height?: number;
}
++/** [email protected] (owner: bot) */
++/**
++ * bot.watch-link-request@1: the watch link an agent asks for on a person's own machine (plan L55). The desk is one an agent works on — the private desk or an agent task's own desk (desk-<name>), never the owner's own screen — and the link lives for minutes, not days.
++ */
++export interface BotWatchLinkRequest {
++ /**
++ * The desk the link shows: private, or the agent task's desk-<name>. The owner's own screen (main) is never an agent's to link.
++ */
++ desk: string;
++ /**
++ * true: the holders may use the mouse and keyboard too, at the level the owner set on the machine. Absent: they may only watch.
++ */
++ control?: boolean;
++ /**
++ * How long the link lives. Absent: 60 minutes.
++ */
++ minutes?: number;
++ /**
++ * Where the owner put the link ("the chat").
++ */
++ label?: string;
++}
++
++/** [email protected] (owner: bot) */
++/**
++ * bot.watch-link-result@1: the watch link itself (plan L55): the page that shows the desk, and when it ends. The link is the machine owner's own, so the page needs no sign-in.
++ */
++export interface BotWatchLinkResult {
++ /**
++ * The page that shows the desk: https://openvibe.bot/screen/<token>.
++ */
++ url: string;
++ /**
++ * When the link ends.
++ */
++ expires_at: string;
++ /**
++ * The desk the link shows.
++ */
++ desk?: string;
++ /**
++ * true: the holders may use the mouse and keyboard too.
++ */
++ control?: boolean;
++ /**
++ * Bot's id for the link.
++ */
++ share_id?: string;
++}
++
/** [email protected] (owner: contracts) */
/**
* One piece of a person's agent work in the Action Center (plan 2026-10-28 §3.10): an agent task, a coding task, an AI run, or an approval waiting on them. Each authority answers its own items in this shape (common.action-list-result@1); OpenVibe.Network merges them into buckets (network.me-actions-result@1). Text is plain (no markup); a cost is what the person was charged in USD, null when unknown or free; href is a page on the authority's own public site.
ddiff --git a/manifests/capabilities/bot.machine.watch_link.json b/manifests/capabilities/bot.machine.watch_link.json
nnew file mode 100644
iindex 00000000..9e8c3eb0
---- /dev/null
++++ b/manifests/capabilities/bot.machine.watch_link.json
@@@ -0,0 +1,22 @@
++{
++ "id": "bot.machine.watch_link",
++ "version": "1.0",
++ "owner": "bot",
++ "status": "active",
++ "visibility": "first-party",
++ "sensitive": true,
++ "description": "A watch link to a person's own machine desk (plan L55): the owner's agent (OpenVibe.Actor) asks Bot for a link that shows the desk it works on (the private desk or its own desk-<name>, never the owner's own screen), live, inside a chat turn. POST /api/v1/machines/:id/watch-links (bot.watch-link-request@1, answered by bot.watch-link-result@1) makes one for the machine the named person owns — never another person's (404) — and it lives for 5 to 240 minutes. The page needs no sign-in (the token is the credential), may sit in a frame on openvibe.chat or openvibe.actor, and carries the mouse and keyboard only when the caller asks for it. Only the owner's agent may make one: the capability alone would let any service that holds it name any person.",
++ "permissions": [
++ "bot:machine:watch_link"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "bot-machine",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/machines/:id/watch-links"
++ ],
++ "inputSchema": "bot.watch-link-request@1",
++ "outputSchema": "bot.watch-link-result@1"
++}
ddiff --git a/manifests/services/bot.json b/manifests/services/bot.json
iindex e8bcdb89..7f91b718 100644
---- a/manifests/services/bot.json
++++ b/manifests/services/bot.json
@@@ -38,7 +38,8 @@
"bot.resource.read",
"bot.resource.control",
"bot.desk.session",
-- "bot.machine.manage"
++ "bot.machine.manage",
++ "bot.machine.watch_link"
],
"eventsProduced": [
"bot.robot.online",
ddiff --git a/package-lock.json b/package-lock.json
iindex 201ad79d..bb203f41 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.267.0",
++ "version": "0.268.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.267.0",
++ "version": "0.268.0",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex da1f9140..405e95dd 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.267.0",
++ "version": "0.268.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",
ddiff --git a/test/bot-manifest.test.js b/test/bot-manifest.test.js
iindex 79cb9fb6..82b2ad90 100644
---- a/test/bot-manifest.test.js
++++ b/test/bot-manifest.test.js
@@@ -14,7 +14,8 @@ const c = require('..');
// bot.desk.session: Run's sessions lease one desk each (0.223.0, the Desks plan's D6).
// bot.machine.manage: the machines hub (0.258.0, plan L34): Network fronts Bot for a person and for the apps that
// person consented to; Bot stays the authority and checks the machine is that person's own.
--const BOT_CAPABILITIES = ['bot.robot.read', 'bot.robot.manage', 'bot.robot.control', 'bot.computer.control', 'bot.machine.ai', 'bot.machine.manage', 'bot.desk.session', 'bot.device.connect', 'bot.job.dispatch', 'bot.resource.read', 'bot.resource.control'];
++// bot.machine.watch_link: the owner's agent asks for a link that shows the desk it works on, inside a chat (plan L55).
++const BOT_CAPABILITIES = ['bot.robot.read', 'bot.robot.manage', 'bot.robot.control', 'bot.computer.control', 'bot.machine.ai', 'bot.machine.manage', 'bot.machine.watch_link', 'bot.desk.session', 'bot.device.connect', 'bot.job.dispatch', 'bot.resource.read', 'bot.resource.control'];
const BOT_EVENTS = ['bot.robot.online', 'bot.robot.offline', 'bot.estop.set', 'bot.estop.cleared', 'bot.command.refused'];
const bot = c.services.get('bot');