Session
The session object every lifecycle method returns or lists.
Additive-optional evolution applies: clients must ignore unknown fields.
Fields and variants
Section titled “Fields and variants”activeTurnIdapprovalModeattentionbranchcreatedAtcreatedByClientfirstUserPromptforkedFromgeneratedNamekindlastActivityAtmodelIdnamenameOriginparentSessionIdpathpermissionState— ExperimentalproviderIdsessionIdsideFromstatustitleturnCountupdatedAtworkspaceRootworktree— 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, per the owner ruling**. Both\nproduction writers hard-code `\"activeTurnId\": null` and nothing\nstrips it, so this is what the binary emits and what the protocol's example\nspells. The optional-absent shape published it as plain `string` and\nREJECTED every idle `Session` frame the host sent — the defect\nclass this PR exists to close.\n\nThe ruling's original evidence for optional-absent (\"every committed\ntranscript shows the omission\") was wrong: those transcripts are\nhand-authored fixtures, not host recordings. They are corrected in the\nsame change under the ruling's `regenerationJustification`.", "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." }, "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" }, "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" }, "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 four-field `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" }, "providerId": { "description": "The winning metadata fold's provider; `null` when that record omits it.", "type": [ "string", "null" ] }, "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`." }, "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": "and origin only.\n**Experimental** (`Session.worktree`; stripped per-connection for\nunopted callers). Omitted when the session runs in no worktree.", "x-msp-descriptor": "Session.worktree", "x-msp-stability": "experimental" } }, "required": [ "activeTurnId", "createdAt", "forkedFrom", "modelId", "path", "providerId", "sessionId", "status", "turnCount", "updatedAt", "workspaceRoot" ], "type": "object"}