@sema-agent/sdk 16.0.1 → 16.2.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.
Files changed (81) hide show
  1. package/README.md +125 -1
  2. package/dist/errors.d.ts +53 -11
  3. package/dist/errors.d.ts.map +1 -1
  4. package/dist/errors.js +32 -4
  5. package/dist/errors.js.map +1 -1
  6. package/dist/events.d.ts +4 -0
  7. package/dist/events.d.ts.map +1 -1
  8. package/dist/events.js.map +1 -1
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/registry/admin.d.ts +3 -1
  13. package/dist/registry/admin.d.ts.map +1 -1
  14. package/dist/registry/admin.js +4 -2
  15. package/dist/registry/admin.js.map +1 -1
  16. package/dist/resources/adoption.d.ts +2 -1
  17. package/dist/resources/adoption.d.ts.map +1 -1
  18. package/dist/resources/adoption.js +2 -1
  19. package/dist/resources/adoption.js.map +1 -1
  20. package/dist/resources/approvals.d.ts +10 -3
  21. package/dist/resources/approvals.d.ts.map +1 -1
  22. package/dist/resources/approvals.js +11 -3
  23. package/dist/resources/approvals.js.map +1 -1
  24. package/dist/resources/assistant.d.ts +4 -2
  25. package/dist/resources/assistant.d.ts.map +1 -1
  26. package/dist/resources/assistant.js.map +1 -1
  27. package/dist/resources/leader.d.ts +5 -4
  28. package/dist/resources/leader.d.ts.map +1 -1
  29. package/dist/resources/leader.js +5 -4
  30. package/dist/resources/leader.js.map +1 -1
  31. package/dist/resources/memory.d.ts +6 -2
  32. package/dist/resources/memory.d.ts.map +1 -1
  33. package/dist/resources/memory.js +3 -1
  34. package/dist/resources/memory.js.map +1 -1
  35. package/dist/resources/ops.d.ts +3 -0
  36. package/dist/resources/ops.d.ts.map +1 -1
  37. package/dist/resources/ops.js +3 -0
  38. package/dist/resources/ops.js.map +1 -1
  39. package/dist/resources/rules.d.ts +4 -3
  40. package/dist/resources/rules.d.ts.map +1 -1
  41. package/dist/resources/rules.js +3 -3
  42. package/dist/resources/rules.js.map +1 -1
  43. package/dist/resources/runs.d.ts +20 -6
  44. package/dist/resources/runs.d.ts.map +1 -1
  45. package/dist/resources/runs.js +3 -2
  46. package/dist/resources/runs.js.map +1 -1
  47. package/dist/resources/session-sync.d.ts +11 -7
  48. package/dist/resources/session-sync.d.ts.map +1 -1
  49. package/dist/resources/session-sync.js +9 -6
  50. package/dist/resources/session-sync.js.map +1 -1
  51. package/dist/resources/sessions.d.ts +16 -5
  52. package/dist/resources/sessions.d.ts.map +1 -1
  53. package/dist/resources/sessions.js +15 -4
  54. package/dist/resources/sessions.js.map +1 -1
  55. package/dist/resources/tasks.d.ts +7 -1
  56. package/dist/resources/tasks.d.ts.map +1 -1
  57. package/dist/resources/tasks.js +7 -1
  58. package/dist/resources/tasks.js.map +1 -1
  59. package/dist/resources/tool-approvals.d.ts +24 -3
  60. package/dist/resources/tool-approvals.d.ts.map +1 -1
  61. package/dist/resources/tool-approvals.js +6 -0
  62. package/dist/resources/tool-approvals.js.map +1 -1
  63. package/dist/resources/workflows.d.ts +5 -2
  64. package/dist/resources/workflows.d.ts.map +1 -1
  65. package/dist/resources/workflows.js +5 -2
  66. package/dist/resources/workflows.js.map +1 -1
  67. package/dist/settings.d.ts +34 -8
  68. package/dist/settings.d.ts.map +1 -1
  69. package/dist/sync.d.ts +19 -2
  70. package/dist/sync.d.ts.map +1 -1
  71. package/dist/sync.js +88 -2
  72. package/dist/sync.js.map +1 -1
  73. package/dist/transport.d.ts +2 -0
  74. package/dist/transport.d.ts.map +1 -1
  75. package/dist/transport.js +2 -0
  76. package/dist/transport.js.map +1 -1
  77. package/dist/types.d.ts +213 -30
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js.map +1 -1
  80. package/openapi.yaml +497 -74
  81. package/package.json +2 -2
package/dist/types.d.ts CHANGED
@@ -253,7 +253,12 @@ export interface TaskRequest {
253
253
  * 要求 `sessionId` **已经存在**。`true` 且会话真的不在(过期/清掉/从未建过)⇒ 这一 run **FAIL LOUD**
254
254
  * (`resume.session_not_found`),而不是静默开一个全新空会话(「看着是热的、其实是冷的」——续传方最贵的
255
255
  * 静默失败形)。缺省/`false` ⇒ 历史的 create-on-miss。**不带 `sessionId` 时送 `true` 也 fail loud**
256
- * (没有可续的东西)。随持久化 body 骑到 resume 腿上。 */
256
+ * (没有可续的东西)。随持久化 body 骑到 resume 腿上。
257
+ *
258
+ * 🔴 **两处拒的码与状态(server ≥7.115.0 / S-1038;此前两处的 `errorCode` 都是状态派生的粗码,码只写在句尾括注里)**:`sessionId` 在本部署不存在 ⇒ **404 `resume.session_not_found`**
259
+ * (前提:会话店答得了归属 `ownerOf` —— SQL / local / 引擎缺省内存店都有);没给 `sessionId` ⇒ **422 `request.field_conflict`**(请求自相矛盾:`sessionId` 是它的前置;**不是**「会话不存在」,
260
+ * 契约里本码唯一的 422)。`POST /v1/tasks` / `/v1/tasks/stream` / `/v1/runs` 三口同体,授权在 SSE 头之前 ⇒ 流式口拿到的也是真状态。按 `errorCode` 分派;
261
+ * 旧粗码 `not_found.resource` / `request.unprocessable` 与句尾括注都不是依据(本包没有按它们分派的代码)。 */
257
262
  requireExistingSession?: boolean;
258
263
  /** 🔴 D1 补型(2026-07-29;形自 server `src/http/wire-types.ts` 亲读)—— design/142-S4:这一 run 归属的**项目**
259
264
  * (center 登记簿键,generic 小写 UUID)。**纯选择器,不是身份/capability**:scope 的 tenant 段永远来自
@@ -304,8 +309,19 @@ export interface TaskRequest {
304
309
  * {@link import("./settings.js").SemaSettings.skillListingMaxDescChars} 两只旋钮。
305
310
  *
306
311
  * Merge: scenario WINS on name collision (user's dropped + warn-logged) — the safety baseline can't be
307
- * overridden. Injected by the trusted BFF, never raw user input. */
312
+ * overridden. Injected by the trusted BFF, never raw user input.
313
+ *
314
+ * 🔴 **server ≥7.116.0:每只技能可带 `allowedTools` / `disallowedTools`(本 run 的 allow / deny 规则来源,不是围栏 —— 读法与比 `settings.permissions.allow` 宽的口径见
315
+ * {@link SkillSpec.allowedTools};探测位 `capabilities.skillToolLists`),技能的 `manifest` 键提交即 400**(core 7.41.0 退役;`manifest.allowTools` 改写成 `allowedTools`)。 */
308
316
  skills?: SkillSpec[];
317
+ /** server ≥7.116.0(core 7.41.0 #1303):**人用名字点过的技能**(壳从人敲的 `/name` 解析出来的,按 {@link SkillSpec.name})—— 非空串数组。这些技能的
318
+ * `allowedTools` / `disallowedTools` **开跑即生效、不出 `Skill` 卡**(人自己点的名就是那句表态);**只管这一次** run(steer 不终止它,下一次提交不带)。
319
+ * 每个名字必须是这一 run 装着的技能(场景出厂 ∪ 本请求 `skills`),否则引擎拒启 **400 `config.user_invoked_skill_unknown`**(同步腿 `POST /v1/tasks`;
320
+ * 异步 / 活流腿 HTTP 2xx、同码落在终态 run 行);`disableSkills: true` 时点任何名字都是这个码。值形坏(裸串 / 含空串 / 含非串 / 对象 / null)⇒ 400
321
+ * `request.field_invalid`。不投递技能正文(正文照旧由 `Skill` 工具 / 调用方负责)。
322
+ * 🔴 **先探 `capabilities.userInvokedSkills`**(恒真):位缺席 = 老 server ⇒ **别发这个键**(≤7.115.x 答 400 `request.body_shape`,`unknownKeys` 逐字列名)。
323
+ * 清单的读法见 {@link SkillSpec.allowedTools}(比同版 `settings.permissions.allow` 宽;托管 / 多租户部署不设开关)。 */
324
+ userInvokedSkills?: string[];
309
325
  /** Per-turn reasoning strength (CC `/effort` parity). One of the core ThinkingLevel tiers:
310
326
  * `off`|`minimal`|`low`|`medium`|`high`|`xhigh`|`max`. Service maps it → `TaskSpec.thinking`
311
327
  * (server.ts reasoningEffort → main.ts:1270); an UNKNOWN value is a 400 (fail-loud). Omit ⇒ engine
@@ -504,7 +520,8 @@ export interface TaskRequest {
504
520
  * 全部去掉」那个形。边界由 core 判,server **原样透传**它的拒绝码供壳渲染:
505
521
  * `resume_at.before_target_not_user`(只接受普通 user 消息作目标)、
506
522
  * `resume_at.before_root_unsupported`(不能倒退过会话根 —— 该开新会话了)、
507
- * `rewind_snapshot.unresolvable`(配 `rewindFiles` 时:分叉点及其之上没有快照)。
523
+ * `rewind_snapshot.unresolvable`(配文件还原 `restoreFiles` 时:目标自己没有文件历史边界 —— `before` 的还原只认目标**自己**的边界、不会越到更早一回合;
524
+ * 退役拼法 `rewindFiles` 的还原义是 core 的迁移拒,点名 `restoreFiles`)。
508
525
  * **只在配 `resumeAt` 时有意义**;单独送 = 400 fail-loud(不是静默 no-op)。 */
509
526
  resumeAtMode?: "at" | "before";
510
527
  /** ⚰️ **退役拼法**(整树快照纪元;S-15 / design/381,server ≥7.52 起;sdk 11.4.0 注改真,与 {@link rewindFilesTo} 同一类陈旧注 [8437] U3)。
@@ -561,8 +578,8 @@ export interface TaskRequest {
561
578
  * · **ABSENT(两个载体都不带模式)= `default`**(不再是「无门」):非只读 shell 命令与每一次写先问;有审批席 / durable park 的腿上是卡,无人应答的
562
579
  * 腿上 headless 拒(拒句点名 `permissionMode:"acceptEdits"` / 接审批席)。要旧的「不问」就显式发 `acceptEdits`(工作区内写不问)或
563
580
  * `bypassPermissions`(托管部署 422 `request.host_posture_refused`)。
564
- * · `bypassPermissions` **放行并披露**可放的九类 ask(写保护、根外读探针、MCP / A2A 工具标记、transcript 写、规则店读不出〔安全轴 fail-open,单列〕、
565
- * 他人共享 artifact 读、模式自己的问、普通 / 形状层的问)—— 逐调用记在 `tool_end.gate.disposition.released`({@link ModeRelease}),每 (模式, 类)
581
+ * · `bypassPermissions` **放行并披露**可放的十类 ask(写保护、根外读探针、MCP / A2A 工具标记、transcript 写、规则店读不出〔安全轴 fail-open,单列〕、
582
+ * 他人共享 artifact 读、模式自己的问、没人表态的服务器工具调用〔`unstated`,server ≥7.115.0〕、普通 / 形状层的问)—— 逐调用记在 `tool_end.gate.disposition.released`({@link ModeRelease}),每 (模式, 类)
566
583
  * 每 run 一帧 `engine_notice` `permission.ask_released_by_mode`;免疫类(部署出身 `operator_forced`、ask / org 规则、hook、祖先、问答 …)照问。
567
584
  * 判不出保护目标的写仍拒(`deniedBy:"mode"`)。
568
585
  * · `auto` 武装 ⟺ `permissionMode === "auto"` ∧ 部署挂了分类器席 ∧ `caps.autoMode !== false`(单极;答旧极性的那一位 server 7.107.0 起删,
@@ -844,7 +861,11 @@ export interface TaskRequest {
844
861
  * `deadlineNudge`/`callCapByDeadline`/`gracefulFinalize`)fresh-submit 一律 400 点名替代——**不进本类型**。
845
862
  * `approachNotice`(server ≥6.1.0):限额临近提示默认 ON(80%/95% 各一次);literal `false` 关,
846
863
  * `{at:[r1,r2]}` 调阈((0,1] 且 r1<=r2,坏形 400)。键集与 server `src/http/wire-types.ts`
847
- * `TaskRequestBody.limits` 同源(server 侧 sdk-live-parity [RB-limits] 臂机器对拍)。 */
864
+ * `TaskRequestBody.limits` 同源(server 侧 sdk-live-parity [RB-limits] 臂机器对拍)。
865
+ *
866
+ * 🔴 键集**闭**(与 server `TaskRequestBody.limits` 发布 d.ts 同四键):`limits.brainCallGuardrailMs`(core 的「单次脑调用外墙」,缺省一小时,`false` / `0` 关)**不在其中** ——
867
+ * server ≥7.115.0 对它**提交即 400 `request.field_invalid`**(毫秒数 / `false` / `0` 三形同拒,句子点名这个键;≤7.114.x 受理但不生效、外墙照旧一小时);
868
+ * 本服务没有给调用方设这道外墙的口。对象字面量里写它 = TS2353;`budgetStreamCancel` / `degrade` 同属「不可由调用方设」。 */
848
869
  limits?: {
849
870
  maxWalltimeMs?: number;
850
871
  maxOutputTokens?: number;
@@ -891,12 +912,20 @@ export interface TaskAgentDefinition {
891
912
  allowTools?: string[];
892
913
  /** Denylist of tool names (subtractive; applied after `allowTools`). */
893
914
  denyTools?: string[];
894
- /** Skills preloaded into the agent: `{ name, description, content }` (+ optional manifest/files). */
915
+ /** Skills preloaded into the agent: `{ name, description, content }` (+ optional allowedTools / disallowedTools / files).
916
+ * server ≥7.116.0:子代技能受理两只清单(`allowedTools` / `disallowedTools`,读法见 {@link SkillSpec.allowedTools};≤7.115.x 是未知键整条拒)。 */
895
917
  skills?: Array<{
896
918
  name: string;
897
919
  description: string;
898
920
  content: string;
921
+ /** @deprecated server ≥7.116.0 **整条技能拒**(子代技能上 `manifest` 是未知键 ⇒ `agent.skills must be …` 400;顶层技能是 400 `request.field_invalid`,
922
+ * 句首 `skill.manifest was retired in core 7.41.0 — `)—— core 7.41.0 退役了技能 `manifest`(硬破坏,零别名)。**改写**:`manifest.allowTools` →
923
+ * 技能的 `allowedTools`(语义变了:allow 规则来源、不是围栏,见 {@link SkillSpec.allowedTools});写围栏 `allowPaths` 没有替身
924
+ * (圈写路径用会话规则 `allowDirs`)。详见 server 随包 `MIGRATION.md` 7.116.0 节。
925
+ * 本成员**留着**:老一代 server(≤7.115.x)仍收它,删公开成员 = major,下个 major 删;对 ≥7.116.0 的 server 别再发。 */
899
926
  manifest?: Record<string, unknown>;
927
+ allowedTools?: string[];
928
+ disallowedTools?: string[];
900
929
  files?: Array<{
901
930
  path: string;
902
931
  content: string;
@@ -2063,7 +2092,17 @@ export interface RunRecord {
2063
2092
  result?: TaskResult | LegacyPlaneTaskResult;
2064
2093
  /** 本**行的列**,7.64.0 未变(照旧说五词);只是数据源改成从 `result.terminal` 投影一次(旧行则直接读平面键)。
2065
2094
  * ⚠️ K-24 / S-173(server ≥7.104.0):`needs_review` park 行上本位 = core 的规范码 **`review.pending`**(此前缺席)——
2066
- * **禁**把「本位在场」读成失败,先读 `status`。`suspended` park 行缺席。 */
2095
+ * **禁**把「本位在场」读成失败,先读 `status`。`suspended` park 行缺席。
2096
+ *
2097
+ * 🔴 **server ≥7.116.0 多三种取值(additive 读面;S-1099)**:run 店自己判的终局此前只在 `error` 句子里,现在同时带机读码 ——
2098
+ * **`run.stalled`**(失联收割:心跳旧于 `REAP_RUN_STALE_SEC` 的 `running` 行被收割;读面在收割落盘前提前折叠的那一形同码;句子 `run stalled (instance lost?)`)·
2099
+ * **`run.orphaned`**(local 车道重启回收 / 会话占用接管回收;句子 `run orphaned by engine restart`)·
2100
+ * **`approval.expired`**(审批过期收割:耐久审批停驻的 run 过期被收割;行上码列早就有,读面此前不投;句子 `approval expired before decision`)。句子照旧。
2101
+ * 这三码都**不是请求写错**,重试同一请求无意义,重新提交才有新 run;按 `error` 句子判「持有者没了」的消费端改按本码判;把「`errorCode` 在场」读成「core 报了错」的消费端
2102
+ * **先读 `status`**(`failed`)再按码分支。本位**仍是开集串**(词表属主在 server / core,分支永远带 `default`),没有闭集可加。
2103
+ * 🔴 **缺席语义(旧行)**:升级前(≤7.115.x)写下的死亡判决行只有 `error` 句子、码列为空 —— 7.116.0 每次起服做**一次性迁移补码**(`one_time_migrations_applied` 的
2104
+ * `holderDeathCodeRowsBackfilled`),SQL 后端的新副本读这种行时同样读成码(升级窗);**但迁移有窗**(发布日 + 30 天之后的第一个小版本把写回与读侧一起删),
2105
+ * 删后仍只有句子的行不再带码、`errorCode` 缺席 —— 所以「本位缺席 ≠ 不是持有者死亡」,**旧行迁移补码之后仍可能无码**,别拿缺席反推别的。 */
2067
2106
  errorCode?: string;
2068
2107
  error?: string;
2069
2108
  /** Work-view correlation. Present when the run has a jobId (omitted when null). LIVE server-side
@@ -2360,19 +2399,35 @@ export type DeniedBy = "policy" | "hook" | "org" | "persisted_rule" | "classifie
2360
2399
  */
2361
2400
  export type PermissionMode = "default" | "acceptEdits" | "plan" | "auto" | "bypassPermissions" | "dontAsk";
2362
2401
  /**
2363
- * 一只问**属于哪一类**(core `ASK_CLASSES`:7.34.0 铸二十词,core 7.39.0 起 `shell_floor` 入册 ⇒ 二十一词;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2402
+ * 一只问**属于哪一类**(core `ASK_CLASSES`:7.34.0 铸二十词,core 7.39.0 起 `shell_floor` 入册 ⇒ 二十一词,core 7.40.0 起 `unstated` 入册 ⇒ 二十二词,core 7.41.0 起 `requires_user_interaction` 入册 ⇒ **二十三词**;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2364
2403
  * {@link ModeRelease.askClass} / `.classes` 与 deny 臂的 `askClass` / `classes` 上,以及通告 `permission.ask_released_by_mode` 的 detail 里;
2365
2404
  * K-37 扩项 / server ≥7.109.0(S-934 ②)起也在审批面:活卡帧 / 卡面 / 运维队列行 / `/stream` `pending` 帧的 `askClass` / `classes`
2366
2405
  * (同样经 core `isAskClass` 筛,读不出整对不投;见 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.askClass})。
2367
- * 🔴 **门记录这一面是真闭集**(server 按 core `isAskClass` 筛,出集整条不上帧)。`bypassPermissions` 只放行其中**可放**的九类
2406
+ * 🔴 **门记录这一面是真闭集**(server 按 core `isAskClass` 筛,出集整条不上帧)。`bypassPermissions` 只放行其中**可放**的十类
2368
2407
  * (core `RELEASABLE_ASK_CLASSES`:`transcript_write` / `rule_unreadable` / `probe` / `write_protection` / `tool_marks_mcp` / `tool_marks_a2a` /
2369
- * `artifact_shared_read` / `mode` / `ordinary`);其余(`operator_forced` 部署出身、`ask_rule` / `org_rule`、`hook`、`ancestor`、`content_question`、
2370
- * `unverifiable_delete`、`governance_unavailable`、`policy_rra` …)任何模式下都照问。
2408
+ * `artifact_shared_read` / `mode` / `unstated` / `ordinary`);其余(`operator_forced` 部署出身、`ask_rule` / `org_rule`、`hook`、`ancestor`、`content_question`、
2409
+ * `unverifiable_delete`、`governance_unavailable`、`policy_rra`、`requires_user_interaction` …)任何模式下都照问。
2410
+ *
2411
+ * 🔴 **`requires_user_interaction`(core 7.41.0;server ≥7.116.0 提货)= 服务器声明「这只工具每次都要用户在场」**:MCP 服务器在工具申报里声明
2412
+ * `_meta["anthropic/requiresUserInteraction"] === true`(只认布尔 `true`)⇒ 这只工具的**每一次**调用都问人 —— **每种模式含 `bypassPermissions`** 都问(**不在**可放十类里),
2413
+ * 且**只有人的答**清得掉:请求 `settings.permissions.allow`、运维 `APPROVAL_GRANT`、技能清单 + `userInvokedSkills`、PreToolUse hook 的显式 allow 都清不掉它;
2414
+ * 无审批席 ⇒ 拒(服务器侧零收到)、无人值守腿不答这一类;帧上同带 `requiresRealApproval:true` / `mandated:true`(`origin:"safety_tighten"`),卡上没有「不再询问」规则。
2415
+ * 按 `askClass` 穷举渲卡的客户端要加这一个词;本型是闭集(server 对 `askClass` / `classes` 按 core `isAskClass` 筛,出集整对不投)。
2416
+ *
2417
+ * 🔴 **`unstated`(core 7.40.0;server ≥7.115.0 提货)= 没人表态的调用**:询问类模式(`default` / `acceptEdits` / `auto` / `plan`)下,MCP 服务器工具 / A2A 技能(引擎里「自己不表态权限」的席位)的调用,
2418
+ * 走到折叠尾**没有任何一层**(规则 / hook / 审批人 / 分类器 / 模式释放)说过「这次可以」⇒ 出一张 `askClass: "unstated"` 的卡(卡句 `The agent requested permission to use <tool>, but it has not been granted yet.`);
2419
+ * 没有审批面(同步 `POST /v1/tasks` 无活审批、无人值守腿无席)⇒ 拒。**清它的出路 = 给出「有人表态」**:请求体 `settings.permissions.allow`(allow 规则,见 {@link import("./settings.js").SettingsPermissions.allow};
2420
+ * 先探 `capabilities.settings.permissions.allowGrant`)· 运维 env `APPROVAL_GRANT` · PreToolUse hook 显式 `permissionDecision:"allow"` · 接审批面 · `permissionMode:"bypassPermissions"`(请求腿);
2421
+ * `plan` 模式下只有**只读**的服务器工具出这张卡。本类说的是「**没人说**」,不是 `ask_rule` / `org_rule` 那种「有人说了问」。
2371
2422
  */
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"
2423
+ export type AskClass = "content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback"
2424
+ /** core 7.41.0 / server ≥7.116.0:服务器工具申报声明「每次调用都要用户在场」(见本型顶注)—— **不在** `bypassPermissions` 可放的十类里,只有人的答清得掉。 */
2425
+ | "requires_user_interaction" | "operator_forced"
2373
2426
  /** 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";
2427
+ * 自己成一类,免得持有另一种强制问的类集把它藏掉。与 `operator_forced` 同样**免疫 bypass**(不在 `bypassPermissions` 可放的十类里)。 */
2428
+ | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode"
2429
+ /** core 7.40.0 / server ≥7.115.0:**没人表态**的服务器工具 / A2A 技能调用(见本型顶注)—— 可放类(bypass / allow 规则 / 分类器都清得掉它),不在免疫类里。 */
2430
+ | "unstated" | "ordinary";
2376
2431
  /**
2377
2432
  * 一个权限**模式放行**了一只本该问人的 ask 的记录(K-32 扩项;server ≥7.106.0 / core 7.34.0 `ModeRelease`,键集逐键同 core
2378
2433
  * `dist/core/gate-outcome.d.ts`)—— 只挂在 `allowed` 臂上({@link GateDisposition}):这一次**没有问任何人**,是模式放的。
@@ -2765,7 +2820,8 @@ export type WiringManifestWriteProtection = {
2765
2820
  * ⚠️ 档名**不是本层的闭集**:词表属主在 core 的 `READ_DENY_BUILTIN_TIERS`(今天五档
2766
2821
  * `credentials` / `shell-history` / `browser` / `wallet` / `agent-config`),server 只判「非空串」逐字透传,
2767
2822
  * 抄一份会把 core 的第六档静默吞成缺席。
2768
- * ⚠️ **部署面语义自 core 7.22.0 翻面**:`READ_DENY_BUILTIN_TIERS` **未设置 = OFF**(此前缺席走 core 缺省四档)。
2823
+ * ⚠️ **部署面缺省(server 配置目录,发布字节读核)**:`READ_DENY_BUILTIN_TIERS` **缺席 ⇒ 出厂两档在岗 `credentials,agent-config`**(core 7.34.0 R-2 起;**7.22.0–7.33.x 曾为 OFF** ——
2824
+ * 旧注写的「未设置 = OFF」只对那一段成立);要全关显式写 `none`,要全五档显式写五个名字,空值拒启。
2769
2825
  * ⚠️ `type` 而不是 `interface`:同 {@link WiringManifestMcpEntry} 顶注那条裁定。
2770
2826
  */
2771
2827
  export type WiringManifestReadDeny = {
@@ -3189,6 +3245,25 @@ export interface SkillSpec {
3189
3245
  name: string;
3190
3246
  description: string;
3191
3247
  content: string;
3248
+ /** server ≥7.116.0(core 7.41.0 技能清单取上游全形):这只技能的**allow 规则来源**(字符串数组;条目文法 = 持久规则文法 ——
3249
+ * 工具名、`mcp__<server>` / `mcp__<server>__*` 一类协议名;`*` / 写路径 / 域名形什么都不授予)。
3250
+ * 🔴 **读法变了:它不是围栏**(≤7.115.x 引擎 7.40 把它当「只许这些」的围栏读)—— 7.116.0 起**没列的工具照常判**(询问类模式下问、
3251
+ * `bypassPermissions` 或部署 allow 下直接跑),不再因为没列被拒;**列着的工具在这只技能被激活之后、本 run 内免问**
3252
+ * (激活 = 请求顶层 {@link TaskRequest.userInvokedSkills} 点了它的名〔开跑即生效、不出 `Skill` 卡〕,或模型调 `Skill` 激活且那张卡被批准)。
3253
+ * 清的是引擎的普通问与「没人表态」两类问,所以**比同版 `settings.permissions.allow` 更宽**(后者仍只是表态,不放内置工具上引擎自己的
3254
+ * 写门 / shell 普通问);deny 规则 / ask 规则 / `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` / shell 地板 / 写保护 / plan 模式的问,清单都清不掉。
3255
+ * 值形:字符串数组(含空数组)⇒ 受理;裸串 / 含非串 / 对象 ⇒ 400 `request.field_invalid`;协议名的服务器段铸不出 / 缺段 / 带通配(`mcp__*`)⇒ 400
3256
+ * (顶层 `skills[]` 与子代 `agents[].skills[]` 两处受理口同判)。
3257
+ * 🔴 **先探 `capabilities.skillToolLists`**:位缺席 = 老 server ⇒ 顶层技能上的两只清单**照收但引擎不读**(静默不生效,没有 400 可探 ——
3258
+ * 别指望清单拦得住工具,圈工具用 deny 规则),子代技能上是未知键整条拒。
3259
+ * 🔴 `manifest` 键 server ≥7.116.0 **提交即拒**(顶层 400 `request.field_invalid`、子代整条技能拒);改写 `manifest.allowTools` → 本键;
3260
+ * 写围栏 `allowPaths` 没有替身(圈写路径用会话规则 `allowDirs`)。本型从不声明 `manifest` ⇒ 顶层按型写不出它。 */
3261
+ allowedTools?: string[];
3262
+ /** server ≥7.116.0:这只技能的 **deny 规则来源**(同 {@link allowedTools} 的文法 / 两道受理门 / 探测位):技能被激活之后,本 run 内这些工具**拒**(不执行、零卡,
3263
+ * `tool_end.gate.disposition` 为 `{ kind: "denied", deniedBy: "policy" }`)。`*` 与域名形(`WebFetch(domain:…)`)在这一侧也读作「无」—— 受理 2xx,
3264
+ * 只进运维面通告 `skills.allowed_tool_not_granted`(core 引擎通告,受众 operator,不上会话流);写路径形(`Write(/tmp/**)`)与其余条目照编 deny 行
3265
+ * (这两句取自 server 契约 / 判据 C2.d·C19.e 对 core `compileSkillGrant` 读数的转述;core 的通告文案把「写路径 / 域名」一并列为「grant or refuse nothing」,**本包未亲跑引擎**核 deny 侧的写路径形)。位缺席 = 老 server(见 {@link allowedTools})。 */
3266
+ disallowedTools?: string[];
3192
3267
  }
3193
3268
  /** A per-request MCP server (CC `.mcp.json` parity) — core-native `McpServerSpec` shape (core types.ts:277).
3194
3269
  * `stdio` = a local command the worker spawns (single-user only); `http` = a remote streamable-HTTP server. */
@@ -3360,15 +3435,18 @@ export interface Capabilities {
3360
3435
  /** #13([1871] web asks;server ≥1.296)fleet 面能力族——对象=面在场,`false`/缺席=无 /v1/fleet/stream
3361
3436
  * (路由 501 同谓词)。`resume: "snapshot"` 是语义广告:总线是 latest-state 非事件日志,每次连接开头
3362
3437
  * 即全量 snapshot 帧 ⇒ 重连=重快照,行状态无丢帧(刻意无 last-event-id 游标——重放缓冲与 snapshot
3363
- * 重复建设);通知帧走 durable inbox 兜底重投。`steerPriority: "advisory"`=steer body.priority 收下+
3364
- * 枚举校验但 no-op(E15,候 core 队列 seam)——诚实不假 yes。开集容未来键。 */
3438
+ * 重复建设);通知帧走 durable inbox 兜底重投。`steerPriority` 答「steer body.priority 在这台 server 上生不生效」,
3439
+ * **两代值**:`steerPriority: "advisory"`(server ≤7.115.x)= 收下 + 枚举校验 + 回显但**不生效**(no-op,诚实不假 yes);
3440
+ * `steerPriority: "engine"`(server ≥7.116.0)= `priority`(`now` / `next` / `later`)交给引擎作注入档位,各档语义只有
3441
+ * 引擎那一个定义 —— `now` **当场**切断在飞的 turn(正在执行的工具收到中止、本副本上挂着的审批卡被撤),`later` 在 run 本会停下的那一 turn 之后才投,不带 = `next`。要不要给用户露出 priority 的选择,先读这一位;
3442
+ * 缺席 / 未知词(开集)⇒ 按「不生效」处理,别当 `"engine"`。开集容未来键。 */
3365
3443
  fleet?: false | {
3366
3444
  stream?: boolean;
3367
3445
  sessionScope?: boolean;
3368
3446
  observe?: boolean;
3369
3447
  resume?: "snapshot" | (string & {});
3370
3448
  bgNotifyFailClosed?: boolean;
3371
- steerPriority?: "advisory" | (string & {});
3449
+ steerPriority?: "advisory" | "engine" | (string & {});
3372
3450
  /** server ≥7.48.0(#281;K-32 扩项补声明 —— server 7.106.0 的复合位成员闭集 `COMPOSITE_CAPABILITY_MEMBERS` 登记了它,本包此前漏了):
3373
3451
  * 本二进制会在 `hook_notice` 帧上发**第二个** kind `hook_non_blocking_failure`(用户自配的 hook 自己坏了:exit ≠ 0 ∧ ≠ 2 / 超时 /
3374
3452
  * 起不来 / 坏 JSON)。缺席 = 老 worker 只发得出 `hook_decision_unavailable` 一个 kind ⇒ 渲染面按 `kind` 分派、未知 kind 别崩。 */
@@ -3422,7 +3500,8 @@ export interface Capabilities {
3422
3500
  /** S-32(server ≥7.53,`routes/capabilities.ts:731`)—— `GET /v1/config/catalog` operator lane(部署配置目录
3423
3501
  * 自描述,DESIGN-278 §5 S2)在**本部署**挂载。谓词**两项合取**,逐项对着路由拒绝臂写:①旋钮
3424
3502
  * `CONFIG_CATALOG_ENABLED` 开着(默认 on;合规部署显式关 ⇒ 路径 404,阀门族先例)∧ ②operator 名单**非空**
3425
- * (空名单下路由对任何身份恒 403)。
3503
+ * (空名单下路由对任何身份恒拒 —— server ≥7.116.0 答 **501 `capability.operator_principals_required`**,≤7.115.x 答 403)。
3504
+ * 🔴 server ≥7.116.0 旋钮关着(`CONFIG_CATALOG_ENABLED=false`)时路径答 **501 `feature.config_catalog_disabled`**(≤7.115.x:404;同路径 `POST` ⇒ 405 + `Allow: GET`)—— 「这台没有」按 `errorCode` 判。
3426
3505
  * 🔴 **部署级可用性,不是调用者授权**(codex R1 验真后订正):调用者自己的身份**不在**谓词里 —— 路由另要求
3427
3506
  * 当前 principal 是显式 operator(`routes/config-catalog.ts` `explicitOperatorOk`,否则 403 `auth.operator_only`),
3428
3507
  * 非 operator 读到 `true` 照样 403。只对**已另行确立**为 operator 的身份展示/调用目录;本位回答的是「这台机
@@ -3516,8 +3595,21 @@ export interface Capabilities {
3516
3595
  * `beginImportStaging` ∧ a file-snapshot store. 🔴 The fourth conjunct is the correction: this doc used to
3517
3596
  * list only three, and that three-item version was DISPROVEN in the field ([2024], cli 取证) — a warm-cache
3518
3597
  * wrapper store forwarded exactly those three and dropped the staging family, so caps said `true` while PUSH
3519
- * Phase A 501'd forever. Gate the whole `client.sessions.sync.*` surface off this — DON'T trial-by-501. */
3598
+ * Phase A 501'd forever. Gate the whole `client.sessions.sync.*` surface off this — DON'T trial-by-501.
3599
+ *
3600
+ * 🔴 **server ≥7.116.0:本位说的是「对话半族」**(manifest / entries / plan / import 两段)—— 文件历史的 **blob 两口**(`PUT …/sync/blobs/:hash` /
3601
+ * `GET …/sync/history/blobs/:hash`)归新位 {@link sessionSyncFileHistory}。三种生产后端(mysql / pg / local)上本位**值不变**,变的是广告的端点收窄;
3602
+ * 判据另加「策略店擦得动」(`deleteBySession`;嵌入方自带的策略店缺这只动词 ⇒ 整族 501 `capability.policy_purge_required`、本位为 `false`,
3603
+ * 7.115.x 只有 consented `overwrite-dst` 的导入在 commit 前答 501)。 */
3520
3604
  sessionSync?: boolean;
3605
+ /** server ≥7.116.0(S-509,契约附录 B.1,谓词类「设施依赖」):**会话同步的文件历史 blob 面**可用 —— `PUT /v1/sessions/:id/sync/blobs/:hash` 与
3606
+ * `GET /v1/sessions/:id/sync/history/blobs/:hash` 两口。= {@link sessionSync} ∧ 文件历史店有 blob 传输面(`syncBlobFaces`;**只有 SQL 后端有**,`DB_BACKEND=local` 上恒 `false`)。
3607
+ * 🔴 **两端都读**:同步是 src → dst 两个 peer,**任一端为 `false` ⇒ 只同步对话**:别推 `fileHistory`、别 PUT blob(把 `fileHistory` 推给没有 blob 面的对端,
3608
+ * commit 之后因缺 blob 422 `missing_blob`)。位为 `false` 时两口答 **501 `capability.snapshot_store_required`**(任何会话 id 同一句,先于属主判);
3609
+ * blob「未被会话历史图引用 / 字节不存在」仍是 404 `not_found.blob`(scope 边界,只在有 blob 面的后端上可达)。
3610
+ * ⚠️ **缺席 = 老 server(≤7.115.x)**:那里 `sessionSync: true` 的 local 部署上 PUT blob 恒 501(位说「能」而口恒拒)—— 缺席时**读不出**这一面能不能用,
3611
+ * 既有 verb 照旧试(`pushSessionBundle` / `pullSessionBundle` 对缺席位照旧尝试,见 {@link import("./sync.js").PushSessionResult.fileHistory})。 */
3612
+ sessionSyncFileHistory?: boolean;
3521
3613
  /** 🔴 K-5 session-resume gates(service src/http/routes/capabilities.ts,§0.5 session 抽象)—— shell 的 `/resume` picker 据此诚实
3522
3614
  * gate,别 trial-by-501:`sessionList` = list 可用(`Boolean(sessionStorage.listSessions ?? runStore.listSessions)`,
3523
3615
  * 喂 picker 行);`sessions` = transcript preview 可用(`Boolean(sessionAudit)`,`GET /v1/sessions/:id`→SessionAudit)。
@@ -3580,7 +3672,9 @@ export interface Capabilities {
3580
3672
  * 也是对象形);② `env` **不再恒 false** —— server 现在发 `env: cwdHonored(config)`,即单用户 host lane
3581
3673
  * (`cwd` 被 honored 的那一形)上 `settings.env` 真被消费。旧的硬编码 `false` 是「TaskSpec 无 per-task
3582
3674
  * env 注入」时代的断言,shellEnv seam 落地后变成了「说没有但其实有」的**活能力被藏**。
3583
- * `hooks` 仍是单用户部署(requirePrincipal!==true)才 true。逐位读,别按整体推断。 */
3675
+ * `hooks` 仍是单用户部署(requirePrincipal!==true)才 true。逐位读,别按整体推断。
3676
+ * ⚠️ `permissions` 只是**受理位**(server 受理 `settings.permissions` 这一面,恒 `true`、仍是布尔,server ≥7.115.0 没动它);
3677
+ * `settings.permissions.allow` 按**哪一种读法**收,看下面的 {@link Capabilities.settings}`.permissions.allowGrant`。 */
3584
3678
  taskSettings?: {
3585
3679
  permissions?: boolean;
3586
3680
  permissionMode?: boolean;
@@ -3590,6 +3684,19 @@ export interface Capabilities {
3590
3684
  hooks?: boolean;
3591
3685
  [k: string]: unknown;
3592
3686
  };
3687
+ /** 🔴 **server ≥7.115.0 起恒在**:`{ permissions: { allowGrant: true } }` —— 「请求体 `settings.permissions.allow` 按**哪一种读法**收」的**版本位**(S-654;wire additive,新顶层键)。
3688
+ * `permissions.allowGrant === true` = 这台 server 把 `allow` 桶编成 **allow 规则**:命中 = 给出「有人表态」(让没人表态的 MCP / A2A 服务器工具调用不再出卡),**不是免问、不是名单**
3689
+ * (名单外的工具不再被拒;引擎对内置工具的写门 / shell 检查照问,deny / ask 照赢;坏形 / 内容形名字提交即 422 —— 读法全文见 {@link import("./settings.js").SettingsPermissions.allow})。
3690
+ * 🔴 **键缺席 = 老 server(≤7.114.x,按名单读 `allow`:名单外一律拒)—— 别投 allow 桶**(投了只是一份收窄,方向安全,但不是你要的「表态」)。
3691
+ * ⚠️ 与 `taskSettings.permissions` 不是一件事:那一位不变、仍是布尔(只说「受理这一面」,读 `=== true` 的旧端不失明);判 allow 的读法只看本位。
3692
+ * 本位是**版本位**:恒 `true`、不随部署形变;部署级「替谁表了态」(运维 env `APPROVAL_GRANT`)不在能力面,在 operator 诊断面 {@link ServerWiringGates.approvalGrant}。 */
3693
+ settings?: {
3694
+ permissions?: {
3695
+ allowGrant?: boolean;
3696
+ [k: string]: unknown;
3697
+ };
3698
+ [k: string]: unknown;
3699
+ };
3593
3700
  /** server ≥1.243 ([1478] R2): TaskRequest.appendSystemPrompt accepted top-level → core TaskSpec.appendSystemPrompt.
3594
3701
  * false/absent ⇒ fall back to the `settings.outputStyle` ride-along (older servers fold it into the same field). */
3595
3702
  appendSystemPrompt?: boolean;
@@ -3728,8 +3835,15 @@ export interface Capabilities {
3728
3835
  s3PublicEndpoint?: string | null;
3729
3836
  /** GET /v1/files/sent 台账面(`routes/capabilities.ts` 的能力对象 `Boolean(sendFileLedger)`)。 */
3730
3837
  sendUserFileLedger?: boolean;
3731
- /** GET /v1/workflows 列表面(`routes/capabilities.ts` 的能力对象 `Boolean(workflowRunStore)`;`workflows` 总位见上)。 */
3838
+ /** GET /v1/workflows 的**列表 / 详情 / 流三口**(`Boolean(workflowRunStore)`;`workflows` 总位见上)。
3839
+ * 🔴 **server ≥7.116.0:本位只说这三口,journal 口看新位 {@link workflowsJournal}**(7.115.x 的本位广告 journal 口,而 journal 店缺席时那一口恒 501 —— 位说「能」而口恒拒)。
3840
+ * 本位**值不变**(= workflow 行店在场)。 */
3732
3841
  workflowsList?: boolean;
3842
+ /** server ≥7.116.0(S-509,谓词类「设施依赖」):`GET /v1/workflows/:id/journal` 可用 = workflow 行店 ∧ journal 店。
3843
+ * 无后端部署(`DB_BACKEND=memory`、多租户裸起、SQL 坐标没配齐)+ 自编排开着的形上 `workflowsList: true`、本位 `false`;位为 `false` 时 journal 口答
3844
+ * **501 `capability.workflow_store_required`**(对任何 id 同一句,先于按行判属主;行店缺席时是 `capability.self_orchestration_required`)。
3845
+ * 🔴 **journal 入口读本位,别读 `workflowsList`**;**缺席 = 老 server(≤7.115.x)**⇒ 按 `workflowsList` 兜底(= 旧行为:位为真而 journal 口可能恒 501)。 */
3846
+ workflowsJournal?: boolean;
3733
3847
  /** device lane 探测位(server `routes/capabilities.ts:162`;design/device-executor-lane-v2 §4.8)——
3734
3848
  * **一个诚实对象或 `false`**,与 {@link fleet} / {@link workspace} 同族三态形。谓词 = `deps.deviceHub`
3735
3849
  * 在场,而那正是 `GET /v1/device/ws` 的 upgrade 处理器挂没挂的**同一个**判据(`server.ts` 的
@@ -3891,13 +4005,14 @@ export interface Capabilities {
3891
4005
  * **例外**是配置被 lock 时,提交口 400 `config.locked_key`(那条 veto 正是让「说 yes ⟺ 路真能用」
3892
4006
  * 在这一形上仍成立的东西)。 */
3893
4007
  a2aInjection?: boolean;
3894
- /** server-as-peer 半场的**旋钮实况**(server `routes/capabilities.ts:564` =
3895
- * `deps.config.a2aServe !== undefined`;DESIGN-269 车2)—— 这台 worker 是否作为一个 A2A agent 对外存在。
3896
- * `true` ⟺ `A2A_SERVE_ENABLED` 开 ⟺ `GET /.well-known/agent-card.json` 与 `POST /v1/a2a` 两条路由存在;
3897
- * `false` ⟺ 两条都 **404**(设计稿 §3.3「卡都不发 = 对外不存在」)。缺席即关。
3898
- * ⚠️ **辖域 = 路由在不在,不是「每个方法都能跑」**:`message/send` / `tasks/get` 还需要 durable run store
3899
- * (缺它时两个方法回具名 JSON-RPC `-32004`,不是静默降级)。server 刻意不把 runStore 折进本位 ——
3900
- * 那会造出「卡还在发、位却是 false」这种更糟的谎。 */
4008
+ /** server-as-peer 半场的**能否对外存在**(DESIGN-269 车2;server ≥7.116.0 谓词 = **`A2A_SERVE_ENABLED` 旋钮 ∧ 有 durable run store**,契约附录 B.1「设施 + config」;
4009
+ * ≤7.115.x 只看旋钮 = `deps.config.a2aServe !== undefined`)—— 这台 worker 是否作为一个 A2A agent 对外存在。
4010
+ * `true` ⟺ 旋钮开 ∧ 有 run 店 ⟺ `GET /.well-known/agent-card.json` 与 `POST /v1/a2a` 两条路由存在;
4011
+ * `false` ⟺ 两条都 **404**(`not_found.route`,反指纹:「卡都不发 = 对外不存在」,**唯一**登记在 404 而非 501 的「不可用」例外)。缺席即关。
4012
+ * 🔴 **7.116.0 的位值变化**:`A2A_SERVE_ENABLED=true` 而**没有 durable run store** 的部署(`DB_BACKEND=memory`、多租户裸起)上,本位由 `true` 变 `false`
4013
+ * —— 那里它广告的两条路由本来就恒拒(7.115.x:卡照发 200,`message/send` / `tasks/get` 恒答 JSON-RPC `-32004`);现在卡与 RPC 都 404,起服日志一行 warn
4014
+ * `a2a_serve_not_served`(`reason` 点名成因)。对端 orchestrator 对这种部署拉卡由 200 变 404(与旋钮关同一形)。出路:`DB_BACKEND=mysql|pg|local`,或关掉 `A2A_SERVE_ENABLED`。
4015
+ * 旧注「server 刻意不把 runStore 折进本位」**作废**(位与路由门现读同一只事实,「位说有而端点恒拒」结构上不可能)。 */
3901
4016
  a2aServe?: boolean;
3902
4017
  /** 后台 agent **名册读面** `GET /v1/agents/roster` 的位(server `routes/capabilities.ts:640` =
3903
4018
  * `Boolean(deps.backgroundAgentStore)`;#A1)。谓词**逐字**是那条路由的 501 门 ⇒「说 yes ⟺ 路由真能用」
@@ -4079,6 +4194,14 @@ export interface Capabilities {
4079
4194
  * ⚠️ **缺席 = 老 server(≤7.108.x)**:那台对请求键答 400 `request.body_shape`(`unknownKeys` 逐字列名)⇒ 别发那个键,如实告诉用户
4080
4195
  * 「这台 server 上出厂技能照装」(CC `--disable-slash-commands` 在那台上兑现不了)。位为真**只**说「认这个键」,不说这台部署有没有出厂技能。 */
4081
4196
  disableSkills?: boolean;
4197
+ /** **请求键 {@link TaskRequest.userInvokedSkills} 的事先读数**(server ≥7.116.0;恒真位,铸点字面 `userInvokedSkills: true`,不挂谓词、无租户门)—— 这台 server 认不认
4198
+ * 顶层 `userInvokedSkills`(人用名字点过的技能,开跑即生效、不出 `Skill` 卡)。位名与请求键**同一个词**。
4199
+ * ⚠️ **缺席 = 老 server(≤7.115.x)**:那台对这个键答 400 `request.body_shape`(`unknownKeys` 逐字列名)⇒ **别发那个键**。位为真**只**说「认这个键」。 */
4200
+ userInvokedSkills?: boolean;
4201
+ /** **技能两只清单 `allowedTools` / `disallowedTools` 的事先读数**(server ≥7.116.0;恒真位):技能上的两只清单**生效**(allow / deny 规则来源,读法见 {@link SkillSpec.allowedTools})。
4202
+ * ⚠️ **缺席 = 老 server(≤7.115.x)**:顶层技能上的两只清单**照收但引擎不读**(静默不生效,**没有 400 可探**)—— 别指望清单拦得住工具,圈工具用 deny 规则
4203
+ * (请求 `settings.permissions.deny`);子代技能(`agents[].skills[]`)上两只清单是未知键 ⇒ 整条技能拒。 */
4204
+ skillToolLists?: boolean;
4082
4205
  [k: string]: unknown;
4083
4206
  }
4084
4207
  /**
@@ -4299,6 +4422,9 @@ export interface LivePendingRow {
4299
4422
  sessionId?: string;
4300
4423
  requiresRealApproval?: true;
4301
4424
  governanceForced?: true;
4425
+ /** server ≥7.116.0:这张卡上「本会话放行」不会被记住(真才带、永不 `false`;缺席 = 记得住 **或** 老 server)。与 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.rememberRefused}
4426
+ * **同一位**(`livePending` 行顶层与其内 {@link frame} 同投)。 */
4427
+ rememberRefused?: true;
4302
4428
  /** server ≥7.101.0(T4① / 车OC;sdk 11.4.0 追平)—— 强制位(`AskRequest.mandated`),与上两位**同层同形**(真才带,
4303
4429
  * 缺席不编 false);值 = 条目上那一位(server `askBroadcast` 铸条目时取自这一次过闸的 `req.mandated`,与 {@link frame}
4304
4430
  * 上同名键同源)。此前只在 `frame` 里。 */
@@ -4413,6 +4539,9 @@ export interface PendingCheckpoint {
4413
4539
  * 以 stream 重发帧为准。additive,**只在为真时在场**,恒不写 false;缺席 ≠「非治理门」,是「无治理
4414
4540
  * 来源证据」。 */
4415
4541
  governanceForced?: true;
4542
+ /** server ≥7.116.0:这张卡上「本会话放行」不会被记住(真才带、永不 `false`;缺席 = 记得住 **或** 老 server;`/v1/approvals` 的 `pending[]` 行与 `/stream` 的 `pending` 帧同投)。
4543
+ * 与 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.rememberRefused} **同一位**。 */
4544
+ rememberRefused?: true;
4416
4545
  /** server ≥7.100.0(S-700)—— 这只 park 住的 ask **只有真人能清**(core park 行孪生座,`=== true` 严判才铸)。
4417
4546
  * 与 inbox 行 / 活卡帧同名位同一件事。缺席 = 「没打这个标」,**不是**「不用人也能清」。 */
4418
4547
  requiresRealApproval?: true;
@@ -4917,6 +5046,39 @@ export interface SyncSnapshot {
4917
5046
  key: string;
4918
5047
  manifest: Array<[string, string]>;
4919
5048
  }
5049
+ /** core `FileHistoryExport`(`formatVersion: "file-history/1"`)的**镜像** —— server ≥7.52(S-15 / design/381)起会话同步搬运文件历史的信封,**取代**已退役的 E19 整树快照
5050
+ * {@link SyncSnapshot}:per-edited-file 的版本链(tracked)+ 边界(boundaries);**blob 字节不在信封里**(按 hash 寻址,经 history blob 两口搬运,见
5051
+ * {@link import("./resources/session-sync.js").SessionSyncResource.getHistoryBlob} / `putBlob`)。SDK 只读 `tracked[].versions[].blobHash`(决定要搬哪些 blob),其余**逐字透传**
5052
+ * (server 的 import 门按 `formatVersion` refuse-not-coerce、复核 `keyKind` / `keyFamily` 闭集 —— SDK 不替它判,也不复制那两张闭集词表:二者按 `string` 读)。
5053
+ * 键集对拍 core `dist/core/file-history-store.d.ts` 的 `FileHistoryExport`。 */
5054
+ export interface FileHistoryExport {
5055
+ /** 今天唯一值 `"file-history/1"`;server 对别的值拒(不是 SDK 的判)。 */
5056
+ formatVersion: string;
5057
+ tracked: Array<{
5058
+ /** 任务根下捕获 ⇒ 相对路径,否则逐字绝对路径。 */
5059
+ relOrAbsPath: string;
5060
+ /** 键的自描述(core 闭集;本包不复制词表)。 */
5061
+ keyKind: string;
5062
+ keyFamily: string;
5063
+ /** `false` ⇒ pristine base 没能捕获(链从 v1 之上起);随图走、不推断。 */
5064
+ baseAvailable: boolean;
5065
+ /** 完整保留链(v1 在先当且仅当 `baseAvailable`)。`blobHash: null` = 「当时不存在」标记(不用搬 blob)。 */
5066
+ versions: Array<{
5067
+ version: number;
5068
+ blobHash: string | null;
5069
+ mode?: number;
5070
+ parentIdent?: string;
5071
+ backupTime: string;
5072
+ }>;
5073
+ }>;
5074
+ boundaries: Array<{
5075
+ entryId: string;
5076
+ files: Array<{
5077
+ relOrAbsPath: string;
5078
+ version: number;
5079
+ }>;
5080
+ }>;
5081
+ }
4920
5082
  /** One E18 resume-at anchor (eventId→entryId + its source owner). `owner` is RE-KEYED to the importing principal
4921
5083
  * on a PUSH (§9) — the local peer sends what it has; the cloud overwrites it. */
4922
5084
  export interface SyncAnchor {
@@ -4936,7 +5098,14 @@ export interface SessionManifest {
4936
5098
  entryCount: number;
4937
5099
  /** The session's current leaf entry id, or null. */
4938
5100
  leafId: string | null;
5101
+ /** 🔴 **server ≥7.52(S-15)起不发这个键、wire 上不再有它**(E19 整树快照纪元退役;server `exportSessionManifest` 铸 `{ sessionId, entryIds, entryCount, leafId, fileHistory, policy, anchors }`,
5102
+ * 7.116.0 发布字节逐键核过)。≤7.51 老 server 仍发它。**本型承诺它恒是数组**:{@link import("./resources/session-sync.js").SessionSyncResource.manifest} 在 wire 缺席时填 `[]`
5103
+ * —— 所以对 ≥7.52 的 server 它恒空,真正的文件历史在 {@link fileHistory}。
5104
+ * 🚧 这是为了不在 minor 里收窄公开型的**披露性过渡**(`snapshots` 本该是可选 / 随退役纪元删除):**下一个 major 把它改可选并删掉 `manifest()` 的填充**。 */
4939
5105
  snapshots: SyncSnapshot[];
5106
+ /** server ≥7.52:per-edited-file 文件历史信封({@link FileHistoryExport});`null` = 没有历史 / 源店导不出;**键缺席 = ≤7.51 老 server**(那一代走 {@link snapshots})。
5107
+ * 搬 blob 前先读两端的 {@link Capabilities.sessionSyncFileHistory}(server ≥7.116.0)。 */
5108
+ fileHistory?: FileHistoryExport | null;
4940
5109
  policy: SessionRulesRecord[];
4941
5110
  anchors: SyncAnchor[];
4942
5111
  }
@@ -4948,6 +5117,8 @@ export interface SessionBundle {
4948
5117
  /** The FULL durable conversation log, verbatim ids/parents/payload (oldest-first). */
4949
5118
  entries: SyncEntry[];
4950
5119
  snapshots: SyncSnapshot[];
5120
+ /** 同 {@link SessionManifest.fileHistory}(server ≥7.52 的文件历史信封;键缺席 = 源是 ≤7.51 老 server)。 */
5121
+ fileHistory?: FileHistoryExport | null;
4951
5122
  policy: SessionRulesRecord[];
4952
5123
  anchors: SyncAnchor[];
4953
5124
  }
@@ -5527,9 +5698,13 @@ export interface WiringManifest {
5527
5698
  session?: {
5528
5699
  store?: string;
5529
5700
  };
5701
+ /** fleet 面:`backgroundAgentStore` / `hostChildEventSink` 是在场位;🔴 `subagentTranscripts`(**server ≥7.115.0 / S-744**,core 7.32.0 的档位上 wire)= 这台部署的**子代转录档位**,
5702
+ * 壳按它如实渲「durable record」文案:`"none"`(没有 agent 行店:子代记录不留)/ `"rows"`(行与终态快照活过重启、**对话不活**:仅本进程 / 会话店 TTL 内可续)/ `"full"`(已结束的子代**跨重启可续**)。
5703
+ * 🔴 **开集读**:三词是 core 今天的词,**不要穷举**(core 的第四个词会被吞成缺席);**未知词 ⇒ 按「未知档位」处置,不要当 `full`**。缺席(老 server / 老引擎)= 不知道,**绝不读成 `"none"`**;租户帧与 operator 帧同投。 */
5530
5704
  fleet?: {
5531
5705
  backgroundAgentStore?: boolean;
5532
5706
  hostChildEventSink?: boolean;
5707
+ subagentTranscripts?: "none" | "rows" | "full" | (string & {});
5533
5708
  };
5534
5709
  /** operator 受众段(部署治理面在场性)。租户可读面上它**不存在**;别按它在不在推断 server 版本。 */
5535
5710
  governance?: {
@@ -6130,6 +6305,9 @@ export interface ApprovalDecisionResult {
6130
6305
  errorCode?: string;
6131
6306
  errorMessage?: string;
6132
6307
  retriable?: boolean;
6308
+ /** 带 `remember` 的 `/decide` 才有的回执位。🔴 **server ≥7.116.0:在带授予的卡上(引擎 `Skill` 卡等,卡面位 `rememberRefused`)恒 `false`** —— 既有键,不是新键:
6309
+ * 决定照收、只放行这一次、豁免店零写;同一条件也使 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.rememberRefused} 在场。
6310
+ * 普通卡上仍是「按请求记」(`true` ⇒ 之后同工具零卡)。 */
6133
6311
  rememberApplied?: boolean;
6134
6312
  /** #368 幂等回放形的判别式(同一份 decide 体重发、命中已决行);回放形**不带** `taskId`/`status:"resuming"`。 */
6135
6313
  idempotent?: true;
@@ -6171,12 +6349,17 @@ export interface ServerWiringGates {
6171
6349
  sessionAutoTitle: PostureKnobReading<boolean>;
6172
6350
  /** checkpoint 店在场(= park 设施;`durableApproval` 开着也可能因后端无 checkpoint 面而缺席)。 */
6173
6351
  checkpointStore: boolean;
6352
+ /** 🔴 **server ≥7.115.0**:运维的 allow 规则 `APPROVAL_GRANT`(env;缺省关)**原样名单**(工具名规则,不是秘密;**空表 = 旋钮未设**,条数 = 长度)。它回答的是**部署替谁表了态**
6353
+ * —— 命中的服务器工具 / A2A 技能调用不再因「没人表态」出卡;**不放掉任何一层自己的问**(deny / ask / 会话规则 / 引擎写门照旧)。**只在本运维面**(operator-only,门在路由上),
6354
+ * **不进** `/v1/capabilities`(那里说的是调用方能用什么,见 {@link Capabilities.settings})。缺席 = <7.115.0 的 server(没有这个旋钮)—— 与 `[]`(有旋钮、没设)是两件事。 */
6355
+ approvalGrant?: string[];
6174
6356
  }
6175
6357
  /**
6176
6358
  * `GET /v1/diagnostics/wiring` 的响应(server ≥7.4.0)—— **operator-only**。门 = `OPERATOR_PRINCIPALS`
6177
6359
  * **非空 ∨ `REQUIRE_PRINCIPAL`**:满足任一,调用方就必须是名单里的 principal,否则 403
6178
6360
  * `auth.operator_only`。**「没开 REQUIRE_PRINCIPAL」不等于开放** —— 列了名单的部署上匿名/非名单一样 403;
6179
6361
  * 唯一开放的姿势是空名单 ∧ 非多租户(单租户 turnkey,唯一的用户就是 operator)。
6362
+ * 🔴 server ≥7.116.0:**多租户形 + 空名单 ⇒ 501 `capability.operator_principals_required`**(对任何身份,先于授权;≤7.115.x 是 403)—— 按 `errorCode` 分支。
6180
6363
  *
6181
6364
  * 🔴 **不含 per-leg 历史**:治理段只出现在 live 帧的 operator 投影里,durable 账本恒存剥后形(账本写的
6182
6365
  * 那一刻不知道未来读者是谁)。要某条历史腿的治理面,只能在它跑的时候以 operator 身份订阅。