Skip to content
Developer Preview

Session

The session object every lifecycle method returns or lists.

Additive-optional evolution applies: clients must ignore unknown fields.

  • activeTurnId
  • approvalMode
  • attention
  • branch
  • createdAt
  • createdByClient
  • currentLimits — Experimental
  • driveHolder
  • firstUserPrompt
  • forkedFrom
  • generatedName
  • itemCount
  • kind
  • lastActivityAt
  • logBytes
  • modelId
  • name
  • nameOrigin
  • parentSessionId
  • path
  • permissionState — Experimental
  • probeDegradedReason
  • providerId
  • quiescent — Experimental
  • resumedByClient
  • runningElsewhere — Experimental
  • sessionId
  • sideFrom
  • spawnedBy
  • status
  • title
  • turnCount
  • updatedAt
  • workspaceRoot
  • worktree — Experimental
Source

schema/msp/experimental/msp.schema.json#/types/Session

{
"description": "The session object every lifecycle method returns or lists.\n\nAdditive-optional evolution applies: clients must ignore unknown fields.",
"properties": {
"activeTurnId": {
"description": "The `turnId` of the current foreground turn when `status` is\n`running`, and `null` when the session is idle.\n\n**Required-nullable.** Every served `Session` carries the member: `null`\nwhen the session is idle or not loaded, the turn id when it is running.\nAn optional-absent shape would publish it as plain `string` and reject\nevery idle `Session` frame the host sends.",
"type": [
"string",
"null"
]
},
"approvalMode": {
"$ref": "#/$defs/EffectiveApprovalModeState",
"description": "The folded effective approval mode. **Additive-optional**: a Session\nobject that omits it means the host has not folded a mode, which is\nwhy the index-derived `session/list` entry may legitimately omit it."
},
"attention": {
"description": "Attention flags. **Additive-optional**,\npresent only when at least one flag is set; absence is a\nNON-assertion (nothing pending, or the loaded session's pending\nsource declined to answer). Loaded sessions only: a `notLoaded` row\nomits it even while its durable pending set is non-empty.",
"items": {
"$ref": "#/$defs/AttentionFlag"
},
"type": "array"
},
"branch": {
"description": "Derived workspace branch — the index's last\nderived value; the live-change signal stays `session/branchChanged`. **Additive-optional**, omitted when underivable.",
"type": "string"
},
"createdAt": {
"description": "RFC3339. For a fork this is the fork session id's UUIDv7 mint instant.",
"type": "string"
},
"createdByClient": {
"$ref": "#/$defs/ClientInfo",
"description": "The handshake `ClientInfo` recorded when the session was opened, echoed verbatim — provenance, never an interpretation, and\nnever a visibility gate. **Additive-optional**; absence has\nfour indistinguishable causes: an in-process open; a\nprevious record; a half stamp where only one of name/version was\nrecorded and `ClientInfo` requires both; and a session with\nno admitting handshake of its own — a fork child or a subagent —\nwhich never carries a stamp to begin with."
},
"currentLimits": {
"$ref": "#/$defs/SessionLimits",
"description": "This session's effective limits: the clamp output — each axis the session chose clamps\nits durable stored choice (the clamp input) to the live ceiling, and\nan axis it never chose reads the daemon default: untrusted unless the\ndaemon serves trusted by default, and the daemon's own posture on the\nsandbox axes, except that a resume over a sandbox-off posture can keep\na recorded sandbox on, and a `session/fork` or `session/sideChat` child\nstarts with its parent's recorded shell, write and sandbox limits,\nclamped to the live ceiling. A sandbox kept on this way\nover a sandbox-off posture runs its recorded network, or `restricted`\nwhen none was recorded, while is open. These are the limits the session\nruns with.\n**Experimental, same-user socket only** (`Session.currentLimits`;\nstripped per-connection for unopted callers). Loaded sessions only\n(`notLoaded` rows and hosts with no limits regime omit it) — absent\nis never fabricated.",
"x-msp-descriptor": "Session.currentLimits",
"x-msp-stability": "experimental"
},
"driveHolder": {
"$ref": "#/$defs/ClientInfo",
"description": "The handshake `ClientInfo` of the connection that currently holds\nthis session's drive grant, served on `session/read` only, as `name`\nand `version` (the handshake's\ndisplay `title` is never served, the `createdByClient` rule).\n**Additive-optional, loaded-only, live**:\npresent exactly when a live connection holds the grant and its\nhandshake is known; absent on `notLoaded` rows, once the holder's\nconnection drops (its orphaned turn included), and for a holder with\nno handshake stamp. Provenance only: whether a client may drive is answered by\n`session/resume` / `turn/start` (`sessionInUse`), never by this\nmember."
},
"firstUserPrompt": {
"description": "Derived first-user-prompt preview.\n**Additive-optional**, omitted when underivable.",
"type": "string"
},
"forkedFrom": {
"anyOf": [
{
"$ref": "#/$defs/ForkProvenance"
},
{
"type": "null"
}
],
"description": "`null` for root sessions; fork provenance otherwise."
},
"generatedName": {
"description": "The served generated short title. **Additive-optional**, **fold-only**: the\nsnapshot fold derives the latest retained generated pair's short\ntitle from the log; `session/list` rows never carry it. Omitted when\nno pair was ever published — absent reads as unpublished, never\nfabricated, never inferred from the name text. `name` stays the\ncanonical name it always was.",
"type": "string"
},
"itemCount": {
"description": "The published head's ordinal (kt-dvw5): the head reference's own\nordinal — the count of head slots in its sequence, including any\nreserved ones — as of the probe that served this row. A sizing\nhint for a first `view/page`, so the Console can size its page\nwithout folding the log. **Additive-optional**, present only on\nmetadata reads (`session/read` with `excludeItems`), where the\nclient has no items to count; full reads carry the items\nthemselves and omit it. Absent when no head is published (unknown),\nnever fabricated. May lag a live log: the head is a snapshot, and\nappends after its publication are not counted.",
"type": "integer"
},
"kind": {
"$ref": "#/$defs/SessionKind",
"description": "What kind of session this is.\n**Open enum**, v1 values `\"root\"` and `\"subagent\"`; a client treats an\nunknown value as an unknown-but-present kind and renders it, never\nrejecting the row. **Additive-optional**: absence asserts nothing —\nthe host could not determine the home shape, or the value is\nnot yet available to serve."
},
"lastActivityAt": {
"description": "Content-activity recency, RFC3339.\n**Additive-optional**: omitted when no content record exists. Never\nadvanced by lifecycle bookkeeping (the resume marker, re-stamps) or\na fork's copied seed-replay records, and never precedes `createdAt`.",
"type": "string"
},
"logBytes": {
"description": "The durable log's byte length at read time (kt-dvw5): the size hint\npaired with `itemCount`, so the Console can size its first page\nwithout folding the log. **Additive-optional**, present only on\nmetadata reads (`session/read` with `excludeItems`); full reads omit\nit. Absent when the log's length is not known (unknown), never\nfabricated. A live log grows after the read; the value is a snapshot.",
"type": "integer"
},
"modelId": {
"description": "The winning metadata fold's model; `null` when that record omits it.",
"type": [
"string",
"null"
]
},
"name": {
"description": "The durable allocated session name. **Additive-optional**: present when the serving path\nholds an allocated name, omitted otherwise — absent is never\nfabricated. Authoritative and renameable via `session/rename`.",
"type": "string"
},
"nameOrigin": {
"$ref": "#/$defs/SessionNameOrigin",
"description": "How the served `name` was set. **Additive-optional**, **fold-only**: the snapshot fold\n(`session/read`, the resume/start/fork-ack snapshot) derives and\ncarries it from the log; `session/list` rows never carry it. Absent —\nand any value the client does not recognize — reads as unknown,\nnever fabricated."
},
"parentSessionId": {
"description": "The containing session's id when `kind` is `\"subagent\"` — the id of the TOP-LEVEL session whose home holds this\nchild, which is **not necessarily the session that spawned it**:\nnative-child homes are physical siblings under the outer session's\n`subagent/` directory, so a subagent spawned by another subagent\nresolves to the outer session, not to its spawner. A client building\na tree from this field gets one level, not a chain.\nFlat rather than nested: there is exactly one fact to\ncarry, unlike `forkedFrom`'s structured `ForkProvenance`.\n**Additive-optional**; a root carries none.",
"type": "string"
},
"path": {
"description": "Absolute path of the session's durable log; non-nullable. Under the\nephemeral session profile it is the **empty string**, meaning \"no\ndurable log exists\" — the one value a client must not\nhand to a filesystem call.",
"type": "string"
},
"permissionState": {
"$ref": "#/$defs/EffectivePermissionState",
"description": "The folded effective permission state. **Additive-optional**: a `\"notLoaded\"` row omits it\n(no live evidence, matching the `attention` precedent) and an\nolder host omits it everywhere; absent is unknown, never active. `approvalMode` stays the effective-mode answer;\nthis never restates it.",
"x-msp-descriptor": "Session.permissionState",
"x-msp-stability": "experimental"
},
"probeDegradedReason": {
"$ref": "#/$defs/ProbeDegradedReason",
"description": "Why the workspace status probe produced no fresh reading — the index's last derived value, like `branch`, so the TUI\ncan show WHY status is unavailable instead of a generic unavailable.\n**Additive-optional**, omitted when the latest probed observation\ncarries no reason or none exists. **Open enum**: a client treats an\nunknown-but-present reason and renders it, never rejecting the row."
},
"providerId": {
"description": "The winning metadata fold's provider; `null` when that record omits it.",
"type": [
"string",
"null"
]
},
"quiescent": {
"description": "Whether the answering host holds no live work for this loaded\nsession: the held predicate the host's idle unload and\nupgrade drain use, over the pending answer `attention` reads. `true`\nwhen it finds no run in flight or finishing its post-run work, no\nowned background task or live background process, no background\ncompletion waiting to wake the session, no session-name or\ngoal-recovery work, and no pending approval, user-input or admission\nrequest; `false` while any is held or a read cannot prove it absent.\n**Experimental** (`Session.quiescent`; stripped per-connection for\nunopted callers) and **loaded-only**: carried by `session/read`,\n`session/list` rows, the `session/resume` result and the\n`session/listChanged` frames built from the same row. A run or a\npending request starting pushes a frame carrying `false`; other held\nwork (session-name maintenance, a leave in progress) shows on the\nnext read. A session served `false` is rechecked about once a second\nand its frame is pushed once it reads `true`. Absent on `notLoaded`\nrows, on a host whose `session_quiescent_witness` gate is off, and\nfor a session with no live pending-request source: absence asserts\nnothing.",
"type": "boolean",
"x-msp-descriptor": "Session.quiescent",
"x-msp-stability": "experimental"
},
"resumedByClient": {
"$ref": "#/$defs/ClientInfo",
"description": "The handshake `ClientInfo` of the connection whose wire\n`session/resume` most recently loaded this session: stamped on the durable `session.resumed`\nmarker, folded into the session index, and served from that column by\nevery carrier; while the session is loaded, the stamp the loading\nresume wrote replaces the column on every carrier (the ack,\n`session/read`, `session/list`, `session/listChanged`), and after the\nnext fold the column serves it. **Additive-optional** and\n**provenance only**; a resume with no admitting handshake\n(TUI, exec) stamps nothing, a warm attach to an already-loaded session\nwrites no marker, and a half stamp serves nothing, so\nabsence asserts nothing. `createdByClient` never follows a resume."
},
"runningElsewhere": {
"$ref": "#/$defs/RunningElsewhere",
"description": "That another live process on this machine runs this session, and\nwhich kind of process when the host can tell (ADR 69811 D5).\n**Experimental** (`Session.runningElsewhere`; stripped per-connection\nfor unopted callers), on `session/list` rows and the\n`session/listChanged` frames built from the same row. No frame is\npushed when only this member changes; a client sees the change on its\nnext `session/list` or on a frame sent for another reason. Present exactly\nwhen the answering host does not hold the session loaded and another\nlive process on this machine does (it holds the session's writer\nlease, or a live local session registry record names the session),\nso only `notLoaded` rows carry it. Absence asserts only that the host\nsaw no other holder when it built the row. Provenance only: whether a\nclient may drive is answered by `session/resume` / `turn/start`\n(`sessionInUse`), never by this member.",
"x-msp-descriptor": "Session.runningElsewhere",
"x-msp-stability": "experimental"
},
"sessionId": {
"description": "The session identity.",
"type": "string"
},
"sideFrom": {
"anyOf": [
{
"$ref": "#/$defs/SideProvenance"
},
{
"type": "null"
}
],
"description": "`null` for root sessions and forks; side provenance otherwise. A session carries at most one of\n`forkedFrom` and `sideFrom`."
},
"spawnedBy": {
"$ref": "#/$defs/SessionSpawnedBy",
"description": "The session that opened this one, recorded once in this session's creation record and served from\nthe session index. Unlike the containing session `parentSessionId`\nnames above, its `parentSessionId` is the exact spawner, except that\nany `muse` started in a later pane of the worker's tmux session or\nHerdr workspace names the worker's manager and carries the worker's\n`project`/`thread` labels (ADR 69621 D8); `project` and `thread` are\nopaque labels the spawner may name beside it.\n**Additive-optional** and **provenance only**: never a\nvisibility or authority gate. Absence asserts nothing — no recorded\nspawner, a later session of the spawned process, a row folded before\nthe member existed, or a session the index has not folded yet."
},
"status": {
"$ref": "#/$defs/SessionStatus",
"description": "Load state as this host knows it; `session/list` reports `notLoaded`\nfor sessions loaded by *other* hosts."
},
"title": {
"description": "Derived display title: a heuristic that may\nevolve — its carriage, not its derivation, is the contract.\n**Additive-optional**, omitted when underivable.",
"type": "string"
},
"turnCount": {
"description": "Completed-turn count from the session view fold.",
"type": "integer"
},
"updatedAt": {
"description": "RFC3339; never precedes `createdAt`.",
"type": "string"
},
"workspaceRoot": {
"description": "The winning metadata fold's workspace root; `null` when that record\nomits it — absent is never fabricated.",
"type": [
"string",
"null"
]
},
"worktree": {
"$ref": "#/$defs/SessionWorktree",
"description": "The worktree this session runs in — path and origin only (the branch\nstays in `branch`). **Experimental** (`Session.worktree`; stripped\nper-connection for unopted callers). Omitted when the session runs in no\nworktree.",
"x-msp-descriptor": "Session.worktree",
"x-msp-stability": "experimental"
}
},
"required": [
"activeTurnId",
"createdAt",
"forkedFrom",
"modelId",
"path",
"providerId",
"sessionId",
"status",
"turnCount",
"updatedAt",
"workspaceRoot"
],
"type": "object"
}