{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/ishlabs-io/json-schema/ishlabs-io-create-session-request-schema.json",
  "title": "CreateSessionRequest",
  "x-generated": "2026-11-13",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/ishlabs-io-openapi.json#/components/schemas/CreateSessionRequest",
  "additionalProperties": false,
  "properties": {
    "decision_mode": {
      "$ref": "#/$defs/DecisionMode",
      "default": "intent"
    },
    "environment": {
      "anyOf": [
        {
          "$ref": "#/$defs/EnvironmentDescriptor"
        },
        {
          "type": "null"
        }
      ],
      "description": "An ad-hoc environment described inline. Mutually exclusive with `environment_id`; supply exactly one."
    },
    "environment_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "A registered environment in this workspace. Mutually exclusive with `environment`; supply exactly one.",
      "title": "Environment Id"
    },
    "environment_version": {
      "anyOf": [
        {
          "maxLength": 120,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Pin this session to a declared version of the registered environment, by label (case-insensitive; the canonical label is recorded). Requires `environment_id`. Omit to use the environment's default version, or to run unversioned when it has none. An unknown label is a 404, never a new bucket.",
      "title": "Environment Version"
    },
    "max_turns": {
      "default": 50,
      "maximum": 200,
      "minimum": 1,
      "title": "Max Turns",
      "type": "integer"
    },
    "observation_retention": {
      "anyOf": [
        {
          "$ref": "#/$defs/ObservationRetention"
        },
        {
          "type": "null"
        }
      ],
      "description": "How long this session's observation frames are retained: `none` (discard after the turn), `30d`, `90d`, or `indefinite`. Omit to inherit the registered environment's setting; an inline environment descriptor defaults to `none`. Resolved once at open and fixed for the session's lifetime. Open union: new values may be added over time; clients must tolerate unknown values rather than failing on them."
    },
    "pacing": {
      "$ref": "#/$defs/PacingContract"
    },
    "person_id": {
      "format": "uuid",
      "title": "Person Id",
      "type": "string"
    },
    "reasoning_effort": {
      "default": "low",
      "enum": [
        "low",
        "medium",
        "high"
      ],
      "title": "Reasoning Effort",
      "type": "string"
    },
    "resolver_guidance": {
      "anyOf": [
        {
          "maxLength": 8000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Resolver Guidance"
    },
    "task": {
      "anyOf": [
        {
          "$ref": "#/$defs/TaskRef"
        },
        {
          "$ref": "#/$defs/TaskDescriptor"
        }
      ],
      "description": "The session's intent: `{instructions}` describes it inline, `{id}` binds a registered task (its instructions are frozen onto the session). Supply exactly one shape.",
      "title": "Task"
    }
  },
  "required": [
    "person_id",
    "task",
    "pacing"
  ],
  "type": "object",
  "$defs": {
    "DecisionMode": {
      "enum": [
        "direct",
        "intent"
      ],
      "title": "DecisionMode",
      "type": "string"
    },
    "EnvironmentDescriptor": {
      "description": "An ad-hoc environment, described inline on the session that uses it.\n\nAlso the shape of the FROZEN SNAPSHOT a session carries after it was opened\nagainst a REGISTERED environment (`environment_id`), so `kind` means the\nsame thing on both paths and on the environments surface: one noun for one\nconcept, rather than a wire that says `platform` where the registry says\n`kind`.",
      "properties": {
        "kind": {
          "description": "The kind of surface (e.g. `web`, `device`, `world`). Open union: new values may be added over time; clients must tolerate unknown values rather than failing on them.",
          "maxLength": 40,
          "minLength": 1,
          "title": "Kind",
          "type": "string"
        },
        "name": {
          "maxLength": 120,
          "minLength": 1,
          "title": "Name",
          "type": "string"
        }
      },
      "required": [
        "name",
        "kind"
      ],
      "title": "EnvironmentDescriptor",
      "type": "object"
    },
    "ObservationRetention": {
      "description": "How long a session's observation frames are kept: `none` (discarded after the turn), `30d`, `90d`, or `indefinite`.\n\nOne field rather than a flag beside a window, so the incoherent pair (off, 90 days) cannot be expressed. Resolved once when the session opens, from the session's own value or the registered environment's default, and fixed for that session's lifetime: editing the environment later never changes what an open session promised.\n\nOpen union: new windows may be added over time; clients must tolerate unknown values rather than failing on them.",
      "enum": [
        "none",
        "30d",
        "90d",
        "indefinite"
      ],
      "title": "ObservationRetention",
      "type": "string"
    },
    "PacingContract": {
      "enum": [
        "pause_on_decide",
        "frame_on_demand",
        "free_running"
      ],
      "title": "PacingContract",
      "type": "string"
    },
    "TaskDescriptor": {
      "additionalProperties": false,
      "description": "A task described inline on the session that uses it.\n\nInstructions only, by design: on this lane your code executes the actions, so verification steps in the create body would hand the answer key to the process being measured. Register a task to attach steps.",
      "properties": {
        "instructions": {
          "description": "What the person is trying to do, in their own terms. Rendered into their prompt as the situation paragraph.",
          "maxLength": 2000,
          "minLength": 1,
          "title": "Instructions",
          "type": "string"
        }
      },
      "required": [
        "instructions"
      ],
      "title": "TaskDescriptor",
      "type": "object"
    },
    "TaskRef": {
      "additionalProperties": false,
      "description": "A registered task in this workspace, bound by id.",
      "properties": {
        "id": {
          "description": "A registered task. Its instructions are frozen onto the session at create; later edits to the registry row never touch this session.",
          "format": "uuid",
          "title": "Id",
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "title": "TaskRef",
      "type": "object"
    }
  }
}