@sema-agent/sdk 15.3.0 → 16.0.0

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/dist/types.d.ts CHANGED
@@ -817,16 +817,21 @@ export interface TaskRequest {
817
817
  * at submit (sibling of {@link promptProfile}). */
818
818
  toolMaterializeStrategy?: "static" | "swap";
819
819
  /** server ≥1.254 — context attachments family (core design/133):literal-true opt-ins
820
- * (todoReminder/planModeReminder/budgetUsd/backgroundTasks/toolsDelta/mcpInstructions;false=省键),
820
+ * (todoReminder/budgetUsd/backgroundTasks/toolsDelta/mcpInstructions;false=省键),
821
821
  * `changedFiles` 可带 {maxFiles};`agentListing`/`skillsListing` 是 core DEFAULT-ON——**explicit false
822
- * 才关**(1.254 起 false 真透传;更老 server 静默丢);`todoReminderMode` "baseline"|"off"。 */
822
+ * 才关**(1.254 起 false 真透传;更老 server 静默丢);`todoReminderMode` "baseline"|"off"。
823
+ *
824
+ * 🔴 **BREAKING(sdk 16.0.0 / K-44)—— `planModeReminder` 已退役,本型删它**(server ≥7.113.0 / core 7.39.0 #1254;零别名零双读):
825
+ * 引擎自此在 `permissionMode: "plan"` 的腿上**自己陈述** plan 姿态(首请求 / 周期提醒 / 退出帧),不再要这个开关。server ≥7.113.0 对提交体里带它的
826
+ * (**任何值,含 `false`** —— 门判 `!== undefined`,不判真假)一律 **400 `request.field_invalid`**(错误句点名退役与出路;此前是受理、引擎在 prepare 才拒);
827
+ * 存量停放体里带这个键的任务续跑时**丢键照跑**(resume 重放不拒)。**迁移 = 删键;要 plan 姿态发 `permissionMode: "plan"`**。
828
+ * 本型是内联对象型(无索引签名):对象字面量里写它直接 TS2353;经变量绕过去时本包原样透传、server 7.113.0 响亮 400。对 ≤7.112.x 的 server 它仍是真键,本包不再替人铺那条路。 */
823
829
  attachments?: {
824
830
  todoReminder?: true;
825
831
  todoReminderMode?: "baseline" | "off";
826
832
  changedFiles?: true | {
827
833
  maxFiles?: number;
828
834
  };
829
- planModeReminder?: true;
830
835
  budgetUsd?: true;
831
836
  backgroundTasks?: true;
832
837
  toolsDelta?: true;
@@ -1000,8 +1005,12 @@ export type TerminalCause = {
1000
1005
  };
1001
1006
  } | {
1002
1007
  kind: "blocked";
1003
- /** agent 为什么完不成(治理判决不是失败)。 */
1008
+ /** 这条 run 为什么没干活(治理判决不是失败)—— 两个来源,由 {@link detail} 分辨:无 `detail` = agent 自己 `ReportBlocked` 的话;
1009
+ * `detail.kind === "prompt_blocked_by_hook"` = 引擎对部署 `userPromptSubmit` hook 的那句陈述(按模型侧车道框成提醒,hook 自己的话在框里)。**别按这段散文分支**。 */
1004
1010
  reason: string;
1011
+ /** server ≥7.113.0(core #1277;K-43 同类封闭对象补键):**谁**让这条 run 没干活 —— 提示**没有被提交**那一形的机读成因(见 {@link TerminalBlockedDetail})。
1012
+ * 在场 ⇔ 就是 hook 挡下提示;缺席 = agent 自己 `ReportBlocked`,或 server <7.113.0。 */
1013
+ detail?: TerminalBlockedDetail;
1005
1014
  } | PausedCause;
1006
1015
  /**
1007
1016
  * 一次耐久暂停的因由(`TerminalCause` 的 paused 臂)—— 提交了 checkpoint,这条 run 可恢复。
@@ -1088,6 +1097,72 @@ export interface SyncSubmitResult extends TaskResult {
1088
1097
  /** 回执词 / ≤7.63 平面词(见上):≥7.104 只在 park 时在场(park 两词);7.64–7.103 只在 park 体上;≤7.63 恒在(平面终局词)。 */
1089
1098
  status?: ParkedRunStatus | LegacyPlaneTaskResult["status"];
1090
1099
  }
1100
+ /**
1101
+ * `abortCause` 的闭集三词(server ≥7.112.0 / S-947;契约 §5.0d)—— **谁让这条 run 停下来**:server 发起的中止的机读成因。每个词有一个真站点:
1102
+ * · `"client_disconnected"` —— `POST /v1/tasks/stream`(**非** detach)客户端断连,断连那一刻本 run 没有流内未决 ask ⇒ 立即中止(「连接断开,run 已中止」,不是引擎错);
1103
+ * · `"ask_park_grace_exhausted"` —— 同一断连臂,断连那一刻有流内未决 ask:server 先把 ask 按窗到期同路转 park、给引擎一个有界宽限(10 s)走完 park,
1104
+ * 宽限用尽 park 仍没落成 ⇒ 中止(「断连时有待决的问答 / 审批,没能停成可续的 park,run 已中止」);
1105
+ * · `"cancel_verb"` —— `POST /v1/runs/:id/cancel`:同副本快路、跨副本耐久取消旗被持有副本轮询到(交互流 / 非流式 / 后台 / 续跑四条腿),
1106
+ * 以及 park 中的 run 被它直接终局化(成因同词)(「已取消」)。
1107
+ * 先到先得:一条腿只被中止一次,先落地的那次定词(断连之后又到的取消动词、取消之后又断连,终局说的都是真正让它停下来的那一个)。
1108
+ * **闭集**,按 additive 规矩只会加词(加词 = server 新版本的 wire 变更〔`wire-changes` 登记〕+ 本包下一版形变,spec 具名 schema `AbortCause` 的 enum 同批):
1109
+ * 认不得的词读作「server 中止,成因不认识」。属主是 server `plugins/store-contracts.ts` 的 `ABORT_CAUSES`(自铸登记 `trace/self-minted-wire.ts#abortCause`);
1110
+ * 测试对已装 server 的真登记做四方相等(server 常量 / 登记 / spec enum / 本型的词)。读法与在场闸见 {@link TaskResult.abortCause}。
1111
+ */
1112
+ export type AbortCause = "client_disconnected" | "ask_park_grace_exhausted" | "cancel_verb";
1113
+ /**
1114
+ * 取消现场快照里的**大脑相位**(server `RunBrainStatusSnapshot`,`turn-activity.ts` `pickRunBrainStatus` 投出的五键子集;K-43,sdk 16.0.0 具名)——
1115
+ * 「取消那一刻引擎正在重试第几次 / 在等什么 / 什么错类」。`phase` 是这只快照的存在理由(没有它就没有快照,不铸半只)。
1116
+ * 🔴 刻意**不含** `detail`(provider 自由文本)与 `retryInMs` / `retryInSec`(相对量,过期即失真);`retryAtMs` 是**发端进程钟域**的墙钟近似,别与本地单调计时器比。
1117
+ */
1118
+ export interface CancelContextBrainStatus {
1119
+ phase: string;
1120
+ attempt?: number;
1121
+ maxRetries?: number;
1122
+ retryAtMs?: number;
1123
+ errClass?: string;
1124
+ }
1125
+ /**
1126
+ * **用户取消的现场快照**(`TaskResult.cancelContext`;server S-94 起〔7.57.0〕,契约 §5.3;K-43 —— sdk 16.0.0 具名,此前只能经 `TaskResult` 的开集索引读成 `unknown`)——
1127
+ * 回答「server 这一侧多久没收到这条 run 的动静了」。**分诊材料,不是状态机输入**。四键全可选,缺席都诚实:
1128
+ * · `lastEventKind` / `lastEventAgeMs` —— 数据源是**同副本进程内**的活性登记;跨副本取消 / 副本重启后读不到 ⇒ 缺席 = 「本副本证不出」,**绝不折成 `0`**
1129
+ * (那会把「挂死 8 分钟」渲成「刚还活着」,方向正好相反)。🔴 `lastEventKind` **比** `lastEventAgeMs` 更容易缺席(有几席打点方只推进时刻、带不出词),
1130
+ * 所以「有 age 无 kind」是合法读数 = 「知道那一刻,说不出那是条什么事件」;
1131
+ * · `lastBrainStatus` —— 这条 run 从没出过 `status` 帧 / 本副本读不到 ⇒ 缺席(恒不铸 `null`);sticky:之后的 text / tool 事件不清它;
1132
+ * · `elapsedMs` —— run 起跑到本次取消的墙钟毫秒;常态在场,行的 `createdAt` 坏到解析不出时缺席(同样不折 0)。
1133
+ * 🔴 **它不是模型调用相位**:server 结构上看不见「首字节等了多久 / 重试了几次」(那半场在引擎流层);`lastEventAgeMs` 也**不是**「模型挂了这么久」(一次长工具调用同样不产账本事件)。
1134
+ * 一键都证不出 ⇒ **整只缺席**(不铸空对象:「缺席」读作「没有取消现场可看」,**不是**「取消时没有异常」)。与 {@link AbortCause} 同住、同一只铸点、同一条在场闸:
1135
+ * `abortCause` 说**谁**让它停的,本对象说那一刻 server 看见了什么。
1136
+ */
1137
+ export interface CancelContext {
1138
+ lastEventKind?: string;
1139
+ lastEventAgeMs?: number;
1140
+ lastBrainStatus?: CancelContextBrainStatus;
1141
+ elapsedMs?: number;
1142
+ }
1143
+ /**
1144
+ * `prompt_blocked_by_hook` 的成因闭集四词(core `PROMPT_BLOCK_CAUSES`;server ≥7.113.0 / core #1277)—— 部署的 `userPromptSubmit` hook 座把提示挡在提交之外的四种收场:
1145
+ * · `"block"` —— hook 答了、拒了(它自己的话在 {@link TerminalBlockedDetail.hookReason});
1146
+ * · `"crashed"` —— hook 抛了 / 拒了承诺;这一座 fail-closed,没筛成的屏不算放行;
1147
+ * · `"timeout"` —— hook 在自己的 `timeoutMs` 内没答;同样 fail-closed;
1148
+ * · `"cancelled"` —— 任务在 hook 还在筛的时候被取消了。
1149
+ * **闭集**,按 additive 规矩只会加词(加词 = core 新版本 + 本包下一版形变,spec 具名 schema `TerminalBlockedDetail` 的 enum 同批);认不得的词读作「hook 座挡下了提示,成因不认识」。
1150
+ * 属主是 core 包根 `PROMPT_BLOCK_CAUSES`;测试对已装 core 的真常量做四方相等(core / spec enum / 本型的词 / server 处置表)。
1151
+ */
1152
+ export type PromptBlockCause = "block" | "crashed" | "timeout" | "cancelled";
1153
+ /**
1154
+ * `terminal.kind:"blocked"` 的机读成因(`TerminalCause` blocked 臂的 `detail`;server ≥7.113.0 / core #1277)。`kind` 闭集、今天一个成员。
1155
+ * 它回答的是**谁**让这条 run 没干活:提示**没有被提交**(目标没成消息、循环没起)—— 改了提示再发才有意义;`cause` 说是 hook 的哪种收场。
1156
+ * **在场 ⇔ 就是这一形**;缺席 = agent 自己 `ReportBlocked`(「我继续不了」),或 server <7.113.0 —— **按 `detail?.kind` 分支,别按 `reason` 的散文**。
1157
+ * 同一只对象四面同形(同步 200 体 / 流 `done.result` / `GET /v1/runs/:id` 的 `result` / 账本 `done` 行)。
1158
+ */
1159
+ export interface TerminalBlockedDetail {
1160
+ kind: "prompt_blocked_by_hook";
1161
+ cause: PromptBlockCause;
1162
+ /** hook **自己**拒绝提示的话:折成一行、有界、引擎的信封标签已拆;**只在 `cause:"block"` 且 hook 给了话时在场**。仍是 hook 的文本 ⇒ 渲染时按**不可信**处理;
1163
+ * 与 `reason` 过同一只脱敏。从不带引擎的提醒框与会话标记(那一句是 `reason`)。 */
1164
+ hookReason?: string;
1165
+ }
1091
1166
  /** Synchronous task result (`POST /v1/tasks`). */
1092
1167
  export interface TaskResult {
1093
1168
  taskId: string;
@@ -1157,6 +1232,26 @@ export interface TaskResult {
1157
1232
  atTurn: number;
1158
1233
  };
1159
1234
  structuredOutput?: unknown;
1235
+ /** server ≥7.57.0(S-94;契约 §5.3;K-43 —— sdk 16.0.0 具名,此前只能经本型的开集索引读成 `unknown`)—— **用户取消的现场快照**,终局结果上的侧记键,与 `abortCause` 并列
1236
+ * (同一只铸点 `mintCancelledResult`、同一条「只补空座」在场闸;都**不**进 `terminal`)。**只在 server 铸的取消终局上在场**;模型自己失败 / 正常完成 ⇒ 缺席;
1237
+ * 四键一键都证不出 ⇒ 整只缺席(**不铸空对象**:缺席读作「没有取消现场可看」,不是「取消时没有异常」)。四键读法与缺席纪律见 {@link CancelContext}。
1238
+ * 落点同 {@link abortCause} 列的取消终局落点(`GET /v1/runs/:id` → `result.cancelContext` 是它最常被读的一处)。 */
1239
+ cancelContext?: CancelContext;
1240
+ /** server ≥7.112.0(S-947;契约 §5.0d;cli L-212;**additive**)—— server 发起的中止的**机读成因**,终局结果上的侧记键,与 `cancelContext` 并列
1241
+ * (**不**进 `terminal`:那是引擎的因由,同一个对象不该有两个铸者)。**在场 ⇔ 这条终局就是 server 那次中止铸出来的取消终局**
1242
+ * (`terminal.kind:"failed"` + `terminal.code:"cancelled"`);本服务 ≥7.112.0 铸的取消终局恒带(铸点的成因是必填参数,引擎从不自铸 `cancelled`)。
1243
+ * 🔴 与 `errorCode: "cancelled"` 并列、**不取代它**:行的 `errorCode` 列 / `terminal.code` 仍是「这是取消终局」的判据,语义不变;本键只回答「谁让它停的」。
1244
+ * **缺席**(不是 server 那次中止铸出来的取消终局):detach 断连(`x-detach-on-disconnect: true`,server 不中止)· 引擎自己的失败 · 正常完成 ·
1245
+ * `POST /v1/runs/:id/interrupt`(终局 `completed` + `haltedByUser`)· park(含 #241 宽限内 park 成)· 与中止**赛跑**的终局(引擎先跑完 / 引擎自带码的失败 ——
1246
+ * 「只补空座」:码、快照、成因一起不挂)· 续跑腿在审批过的动作开跑**之前**被取消(引擎改判 `resume.reopened_unstarted`、park 重开,run 没被结掉)· 抢占 · 有序关停 · 失联收割。
1247
+ * 🔴 **7.112.0 之前落盘的取消行没有这一位,本版不回填**:一条 `errorCode:"cancelled"` 而本键缺席 = 老行,读作「成因未记录」,**别折成任何一个词**。
1248
+ * 四个落点(同一个值):`GET /v1/runs/:id` → `result.abortCause`(与 `result.cancelContext` 并列)· `POST /v1/tasks/stream` 的 `done.result.abortCause` ·
1249
+ * `POST /v1/tasks` 200 体**顶层** `abortCause`(体 = 结果本身,§5.0c)· `GET /v1/runs/:id/events` 的 `done` 行 `result.abortCause`;
1250
+ * **没有 `done` 可落**的取消形(断连后没读到 done / 腿在终局前被中止抛出)落 `failed` 行**顶层**、与 `errorCode` 并列(见 `events.ts` 的 `failed` 臂)。
1251
+ * ⚠️ 同批两处 wire **值**变更(不是新键):① 续跑腿**审批过的动作开跑后**被取消 ⇒ `failed` + `errorCode:"cancelled"` + `cancelContext` 快照 + `abortCause:"cancel_verb"`
1252
+ * (修前是**无码**的 `failed`);② `POST /v1/tasks/stream` 没读到 `done` 且本腿**没被** server 中止 ⇒ 诚实失败句 `stream ended before a terminal event`
1253
+ * (无码、无 `abortCause`;修前一律铸成「客户端断连」的取消终局)。三词各自是谁发起、怎么读:{@link AbortCause}。 */
1254
+ abortCause?: AbortCause;
1160
1255
  [k: string]: unknown;
1161
1256
  /** server ≥7.92.0(additive,老 server 缺席——判 `'wiringManifest' in result`,不判 `=== undefined`):**起手接线回执**,
1162
1257
  * = 该 run 的 `wiring_manifest` 帧(引擎接线后、首 turn 前那一帧)经与流式腿**同一只**投影器投出的对象(租户形剥
@@ -2009,6 +2104,19 @@ export interface RunRecord {
2009
2104
  * 字段 OMIT(不是伪造空对象)。此前误放进 `TaskStats`(嵌套,永远读不到)且误标量成 number(真实是
2010
2105
  * `{llm,infra,totalMicroUsd}` 富对象)——两处都改。 */
2011
2106
  supervisorCost?: SupervisorCostBreakdown;
2107
+ /** 🔴 K-43(sdk 16.0.0 补型;**server ≥7.73.0 / S-230 P-45 起就在真 `GET /v1/runs/:id` 上**,契约 §5.5 (c),封闭 spec 一直没声明 —— K-41 同病)——
2108
+ * **此刻持有**这条 run 的副本(行的 `instance_id`:`createRun` 写、跨副本续跑的 `markResuming` **接管**),答的是「活腿现在在哪」,不是「谁建的行」。
2109
+ * server ≥7.73.0 上**恒在场**,**显式 `null`**(不是键缺席)= 没有副本持有;< 7.73.0 缺席。
2110
+ * 🔴 契约:`heldBy` 变 `null` **或** run 进终态 = 这条 claim 已释放(两者任一);终态行上的 `heldBy` 读作「哪个副本跑完的」这一历史事实,不是「还占着」。
2111
+ * ⚠️ 唯一例外是 **stale 折叠**:`running` 且超过 stale 窗的行,读面把 `status` 折成 `failed`(伴 `error: "run stalled (instance lost?)"`)—— 那是读面的判断,
2112
+ * 盘上的行仍是 `running`、claim 要到 reaper 下一拍才释放,`heldBy` 照旧逐字给出那台**失联**副本的 id(排障时唯一有用的坐标)。
2113
+ * 部署内的副本标识,**不是**用户可读的位置。 */
2114
+ heldBy?: string | null;
2115
+ /** 🔴 K-43(同上,server ≥7.73.0 / S-230 P-45 起恒在场,契约 §5.5 (c))—— **耐久取消旗**(跨副本;持有副本的心跳拍 poll 它)。
2116
+ * ⚠️ 它是**待生效**的取消:已经取消掉的 run 由 `status` + `errorCode:"cancelled"` 说(park 臂的取消**根本不经这面旗**,直接把行终局化);
2117
+ * 续跑认领会把旗清零(撞上 suspend 的取消不许在恢复之后再杀一遍)。⇒ **别**把 `cancelRequested` 翻回 `false` 读成「取消完成」—— 等终态 `status` + `errorCode:"cancelled"`。
2118
+ * `POST /v1/runs/:id/cancel` 的受理体带同一个键({@link CancelAck.cancelRequested},同一个谓词)。< 7.73.0 缺席。 */
2119
+ cancelRequested?: boolean;
2012
2120
  }
2013
2121
  /** Run list item (`GET /v1/tasks` items) — the live cheap `runSummary` shape (service Drift 1).
2014
2122
  * NOTE wire names: `id` (not taskId), `startedAt` (not createdAt), `costMicroUsd` (micro-USD); no sessionId. */
@@ -2252,7 +2360,7 @@ export type DeniedBy = "policy" | "hook" | "org" | "persisted_rule" | "classifie
2252
2360
  */
2253
2361
  export type PermissionMode = "default" | "acceptEdits" | "plan" | "auto" | "bypassPermissions" | "dontAsk";
2254
2362
  /**
2255
- * 一只问**属于哪一类**(core 7.34.0 `ASK_CLASSES`,二十词;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2363
+ * 一只问**属于哪一类**(core `ASK_CLASSES`:7.34.0 铸二十词,core 7.39.0 起 `shell_floor` 入册 ⇒ 二十一词;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2256
2364
  * {@link ModeRelease.askClass} / `.classes` 与 deny 臂的 `askClass` / `classes` 上,以及通告 `permission.ask_released_by_mode` 的 detail 里;
2257
2365
  * K-37 扩项 / server ≥7.109.0(S-934 ②)起也在审批面:活卡帧 / 卡面 / 运维队列行 / `/stream` `pending` 帧的 `askClass` / `classes`
2258
2366
  * (同样经 core `isAskClass` 筛,读不出整对不投;见 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.askClass})。
@@ -2261,7 +2369,10 @@ export type PermissionMode = "default" | "acceptEdits" | "plan" | "auto" | "bypa
2261
2369
  * `artifact_shared_read` / `mode` / `ordinary`);其余(`operator_forced` 部署出身、`ask_rule` / `org_rule`、`hook`、`ancestor`、`content_question`、
2262
2370
  * `unverifiable_delete`、`governance_unavailable`、`policy_rra` …)任何模式下都照问。
2263
2371
  */
2264
- export type AskClass = "content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "operator_forced" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "ordinary";
2372
+ export type AskClass = "content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "operator_forced"
2373
+ /** core 7.39.0(#1260;server ≥7.113.0 提货):运维旋钮 `shellGate: "always"` 在**跑 shell 的席位**上的地板 —— `operator_always` 授权词所披露的那一问,
2374
+ * 自己成一类,免得持有另一种强制问的类集把它藏掉。与 `operator_forced` 同样**免疫 bypass**(不在 `bypassPermissions` 可放的九类里)。 */
2375
+ | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "ordinary";
2265
2376
  /**
2266
2377
  * 一个权限**模式放行**了一只本该问人的 ask 的记录(K-32 扩项;server ≥7.106.0 / core 7.34.0 `ModeRelease`,键集逐键同 core
2267
2378
  * `dist/core/gate-outcome.d.ts`)—— 只挂在 `allowed` 臂上({@link GateDisposition}):这一次**没有问任何人**,是模式放的。
@@ -2375,6 +2486,19 @@ export type Settlement = {
2375
2486
  when: number;
2376
2487
  /** 拒批人附的那句话。**没有 note 的拒 = 一句干脆的「不」**,不是「没说理由的 bug」。 */
2377
2488
  note?: string;
2489
+ } | {
2490
+ /** 🔴 **policy 一方**(core 7.39.0 / server ≥7.113.0;sdk 16.0.0 补型 —— 查漏轮逼出,不在 7.113.0 发车帖七件里):**这台部署自己的策略**做了决定 —— 审批通道报告「答这一问的是机器、不是人」。
2491
+ * 人与策略是两类**决策者**:各自可答可拒,只在记录点名谁的决定上不同(`human_*` 点名人,`policy_*` 点名策略)。
2492
+ * server 7.113.0 的**值变更**(MIGRATION「审计面」):无人值守腿(leader worker / 修复腿 / `sema` CLI 及其续跑)上**机器按类放行**的那一问,结算从 `human_allowed` + `who.party:"person"`
2493
+ * 改为 **`policy_allowed` + `who.party:"policy"` + `who.approver:"unattended_class_answer"`**;一切**策略拒**(`UNATTENDED_APPROVAL_POLICY=deny`、run-local 无 TTY 的拒、`settledBy:"policy"` 的决裁)
2494
+ * 是 `policy_refused` + **`who.party:"policy"`**(此前是 `"none"`;下面 fail-closed 臂里那一形仍是 server 7.93.3 – 7.112.x 的真形,支持区间内保留)。按 party 词分桶的审计读者改读新词;
2495
+ * 7.112.x 的读面不认 party `policy`,读到 7.113.0 写下的这两种记录会把整条 `gate` 扣下。策略拒的话由引擎当**策略的话**送给模型,**不在**本记录上(没有 `note` 席)。 */
2496
+ kind: "policy_allowed" | "policy_refused";
2497
+ who: {
2498
+ party: "policy";
2499
+ approver?: string;
2500
+ };
2501
+ when: number;
2378
2502
  } | {
2379
2503
  /** 审批窗走完了没人答:引擎自己的审批工厂窗,或同步宿主 approver 报「我的窗到了」。 */
2380
2504
  kind: "approval_window_expired";
@@ -2413,7 +2537,8 @@ export type Settlement = {
2413
2537
  * 用户的指示,一条策略的「不行」是这次 run 的一项能力。与 `no_approver` 分家是因为审批通道**在**且
2414
2538
  * 答了 —— 引擎没有回落到它自己的 headless 姿态。🔴 **本臂没有 `note` 席**:那一席属于两个 human 词
2415
2539
  * 〔它的**缺席**在那两个词上是一条控制流事实〕;策略自己的话由引擎当**策略的话**上围栏送给模型)/
2416
- * `task_aborted`(等待的中止信号结束了它)。 */
2540
+ * `task_aborted`(等待的中止信号结束了它)。
2541
+ * 🔴 **server ≥7.113.0(core 7.39.0)起策略拒写成 `who.party:"policy"`**(见上面的 policy 臂);本臂里 `policy_refused` + `none` 是 server 7.93.3 – 7.112.x 的老形,支持区间内保留。 */
2417
2542
  kind: "no_approver" | "approver_unavailable" | "approver_error" | "approver_contract" | "presentation_failed" | "blanket_allow_refused" | "policy_refused" | "task_aborted";
2418
2543
  who: {
2419
2544
  party: "none";
@@ -2435,7 +2560,7 @@ export type Settlement = {
2435
2560
  * · **I2** `deniedBy === "ask_resolution"` ⇒ `settlement` 在场且是拒绝类词;
2436
2561
  * · **I3** `human_allowed` 结算旁边出现 `denied` 处置 ⇒ 那是**人批了之后的复查**否决,`deniedBy` 必是可否决层
2437
2562
  * (`policy` / `hook` / `org` / `write_protection`),而 approver 留在结算上(这不是 approver 的拒);
2438
- * · **I4** `allowed` 处置 ⇒ `settlement` 缺席或恰是 `human_allowed`。
2563
+ * · **I4** `allowed` 处置 ⇒ `settlement` 缺席或恰是一只**决策者的放行词**(`human_allowed`,server ≥7.113.0 起还有 `policy_allowed`)。
2439
2564
  *
2440
2565
  * 🔴 **没有任何一项从缺席读出来**:普通放行是 `{ disposition: { kind: "allowed" } }`,直接策略拒是
2441
2566
  * `{ disposition: { kind: "denied", deniedBy: "policy" } }`,两者都不带结算 —— 因为两者都没结算过什么。
@@ -4382,7 +4507,8 @@ export interface SessionRecord {
4382
4507
  * in `messages`. */
4383
4508
  promptEpoch?: PromptEpoch;
4384
4509
  /** server ≥7.110.0(S-928 用户输入受理账本):这个会话里**崩溃丢掉**的用户输入 —— server 回了 200 `applied`(interrupt{text}:202)、
4385
- * 承载它的 server 进程却在那条 run 收场前死了(消费与否**未知**,见 `engine_notice` `task.user_steer_undrained{cause:"crashed"}`)。
4510
+ * 承载它的 server 进程却在那条 run 收场前死了(**引擎在进程死前没来得及确认消费**;server ≥7.113.0 / core 7.39.0 #1273 起引擎确认消费过的受理结清成 `consumed`、
4511
+ * **不再**列在这里 —— 7.112.x 及以前「消费与否未知」的口径随之收窄;它**仍不**说「从未消费」,见 `engine_notice` `task.user_steer_undrained{cause:"crashed"}`)。
4386
4512
  * 只列收敛行、同 (taskId, messageId) 一行、至多最新 500 条;`announced` = 已在哪条新 run 首拍告知过。server ≥7.111.0(S-966)起行里**含同步子代的 steer**
4387
4513
  * (记在回执上那条 run 名下,`messageId` = 那张子代 steer 回执的 `messageId`,行形与 run steer 同 —— `kind` 仍只有 `"steer"`)。**缺席 = 这一次读没有可报的条目**
4388
4514
  * (零条,或这一次账本读不出 —— 权威告知是 run 流上的通告帧,不是本键);`?message=` 单条形不带。 */
@@ -4901,6 +5027,10 @@ export interface CancelAck {
4901
5027
  * (可为显式 `null`),而不是伪造一个 `cancelled`。
4902
5028
  * 纯 `cancelling` 受理形(`:537`)与 no-op 分支则整个 OMIT 这个键(不是恒在场)。 */
4903
5029
  errorCode?: string | null;
5030
+ /** 🔴 K-43(sdk 16.0.0 补型;**server ≥7.73.0 / S-230 P-45 起每一个 2xx 受理体都带它**,契约 §5.5 (c),封闭 spec 一直没声明)—— 与
5031
+ * {@link RunRecord.cancelRequested} **同一个谓词**(耐久取消旗):`status:"cancelling"` 那一支为 `true`(CAS 刚赢,旗在行上,持有副本下一拍读到);
5032
+ * park 臂的终局支为 `false`(park 的 run 被直接终局化,不需要旗);幂等 no-op 与并发终局化两支如实回**行上的旗值**(契约 §5.5 (c) 的账是 `false`)。< 7.73.0 缺席。 */
5033
+ cancelRequested?: boolean;
4904
5034
  }
4905
5035
  /** Leader run (`POST /v1/leader`) — the **v2 leader pipeline** (E2B workers + git push), gated server-side
4906
5036
  * (`LEADER_ENABLED` + `REMOTE_EXEC=e2b`, both default OFF). Mode is a SERVER deploy flag, NOT a client choice: