@sema-agent/sdk 21.1.0 → 22.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/openapi.yaml CHANGED
@@ -881,6 +881,7 @@ paths:
881
881
  schema:
882
882
  type: object
883
883
  required: [text]
884
+ additionalProperties: false
884
885
  properties:
885
886
  text: { type: string, description: 'The steering direction (untrusted DATA; the server fences it).' }
886
887
  priority:
@@ -1067,7 +1068,7 @@ paths:
1067
1068
  schema:
1068
1069
  type: object
1069
1070
  # text 形对多余键宽容(冻结契约,steer 同族);bare 形零键纪律由 400 执法(见下)。
1070
- additionalProperties: true
1071
+ additionalProperties: false
1071
1072
  properties:
1072
1073
  text:
1073
1074
  type: string
@@ -1184,6 +1185,7 @@ paths:
1184
1185
  schema:
1185
1186
  type: object
1186
1187
  required: [content]
1188
+ additionalProperties: false
1187
1189
  properties:
1188
1190
  content: { type: string, description: 'The message for the subagent (untrusted DATA; the server fences it — same framing as the workflow-agent steer).' }
1189
1191
  responses:
@@ -5991,6 +5993,7 @@ paths:
5991
5993
  schema:
5992
5994
  type: object
5993
5995
  required: [content]
5996
+ additionalProperties: false
5994
5997
  properties:
5995
5998
  content: { type: string, minLength: 1 }
5996
5999
  responses:
@@ -7414,11 +7417,12 @@ components:
7414
7417
  `acceptEdits` (in-workspace writes do not ask) or `bypassPermissions` (422 `request.host_posture_refused` on hosted
7415
7418
  deployments) for the old no-ask posture. `auto` arms iff `permissionMode === "auto"` ∧ a classifier seat is mounted ∧
7416
7419
  `caps.autoMode !== false` (one polarity); when the requested mode does not take effect the stream gets `engine_notice`
7417
- `config.permission_mode_unavailable`. `bypassPermissions` RELEASES the ten releasable ask classes (server >= 7.115.0: the tenth is `unstated`, a server-tool call nobody stated)
7420
+ `config.permission_mode_unavailable`. `bypassPermissions` RELEASES the releasable ask classes (nine on every face from server >= 7.127.0; ten on
7421
+ server 7.115.0–7.126.x, where the extra one is `rule_unreadable`; `unstated`, a server-tool call nobody stated, is releasable from server >= 7.115.0)
7418
7422
  and DISCLOSES each (`tool_end.gate.disposition.released` + one `engine_notice` `permission.ask_released_by_mode` per (mode, class) per run);
7419
7423
  immune classes (deployment-authored, ask / org rules, hooks, ancestors, questions …) still ask; a write whose protection
7420
7424
  cannot be judged is refused (`deniedBy: mode`) on the file tools — and, from server >= 7.122.0 / core 7.47.0, RELEASED on the SHELL face
7421
- (an eleventh class, `write_protection_unresolved`, for a caller-supplied tool whose wire name is exactly `Bash` or `Monitor` and which
7425
+ (the class the shell face adds, `target_unresolved` from server >= 7.126.0 — the previous spelling on 7.122.0–7.125.x — for a caller-supplied tool whose wire name is exactly `Bash` or `Monitor` and which
7422
7426
  declares a write-path target; see `ModeRelease.reason`). `plan` (server >= 7.122.0): the engine's plan mode and nothing the service adds —
7423
7427
  the tool table equals `default`'s, the engine mounts the plan-presenting tool, and a write or any non-read-only call is asked AT CALL TIME by the
7424
7428
  engine's plan gate (a card where somebody can answer, a refusal where nobody can; a delegated sub-agent inherits plan as its ceiling); up to
@@ -8008,6 +8012,75 @@ components:
8008
8012
  blocked: '#/components/schemas/TerminalCause_blocked'
8009
8013
  paused: '#/components/schemas/PausedCause'
8010
8014
 
8015
+ ToolOutput:
8016
+ description: >
8017
+ The two shapes of a tool's model-facing body (`Event_tool_end.output`, the turns face `tool-result.output`, the trace stream
8018
+ `tool-result.data.output` — one schema, three faces): a STRING (a string result; over the core text cap it is cut and ends with
8019
+ `…[+N chars truncated]`) or an ARRAY of `ToolOutputBlock` (each block keeps its slot). Handle both. Only the core tool contract
8020
+ is described — a third-party tool that returns content outside it (a body that is neither, a block outside the contract) is
8021
+ the tool's breach, not a third wire shape.
8022
+ oneOf:
8023
+ - type: string
8024
+ - type: array
8025
+ items: { $ref: '#/components/schemas/ToolOutputBlock' }
8026
+
8027
+ ToolOutputBlock:
8028
+ description: >
8029
+ One block of an array-shaped `ToolOutput` (core 7.50.0 `tool_end` output note). Closed, four arms: text; an admitted image /
8030
+ document with its base64 `data`; that same media block's DESCRIPTOR when it did not travel on this face (`{ type, mimeType?,
8031
+ bytes, truncated: true }` — `bytes` = decoded size, a media type over 255 characters is not echoed); and the ONE `omitted`
8032
+ summary core folds the rest of the media into when not even a descriptor fits. Media block vs descriptor share `type` —
8033
+ tell them apart by `data`. Which face sees which (server >= 7.127.0): the LIVE face carries media whole (only a connection
8034
+ backlog over 64 MiB degrades that frame's media to descriptors); the ledger and replay faces (`GET /v1/runs/:id/events`, the
8035
+ turns face, the trace stream) always carry descriptors, with the frame-level `truncated: true`. Render a block with no
8036
+ `data` and `truncated: true` as "not delivered" from its `mimeType` / `bytes`.
8037
+ oneOf:
8038
+ - $ref: '#/components/schemas/ToolOutputTextBlock'
8039
+ - $ref: '#/components/schemas/ToolOutputMediaBlock'
8040
+ - $ref: '#/components/schemas/ToolOutputMediaDescriptor'
8041
+ - $ref: '#/components/schemas/ToolOutputOmittedBlock'
8042
+
8043
+ ToolOutputTextBlock:
8044
+ type: object
8045
+ description: 'The text arm of `ToolOutputBlock` (core `TextContent`).'
8046
+ additionalProperties: false
8047
+ required: [type, text]
8048
+ properties:
8049
+ type: { const: text }
8050
+ text: { type: string }
8051
+
8052
+ ToolOutputMediaBlock:
8053
+ type: object
8054
+ description: 'The media arm of `ToolOutputBlock` (core `ImageContent` / `DocumentContent`) — on the LIVE face only; the ledger / replay faces carry `ToolOutputMediaDescriptor` instead.'
8055
+ additionalProperties: false
8056
+ required: [type, data, mimeType]
8057
+ properties:
8058
+ type: { type: string, enum: [image, document] }
8059
+ data: { type: string, description: 'base64 bytes (not text-redacted: it is an encoding of bytes).' }
8060
+ mimeType: { type: string }
8061
+
8062
+ ToolOutputMediaDescriptor:
8063
+ type: object
8064
+ description: 'The descriptor arm of `ToolOutputBlock`: the same media block did not travel on this face (core budget degrade / the server''s ledger face / a backlogged live connection).'
8065
+ additionalProperties: false
8066
+ required: [type, bytes, truncated]
8067
+ properties:
8068
+ type: { type: string, enum: [image, document] }
8069
+ mimeType: { type: string, description: 'Echoed when it is at most 255 characters.' }
8070
+ bytes: { type: integer, minimum: 0, description: 'Decoded byte size of the media that did not travel.' }
8071
+ truncated: { const: true }
8072
+
8073
+ ToolOutputOmittedBlock:
8074
+ type: object
8075
+ description: 'The summary arm of `ToolOutputBlock` (core 7.50.0): when not even a descriptor fits, this media block and every later one fold into this ONE block.'
8076
+ additionalProperties: false
8077
+ required: [type, blocks, bytes, truncated]
8078
+ properties:
8079
+ type: { const: omitted }
8080
+ blocks: { type: integer, minimum: 1 }
8081
+ bytes: { type: integer, minimum: 0 }
8082
+ truncated: { const: true }
8083
+
8011
8084
  TerminalCause_completed:
8012
8085
  type: object
8013
8086
  additionalProperties: false
@@ -8015,6 +8088,24 @@ components:
8015
8088
  required: [kind]
8016
8089
  properties:
8017
8090
  kind: { const: completed }
8091
+ detail:
8092
+ allOf: [{ $ref: '#/components/schemas/TerminalCompletedDetail' }]
8093
+ description: >
8094
+ server >= 7.126.0 (core 7.49.0 `TerminalCompletedDetail`, forwarded verbatim): a machine-readable account BESIDE a completion, for the one
8095
+ shape that completes yet may be short. PRESENT only when the final assistant message carried the provider's unknown stream-end word and
8096
+ the run completed on that turn; every other completion leaves it absent.
8097
+
8098
+ TerminalCompletedDetail:
8099
+ type: object
8100
+ additionalProperties: false
8101
+ description: >
8102
+ The account a `completed` cause may carry (server >= 7.126.0; core 7.49.0 `dist/core/terminal-cause.d.ts`, key-for-key). `kind` is CLOSED with one
8103
+ member: `finish_reason_unknown` — the final turn's provider ended it with a stream-end word the engine does not read; the turn was kept as
8104
+ the model left it and the run announced it (`route.finish_reason_unknown`). Read it as "completed, but the last answer may be cut", never as a failure.
8105
+ required: [kind, finishReasonUnknown]
8106
+ properties:
8107
+ kind: { const: finish_reason_unknown }
8108
+ finishReasonUnknown: { type: string, description: 'The provider''s stream-end word in the provider echo shape (bytes outside it become `?`); not an engine word.' }
8018
8109
 
8019
8110
  TerminalCause_failed:
8020
8111
  type: object
@@ -9113,6 +9204,9 @@ components:
9113
9204
  properties:
9114
9205
  type: { type: string, description: 'thinking | content | tool-call | tool-result | (open)' }
9115
9206
  text: { type: string }
9207
+ output:
9208
+ allOf: [{ $ref: '#/components/schemas/ToolOutput' }]
9209
+ description: 'tool-result — the model-facing body, the SAME two shapes as `Event_tool_end.output` (one block schema, three faces). This is a ledger face: a media block is always its descriptor here (server >= 7.127.0).'
9116
9210
  id: { type: string, description: tool-call — matches approvals toolCallId. }
9117
9211
  name: { type: string }
9118
9212
  input: { description: tool-call — redacted args. }
@@ -12703,6 +12797,12 @@ components:
12703
12797
  (where only the `error` frame carried it). Equal to the SSE `event:` line verbatim — its reason
12704
12798
  to exist is the proxy/relay case that strips the `event:` line and forwards only the data JSON,
12705
12799
  where this is the only key left to dispatch on. Heartbeats (`data: {}`) carry none.
12800
+ output:
12801
+ allOf: [{ $ref: '#/components/schemas/ToolOutput' }]
12802
+ description: >
12803
+ `tool-result` frames only (no other known event carries this key; the data object stays open for the rest): the model-facing
12804
+ body in the SAME two shapes as `Event_tool_end.output` and the turns face (one block schema, three faces). A ledger face — a
12805
+ media block is always its descriptor here (server >= 7.127.0).
12706
12806
 
12707
12807
  PendingList:
12708
12808
  type: object
@@ -12713,15 +12813,55 @@ components:
12713
12813
  # 结构性不可见)。ADDITIVE / tolerate-absent:键缺席=「协调器未装配(本部署无 live 审批面)」或
12714
12814
  # 旧 server;空数组=「有面、此刻无待批」——两义可判别,消费端测 presence。**分数组不混编**:
12715
12815
  # live 行的决议口=POST /v1/tool-approvals/{approvalId}/respond,durable 行=decide 口;数组名即路由判据。
12816
+ # 22.0.0:第三、四顶层键此前漏声明 —— 封闭 schema 上一个真键 = 合法信封被严格校验器拒收。
12716
12817
  additionalProperties: false
12717
12818
  required: [pending]
12718
12819
  properties:
12719
12820
  pending:
12720
12821
  type: array
12721
12822
  items: { $ref: '#/components/schemas/PendingCheckpoint' }
12823
+ serverNowMs:
12824
+ type: integer
12825
+ description: >
12826
+ server >= 7.57.0 (always present from that version): the server's clock at the moment THIS response was minted. Render a countdown as
12827
+ `deadline − serverNowMs`, never against the local clock (a terminal with clock skew would show a card as alive that already expired).
12828
+ Not repeated per row — one response has one "now".
12722
12829
  livePending:
12723
12830
  type: array
12724
12831
  items: { $ref: '#/components/schemas/LivePendingRow' }
12832
+ crashConverged:
12833
+ type: array
12834
+ items: { $ref: '#/components/schemas/CrashConvergedRow' }
12835
+ description: >
12836
+ server >= 7.55.0: approval asks the previous process left pending, converged at boot to NOT DECIDABLE (audit rows, not queue rows — no
12837
+ decide route, no run revival). Present iff the local-lane ask audit store is wired; `[]` = the face exists and nothing was converged;
12838
+ absent = no such face on this deployment (or an older server).
12839
+
12840
+ CrashConvergedRow:
12841
+ type: object
12842
+ description: >
12843
+ One `GET /v1/approvals` `crashConverged[]` row (server >= 7.55.0; server `src/approval-ask-audit-store.ts` `CrashConvergedRow`, key-for-key):
12844
+ an ask whose carrying leg died, converged at boot so it can no longer be decided. Args / card body are NOT listed (same rule as
12845
+ `livePending` rows). Open like the other response row projections (a strict consumer must not reject a row for a key added later).
12846
+ additionalProperties: true
12847
+ required: [approvalId, toolName, taskId, ts, expiresAtMs, decision, cause, orphanState, convergedAtMs, resumeSafe]
12848
+ properties:
12849
+ approvalId: { type: string }
12850
+ toolName: { type: string }
12851
+ taskId: { type: string }
12852
+ sessionId: { type: string }
12853
+ ts: { type: number, description: 'Mint time (ms epoch; named like `livePending[].ts`).' }
12854
+ expiresAtMs: { type: number }
12855
+ decision: { const: denied, description: 'Discriminating constant: the card can no longer be decided.' }
12856
+ cause:
12857
+ type: string
12858
+ enum: [crashed_before_park, shutdown_before_park]
12859
+ description: '`crashed_before_park` = the process crashed; `shutdown_before_park` (server >= 7.108.0) = an orderly shutdown cut the leg. The SAME word as the decide door''s 410 `gone.ask` body `cause`.'
12860
+ orphanState: { type: string, enum: [pending, decided], description: '`pending` = the tool provably never ran; `decided` = a person had answered, a partial side effect is possible.' }
12861
+ originalDecision: { const: approve, description: 'decided arm only: the person had approved.' }
12862
+ decidedAtMs: { type: number }
12863
+ convergedAtMs: { type: number }
12864
+ resumeSafe: { type: boolean, description: 'pending arm = a re-run (the engine''s resume compensation leg) is safe and a shell may resume by default; decided arm = leave it to a person.' }
12725
12865
 
12726
12866
  LivePendingRow:
12727
12867
  type: object
@@ -14618,6 +14758,7 @@ components:
14618
14758
  - $ref: '#/components/schemas/Event_compacted'
14619
14759
  - $ref: '#/components/schemas/Event_suggestions'
14620
14760
  - $ref: '#/components/schemas/Event_status'
14761
+ - $ref: '#/components/schemas/Event_task_started'
14621
14762
  - $ref: '#/components/schemas/Event_task_progress'
14622
14763
  - $ref: '#/components/schemas/Event_workspace_changed'
14623
14764
  - $ref: '#/components/schemas/Event_engine_notice'
@@ -14693,6 +14834,7 @@ components:
14693
14834
  compacted: '#/components/schemas/Event_compacted'
14694
14835
  suggestions: '#/components/schemas/Event_suggestions'
14695
14836
  status: '#/components/schemas/Event_status'
14837
+ task_started: '#/components/schemas/Event_task_started'
14696
14838
  task_progress: '#/components/schemas/Event_task_progress'
14697
14839
  workspace_changed: '#/components/schemas/Event_workspace_changed'
14698
14840
  engine_notice: '#/components/schemas/Event_engine_notice'
@@ -15143,42 +15285,55 @@ components:
15143
15285
  `UNATTENDED_PERMISSION_MODE=dontAsk`).
15144
15286
  AskClass:
15145
15287
  type: string
15146
- enum: [content_question, hook, ancestor, dangerous_delete, unverifiable_delete, transcript_write, org_rule, governance_unavailable, rule_unreadable, ask_rule, denial_limit_fallback, classifier_no_ruling, requires_user_interaction, operator_forced, shell_floor, write_protection_unresolved, probe, write_protection, tool_marks_mcp, tool_marks_a2a, policy_rra, artifact_shared_read, mode, unstated, ordinary]
15288
+ enum: [content_question, hook, ancestor, dangerous_delete, unverifiable_delete, unverifiable_shell_text, transcript_write, org_rule, governance_unavailable, rule_unreadable, ask_rule, denial_limit_fallback, classifier_no_ruling, requires_user_interaction, operator_forced, shell_floor, target_unresolved, probe, write_protection, tool_marks_mcp, tool_marks_a2a, policy_rra, artifact_shared_read, mode, unstated, ordinary]
15147
15289
  description: >
15148
- core `ASK_CLASSES` (twenty-two words as of core 7.40.0, twenty-three as of core 7.41.0, twenty-four as of core 7.43.0, twenty-five as of core 7.45.0 — 7.34.0 minted twenty; `shell_floor` joined in 7.39.0 #1260 and rides
15290
+ core `ASK_CLASSES` (twenty-two words as of core 7.40.0, twenty-three as of core 7.41.0, twenty-four as of core 7.43.0, twenty-five as of core 7.45.0, twenty-six as of core 7.49.0 — 7.34.0 minted twenty; `unverifiable_shell_text` joined in 7.49.0 #1505 and rides server >= 7.126.0, where the
15291
+ unresolved-write-target class was also RENAMED to `target_unresolved` (#955; zero alias — the previous spelling is in the SDK README's 22.0.0 migration table); `shell_floor` joined in 7.39.0 #1260 and rides
15149
15292
  server >= 7.113.0; `unstated` joined in 7.40.0 and rides server >= 7.115.0; `requires_user_interaction` joined in 7.41.0 and rides
15150
15293
  server >= 7.116.0; `classifier_no_ruling` joined in 7.43.0 #1353 and rides server >= 7.118.0; `dangerous_delete` joined in 7.45.0 and rides
15151
15294
  server >= 7.119.0) — which CLASS an ask falls in (the columns of the mode × class arbitration table).
15152
15295
  `dangerous_delete` = a DELETE OF A PROTECTED PLACE: an `rm` / `rmdir` whose target is the filesystem root, a top-level directory, the home
15153
15296
  directory, the task root / working directory / an added working directory or an ancestor of one (including `rm -rf *` at the task root and
15154
- `rm -rf ~/*`), or a shell handed a script that is only assembled at run time (`bash -c "$CMD"`, `eval "$(…)"`). ONLY A PERSON'S ANSWER clears
15297
+ `rm -rf ~/*`); on server 7.119.0–7.125.x it also covered a shell handed a script that is only assembled at run time, which is
15298
+ `unverifiable_shell_text` from server >= 7.126.0. ONLY A PERSON'S ANSWER clears
15155
15299
  it: no mode (`bypassPermissions` included), no allow (request `settings.permissions.allow`, operator `APPROVAL_GRANT`, a stored allow row, a
15156
15300
  skill's tool list, a hook's allow) and no `auto` classifier does; the frame carries `requiresRealApproval: true`, nobody answering means the
15157
- call does not run (the unattended leg refuses), and it is bypass-IMMUNE (not one of the ten releasable classes).
15301
+ call does not run (the unattended leg refuses), and it is bypass-IMMUNE (not a releasable class).
15302
+ `unverifiable_shell_text` (core 7.49.0 #1505, server >= 7.126.0) = the engine CANNOT READ the text this shell will execute — the shell is fed
15303
+ text the command does not spell (a program's output, a substitution, a file's content, an argv a stream fills in: `bash -c "$CMD"`,
15304
+ `eval "$(…)"`, `xargs sh -c …`; shell text that does not parse or is nested too deep lands here too). Its arbitration row is
15305
+ `unverifiable_delete`'s save the classifier column: bypass-IMMUNE, no allow rule clears it, the `auto` classifier is not asked, `dontAsk`
15306
+ refuses; only a person's answer clears it. The card carries no `mandate` word.
15307
+ `target_unresolved` (core 7.49.0 #955, server >= 7.126.0; the previous spelling was used on 7.122.0–7.125.x) = WHERE A WRITE LANDS COULD NOT BE
15308
+ DETERMINED (a link on the way could not be examined, or the environment could not resolve the target), so whether it lands on a guarded path
15309
+ (the write-protection table, the sensitive-path list) is unknown. Refused on the file tools; on the SHELL face `bypassPermissions` releases it and
15310
+ names it in `ModeRelease.reason`. The same word is a `PersistedRuleMandate` member.
15158
15311
  `classifier_no_ruling` = the auto-mode classifier did not rule (it could not run — `error` / `timeout` — or replied with no verdict —
15159
15312
  `parse_error`), so a person decides: the denial-limit fallback's row (bypass-immune, no allow rule clears it, the classifier is not asked
15160
15313
  again); the live frame and the inbox row also carry the cause as `classifierNoRuling`.
15161
15314
  `requires_user_interaction` = the MCP server declared, in the tool's advertisement, `_meta["anthropic/requiresUserInteraction"] === true`
15162
- (only the boolean `true`): EVERY call of that tool asks the human, in EVERY mode including `bypassPermissions` (it is not one of the ten
15163
- RELEASABLE classes), and only the human's answer clears it — `settings.permissions.allow`, operator `APPROVAL_GRANT`, a skill's tool list +
15315
+ (only the boolean `true`): EVERY call of that tool asks the human, in EVERY mode including `bypassPermissions` (it is not a
15316
+ RELEASABLE class), and only the human's answer clears it — `settings.permissions.allow`, operator `APPROVAL_GRANT`, a skill's tool list +
15164
15317
  `userInvokedSkills` and a hook's explicit allow all fail to; with no approval seat the call is refused (the server sees nothing). The frame
15165
15318
  also carries `requiresRealApproval: true` / `mandated: true` (`origin: "safety_tighten"`). A client that renders cards by exhaustive `askClass`
15166
15319
  adds this one word.
15167
15320
  `unstated` = NOBODY STATED IT: in an ask-class mode (`default` / `acceptEdits` / `auto` / `plan`) a call to an MCP server tool or A2A skill
15168
15321
  (a seat that states no permission of its own) reached the end of the fold with no layer — rule / hook / approver / classifier / mode
15169
15322
  release — having said "this time is fine"; the engine raises a card with `askClass: "unstated"` (sentence `The agent requested permission to use <tool>,
15170
- but it has not been granted yet.`), and with no approval surface the call is refused. It is clearable (one of the ten RELEASABLE
15171
- classes: an allow rule — `settings.permissions.allow` / operator `APPROVAL_GRANT` — an explicit hook `permissionDecision: "allow"`, the auto-mode
15323
+ but it has not been granted yet.`), and with no approval surface the call is refused. It is clearable (a RELEASABLE
15324
+ class: an allow rule — `settings.permissions.allow` / operator `APPROVAL_GRANT` — an explicit hook `permissionDecision: "allow"`, the auto-mode
15172
15325
  classifier or `bypassPermissions` clears it); under `plan` only READ-ONLY server tools raise it.
15173
15326
  `shell_floor` = the operator's `shellGate: "always"` floor on a shell-running seat (the question the `operator_always` mandate
15174
15327
  word discloses), a class of its own so a set that holds another forced question still holds it; like `operator_forced` it is
15175
15328
  bypass-IMMUNE (not releasable).
15176
- CLOSED on the gate record (screened with core `isAskClass`). `bypassPermissions` releases only the ten RELEASABLE classes
15177
- (`transcript_write` / `rule_unreadable` / `probe` / `write_protection` / `tool_marks_mcp` / `tool_marks_a2a` /
15178
- `artifact_shared_read` / `mode` / `unstated` / `ordinary`) — on every face — plus, from server >= 7.122.0 / core 7.47.0, an eleventh on the SHELL
15179
- face only: `write_protection_unresolved` (core `releasableAskClassesFor(face)`: shell 11, other faces 10; on the file tools that class is
15180
- refused, `deniedBy: mode`); every other class (deployment-authored `operator_forced`, ask / org rules, hook,
15181
- ancestor, content question, …) asks under every mode.
15329
+ CLOSED on the gate record (screened with core `isAskClass`). `bypassPermissions` releases only the RELEASABLE classes (core
15330
+ `releasableAskClassesFor(face)`). Server >= 7.127.0 (core 7.50.0): nine on every face (`transcript_write` / `probe` / `write_protection` /
15331
+ `tool_marks_mcp` / `tool_marks_a2a` / `artifact_shared_read` / `mode` / `unstated` / `ordinary`) plus a tenth on the SHELL face only,
15332
+ `target_unresolved` (shell 10, other faces 9; on the file tools that class is refused, `deniedBy: mode`); `rule_unreadable` is no longer released
15333
+ by any mode (bypass asks too, and the run gets one `permission.rule_store_unavailable` notice). Server 7.122.0–7.126.x (core 7.47.0–7.49.x) also
15334
+ released `rule_unreadable` on every face: ten RELEASABLE classes plus an eleventh on the SHELL face (shell 11, other faces 10). Up to 7.121.x the
15335
+ `RELEASABLE_ASK_CLASSES` constant (deleted in core 7.47.0) held ten, face-blind. Every other class (deployment-authored `operator_forced`, ask / org
15336
+ rules, hook, ancestor, content question, `unverifiable_shell_text`, …) asks under every mode.
15182
15337
  ModeRelease:
15183
15338
  type: object
15184
15339
  additionalProperties: false
@@ -15194,24 +15349,26 @@ components:
15194
15349
  classes: { type: array, items: { $ref: '#/components/schemas/AskClass' } }
15195
15350
  origin:
15196
15351
  type: string
15197
- enum: [content_question, ancestor_marked, org_unavailable, org_rule, rule_store_unavailable, hook, ask_rule, denial_limit_fallback, shell_gate_tighten, safety_tighten, policy]
15352
+ enum: [content_question, plan_review, ancestor_marked, org_unavailable, org_rule, rule_store_unavailable, hook, ask_rule, denial_limit_fallback, shell_gate_tighten, safety_tighten, policy]
15198
15353
  description: 'The origin word the card would have shown (core `ASK_ORIGINS`; screened closed on this face, same list as `GateOutcome.origin`).'
15199
15354
  mandate: { $ref: '#/components/schemas/PersistedRuleMandate' }
15200
15355
  reason:
15201
15356
  type: string
15202
- enum: [rule_unreadable, write_protection_unresolved]
15357
+ enum: [target_unresolved]
15203
15358
  description: >
15204
15359
  WHAT the release went over — one word: the FIRST member (in core `MODE_RELEASE_REASONS` array order) that the ask's class
15205
- set holds; ABSENT when the set holds none. CLOSED set — the server screens it with core `isModeReleaseReason`, so a word
15206
- outside it withholds the whole `gate` from the frame (and a consumer that dispatches on the word must learn each new one).
15207
- `rule_unreadable` = the release went over a rule this call could not be read against (the rule store was unreadable — a
15208
- security-axis fail-open direction the server discloses on its own).
15209
- `write_protection_unresolved` (server >= 7.122.0 / core 7.47.0) = the release went over a write whose target the
15210
- write-protection judge could not RESOLVE (whether it lands on the protected table is unknown). It is released on the SHELL
15360
+ set holds; ABSENT when the set holds none. CLOSED set of ONE word — the server screens it with core `isModeReleaseReason`, so a word
15361
+ outside it withholds the whole `gate` from the frame.
15362
+ `target_unresolved` = the release went over a write whose landing place could not be determined (a link on the way could not be examined,
15363
+ or the environment could not resolve the target), so whether it lands on a guarded path is unknown. It is released on the SHELL
15211
15364
  face only: a caller-supplied tool whose wire name is exactly `Bash` or `Monitor` and which declares a write-path target,
15212
15365
  under `bypassPermissions`; on the file tools the same unresolved write is still refused (`deniedBy: mode`). The engine's
15213
15366
  own `Bash` / `Monitor` cannot mint this class and the server mounts no such tool — it comes from a caller-embedded tool of
15214
- those names. Before server 7.122.0 / core 7.47.0 the set was `rule_unreadable` alone.
15367
+ those names.
15368
+ History (this SDK's type and this enum hold the one word from 22.0.0; a word an older server sends reads as OUT OF SET and is not rewritten):
15369
+ server 7.122.0–7.125.x (core 7.47.0–7.48.x) spelled this member differently (the SDK README's 22.0.0 migration table); server <= 7.126.x also
15370
+ had `rule_unreadable` (the release went over a rule this call could not be read against) — core 7.50.0 / server >= 7.127.0 releases an
15371
+ unreadable rule under no mode, so that member left (`rule_unreadable` stays an `AskClass`). Before server 7.122.0 the set was `rule_unreadable` alone.
15215
15372
 
15216
15373
  GateClassifierAttribution:
15217
15374
  # sdk 9.5.0:具名 —— 同一份形挂在 `GateDisposition` 的两只臂上,内联会立刻是两份会各自漂的镜像。
@@ -15296,7 +15453,7 @@ components:
15296
15453
  # 服务对缺陷记录是整条不上帧 ⇒ 词表外的值在这条 wire 上到不了消费端。审批帧那一面不判成员,
15297
15454
  # 所以 `AskOrigin` 本体保持真开(见该 schema 的长注)。这张 enum 是本 spec 里该词表的**唯一**
15298
15455
  # 执法点;core 加词时改这一处。
15299
- - enum: [content_question, ancestor_marked, org_unavailable, org_rule, rule_store_unavailable, hook, ask_rule, denial_limit_fallback, shell_gate_tighten, safety_tighten, policy]
15456
+ - enum: [content_question, plan_review, ancestor_marked, org_unavailable, org_rule, rule_store_unavailable, hook, ask_rule, denial_limit_fallback, shell_gate_tighten, safety_tighten, policy]
15300
15457
  description: >
15301
15458
  WHO ASKED. Same-present/same-absent as `settlement` (I1). CLOSED here (and only here) — see the
15302
15459
  enum note above.
@@ -15389,10 +15546,13 @@ components:
15389
15546
  Event_tool_end:
15390
15547
  type: object
15391
15548
  description: >
15392
- design/99 §E1 (SHIPPED) — `output` is the model-facing action-card BODY: NON-UNIFORM (a string, or a
15393
- (TextContent|ImageContent)[] block array) and degrades to a single TRUNCATED string over the core size cap
15394
- (`truncated: true`). Absent ⇒ the tool produced no body. 🔴 UNTRUSTED RAW + observability-only: the service
15395
- has redactDeep'd + size-bounded it; a consumer MAY further bound, MUST never re-feed it to a model.
15549
+ design/99 §E1 (SHIPPED) — `output` is the model-facing action-card BODY in TWO shapes (`ToolOutput`: a string, or a
15550
+ `ToolOutputBlock` array — handle both). A string over the core text cap is cut and ends with the marker; in a block array
15551
+ the text stream is cut in place and image / document blocks ride whole on the LIVE face (core 7.50.0 / server >= 7.127.0;
15552
+ a connection backlog over 64 MiB degrades that frame's media to descriptors), while the ledger and replay faces always
15553
+ carry descriptors. `truncated: true` ⇔ the body is not the tool's content as returned. Absent ⇒ the tool produced no body.
15554
+ 🔴 UNTRUSTED RAW + observability-only: the service has redacted the text + size-bounded it (media `data` is bytes and rides
15555
+ verbatim); a consumer MAY further bound, MUST never re-feed it to a model.
15396
15556
  allOf:
15397
15557
  - { $ref: '#/components/schemas/EventIdentity' }
15398
15558
  # 🔴 现役写口与退役四词**互斥**(S-170 codex r2 [medium] 验真后补):退役四词只出现在 <=7.63.0 写下的
@@ -15429,9 +15589,9 @@ components:
15429
15589
  a retired name the roster still answers to). Present ONLY on a refused call (`gate.disposition.kind === "denied"`), and absent when the station that refused it did not know the roster name; per-tool refusal accounting reads this, not `toolName`.
15430
15590
  structured: {} # core 1.203 CC 卡片明细;与 output 同一 UNTRUSTED RAW 待遇(已 redactDeep),形状开放
15431
15591
  isError: { type: boolean }
15432
- output: {} # NON-UNIFORM: string | (TextContent|ImageContent)[] | (truncated) string. Absent ⇒ no body.
15433
- truncated: { type: boolean }
15434
- totalChars: { type: integer, description: 'core >=1.442 (RB-210): honest ORIGINAL size when truncated — sum of each block''s true size (text=chars, image/document=base64 bytes), no JSON-wrapping overhead. Absent on older cores / untruncated results.' } # true ⇒ output was size-bounded to a truncated string.
15592
+ output: { $ref: '#/components/schemas/ToolOutput' } # 22.0.0: two shapes, one block schema shared with the trace faces
15593
+ truncated: { type: boolean, description: 'true exactly when `output` is not the content the tool returned (text cut, a media block replaced by its descriptor or folded into the `omitted` summary — by core, or by the server on the ledger / replay faces and on a backlogged live connection).' }
15594
+ totalChars: { type: integer, description: 'core >=1.442 (RB-210): honest ORIGINAL size when truncated — sum of each block''s true size (text=chars, image/document=base64 length, whether the block rode or was replaced by its descriptor), no JSON-wrapping overhead. PRESENT ⇒ `truncated`; the converse does not hold (core omits it when the content could not be read). When server >= 7.127.0 replaces media by descriptors (ledger / replay faces, a backlogged live connection) it sets `truncated` AND this key (core''s value kept as is, otherwise the per-block true sizes summed). Absent on older cores / untruncated results / unreadable content — never read it as 0.' } # true ⇒ output was size-bounded to a truncated string.
15435
15595
  # 🔴 BREAKING (server >=7.64.0, core 7.6.0 S6-A): `settledBy` / `resolution` / `autoDenied` / `approver`
15436
15596
  # are RETIRED and replaced by the ONE `gate` record below. NO 7.64.0+ writer mints them, and the TS type
15437
15597
  # does NOT carry them — nobody should code against a dead vocabulary.
@@ -15650,6 +15810,46 @@ components:
15650
15810
  errClass: { type: string, description: "connect_refused | transport | rate_limit | server | http | output_cap — retry-wait frames ONLY; never inferred from phase" }
15651
15811
  providerCondition: { type: string, description: "server >= 7.126.0 (core 7.49.0 #1454, passed through verbatim): what the provider said about the account / capacity — core's closed `PROVIDER_CONDITIONS`; a retry frame carries only the three retryable words `throttled | overloaded | unknown` (`quota_exhausted` / `stop_other` do not retry and ride the terminal `detail.providerCondition`). Presence law as `errorStatus`; read as an OPEN set (keep a default arm). ABSENT = not judged, read the same as `unknown` (back off, do not assert quota). Moves with `providerConditionSource`." }
15652
15812
  providerConditionSource: { type: string, description: "server >= 7.126.0 (core 7.49.0 #1454): the evidence the `providerCondition` verdict rests on — `unified_header | provider_code | status`; present exactly when `providerCondition` is; read as an OPEN set." }
15813
+ retryAtMs: { type: number, description: "server >= 7.52.0 (core 7.0.0): the WALL-CLOCK end of the wait = `Date.now() + retryInMs` at emit, on the emitting process's clock (not monotonic — never compare it with a local monotonic timer). `retryInMs` stays the authoritative RELATIVE amount; this is the producer's absolute note (a reader several hops away recomputing it would reset the countdown on every replay). Moves with `retryInMs`; absent ⇒ not minted." }
15814
+ errorStatus: { type: integer, description: "server >= 7.54.0 (core 7.1.0): the HTTP status of the attempt that just failed, present ONLY when that status names the failure (absent on a transport non-answer, a mid-stream tear, a local circuit-open verdict and the `recovered` / `gave_up` frames). Absent = no status named the failure — not 0; a 2xx never appears." }
15815
+ elapsedMs: { type: number, description: "server >= 7.58.0 (core 7.3.1): ONLY on the `waiting_first_token` phase — how long the current segment has waited so far (at emit, emitting process's clock). Absent = unknown, not 0. A waiting frame never carries `retryInMs` / `retryAtMs` (it OBSERVES a wait, it does not ANNOUNCE one) — do not merge the two families into one countdown." }
15816
+ timeoutMs: { type: number, description: "server >= 7.58.0 (core 7.3.1): present with `elapsedMs` on the same phase — the bound of the segment being waited on (core 7.33.0+: the first-byte window before the response head, the first-token watchdog after it; each segment counts from 0)." }
15817
+ eventId: { type: string }
15818
+ parentToolCallId: { type: string }
15819
+ sourceTaskId: { type: string }
15820
+ bgAgentId: { type: string }
15821
+ Event_task_started:
15822
+ type: object
15823
+ description: >
15824
+ server >= 7.127.0 (core 7.50.0 `task_started`; server projection `taskStartedEventData`, an explicit per-key whitelist) — a
15825
+ delegated child STARTED: one frame per cycle (first spawn / revival; a durable continuation leg mints none), after the child's
15826
+ `wiring_manifest` and before its first `task_progress` and first model request, so a consumer opens the child row at start.
15827
+ Every member is a value `task_progress` already carries with the same meaning. 🔴 LIVE AND LEDGERED, like `task_progress`: it rides
15828
+ the same door (sync stream main leg, forward lane, the child tail stream) AND is persisted, so the async lane's ledger tail and the
15829
+ `GET /v1/runs/:id/events` replay carry it (before the child's first `task_progress`). Core's "never persisted, never replayed on
15830
+ resume" binds the ENGINE (session tree, checkpoints, resume replay); the server ledgers it because `agentType` / `rootSessionId` /
15831
+ `parentSessionId` / `startedAt` ride only this frame. `name` / `workflowAgentLabel` are UNTRUSTED display text, redacted by the server; `spawnName`
15832
+ is a validated identity key, verbatim. Absent optional keys stay absent (`taskType` absent = a foreground child; `seq`
15833
+ absent = no `a*` row, never cycle 1). Servers <= 7.126.x never send it.
15834
+ allOf: [{ $ref: '#/components/schemas/EventIdentity' }]
15835
+ additionalProperties: false # 封闭 + identity 本地镜像:见 Event_reasoning 处的长注(builder=taskStartedEventData)
15836
+ required: [type, taskId, sessionId, model]
15837
+ properties:
15838
+ type: { const: task_started }
15839
+ taskId: { type: string, description: 'The child RUN id (`spec.taskId ?? sessionId`) — the key its `task_progress` frames carry.' }
15840
+ sessionId: { type: string, description: 'The child run''s session id.' }
15841
+ taskType: { type: string, description: 'As `task_progress.taskType`: absent for a foreground (synchronous) child. Open on read.' }
15842
+ seq: { type: integer, description: 'As `task_progress.seq`: the registry row''s cycle generation; absent when there is no `a*` row.' }
15843
+ workflowRunId: { type: string }
15844
+ workflowAgentLabel: { type: string, description: 'UNTRUSTED display text (redacted).' }
15845
+ parentTaskId: { type: string }
15846
+ parentSessionId: { type: string }
15847
+ rootSessionId: { type: string }
15848
+ name: { type: string, description: 'The child''s display label (the same value as `task_progress.name`) — UNTRUSTED, redacted.' }
15849
+ spawnName: { type: string, description: 'The explicit `Agent({name})` spawn identity, verbatim; present when the spawn carried one.' }
15850
+ agentType: { type: string, description: 'The resolved subagent type (absent on a workflow-lane agent).' }
15851
+ model: { type: string, description: 'The model the child leg was PREPARED with.' }
15852
+ startedAt: { type: number, description: 'Epoch ms at the mint (sent only when finite).' }
15653
15853
  eventId: { type: string }
15654
15854
  parentToolCallId: { type: string }
15655
15855
  sourceTaskId: { type: string }
@@ -15730,7 +15930,9 @@ components:
15730
15930
  `message_committed` + stream order). Live emissions PRECEDE the commit and omit `entryId`.
15731
15931
  SERVICE PROJECTION: core's `principal` is deliberately NOT forwarded (the stream is already owner-scoped —
15732
15932
  the frame does not restate the tenant). `issuer` / `actor.id` / `actor.issuer` are host-derived identity
15733
- strings and arrive SECRET-REDACTED.
15933
+ strings and arrive SECRET-REDACTED. Server >= 7.127.0 does NOT project core 7.50.0's `attachments` member (always absent here)
15934
+ and does not accept the engine's request-layer `userAttachments` key: a submit / resume body carrying it is 400
15935
+ `request.body_shape` (named in `unknownKeys`).
15734
15936
  allOf: [{ $ref: '#/components/schemas/EventIdentity' }]
15735
15937
  additionalProperties: false # 封闭 + identity 本地镜像:见 Event_reasoning 处的长注
15736
15938
  required: [type, inputId]
@@ -17458,7 +17660,7 @@ components:
17458
17660
  # 当天,一个**合法**的审批卡就会被严格消费端拒收。`x-open-enum` 只是意图标记,不解除 enum 的执法 ——
17459
17661
  # 这正是本车刚从 `CheckpointGate` 拆掉的那个假开集,不在这里换个地方重犯。
17460
17662
  # 闭集**执法**只属于**筛过的**那一面(`GateOutcome.origin`:引擎的 `screenGateOutcome` 判成员,
17461
- # 出集即整条不上帧),所以那张 enum 落在**那个引用点**,恰一处。已知十一词见下面的描述。
17663
+ # 出集即整条不上帧),所以那张 enum 落在**那个引用点**,恰一处。已知十二词(core 7.49.0 +plan_review)见下面的描述。
17462
17664
  description: >
17463
17665
  WHO raised an ask (`ToolApprovalFrame.origin`; server >= 7.57.0 / core 7.5.0, S-125③/#564) — core's
17464
17666
  `ASK_ORIGINS`, ENGINE-STAMPED at the gate (core's words: "engine-stamped at the gate, never a policy's
@@ -17485,13 +17687,19 @@ components:
17485
17687
  fails closed to a person. It is the personal-store sibling of `org_unavailable` (a governance source that
17486
17688
  cannot be read means ASK, never a silent allow).
17487
17689
 
17690
+ 🔴 core 7.49.0 ADDS A TWELFTH WORD (server >= 7.126.0), second in authority order: `plan_review` = a durable PLAN pause — the
17691
+ model's own request (the first-party plan tool) stopped the run for a human verdict on a plan. Same family as
17692
+ `content_question` (a content-routing ask, never a permission question: no permission decider, classifier or mode answers it
17693
+ and it never reaches an approver as an `AskRequest`); only the plan pause's decide lane stamps it, so the decided row's record
17694
+ names the ask it settled.
17695
+
17488
17696
  The SAME type is the `origin` member of `GateOutcome` on `tool_end` — one vocabulary, two faces.
17489
17697
 
17490
17698
  server >= 7.102.0 (S-755 / cli L-695 / C-R111): the word now also rides the `livePending` row top level
17491
17699
  (read once with the frame's) and the operator queue row (`GET /v1/approvals` `pending[]` + the `/stream`
17492
17700
  `pending` frame — the park-row twin seat, screened by core's `isAskOrigin`), besides the frame and the inbox
17493
17701
  row — five faces, one word. `card_json` / the `approval_request` frame still do not carry it (the card is
17494
- `.strict()`). The eleven known words are exported at runtime as the SDK's `ASK_ORIGINS` (core 7.32.1
17702
+ `.strict()`). The known words (twelve from core 7.49.0) are exported at runtime as the SDK's `ASK_ORIGINS` (core 7.32.1
17495
17703
  `ASK_ORIGINS`, verbatim and in order) — known words, NOT an enforcement table.
17496
17704
 
17497
17705
  AllowRuleMember:
@@ -17544,11 +17752,12 @@ components:
17544
17752
 
17545
17753
  PersistedRuleMandate:
17546
17754
  type: string
17547
- enum: [operator_always, tool_marks, probe_mandate, probe_unanswered, write_protection, write_protection_unresolved]
17755
+ enum: [operator_always, tool_marks, probe_mandate, probe_unanswered, write_protection, target_unresolved]
17548
17756
  description: >
17549
17757
  WHICH WORD a mandated ask stands on (server >= 7.102.0 / S-721 / core 7.32.0 #1092) — core's
17550
17758
  `PERSISTED_RULE_MANDATES` six words, transcribed verbatim and in order (core 7.32.1
17551
- `dist/core/ask-origin.d.ts:349`; the vocabulary's owner is core). Rides FOUR faces with one value: the
17759
+ `dist/core/ask-origin.d.ts:349`; the vocabulary's owner is core; the sixth word is `target_unresolved` from core 7.49.0 #955 / server >= 7.126.0 —
17760
+ server 7.122.0–7.125.x sent the previous spelling, which reads as out of set here, see the SDK README's 22.0.0 migration table). Rides FOUR faces with one value: the
17552
17761
  `tool_approval` frame, the `livePending` row top level, the operator queue row (`GET /v1/approvals`
17553
17762
  `pending[]` + the `/v1/approvals/stream` `pending` frame) and the inbox row. NOT on `card_json` / the
17554
17763
  `approval_request` frame (live or reconnect replay — `ApprovalCardSchema` is `.strict()`), same as `mandated`.
@@ -17613,12 +17822,17 @@ components:
17613
17822
  rules (`//abs`, `~/`, root-relative, cwd-relative; `*` within a segment, `**` across segments). `name` /
17614
17823
  `name_prefix` (server >= 7.118.0 / core 7.43.0 #1318) = the `Skill` name grammar: `Skill(<name>)` exact,
17615
17824
  `Skill(<prefix>:*)` a name prefix with NO word boundary; a skill card's "don't ask again" offer carries
17616
- `match: "name"`. A replica rolled back to 7.117.x reads a `name` / `name_prefix` row as a damaged row.
17825
+ `match: "name"`. A replica rolled back to 7.117.x reads a `name` / `name_prefix` row as a damaged row. `host` /
17826
+ `subdomain` (server >= 7.126.0 / core 7.49.0 #1365) = the `WebFetch` domain grammar: `WebFetch(domain:<host>)` one exact
17827
+ host, `WebFetch(domain:*.<domain>)` every host under that domain — ALLOW rows only; the server's `Bash` card edit face
17828
+ always refuses these two words (no network grant is minted through a card). A replica rolled back to 7.125.x reads such a
17829
+ row as a damaged row.
17617
17830
 
17618
- 🔴 SEVEN MEMBERS, closed: the server validates the member on both faces. A consumer type narrower than the
17831
+ 🔴 NINE MEMBERS, closed: the server validates the member on both faces. A consumer type narrower than the
17619
17832
  mint point is a lie — it lets a `switch` claim exhaustiveness the wire does not honour (SDK <= 16 declared
17620
- four here, so a `path` offer and every 7.118.0 skill-card offer were dropped as malformed).
17621
- enum: [exact, prefix, wildcard, subpath, path, name, name_prefix]
17833
+ four here, so a `path` offer and every 7.118.0 skill-card offer were dropped as malformed; SDK <= 21 declared
17834
+ seven, so every domain grant row on `GET /v1/rules` was dropped the same way).
17835
+ enum: [exact, prefix, wildcard, subpath, path, name, name_prefix, host, subdomain]
17622
17836
 
17623
17837
  RuleOfferUncoveredReason:
17624
17838
  type: string
@@ -18753,6 +18967,16 @@ components:
18753
18967
  core-stream `eventId`, so this is its own time coordinate. 🔴 It MUST be declared here: this schema
18754
18968
  is `additionalProperties: false`, so omitting a key the server really sends makes a strict validator
18755
18969
  reject a legitimate frame. Absent on servers < 7.3.0.
18970
+ expiresInMs:
18971
+ type: integer
18972
+ description: >
18973
+ server >= 7.39.0, OPEN frame only: the coordinator's OWN answer window (`QUESTION_TTL_MS`, default 5 minutes) — at expiry the ask is
18974
+ released as nobody reachable (`unanswered`) and the engine decides park vs continue. Minted from the SAME ttl the release timer arms
18975
+ (one source, so a countdown rendered from it never disagrees with the release). Relative; with `expiresAtMs` and `serverNowMs` it is a
18976
+ clock-skew-proof trio.
18977
+ expiresAtMs:
18978
+ type: integer
18979
+ description: 'server >= 7.39.0, OPEN frame only: `serverNowMs + expiresInMs` — the absolute deadline on the server''s clock.'
18756
18980
  Event_question_complete:
18757
18981
  type: object
18758
18982
  description: >
@@ -19731,7 +19955,9 @@ components:
19731
19955
  A leg's LSP code-intelligence seam (core 7.18.0 #789). 🔴 THE TWO BITS ARE INDEPENDENT AND MUST NOT BE
19732
19956
  READ AS ONE: `mounted` is the ROSTER fact (a wired manager whose `LSP` tool was excluded reports
19733
19957
  `false`), while `lane` arms on the manager / the hands / the opt-out and NOT on the mount — so
19734
- `{mounted: false, lane: "diagnostics"}` is a REAL, REACHABLE state, not bad data.
19958
+ `{mounted: false, lane: "diagnostics"}` is a REAL, REACHABLE state, not bad data. LANE REACH (server >= 7.127.0 / core 7.50.0):
19959
+ LSP mounts only on a lane that binds reads to the object it judged — today the host lane; on e2b / k8s (and ssh / adb / device /
19960
+ local-docker / in-process) this section is always absent and the roster has no LSP tool (the server logs `lsp_not_mounted` at boot).
19735
19961
  additionalProperties: false
19736
19962
  required: [mounted]
19737
19963
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/sdk",
3
- "version": "21.1.0",
3
+ "version": "22.0.1",
4
4
  "description": "Typed, zero-runtime-dependency SDK for the Sema agent fleet usage plane. The shared substrate for all doors (CC/Codex MCP façade + web). Server-side only — tokens never enter the browser.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -52,6 +52,6 @@
52
52
  "prepublishOnly": "rm -f tsconfig.tsbuildinfo && npm run build && npm run typecheck --workspaces=false --prefix ../.. && npm test --workspaces=false --prefix ../.. && npm run prepack"
53
53
  },
54
54
  "devDependencies": {
55
- "@sema-agent/settings-schema": "^11.2.0"
55
+ "@sema-agent/settings-schema": "^12.2.1"
56
56
  }
57
57
  }