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

FieldTypeRequiredDescriptionConstraints
session_idstringyesThe sandbox session's id (ULID, Crockford base32).
  • pattern ^sbs_[0-9A-HJKMNP-TV-Z]{26}$
taskobjectyesThe task the desk is running for the queue.
  • no other fields
task.idstringyesThe task's id in Codes.
  • minLength 1
  • maxLength 200
task.titlestringyes
  • minLength 1
  • maxLength 200
ownerstringyesThe person the session spends their own allowance for.
  • pattern ^usr_[0-9A-HJKMNP-TV-Z]{26}$
stateenumyesWhere 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.
  • one of "idle", "armed", "running", "paused", "wiped", "ended"
time_box_minutesintegeryesHow long one request may run, in minutes (the owner sets 5 to 30; the default is 10).
  • minimum 5
  • maximum 30
step_budgetintegeryesHow many steps one request may take.
  • minimum 1
capobjectyesThe owner's cap for the session: the money and the minutes it may spend. When it is spent, the queue closes.
  • no other fields
cap.money_centsintegeryesThe cap in cents.
  • minimum 0
cap.minutesintegeryesThe cap in minutes of work.
  • minimum 1
spendobjectyesWhat the session has spent so far.
  • no other fields
spend.money_centsintegeryes
  • minimum 0
spend.secondsintegeryes
  • minimum 0
spend.stepsintegeryes
  • minimum 0
armedbooleanyesWhether the owner pressed Go. The first request of a session waits for it.
armed_atstring | nullWhen the owner pressed Go.
  • format date-time
started_atstring | null
  • format date-time
ended_atstring | null
  • format date-time
wiped_atstring | nullWhen Wipe now reset the sandbox.
  • format date-time
egress_public_onlyconstyesAlways true: the sandbox reaches public addresses only, and no private address is reachable.
  • = true
scratch_siteobject | nullThe 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 }] }