openvibers/openvibe.contracts Commits

actor.assignment@1: the tree of delegated work, its capabilities and a step assignment id (0.328.0) (#336)

OP OpenVibers committed 6 days ago · ff03a6845d · 73 files, +1330 −94

* actor.assignment@1: the tree of delegated work, its capabilities and a step's assignment id (0.327.0)

Add the actor.assignment@1 contract and its two response shapes (the node and
its children, the cancel result), name the read and cancel capabilities in
Actor's service manifest, and add assignment_id to an actor.task-event@2 step.
Expand-only: all three new contracts, two new capabilities and an optional
field; the existing event and every old row stay valid.

Fixtures cover a root, a child, outside work, the tree and the cancel result,
and the bad origin, depth, state, budget and unknown key are refused.

* Merge remote-tracking branch 'origin/main' into a2-assignment-contract

# Conflicts:
#	CHANGELOG.md
#	generated/openapi/index.json

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 307ee56c..c17707f4 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -1,5 +1,11 @@
# Changelog
++## 0.328.0 — 2026-11-07
++
++- Add `actor.assignment@1`: one node of the tree of delegated work (plan §12) — id, root, parent, depth, origin (`person`, `routine`, `outside`), mode (`work`, `consult`, `notify`), reply (`resume`, `poll`, `none`), the agent and task it runs as, the node's level and effective level, the root's budget (limit, spent and remaining), state and timestamps. A node is one hand-off: a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. The effective level is the higher of the agent's own and the one inherited along a person's or routine's line; outside work never passes a level down. A cancel cascades down the tree, and a root's budget stops its children when spent. `GET /api/v1/assignments/:id` answers the node and its children and `POST /api/v1/assignments/:id/cancel` cancels the subtree; both are owner-only and another person gets 404. An existing task gets a root lazily.
++- Add the capabilities `actor.assignment.read` and `actor.assignment.cancel`, and name them in Actor's service manifest. They are the two assignment routes above.
++- `actor.task-event@2` gains an optional `assignment_id` on a step event, so the Dock's timeline can draw the work tree later. Additive: an event without one stays valid, and the task record is still the source of truth.
++
## 0.327.0 — 2026-11-07
- One Computer across Surf, Actor and the Dock (plan 2026-11-07: "Surf, Computer and Actor are one experience"): `platform.task@1` gains optional `computer` (`session_id`, `machine`, `where`, `cost_hint`, `driving`) — the browser or desktop session a running task opened, wherever it runs. `session_id` is OpenVibe.Run's `ses_…`; it is null only when the desk runs directly on the person's own machine through OpenVibe.Bot, where there is no Run session. `where` is `yours`, `home` or `network`, and `machine` is the person's own word for it.
ddiff --git a/contracts/actor/assignment-cancel-result.v1.json b/contracts/actor/assignment-cancel-result.v1.json
nnew file mode 100644
iindex 00000000..59408adf
---- /dev/null
++++ b/contracts/actor/assignment-cancel-result.v1.json
@@@ -0,0 +1,24 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment-cancel-result.v1.json",
++ "title": "ActorAssignmentCancelResult",
++ "description": "actor.assignment-cancel-result@1: POST /api/v1/assignments/:id/cancel (capability actor.assignment.cancel): the node as it is now and every node the cancel stopped, the node included and its children below it. The tasks those nodes ran are cancelled too. Only the owner can cancel; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "cancelled"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "assignment.v1.json"
++ },
++ "cancelled": {
++ "type": "array",
++ "maxItems": 1000,
++ "items": {
++ "$ref": "assignment.v1.json"
++ }
++ }
++ }
++}
ddiff --git a/contracts/actor/assignment-tree.v1.json b/contracts/actor/assignment-tree.v1.json
nnew file mode 100644
iindex 00000000..c91ecc64
---- /dev/null
++++ b/contracts/actor/assignment-tree.v1.json
@@@ -0,0 +1,24 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment-tree.v1.json",
++ "title": "ActorAssignmentTree",
++ "description": "actor.assignment-tree@1: GET /api/v1/assignments/:id (capability actor.assignment.read): the node and its direct children, oldest first. Each node is an actor.assignment@1. Only the owner can read the tree; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "children"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "assignment.v1.json"
++ },
++ "children": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "$ref": "assignment.v1.json"
++ }
++ }
++ }
++}
ddiff --git a/contracts/actor/assignment.v1.json b/contracts/actor/assignment.v1.json
nnew file mode 100644
iindex 00000000..c4a5ab94
---- /dev/null
++++ b/contracts/actor/assignment.v1.json
@@@ -0,0 +1,159 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment.v1.json",
++ "title": "ActorAssignment",
++ "description": "actor.assignment@1: one node of the tree of delegated work (plan §12). A node is a hand-off — a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. ID is the node; ROOT names the node whose BUDGET the whole tree spends, PARENT the node that handed this work over (null on a root) and DEPTH its distance from the root (0 on a root). ORIGIN says who started the line: a person (person), a routine or Watch trigger (routine), or work from outside Actor (outside). MODE is the hand-off's kind (work, consult, notify) and REPLY how its result comes back (resume into the parent, poll, or none). LEVEL is the node's own level and EFFECTIVE_LEVEL the level its steps run at: the higher of the agent's own level and the one inherited from a person's or routine's line. Outside work never passes a level down. BUDGET is the root's budget and what the tree has spent. A cancel cascades down the tree. GET /api/v1/assignments/:id returns { assignment, children } and POST /api/v1/assignments/:id/cancel returns { assignment, cancelled }; both are owner-only, and another person's node is the same 404 as one that does not exist. A task has no node until one is made for it: an existing task gets a root lazily.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "root",
++ "parent",
++ "depth",
++ "origin",
++ "mode",
++ "reply",
++ "agent_id",
++ "task_id",
++ "level",
++ "effective_level",
++ "budget",
++ "state",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "root": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "parent": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "depth": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "origin": {
++ "type": "string",
++ "enum": [
++ "person",
++ "routine",
++ "outside"
++ ]
++ },
++ "mode": {
++ "type": "string",
++ "enum": [
++ "work",
++ "consult",
++ "notify"
++ ]
++ },
++ "reply": {
++ "type": "string",
++ "enum": [
++ "resume",
++ "poll",
++ "none"
++ ]
++ },
++ "agent_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "task_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^tsk_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "effective_level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "budget": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "The budget of the root of this tree, and what the tree has spent of it. Every node carries the same root budget.",
++ "required": [
++ "limit_usd",
++ "spent_usd",
++ "remaining_usd"
++ ],
++ "properties": {
++ "limit_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "spent_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "remaining_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "state": {
++ "type": "string",
++ "enum": [
++ "queued",
++ "running",
++ "waiting",
++ "succeeded",
++ "failed",
++ "cancelled"
++ ]
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "started_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ }
++ }
++}
ddiff --git a/contracts/actor/task-event.v2.json b/contracts/actor/task-event.v2.json
iindex 19b75471..040bca76 100644
---- a/contracts/actor/task-event.v2.json
++++ b/contracts/actor/task-event.v2.json
@@@ -58,6 +58,11 @@
"handoff"
]
},
++ "assignment_id": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The assignment node this step belongs to (actor.assignment@1): the work tree the Dock may draw later. Older events and work with no assignment have none."
++ },
"text": {
"type": "string",
"maxLength": 8000
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex e196797d..d50e83ea 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -7307,6 +7307,36 @@
"status": "active",
"adr": "ADR-044"
},
++ {
++ "id": "actor.assignment",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "actor/assignment.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active",
++ "adr": "ADR-044"
++ },
++ {
++ "id": "actor.assignment-tree",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "actor/assignment-tree.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active",
++ "adr": "ADR-044"
++ },
++ {
++ "id": "actor.assignment-cancel-result",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "actor/assignment-cancel-result.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active",
++ "adr": "ADR-044"
++ },
{
"id": "actor.agent-list-result",
"version": "1.0.0",
ddiff --git a/fixtures/actor.assignment-cancel-result/invalid/missing-cancelled.json b/fixtures/actor.assignment-cancel-result/invalid/missing-cancelled.json
nnew file mode 100644
iindex 00000000..2ba1f829
---- /dev/null
++++ b/fixtures/actor.assignment-cancel-result/invalid/missing-cancelled.json
@@@ -0,0 +1,19 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "cancelled",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:05.000Z"
++ }
++}
ddiff --git a/fixtures/actor.assignment-cancel-result/invalid/not-cancelled.json b/fixtures/actor.assignment-cancel-result/invalid/not-cancelled.json
nnew file mode 100644
iindex 00000000..8d451ead
---- /dev/null
++++ b/fixtures/actor.assignment-cancel-result/invalid/not-cancelled.json
@@@ -0,0 +1,24 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": {
++ "limit_usd": 0.05,
++ "spent_usd": 0,
++ "remaining_usd": 0.05
++ },
++ "state": "paused",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:05.000Z"
++ },
++ "cancelled": []
++}
ddiff --git a/fixtures/actor.assignment-cancel-result/valid/root-and-child.json b/fixtures/actor.assignment-cancel-result/valid/root-and-child.json
nnew file mode 100644
iindex 00000000..06555d51
---- /dev/null
++++ b/fixtures/actor.assignment-cancel-result/valid/root-and-child.json
@@@ -0,0 +1,40 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "cancelled",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:05.000Z",
++ "ended_at": "2026-11-07T10:00:05.000Z"
++ },
++ "cancelled": [
++ {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "cancelled",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:05.000Z",
++ "ended_at": "2026-11-07T10:00:05.000Z"
++ }
++ ]
++}
ddiff --git a/fixtures/actor.assignment-tree/invalid/bad-child.json b/fixtures/actor.assignment-tree/invalid/bad-child.json
nnew file mode 100644
iindex 00000000..35f7c4e1
---- /dev/null
++++ b/fixtures/actor.assignment-tree/invalid/bad-child.json
@@@ -0,0 +1,46 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": {
++ "limit_usd": 0.05,
++ "spent_usd": 0,
++ "remaining_usd": 0.05
++ },
++ "state": "running",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++ },
++ "children": [
++ {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPT",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 1,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": {
++ "limit_usd": 0.05,
++ "spent_usd": 0,
++ "remaining_usd": 0.05
++ },
++ "state": "paused",
++ "created_at": "2026-11-07T10:00:01.000Z",
++ "updated_at": "2026-11-07T10:00:01.000Z"
++ }
++ ]
++}
ddiff --git a/fixtures/actor.assignment-tree/invalid/missing-children.json b/fixtures/actor.assignment-tree/invalid/missing-children.json
nnew file mode 100644
iindex 00000000..c52d6ade
---- /dev/null
++++ b/fixtures/actor.assignment-tree/invalid/missing-children.json
@@@ -0,0 +1,19 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "running",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++ }
++}
ddiff --git a/fixtures/actor.assignment-tree/valid/root-with-child.json b/fixtures/actor.assignment-tree/valid/root-with-child.json
nnew file mode 100644
iindex 00000000..d660b07c
---- /dev/null
++++ b/fixtures/actor.assignment-tree/valid/root-with-child.json
@@@ -0,0 +1,38 @@
++{
++ "assignment": {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "running",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++ },
++ "children": [
++ {
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPT",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "depth": 1,
++ "origin": "person",
++ "mode": "consult",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "full",
++ "effective_level": "full",
++ "budget": { "limit_usd": 0.05, "spent_usd": 0, "remaining_usd": 0.05 },
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:01.000Z",
++ "updated_at": "2026-11-07T10:00:01.000Z"
++ }
++ ]
++}
ddiff --git a/fixtures/actor.assignment/invalid/bad-origin.json b/fixtures/actor.assignment/invalid/bad-origin.json
nnew file mode 100644
iindex 00000000..a2f79614
---- /dev/null
++++ b/fixtures/actor.assignment/invalid/bad-origin.json
@@@ -0,0 +1,17 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "webhook",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 1, "spent_usd": 0, "remaining_usd": 1 },
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++}
ddiff --git a/fixtures/actor.assignment/invalid/bad-state.json b/fixtures/actor.assignment/invalid/bad-state.json
nnew file mode 100644
iindex 00000000..2c021eaf
---- /dev/null
++++ b/fixtures/actor.assignment/invalid/bad-state.json
@@@ -0,0 +1,17 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 1, "spent_usd": 0, "remaining_usd": 1 },
++ "state": "paused",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++}
ddiff --git a/fixtures/actor.assignment/invalid/missing-budget.json b/fixtures/actor.assignment/invalid/missing-budget.json
nnew file mode 100644
iindex 00000000..bf726763
---- /dev/null
++++ b/fixtures/actor.assignment/invalid/missing-budget.json
@@@ -0,0 +1,16 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++}
ddiff --git a/fixtures/actor.assignment/invalid/negative-depth.json b/fixtures/actor.assignment/invalid/negative-depth.json
nnew file mode 100644
iindex 00000000..c7c2510e
---- /dev/null
++++ b/fixtures/actor.assignment/invalid/negative-depth.json
@@@ -0,0 +1,17 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": -1,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 1, "spent_usd": 0, "remaining_usd": 1 },
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z"
++}
ddiff --git a/fixtures/actor.assignment/invalid/unknown-field.json b/fixtures/actor.assignment/invalid/unknown-field.json
nnew file mode 100644
iindex 00000000..095ef1fd
---- /dev/null
++++ b/fixtures/actor.assignment/invalid/unknown-field.json
@@@ -0,0 +1,18 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": null,
++ "task_id": null,
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": { "limit_usd": 1, "spent_usd": 0, "remaining_usd": 1 },
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:00.000Z",
++ "owner": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPS"
++}
ddiff --git a/fixtures/actor.assignment/valid/child.json b/fixtures/actor.assignment/valid/child.json
nnew file mode 100644
iindex 00000000..d7b8dcb7
---- /dev/null
++++ b/fixtures/actor.assignment/valid/child.json
@@@ -0,0 +1,21 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPT",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "depth": 1,
++ "origin": "routine",
++ "mode": "consult",
++ "reply": "poll",
++ "agent_id": null,
++ "task_id": null,
++ "level": "auto-edits",
++ "effective_level": "auto-edits",
++ "budget": {
++ "limit_usd": 0.05,
++ "spent_usd": 0.0012,
++ "remaining_usd": 0.0488
++ },
++ "state": "queued",
++ "created_at": "2026-11-07T10:00:02.000Z",
++ "updated_at": "2026-11-07T10:00:02.000Z"
++}
ddiff --git a/fixtures/actor.assignment/valid/outside-done.json b/fixtures/actor.assignment/valid/outside-done.json
nnew file mode 100644
iindex 00000000..d01468a6
---- /dev/null
++++ b/fixtures/actor.assignment/valid/outside-done.json
@@@ -0,0 +1,23 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPX",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPX",
++ "parent": null,
++ "depth": 0,
++ "origin": "outside",
++ "mode": "notify",
++ "reply": "none",
++ "agent_id": null,
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPT",
++ "level": "full",
++ "effective_level": "ask",
++ "budget": {
++ "limit_usd": 0,
++ "spent_usd": 0,
++ "remaining_usd": 0
++ },
++ "state": "succeeded",
++ "created_at": "2026-11-07T10:00:03.000Z",
++ "updated_at": "2026-11-07T10:00:09.000Z",
++ "started_at": "2026-11-07T10:00:03.000Z",
++ "ended_at": "2026-11-07T10:00:09.000Z"
++}
ddiff --git a/fixtures/actor.assignment/valid/root.json b/fixtures/actor.assignment/valid/root.json
nnew file mode 100644
iindex 00000000..aae25d81
---- /dev/null
++++ b/fixtures/actor.assignment/valid/root.json
@@@ -0,0 +1,23 @@
++{
++ "id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "root": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "parent": null,
++ "depth": 0,
++ "origin": "person",
++ "mode": "work",
++ "reply": "resume",
++ "agent_id": "agt_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "level": "ask",
++ "effective_level": "ask",
++ "budget": {
++ "limit_usd": 0.05,
++ "spent_usd": 0.0012,
++ "remaining_usd": 0.0488
++ },
++ "state": "running",
++ "created_at": "2026-11-07T10:00:00.000Z",
++ "updated_at": "2026-11-07T10:00:05.000Z",
++ "started_at": "2026-11-07T10:00:01.000Z",
++ "ended_at": null
++}
ddiff --git a/fixtures/actor.task-event/valid/with-assignment.json b/fixtures/actor.task-event/valid/with-assignment.json
nnew file mode 100644
iindex 00000000..3a576d4f
---- /dev/null
++++ b/fixtures/actor.task-event/valid/with-assignment.json
@@@ -0,0 +1,11 @@
++{
++ "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "seq": 6,
++ "kind": "output",
++ "at": "2026-11-07T10:00:02.000Z",
++ "agent": "openvibe-runtime",
++ "step": "tool_call",
++ "tool": "computer_run",
++ "input": "npm test",
++ "assignment_id": "asg_01JAB2C3D4E5F6G7H8J9K0MNPS"
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex e8800304..5b136aa9 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -84526,6 +84526,11 @@
"handoff"
]
},
++ "assignment_id": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The assignment node this step belongs to (actor.assignment@1): the work tree the Dock may draw later. Older events and work with no assignment have none."
++ },
"text": {
"type": "string",
"maxLength": 8000
@@@ -84718,6 +84723,228 @@
}
}
},
++ "actor.assignment": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment.v1.json",
++ "title": "ActorAssignment",
++ "description": "actor.assignment@1: one node of the tree of delegated work (plan §12). A node is a hand-off — a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. ID is the node; ROOT names the node whose BUDGET the whole tree spends, PARENT the node that handed this work over (null on a root) and DEPTH its distance from the root (0 on a root). ORIGIN says who started the line: a person (person), a routine or Watch trigger (routine), or work from outside Actor (outside). MODE is the hand-off's kind (work, consult, notify) and REPLY how its result comes back (resume into the parent, poll, or none). LEVEL is the node's own level and EFFECTIVE_LEVEL the level its steps run at: the higher of the agent's own level and the one inherited from a person's or routine's line. Outside work never passes a level down. BUDGET is the root's budget and what the tree has spent. A cancel cascades down the tree. GET /api/v1/assignments/:id returns { assignment, children } and POST /api/v1/assignments/:id/cancel returns { assignment, cancelled }; both are owner-only, and another person's node is the same 404 as one that does not exist. A task has no node until one is made for it: an existing task gets a root lazily.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "root",
++ "parent",
++ "depth",
++ "origin",
++ "mode",
++ "reply",
++ "agent_id",
++ "task_id",
++ "level",
++ "effective_level",
++ "budget",
++ "state",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "root": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "parent": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "depth": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "origin": {
++ "type": "string",
++ "enum": [
++ "person",
++ "routine",
++ "outside"
++ ]
++ },
++ "mode": {
++ "type": "string",
++ "enum": [
++ "work",
++ "consult",
++ "notify"
++ ]
++ },
++ "reply": {
++ "type": "string",
++ "enum": [
++ "resume",
++ "poll",
++ "none"
++ ]
++ },
++ "agent_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "task_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^tsk_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "effective_level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "budget": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "The budget of the root of this tree, and what the tree has spent of it. Every node carries the same root budget.",
++ "required": [
++ "limit_usd",
++ "spent_usd",
++ "remaining_usd"
++ ],
++ "properties": {
++ "limit_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "spent_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "remaining_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "state": {
++ "type": "string",
++ "enum": [
++ "queued",
++ "running",
++ "waiting",
++ "succeeded",
++ "failed",
++ "cancelled"
++ ]
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "started_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ }
++ }
++ }
++ },
++ "actor.assignment-tree": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment-tree.v1.json",
++ "title": "ActorAssignmentTree",
++ "description": "actor.assignment-tree@1: GET /api/v1/assignments/:id (capability actor.assignment.read): the node and its direct children, oldest first. Each node is an actor.assignment@1. Only the owner can read the tree; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "children"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "assignment.v1.json"
++ },
++ "children": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "$ref": "assignment.v1.json"
++ }
++ }
++ }
++ }
++ },
++ "actor.assignment-cancel-result": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/assignment-cancel-result.v1.json",
++ "title": "ActorAssignmentCancelResult",
++ "description": "actor.assignment-cancel-result@1: POST /api/v1/assignments/:id/cancel (capability actor.assignment.cancel): the node as it is now and every node the cancel stopped, the node included and its children below it. The tasks those nodes ran are cancelled too. Only the owner can cancel; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "cancelled"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "assignment.v1.json"
++ },
++ "cancelled": {
++ "type": "array",
++ "maxItems": 1000,
++ "items": {
++ "$ref": "assignment.v1.json"
++ }
++ }
++ }
++ }
++ },
"actor.agent-list-result@1": {
"version": "1.0.0",
"owner": "actor",
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex e8ec2b9d..4eb59c0b 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.327.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.328.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"
@@@ -825,6 +825,118 @@
}
}
},
++ "/api/v1/assignments/{id}": {
++ "get": {
++ "operationId": "get_api_v1_assignments_id",
++ "summary": "Read one node of your assignment tree and its children with GET /api/v1/assignments/:id (actor.assignment@1): the hand-off, who started it, its mode and reply, the agent and task it runs as, its level",
++ "description": "**actor.assignment.read** (public): Read one node of your assignment tree and its children with GET /api/v1/assignments/:id (actor.assignment@1): the hand-off, who started it, its mode and reply, the agent and task it runs as, its level and effective level, the root's budget and the state. Only the person whose work it is can read it; another person gets the same 404 as a node that does not exist.",
++ "tags": [
++ "actor.assignment"
++ ],
++ "x-openvibe-capabilities": [
++ "actor.assignment.read"
++ ],
++ "x-openvibe-visibility": [
++ "public"
++ ],
++ "x-openvibe-quota-class": "actor-read",
++ "security": [
++ {
++ "openvibeToken": [
++ "actor.assignment.read"
++ ]
++ }
++ ],
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/actor.assignment-tree.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/assignments/{id}/cancel": {
++ "post": {
++ "operationId": "post_api_v1_assignments_id_cancel",
++ "summary": "Cancel your assignment tree from one node down with POST /api/v1/assignments/:id/cancel: every child node is cancelled and every task still running under the tree is stopped.",
++ "description": "**actor.assignment.cancel** (public): Cancel your assignment tree from one node down with POST /api/v1/assignments/:id/cancel: every child node is cancelled and every task still running under the tree is stopped. It answers the node and the nodes it cancelled. Only the person whose work it is can cancel it; another person gets the same 404 as a node that does not exist.",
++ "tags": [
++ "actor.assignment"
++ ],
++ "x-openvibe-capabilities": [
++ "actor.assignment.cancel"
++ ],
++ "x-openvibe-visibility": [
++ "public"
++ ],
++ "x-openvibe-quota-class": "actor-write",
++ "security": [
++ {
++ "openvibeToken": [
++ "actor.assignment.cancel"
++ ]
++ }
++ ],
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/actor.assignment-cancel-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/me/agents": {
"get": {
"operationId": "get_api_v1_me_agents",
@@@ -3906,6 +4018,207 @@
}
}
},
++ "actor.assignment-cancel-result.v1": {
++ "title": "ActorAssignmentCancelResult",
++ "description": "actor.assignment-cancel-result@1: POST /api/v1/assignments/:id/cancel (capability actor.assignment.cancel): the node as it is now and every node the cancel stopped, the node included and its children below it. The tasks those nodes ran are cancelled too. Only the owner can cancel; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "cancelled"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "#/components/schemas/actor.assignment.v1"
++ },
++ "cancelled": {
++ "type": "array",
++ "maxItems": 1000,
++ "items": {
++ "$ref": "#/components/schemas/actor.assignment.v1"
++ }
++ }
++ }
++ },
++ "actor.assignment-tree.v1": {
++ "title": "ActorAssignmentTree",
++ "description": "actor.assignment-tree@1: GET /api/v1/assignments/:id (capability actor.assignment.read): the node and its direct children, oldest first. Each node is an actor.assignment@1. Only the owner can read the tree; another person gets 404.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "assignment",
++ "children"
++ ],
++ "properties": {
++ "assignment": {
++ "$ref": "#/components/schemas/actor.assignment.v1"
++ },
++ "children": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "$ref": "#/components/schemas/actor.assignment.v1"
++ }
++ }
++ }
++ },
++ "actor.assignment.v1": {
++ "title": "ActorAssignment",
++ "description": "actor.assignment@1: one node of the tree of delegated work (plan §12). A node is a hand-off — a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. ID is the node; ROOT names the node whose BUDGET the whole tree spends, PARENT the node that handed this work over (null on a root) and DEPTH its distance from the root (0 on a root). ORIGIN says who started the line: a person (person), a routine or Watch trigger (routine), or work from outside Actor (outside). MODE is the hand-off's kind (work, consult, notify) and REPLY how its result comes back (resume into the parent, poll, or none). LEVEL is the node's own level and EFFECTIVE_LEVEL the level its steps run at: the higher of the agent's own level and the one inherited from a person's or routine's line. Outside work never passes a level down. BUDGET is the root's budget and what the tree has spent. A cancel cascades down the tree. GET /api/v1/assignments/:id returns { assignment, children } and POST /api/v1/assignments/:id/cancel returns { assignment, cancelled }; both are owner-only, and another person's node is the same 404 as one that does not exist. A task has no node until one is made for it: an existing task gets a root lazily.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "root",
++ "parent",
++ "depth",
++ "origin",
++ "mode",
++ "reply",
++ "agent_id",
++ "task_id",
++ "level",
++ "effective_level",
++ "budget",
++ "state",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "root": {
++ "type": "string",
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "parent": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^asg_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "depth": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "origin": {
++ "type": "string",
++ "enum": [
++ "person",
++ "routine",
++ "outside"
++ ]
++ },
++ "mode": {
++ "type": "string",
++ "enum": [
++ "work",
++ "consult",
++ "notify"
++ ]
++ },
++ "reply": {
++ "type": "string",
++ "enum": [
++ "resume",
++ "poll",
++ "none"
++ ]
++ },
++ "agent_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "task_id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^tsk_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "effective_level": {
++ "type": "string",
++ "enum": [
++ "ask",
++ "auto-edits",
++ "approve-for-me",
++ "full"
++ ]
++ },
++ "budget": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "The budget of the root of this tree, and what the tree has spent of it. Every node carries the same root budget.",
++ "required": [
++ "limit_usd",
++ "spent_usd",
++ "remaining_usd"
++ ],
++ "properties": {
++ "limit_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "spent_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "remaining_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "state": {
++ "type": "string",
++ "enum": [
++ "queued",
++ "running",
++ "waiting",
++ "succeeded",
++ "failed",
++ "cancelled"
++ ]
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "started_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ }
++ }
++ },
"actor.model-manage-request.v1": {
"title": "ActorModelManageRequest",
"description": "actor.model-manage-request@1: the body of PUT /api/v1/me/model on OpenVibe.Actor: { choice, model? }. choice is 'auto' (Actor decides, as before), 'openvibe' (OpenVibe's own keys, through OpenVibe.AI) or 'own:<provider>' (your own key for that provider: openai, anthropic, deepseek, google, openrouter or mistral). model is the model id you picked for it, or nothing: OpenVibe.AI then routes the call. The key itself never reaches Actor: it stays sealed in OpenVibe.AI. An unknown provider or a model id that is not one is 422 actor.model.invalid.",
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex c98889a1..19344f1a 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.327.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 7ce36a04..2279876c 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.327.0",
-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 61ea2609..107d4bf7 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.327.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 58b66ec4..5346dc90 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.327.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 ea2a8a04..8a3d28fc 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.327.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.328.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/chat.json b/generated/openapi/chat.json
iindex c809362b..f4abfcd9 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.327.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 d1986002..125c53a5 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.327.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 1a1145fb..5fcbdc5d 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.327.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.328.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/connect.json b/generated/openapi/connect.json
iindex fc5f67b2..1a0ece03 100644
---- a/generated/openapi/connect.json
++++ b/generated/openapi/connect.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe Connect API",
-- "version": "0.327.0",
-- "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 7d91f7f6..f421af77 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.327.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 1cf235aa..790a4fc7 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.327.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.328.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/design.json b/generated/openapi/design.json
iindex f5137bc7..e272794d 100644
---- a/generated/openapi/design.json
++++ b/generated/openapi/design.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Design API",
-- "version": "0.327.0",
-- "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 51ed729d..5cbe8a5d 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.327.0",
-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 57cd409a..dbc5b106 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.327.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 ce78f217..45d62a28 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.327.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 75bc4c96..c0e9f083 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.327.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 366959f6..9257a85e 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.327.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 f1156cc1..b8f94bc8 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -5,8 +5,8 @@
"service": "actor",
"name": "OpenVibe.Actor",
"origin": "https://openvibe.actor",
-- "operations": 49,
-- "capabilities": 14
++ "operations": 51,
++ "capabilities": 16
},
{
"service": "ai",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 2fad5b67..fc6ab373 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.327.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 286075af..4434c549 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.327.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 5c42243b..c5093823 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.327.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 eef0cfa5..db4d3dbc 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.327.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 40c58445..7f2b6723 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.327.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 34b32273..b8875fcd 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.327.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 aee0f12b..7d225ded 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.327.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 e5371222..1ca59dae 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.327.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 0ea04e26..fcd4e670 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.327.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 cbad4e3c..e9963eea 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.327.0",
-- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 aaec6381..bd6d9dfe 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.327.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 589f970a..e6511087 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.327.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 afa0de08..5852d986 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.327.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 105e2cf4..0b36a08b 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.327.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 032c1de6..bfde4ee7 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.327.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 096012e3..880f83e5 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.327.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 a4deced4..f43aa57c 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.327.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 aa71dc8c..877a4e03 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.327.0",
-- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 040f9628..b871c02c 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.327.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 c8ece2a0..b636d1b7 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.327.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 f1d459b6..c00b7f41 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.327.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 5f491c20..208504de 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.327.0",
-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 bda1a22a..f2e855ff 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.327.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 624acdb4..7464f89a 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.327.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 d191cbb1..190baa1f 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.327.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 5fded900..63ca7c2a 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.327.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.327.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.328.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.328.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 2c8b9d9e..efcb2f1a 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -265936,6 +265936,61 @@ export interface ActorTaskWebhook {
task: Task;
}
++/** [email protected] (owner: actor) */
++/**
++ * actor.assignment@1: one node of the tree of delegated work (plan §12). A node is a hand-off — a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. ID is the node; ROOT names the node whose BUDGET the whole tree spends, PARENT the node that handed this work over (null on a root) and DEPTH its distance from the root (0 on a root). ORIGIN says who started the line: a person (person), a routine or Watch trigger (routine), or work from outside Actor (outside). MODE is the hand-off's kind (work, consult, notify) and REPLY how its result comes back (resume into the parent, poll, or none). LEVEL is the node's own level and EFFECTIVE_LEVEL the level its steps run at: the higher of the agent's own level and the one inherited from a person's or routine's line. Outside work never passes a level down. BUDGET is the root's budget and what the tree has spent. A cancel cascades down the tree. GET /api/v1/assignments/:id returns { assignment, children } and POST /api/v1/assignments/:id/cancel returns { assignment, cancelled }; both are owner-only, and another person's node is the same 404 as one that does not exist. A task has no node until one is made for it: an existing task gets a root lazily.
++ */
++export interface ActorAssignment {
++ id: string;
++ root: string;
++ parent: string | null;
++ depth: number;
++ origin: "person" | "routine" | "outside";
++ mode: "work" | "consult" | "notify";
++ reply: "resume" | "poll" | "none";
++ agent_id: string | null;
++ task_id: string | null;
++ level: "ask" | "auto-edits" | "approve-for-me" | "full";
++ effective_level: "ask" | "auto-edits" | "approve-for-me" | "full";
++ /**
++ * The budget of the root of this tree, and what the tree has spent of it. Every node carries the same root budget.
++ */
++ budget: {
++ limit_usd: number;
++ spent_usd: number;
++ remaining_usd: number;
++ };
++ state: "queued" | "running" | "waiting" | "succeeded" | "failed" | "cancelled";
++ created_at: string;
++ updated_at: string;
++ started_at?: string | null;
++ ended_at?: string | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * actor.assignment-tree@1: GET /api/v1/assignments/:id (capability actor.assignment.read): the node and its direct children, oldest first. Each node is an actor.assignment@1. Only the owner can read the tree; another person gets 404.
++ */
++export interface ActorAssignmentTree {
++ assignment: ActorAssignment;
++ /**
++ * @maxItems 100
++ */
++ children: ActorAssignment[];
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * actor.assignment-cancel-result@1: POST /api/v1/assignments/:id/cancel (capability actor.assignment.cancel): the node as it is now and every node the cancel stopped, the node included and its children below it. The tasks those nodes ran are cancelled too. Only the owner can cancel; another person gets 404.
++ */
++export interface ActorAssignmentCancelResult {
++ assignment: ActorAssignment;
++ /**
++ * @maxItems 1000
++ */
++ cancelled: ActorAssignment[];
++}
++
/** [email protected] (owner: actor) */
/**
* actor.agent-list-result@1: GET /api/v1/agents (capability actor.agent.read): every agent system Actor can route a task to. KIND is the backend class (ADR-044): openvibe-runtime (OpenVibe's own agent, acting through OpenVibe services), agent-platform (another platform's agent, called through its API), open-model (an open model on OpenVibe's own hardware), codes (coding work through OpenVibe.Codes), node and run (a person's machine or OpenVibe.Run). TRUST is ADR-046's class; private mode takes only first-party ones. CAN are the task classes and tools it takes (task:<class>, tool:<name>). RATE_CARD is the published price, revised by review and never written by a model (SOURCE says where it comes from, VERIFIED_AT when a person last checked it). AVAILABLE says whether it can take a task now and REASON why not.
ddiff --git a/manifests/capabilities/actor.assignment.cancel.json b/manifests/capabilities/actor.assignment.cancel.json
nnew file mode 100644
iindex 00000000..b51c9622
---- /dev/null
++++ b/manifests/capabilities/actor.assignment.cancel.json
@@@ -0,0 +1,21 @@
++{
++ "id": "actor.assignment.cancel",
++ "version": "1.0",
++ "owner": "actor",
++ "status": "active",
++ "visibility": "public",
++ "description": "Cancel your assignment tree from one node down with POST /api/v1/assignments/:id/cancel: every child node is cancelled and every task still running under the tree is stopped. It answers the node and the nodes it cancelled. Only the person whose work it is can cancel it; another person gets the same 404 as a node that does not exist.",
++ "inputSchema": "common.no-body@1",
++ "permissions": [
++ "actor:assignments:cancel"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "actor-write",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/assignments/:id/cancel"
++ ],
++ "outputSchema": "actor.assignment-cancel-result@1"
++}
ddiff --git a/manifests/capabilities/actor.assignment.read.json b/manifests/capabilities/actor.assignment.read.json
nnew file mode 100644
iindex 00000000..b7f6dfff
---- /dev/null
++++ b/manifests/capabilities/actor.assignment.read.json
@@@ -0,0 +1,21 @@
++{
++ "id": "actor.assignment.read",
++ "version": "1.0",
++ "owner": "actor",
++ "status": "active",
++ "visibility": "public",
++ "description": "Read one node of your assignment tree and its children with GET /api/v1/assignments/:id (actor.assignment@1): the hand-off, who started it, its mode and reply, the agent and task it runs as, its level and effective level, the root's budget and the state. Only the person whose work it is can read it; another person gets the same 404 as a node that does not exist.",
++ "inputSchema": "common.no-body@1",
++ "permissions": [
++ "actor:assignments:read"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "actor-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/assignments/:id"
++ ],
++ "outputSchema": "actor.assignment-tree@1"
++}
ddiff --git a/manifests/services/actor.json b/manifests/services/actor.json
iindex d9452494..58e0c22d 100644
---- a/manifests/services/actor.json
++++ b/manifests/services/actor.json
@@@ -29,7 +29,9 @@
"actor.model.manage",
"actor.a2a.task",
"actor.config.manage",
-- "actor.timeline.read"
++ "actor.timeline.read",
++ "actor.assignment.read",
++ "actor.assignment.cancel"
],
"eventsProduced": [
"agent.step.started",
ddiff --git a/package-lock.json b/package-lock.json
iindex 53806bf0..135cfb7e 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.327.0",
++ "version": "0.328.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.327.0",
++ "version": "0.328.0",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex fb7f9a39..59230c50 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.327.0",
++ "version": "0.328.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",