---
title: "actor.assignment@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/actor.assignment"
updated: null
---

# actor.assignment@1 · OpenVibe.Services

HTML: [actor.assignment@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/actor.assignment)

# ActorAssignment `actor.assignment@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: actor
- Visibility: public
- Status: active
- Compatibility: backward
- Decision: [ADR-044](/docs/adr/ADR-044)
- Schema: [`https://openvibe.network/contracts/actor/assignment.v1.json`](/docs/contracts/actor.assignment.json)

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.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `id` | string | yes |  | - `pattern ^asg_[0-9A-HJKMNP-TV-Z]{26}$` |
| `root` | string | yes |  | - `pattern ^asg_[0-9A-HJKMNP-TV-Z]{26}$` |
| `parent` | string \| null | yes |  | - `pattern ^asg_[0-9A-HJKMNP-TV-Z]{26}$` |
| `depth` | integer | yes |  | - `minimum 0` |
| `origin` | enum | yes |  | - `one of "person", "routine", "outside"` |
| `mode` | enum | yes |  | - `one of "work", "consult", "notify"` |
| `reply` | enum | yes |  | - `one of "resume", "poll", "none"` |
| `agent_id` | string \| null | yes |  | - `pattern ^agt_[0-9A-HJKMNP-TV-Z]{26}$` |
| `task_id` | string \| null | yes |  | - `pattern ^tsk_[0-9A-HJKMNP-TV-Z]{26}$` |
| `level` | enum | yes |  | - `one of "ask", "auto-edits", "approve-for-me", "full"` |
| `effective_level` | enum | yes |  | - `one of "ask", "auto-edits", "approve-for-me", "full"` |
| `budget` | object | yes | The budget of the root of this tree, and what the tree has spent of it. Every node carries the same root budget. | - `no other fields` |
| `budget.limit_usd` | number | yes |  | - `minimum 0` |
| `budget.spent_usd` | number | yes |  | - `minimum 0` |
| `budget.remaining_usd` | number | yes |  | - `minimum 0` |
| `state` | enum | yes |  | - `one of "queued", "running", "waiting", "succeeded", "failed", "cancelled"` |
| `created_at` | string | yes |  | - `format date-time` |
| `updated_at` | string | yes |  | - `format date-time` |
| `started_at` | string \| null |  |  | - `format date-time` |
| `ended_at` | string \| null |  |  | - `format date-time` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: child

~~~~
{
  "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"
}
~~~~

Valid: outside-done

~~~~
{
  "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"
}
~~~~

Valid: root

~~~~
{
  "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
}
~~~~

Rejected: bad-origin

~~~~
{
  "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"
}
~~~~

Rejected: bad-state

~~~~
{
  "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"
}
~~~~

Rejected: missing-budget

~~~~
{
  "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"
}
~~~~

Rejected: negative-depth

~~~~
{
  "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"
}
~~~~

Rejected: unknown-field

~~~~
{
  "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"
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('actor.assignment@1', value);   // { valid, errors: [{ path, message }] }
~~~~
