CodesSandboxSession codes.sandbox-session@1
Generated at from
openvibe-contracts v0.419.0 and
openvibe-sdk v0.161.0.
- Version
- 1.0.0
- Owner
- codes
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/codes/sandbox-session.v1.json
codes.sandbox-session@1 (the Agent Streams plan, S6): the sandbox desk a chat plays session runs on. The desk is started with `--shared`: no profile, no keys, no person's files, public egress only (no private address is reachable) and a fresh workspace, and it is wiped at the end of the session. The owner sets the time box (5 to 30 minutes) and the cap (money and minutes), and arms the session with Go before the first request may run. The scratch site is a throwaway OpenVibe.Space address that is removed after 24 hours unless the owner keeps it.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
session_id | string | yes | The sandbox session's id (ULID, Crockford base32). |
|
task | object | yes | The task the desk is running for the queue. |
|
task.id | string | yes | The task's id in Codes. |
|
task.title | string | yes |
| |
owner | string | yes | The person the session spends their own allowance for. |
|
state | enum | yes | Where the desk stands: idle (nothing yet), armed (the owner pressed Go, the first request may run), running, paused, wiped (Wipe now reset the sandbox) or ended. |
|
time_box_minutes | integer | yes | How long one request may run, in minutes (the owner sets 5 to 30; the default is 10). |
|
step_budget | integer | yes | How many steps one request may take. |
|
cap | object | yes | The owner's cap for the session: the money and the minutes it may spend. When it is spent, the queue closes. |
|
cap.money_cents | integer | yes | The cap in cents. |
|
cap.minutes | integer | yes | The cap in minutes of work. |
|
spend | object | yes | What the session has spent so far. |
|
spend.money_cents | integer | yes |
| |
spend.seconds | integer | yes |
| |
spend.steps | integer | yes |
| |
armed | boolean | yes | Whether the owner pressed Go. The first request of a session waits for it. | |
armed_at | string | null | When the owner pressed Go. |
| |
started_at | string | null |
| ||
ended_at | string | null |
| ||
wiped_at | string | null | When Wipe now reset the sandbox. |
| |
egress_public_only | const | yes | Always true: the sandbox reaches public addresses only, and no private address is reachable. |
|
scratch_site | object | null | The throwaway site the run left, or null before the first one. |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: armed
{
"session_id": "sbs_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"title": "Chat plays"
},
"owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"state": "armed",
"time_box_minutes": 10,
"step_budget": 40,
"cap": {
"money_cents": 500,
"minutes": 30
},
"spend": {
"money_cents": 0,
"seconds": 0,
"steps": 0
},
"armed": true,
"armed_at": "2026-11-06T20:00:00.000Z",
"started_at": null,
"ended_at": null,
"wiped_at": null,
"egress_public_only": true,
"scratch_site": null
}Valid: running
{
"session_id": "sbs_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"title": "Chat plays"
},
"owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"state": "running",
"time_box_minutes": 10,
"step_budget": 40,
"cap": {
"money_cents": 500,
"minutes": 30
},
"spend": {
"money_cents": 42,
"seconds": 180,
"steps": 6
},
"armed": true,
"armed_at": "2026-11-06T20:00:00.000Z",
"started_at": "2026-11-06T20:01:00.000Z",
"ended_at": null,
"wiped_at": null,
"egress_public_only": true,
"scratch_site": {
"url": "https://scratch.openvibe.space/snake-4f2a",
"expires_at": "2026-11-07T20:01:00.000Z",
"kept": false
}
}Rejected: egress-not-public-only
{
"session_id": "sbs_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"title": "Chat plays"
},
"owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"state": "armed",
"time_box_minutes": 10,
"step_budget": 40,
"cap": {
"money_cents": 500,
"minutes": 30
},
"spend": {
"money_cents": 0,
"seconds": 0,
"steps": 0
},
"armed": true,
"armed_at": "2026-11-06T20:00:00.000Z",
"started_at": null,
"ended_at": null,
"wiped_at": null,
"egress_public_only": false,
"scratch_site": null
}Rejected: no-cap
{
"session_id": "sbs_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"title": "Chat plays"
},
"owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"state": "armed",
"time_box_minutes": 10,
"step_budget": 40,
"spend": {
"money_cents": 0,
"seconds": 0,
"steps": 0
},
"armed": true,
"armed_at": "2026-11-06T20:00:00.000Z",
"started_at": null,
"ended_at": null,
"wiped_at": null,
"egress_public_only": true,
"scratch_site": null
}Rejected: time-box-out-of-range
{
"session_id": "sbs_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"title": "Chat plays"
},
"owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"state": "armed",
"time_box_minutes": 2,
"step_budget": 40,
"cap": {
"money_cents": 500,
"minutes": 30
},
"spend": {
"money_cents": 0,
"seconds": 0,
"steps": 0
},
"armed": true,
"armed_at": "2026-11-06T20:00:00.000Z",
"started_at": null,
"ended_at": null,
"wiped_at": null,
"egress_public_only": true,
"scratch_site": null
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('codes.sandbox-session@1', value); // { valid, errors: [{ path, message }] }