@sema-agent/client-core 0.93.0 → 0.93.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/CHANGELOG.md +48 -0
- package/README.md +3 -1
- package/dist/hitl/approvalResolution.d.ts +3 -2
- package/dist/hitl/approvalResolution.js +13 -0
- package/dist/hitl/hitlHostSurface.d.ts +3 -0
- package/dist/hitl/hitlHostSurface.js +11 -0
- package/dist/hitl/toolApprovalWire.d.ts +10 -0
- package/dist/hitl/toolApprovalWire.js +150 -6
- package/docs/INTEGRATION-CLIENTS.md +99 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,54 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.93.1(2026-10-09)
|
|
53
|
+
|
|
54
|
+
> 主题:**patch**,两件 —— 其一,耐久停驻审批的决断口单一持有者(CC-491;外部验收 [9516]):同一只停驻审批被两条路各接一次(终端在引擎换代之后重摆的那张卡,与停驻解析器在新流上重接的那张)时,宿主只呈一张、只答一个,另一路此前永远等 —— 卡停在屏上、下一张卡不来、不自愈。现在同一把审批身份键同时只有一次决断在路上,后到的调用方拿同一个结局、自己不呈卡不发决断。`FsApprovalOutcome` 四臂各 +1 可选位 `joinedInFlight?: true`。其二,活卡审批 respond 回 `202 parking_in_progress` 读成明确的「停驻中、这一发没生效」结局(CC-492;外部验收 [9533]):引擎上这张卡的行正转停驻时,用户按下的答复没有生效,而修前这个 202 体没有 200 回执的 `delivery` 键、被读成「没有回执」,结局落成已批准 —— 终端据此注销卡、屏上不说话,重启后要再答一次。现在结局带 `parking` 位、判别口读成既有 `unsettled` 臂的新 cause `parking_in_progress`,包替用户上屏一句,不重发、不去键、不换名。**型面**:`ApprovalUnsettledCause` 词表 +1 词(对 cause 做 `never` 穷举的写法编译红一次;`kind` 联合仍三臂,按 `kind` 的写法不受影响,既有对 `unsettled` 的有界重呈对它默认安全);`ToolApprovalFrameOutcome` +1 可选位 `parking?`;根公面运行期导出不变(读器是包内件)。**谁必须动**:终端换钉 `^0.93.1` 时删工具门行上的「拒开第二张」判读,并改 respond 包装处(§120d);管理台与桌面端的直调点必改(§120d);网页端已有本地判读,可换读这一 cause(零必改)。
|
|
55
|
+
|
|
56
|
+
> 净值(相对 0.93.0):根公面运行期导出不变;公面类型名 +1(`ToolApprovalRespondParkingView`);`APPROVAL_UNSETTLED_CAUSES` +1 词;门清单 196 → 198;单例清单 676 → 677(dupRisk high 140 → 141);带理由的吞 44 → 45;退役登记在册 +1(RL-78)。
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- **`FsApprovalOutcome` 四臂各 +1 可选位 `joinedInFlight?: true`**(CC-491;接入文档 **§120 SH-1**):present-iff,只在「这只结局是另一路持有的那一次决断的拷贝」时在场;缺席 = 本次调用自己持有那一次决断(或没走到登记那一步,如取件失败),绝不铸 `false`。在场的那一路自己没呈卡、没发决断、没重发、没上屏告知;其余各位(`denied` / `receipt` / 归因各位 / 失败各位)说的都是持有者那一次决断,原样搬。`aborted` 臂上在场 = 这一只决断被中断了(哪一路的信号中止都算,见下条),中断拒绝只由持有者发一次。
|
|
61
|
+
|
|
62
|
+
- **`ToolApprovalFrameOutcome.parking?`、`APPROVAL_UNSETTLED_CAUSES` +`'parking_in_progress'`、`ApprovalResolutionUnsettled.parking?`**(CC-492;接入文档 **§120 PK-1**):活卡 respond 回 `202 { reason: "parking_in_progress", retryAfterMs, … }`(行正转停驻,这一发没有生效)时,结局为 `{ decision: 'unresolved', parking: { approvalId, retryAfterMs?, decidePath? } }` —— present-iff,绝不铸 `false`;判别口 `approvalResolutionOf` 读成 `{ kind: 'unsettled', cause: 'parking_in_progress', parking }`(`kind` 联合仍三臂;`parking` 位只在这一 cause 上在场;撤卡 / 编辑被拒仍压过它,它压过决断词)。这一 cause 与其它 `unsettled` 的差别:字节已出站、引擎答了,答的是「停驻中、这一发没生效」,卡会以停驻卡的形再回来 —— 壳据此不注销卡、不说已批准;既有的有界重呈路径对它默认安全。停驻事实只由自有数据位 `reason` 恰为 `parking_in_progress` ∧ `approvalId` 非空串且对得上这张卡承载;`retryAfterMs`(有限非负数)与 `decidePath`(服务端预告在 202 体上带的停驻卡决定口路径;契约位候服务端登清单,本包按 202 体的键名读;非空串、原字节、不猜不拼、不上屏)是两个可选提示位,各自的坏值只丢各自那一键、停驻照认。判停驻的读器是包内件(不上根入口,根公面不增名);与 `readToolApprovalRespondAck`(只认 `delivery: "applied"`)并列、后者一字未动。
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **`surfaceFsApprovalAndDecide` 对同一把审批身份键单一持有**(CC-491;🔴 行为面:只在同一把键上有并发调用时;**§120 SH-1**):身份 = 取件那一行的会话 + run + `toolCallId ?? boundCallId`(行上都没有 call id 时退 `taskId`);其中的 call 部分与交给卡口的 `callKey` 同一把,会话与 run 两段保证不同 run 恰好同名的 call 不会被并成一次决断。
|
|
67
|
+
- 先到的调用方持有整次决断(呈卡 → 等答 → 发决断,含包内各种重发);后到的调用方等它的结局,交回浅拷贝 + `joinedInFlight: true`(持有者交回的对象不被改写);持有者抛 ⇒ 后到者以同一只抛出物拒绝。持有者落定的同一拍清登记,之后同键再来是新决断。
|
|
68
|
+
- **读起点也算**:后到者的取件开始于持有者落定之前、回来于之后 ⇒ 同样拿那一只刚落定的结局(那份行快照对这把键是陈旧的),不再呈一张已经答过的卡;取件开始于落定之后 ⇒ 新决断。
|
|
69
|
+
- 中止:**任一路的信号中止 = 这一只决断被中断** —— 持有者照「自己的信号中止」那条既有路径走:卡口收到中止、答 `aborted`,持有者发恰一发中断拒绝、立即交回 `aborted`;后到者等到同一个结局,交回 `aborted` + `joinedInFlight: true`。谁先中止、或两路同一拍中止,都只有那一发;持有者已落定之后才中止 ⇒ 不再中断,拿已落定的结局;卡已答、决断正在发时中断不打断那一发。为此耐久口交给卡口的请求恒带 `signal`(调用方没给信号时也带一只,只在同一只决断的另一路被中止时触发);那一发中断拒绝落定(成败都算)之前登记不清,期间进来的调用方同样拿这次的 `aborted`,不会在拒绝落地之前再呈一张卡、再发一次批准。
|
|
70
|
+
- 回调:后到者的 `onDecideOperation` 恒不报(它不发);`onPresented` 只在持有者真把卡交给了卡口时回调一次,抛错不改结局。宿主卡口每次决断恰收一次请求;`surfaceApprovalCard` 与 `FsApprovalWireDeps` 不变。
|
|
71
|
+
- 没有并发(一个接一个)的调用与 0.93.0 逐字节同;不同键互不影响。
|
|
72
|
+
|
|
73
|
+
- **`surfaceToolApprovalFrameAndRespond` 对 `202 parking_in_progress` 回体的处置**(CC-492;🔴 行为面:只在引擎真回 202 时;**§120 PK-1**):修前 202 体(`{ approvalId, askId, reason: "parking_in_progress", retryAfterMs }`,没有 `delivery`)读成「没有回执」,结局 `{ decision: <用户按的词> }`,持久臂被丢的伴随通知(「审批本身过了」一类)与归因旗位(`denyAttributionRenamed` / `denyAttributionDropped`)也照 200 的路径铸出。后:结局 `{ decision: 'unresolved', parking }`,没有 `ack`,归因各位与伴随通知一概不铸,上屏一句「This approval is being parked; answer it again on the parked card when it appears.」(`retryAfterMs` 在场时句尾 ` (the engine suggested waiting about N s)`,N 以秒计、向上取到 0.1;`decidePath` 在场时措辞不变、路径不上屏);respond 恰一发(归因键重发的两形恰好撞上 202 时恰两发,不再有第三发);本包不替宿主等 `retryAfterMs`。`retryAfterMs` / `decidePath` 坏值只丢各自那一键(句子无句尾 / 路径不带),停驻照认;读某一键抛错(宿主注入的代理)同样按键隔离 —— `approvalId` 读抛按未落定、提示位读抛只丢那一键,不会因一只键的抛错把整只体当成不是停驻体。202 体自称停驻(`reason` 恰是停驻词)却认不出这张卡(`approvalId` 缺 / 空 / 非串,或点名的是另一张卡)⇒ 不落 parking(不伪造),但也不落回「没有回执 ⇒ 已批准」:结局 `{ decision: 'unresolved' }`(判别口 `unsettled` / `respond_failed`、便签 `settled: false`、零通知、不重发)。不是停驻体的其余形(含只有 `delivery` 键的体)走既有「回执读不懂」路径,不变。悬挂 ask(盲卡)路径是同一条链,同判。200 回执与其余非回执 200 体(赎回 / 幂等回放)的读法一字未动。
|
|
74
|
+
- **接入文档 §120a′:§119 勘误(三)**(0.93.0 外部验收 [9596] 指出五处;🔴 已发的 §119 不回改):G-RT2 帧键镜像「长度 34」→ 实读 37;G-PM8 第五句触发面限定;G-DX4「取值器抛 ⇒ 整格删」限定到读口工厂路径(同族两律登 CC-507);G-DB4 / G-DB10 的 AST 半场标为包侧门;119a WD2-1「无型面变化」补 `RULE_NOT_SENT_REJECTED_WARN_TEXT` 一处限定。
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
|
|
78
|
+
- **引擎换代之后刚批准的停驻卡停屏、会话卡死不自愈**(CC-491;外部验收 [9516];**§120 SH-1**):改设置 / 换默认模型 / 更新触发引擎换代,空闲机上新引擎先起来、终端稍后复查挂起审批 —— 停驻解析器与终端重摆路对同一行各调一次决断口,宿主只答其中一个,另一路零超时永远等:那一步一直在跑、下一张卡不来;用 Esc / 敲字解开之后,刚批准且已执行的那一步被说成没做。现在后到的那一路 join 先到的那一次决断,两路同结局、解析器那条流照常往下读。终端那一侧的收尾见 §120d。
|
|
79
|
+
|
|
80
|
+
- **停驻中的审批卡上作答被当成已批准、卡被注销**(CC-492;外部验收 [9533];**§120 PK-1**):引擎排空或卡窗到期时,卡的行转停驻,这时用户选 Yes,引擎回 202 `parking_in_progress` 不执行;修前本包把这个 202 读成已批准,终端注销卡、屏上不说话,重启后要再答一次,终屏还把已执行的那一步写成「Operation aborted」。现在结局带 `parking` 位、判别口读成 `unsettled` / `parking_in_progress`,包上屏一句、不重发;终端的收尾见 §120d。
|
|
81
|
+
|
|
82
|
+
### Gates
|
|
83
|
+
|
|
84
|
+
- 新门 **`run-durable-decision-single-holder-test.mjs`**(76 格):G-SH1 两路并发同键(allow / deny)⇒ 恰一张卡、恰一次 decide、两路同结局、后到者带位;G-SH2 真解析器 × 终端重摆形直调,解析器先 / 重摆路先两序;G-SH3 decide 500 与卡口抛 ⇒ 两路同失败、登记清;G-SH4 任一路中止 = 这一只决断被中断(后到者中止 / 进来时已中止 ⇒ 持有者撤卡、恰一发中断拒绝、两路 aborted;真解析器 turn 中止两序读数逐字相同;持有者落定后才中止 ⇒ 零拒绝、拿已落定结局;两路同拍中止仍一发;持有者中止;中断拒绝还在路上时第三路进来 ⇒ join、不另起决断,落定后才清);G-SH5 不同键;G-SH6 落定后再来;G-SH7 读起点早于 / 晚于落定;G-SH8 两只回调(含后到者中止之后持有者才落定时回执不报第二次);G-SH9 present-iff 与拷贝、d.ts 四臂;G-SH10 与换名重发的交互;G-SH11 源码结构(join 与登记路径零呈卡 / 决断 / 告知引用,带植入违例自证);G-SH12 不同 run 同名 call id ⇒ 各自一张卡、各自一次决断、互不 join。红先:修前 45 格红(两张卡、一路 1 秒有界等待挂住;真解析器那条流挂住;后到者中止时发出一发中断拒绝);G-SH4k–4m 另在「后到者中止只退出等待」的中间形上红先(零拒绝、卡留屏、重摆调用挂住)。
|
|
85
|
+
- **approval-decided-by-capability** AB5b:耐久口的决定函数调用点改按它的持有者体认(入口只取件 + 登记;238 格不变)。
|
|
86
|
+
- 登记物:单例清单 +1(`durableDecisionHolds`,dupRisk high;棘轮 140 → 141)· 带理由的吞棘轮 44 → 45(后到者交回结局前的呈现回执)· 退役登记 +RL-78(`client-event`,retireBy 0.94.0:终端删掉工具门行的「拒开第二张」判读之后,复核本口的决断操作起止回调位去留)。
|
|
87
|
+
|
|
88
|
+
- 新门 **`run-approval-respond-parking-test.mjs`**(149 格):G-PK1 202 金样体 ⇒ 停驻结局(结局恰 `{ decision: 'unresolved', parking }`、无 ack、respond 恰一发、卡口恰一次、恰一条停驻句、伴随通知零、归因各位不铸;三种决断词与 policy 拒绝同判;悬挂 ask 盲卡与真消费路径 `routeFrame` 同判;判别口 `unsettled` / `parking_in_progress`、三判官、结局便签;`decidePath` 带 / 缺席两形);G-PK2 200 回执对照与非回执 200 体不变;G-PK3 停驻事实只由 `reason` ∧ `approvalId` 承载(`approvalId` 缺 / 空 / 非串 / 原型链 / 访问器 / 对不上这张卡 ⇒ 不落 parking、未落定、零通知、不是已批准;`retryAfterMs` 与 `decidePath` 坏值 ⇒ 只丢各自那一键、停驻照认;按键抛错的代理三形 ⇒ `approvalId` 读抛按未落定、提示位读抛只丢那一键;根本不是停驻体 ⇒ 既有路径不变;访问器代码一次不跑);G-PK4 与 SH-1 的交互(耐久路径 join 不长 parking、活卡路径并发每路至多一发);G-PK5 零重发 / 去键 / 换名(两条重发路径恰好撞上 202 各恰两发、30 s 提示不自己等);G-PK6 停驻句逐字与句尾八形;G-PK7 `kind` 联合仍三臂、cause 词表 +1、判别序;G-PK8 AST 单源(线上词读器一处、cause 词两处;植入违例自证);G-PK9 服务端 12 代夹具的 202 体铸点钉。红先:修前 72 格红(首版共 136 格;金样体结局 `{ decision: 'allow' }`、持久臂被丢的伴随句照说、换名 / 去键旗位照铸);其后补入的格(`decidePath`、`approvalId` 认不出的未落定形、提示位坏值的停驻照认形、判别口落 cause)红先在对应的回落形上。**触碰门**:`run-approval-resolution-test.mjs` 56 → 58 格(parking cause 覆盖 + `parking` 位 present-iff 钉)。
|
|
89
|
+
|
|
90
|
+
### Known limits(本版新增)
|
|
91
|
+
|
|
92
|
+
- KL-607 行上没有 `toolCallId` / `boundCallId` 的匿名行(支持底线之下才有)身份键退成 `taskId`:同一 run 两条匿名行会被当成同一把键,后到者拿前一只的结局、本路不呈卡不发 —— 少做方向,那一行仍挂着,下一次读照常呈。
|
|
93
|
+
- KL-608 同一进程装了两份本包 ⇒ 两张登记表互不相见,单一持有不成立。
|
|
94
|
+
- KL-609 持有者那一发中断拒绝的寿命以客户端的单发超时与本包重试窗为上界;注入的客户端不带超时且那一发永不落定时,同键后到者一直拿这次的 `aborted`(不另起决断)。
|
|
95
|
+
- KL-610 持有者那张卡的卡口 Promise 永不落定(宿主撤卡不回 `retracted`、界面重挂丢了卡,也不理会卡上的中止信号)⇒ 同键后到者一并等,不再另呈一张;出路是任一路的信号中止(这一只决断被中断:卡上的中止信号触发,宿主照契约答 `aborted`,登记随之清)或宿主按卡口契约回 `retracted`。
|
|
96
|
+
- KL-611 问答类停驻与流内活卡不在本登记的射程:前者在终端是自己铸卡、自己发决断,不经本口;后者的两个包内来路(流内帧 / 悬挂 ask)按引擎铸法互斥。
|
|
97
|
+
- KL-612 headless env 车道的降档 / 非法值告警是进程内一次性闩;射程 = print 车道一进程一次 run,同进程多 run 的宿主今天不存在(记档,0.93.0 外部验收旁见)。
|
|
98
|
+
- 完整台账见接入文档 §120 末行「包侧缺口」。
|
|
99
|
+
|
|
52
100
|
## 0.93.0(2026-10-09)
|
|
53
101
|
|
|
54
102
|
> 主题:**minor** —— 服务端 7.118.0 / 7.119.0(引擎 7.43.0 – 7.45.0 随带)提货与一批读口归包:审批决定口的出处键 `decidedBy` 与退役键拒绝臂 · 能力位 `permissionModes` / `approvalDecidedBy` 两只读器与 `dontAsk` 按位发词 · workflow 子代审批决定口的两只 409 · MCP 会话内重拨的「没等到结果」臂 · 场景指派悬空的 503 · 终局 `blocked` 的机读成因 · 连接失败现场判读口 · 交出后台的引擎 Bash 登记 · `/health` 配置落地读器与漂移判决 · 引擎装机 core 版本的三态口 · 联网搜索密钥的头值判臂 · 多成因措辞存量两批 · 429 不再一律渲成额度耗尽与错误记录定位句先洗后折两处修复 · 开发依赖引擎 `~7.44.0`。**型面 BREAKING 两处**:0.92.0 预告「0.93.0 删」的八组公面名 / 型位 / 参数按预告硬删(根入口运行期导出 −21 名;支持底线 server 7.106.0 / core 7.35.2 之下的行为不再承诺),与 device 车道读器 `present.management` 由布尔改三态字面;另有四处联合各 +1 员(`DenyAttributionRefusalKind` +`retired_key`、`McpReconnectVerdict` +`unsettled`、`PermissionMode` 一族 +`dontAsk`、联网搜索判决 `malformed` 臂的 `source` +`host`),对这些联合穷举并带 `never` 兜底的写法编译红一次,另有一个导出名与三处公面位标弃用、预告 0.94.0 删。**谁必须动**:换钉 `^0.93.0` 之前,终端与网页端按接入文档 §119d RT 逐处删读点(终端另有两处逻辑改动、一处自补的登记臂要同批删),管理台与桌面端无必改项;编译红清单见 §119y 第 1 条。
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
|
|
|
35
35
|
|
|
36
36
|
## Scope
|
|
37
37
|
|
|
38
|
-
**Version:** 0.93.
|
|
38
|
+
**Version:** 0.93.1
|
|
39
39
|
|
|
40
40
|
- **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
|
|
41
41
|
B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
|
|
@@ -489,6 +489,8 @@ guard still cross-checks the table by name).
|
|
|
489
489
|
| `scripts/run-permission-modes-capability-test.mjs` | The permission-modes capability reader and the bit-gated `dontAsk` mode. The server's capabilities body lists the permission modes its request face accepts; the reader keeps three states (a non-empty list of non-empty words is present, a missing key is an older worker that reports nothing, any malformed shape is dropped as unreadable and reads as not observed), copies the list instead of sharing the caller's array, freezes what it stores, ignores keys that exist only on the prototype, reads the top-level key once and never throws, and its stored reading is discarded automatically when the engine's capability cache changes generation. One judge, `permissionModeAdmitted`, answers true only when the reading is present, the whole list passes the same strict rule as the reader (non-empty, every item an own non-empty string) and it contains the exact word; the headless resolver reads a hand-built reading once per resolution The shell-mode normaliser gives `dontAsk` through only when that judge says yes; with no reading, an older worker, a list without it or a damaged reading it still maps `dontAsk` to `default` (the stricter direction, byte-identical to the previous release), `manual` always maps to `default`, and every other word passes through unchanged whatever reading is given. The field projector never stamps `dontAsk` on its own, and the headless flag lane and environment lane both follow the same rule (the environment lane says so in one warning line when it downgrades). The request-face intent table and the deployment knob's word list are derived from the one tuple, now six words with `dontAsk` last, and equal each other |
|
|
490
490
|
| `scripts/run-server-7119-fixture-test.mjs` | Checks against the published 7.119.0 server package and every older package in the list, each held to an exact per-generation table with the raw readings stored. The retired decision-body key is produced by the server's own routes (the live respond route, the durable ask route and the decide route, including the unknown-keys shape and the shape-sentence shape); from 7.119.0 every refusal body carries the retired key's name as `field`, and through both SDK error mappings the decision-refusal reader recognises it by code and field, never by sentence, while the 7.118.x bodies without a field are not claimed. The capabilities route mints six permission modes in the engine's order, the real admission accepts `dontAsk` only where that list says so (unknown words are refused with the same field error in every generation), and the loop capability reading, bit-gated normaliser, field projector and admission is closed on both sides. The store posture's degraded-reason list no longer contains `db_unreachable` from 7.119.0 (the reader still understands it for older servers), and the health body's session backend label stays a string. The new 503 for an assignment naming a scenario the deployment does not have is produced by the real gate and serialised by the real admission path and is read by code with its detail. A source scan pins that this package has no reader of the council result's output keys. The decision-attribution key is chosen by the capability bit: each generation's three decision routes (live respond, durable ask, decide) accept the key this package would send and apply it as a policy answer, the other key is refused with the retired-key error from 7.118.0 on, and on older generations the new key is refused by two routes and silently dropped by the live one (recorded as a person's answer), which is why a missing bit always means the old key; both of this package's decision legs are driven against the real routes of every generation, including the direct-door refusal (its code changed name with the key) and the single resend without the key, and the two kinds of out-of-set refusal are told apart by code. Every older package is held to its own table. The device lane in the capabilities route is minted in exactly two shapes in every generation from 7.106.0 on (the whole position `false` when no hub is mounted, or an object with `enabled: true`), and the package's one lane reader is held to each: with no hub it reads the lane as absent, with only a hub it reads a present lane whose management bit is off and whose three lane facts equal what the route minted, and with the device store, enrollment and run store plus a configured per-device in-flight cap it reads the bit as on with that cap (not the default); the whole body read back through the tee gives the same reading, and an object forged with `enabled: false` is read as unreadable |
|
|
491
491
|
| `scripts/run-approval-decided-by-capability-test.mjs` | The approval decision-attribution capability reader and the way both decision legs choose their key from it. The server's capabilities body carries a constant bit saying its three decision routes accept the `decidedBy` attribution key; the reader keeps three states (the literal `true` is present, a missing key is an older worker, anything else is dropped as unreadable and reads as not observed — a constant version bit has no meaningful `false`), ignores keys that exist only on the prototype, reads the top-level key once and never throws, and its stored reading is discarded automatically when the engine's capability cache changes generation. One judge, `approvalDecidedByAdmitted`, answers true only for a reading whose own data property `kind` is `present` and whose own data property `value` is `true` (accessors are never run, even if they return the right values). A single exported function, `decisionAttributionKeyOf`, decides the attribution key for both the durable decision leg and the live respond leg (and for any sender outside the package that needs the same answer), and a syntax-tree scan pins that it is declared once, called exactly twice inside the package and that no other place there builds a policy attribution literal (with planted violations proving the scan can fail): a policy refusal goes out as `decidedBy: 'policy'` only when the reading is present, as the old `settledBy: 'policy'` for every other reading (not reported, not observed, damaged, missing, unreadable, or none supplied), and with no attribution key at all for a human refusal, an absent or out-of-set word, an allow card, a failed card port or an abandoned card; the reading is judged once per decision before the first await. The direct-door refusal (its code changed name with the key, both codes read as the same arm) is answered with exactly one resend of the same body without the attribution key, whichever of the two names it carried; a second refusal is not resent, a body that carried no key, a caller that has aborted, the retired-key refusal and every other 400 are not resent, and the classification of a later refusal follows the key actually carried by the last send. The reading supplied through the host lane reaches both legs (the live frame route and the durable park path); only an own data property of the lane counts (a prototype-polluted key, an inherited key or an accessor is treated as not supplied, and the accessor is never run), and a lane that throws when read counts as not supplied, and the bridge's whitelist copy matches each key against `'policy'`, reads only own data properties (a polluted prototype or an accessor never adds a key, including on the resend body) and writes only one of them |
|
|
492
|
+
| `scripts/run-durable-decision-single-holder-test.mjs` | The single holder of a durable approval decision: for one approval identity (the call id of the fetched pending row, or the task id when the row has none), one decision (card, answer, decide including the package's own resends) is in flight per process, and any other caller that arrives while it is in flight, or that started reading the queue before it settled, gets a copy of that same outcome marked `joinedInFlight: true` without presenting a card, sending a decision or resending anything. Two concurrent callers produce exactly one card and one decide in both arrival orders, including the real park resolver racing a direct re-presentation of the same row (the stream finishes and both sides settle); a failed decide or a throwing card port gives both callers the same failure and clears the registration so the next call is a new decision; an abort signal from either caller interrupts that one decision: the holder's card is withdrawn and the holder alone sends exactly one interruption deny that both callers report, with identical readings whichever path holds, while an abort that arrives after the decision settled sends nothing and returns the settled outcome; different identities never join; the joining caller reports the holder's card through `onPresented` only when that card was actually handed to the card port (a throwing callback does not change its outcome) and never reports a decide operation; the copy never alters the holder's object and the flag is never written as `false`; and a syntax-tree scan pins that the joining and registration code paths contain no card, decide or notice call (with a planted violation proving the scan can fail) |
|
|
493
|
+
| `scripts/run-approval-respond-parking-test.mjs` | The live-card respond answer when the engine replies `202` with the reason `parking_in_progress`: the card's row is moving to parked, so the answer did not take effect. The outcome is `decision: 'unresolved'` plus a `parking` position carrying the approval id and, when the engine supplies them, the suggested retry interval and the decide path of the parked card; the resolution reader reports it on the existing unsettled arm with the new cause `parking_in_progress` (the union keeps its three arms; a retracted or edit-refused card still wins over it, and it wins over the decision word). The parking fact is carried only by an own data property naming the reason and a non-empty approval id that matches the card; a retry interval or decide path that is unusable drops only itself and the parking still stands. A body that names the parking reason but whose approval id is missing, unusable or belongs to another card is reported as not settled, never as decided and never as parked, with no notice and no resend. The answer is never re-sent, never has its attribution key dropped or renamed afterwards, and the package does not wait for the interval; no accompanying notice (for example the one saying the approval itself went through) and no attribution position is produced; exactly one user-facing sentence is shown (with the engine's suggested wait appended in seconds when given) and it contains no engine text. A 200 acknowledgement keeps its reading unchanged, bodies that are neither acknowledgements nor parking bodies are not read as parking, the durable decision path and its single holder have no parking cause, and a syntax-tree scan pins one reader declaration, one call site and the places where the reason word is minted, while the 202 body shape is pinned against every server generation in the fixture list |
|
|
492
494
|
|
|
493
495
|
Each suite carries a floor that only moves up — a refactor that stops executing a group of
|
|
494
496
|
assertions is a failure, not a quieter pass. Guards anchor on the **installed artefact's content**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { DecideReceiptView } from '../decideReceipt.js';
|
|
2
2
|
import type { HitlSafetyCode } from './hitlBridge.js';
|
|
3
|
-
import type { FsApprovalOutcome, ToolApprovalFrameOutcome, ToolApprovalRespondAckView, ToolApprovalRespondDecision } from './toolApprovalWire.js';
|
|
3
|
+
import type { FsApprovalOutcome, ToolApprovalFrameOutcome, ToolApprovalRespondAckView, ToolApprovalRespondDecision, ToolApprovalRespondParkingView } from './toolApprovalWire.js';
|
|
4
4
|
export declare const APPROVAL_NOT_SENT_CAUSES: readonly ["retracted", "edit_refused", "no_pending", "fetch_failed", "no_input", "card_unavailable"];
|
|
5
5
|
export type ApprovalNotSentCause = (typeof APPROVAL_NOT_SENT_CAUSES)[number];
|
|
6
|
-
export declare const APPROVAL_UNSETTLED_CAUSES: readonly ["engine_refused", "decide_failed", "transport_exhausted", "safety_stop", "respond_failed", "interrupted", "orchestration", "unreadable"];
|
|
6
|
+
export declare const APPROVAL_UNSETTLED_CAUSES: readonly ["engine_refused", "decide_failed", "transport_exhausted", "safety_stop", "respond_failed", "parking_in_progress", "interrupted", "orchestration", "unreadable"];
|
|
7
7
|
export type ApprovalUnsettledCause = (typeof APPROVAL_UNSETTLED_CAUSES)[number];
|
|
8
8
|
export interface ApprovalResolutionDecided {
|
|
9
9
|
kind: 'decided';
|
|
@@ -26,6 +26,7 @@ export interface ApprovalResolutionUnsettled {
|
|
|
26
26
|
errorCode?: string;
|
|
27
27
|
status?: number;
|
|
28
28
|
detail?: string;
|
|
29
|
+
parking?: ToolApprovalRespondParkingView;
|
|
29
30
|
}
|
|
30
31
|
export type ApprovalResolution = ApprovalResolutionDecided | ApprovalResolutionNotSent | ApprovalResolutionUnsettled;
|
|
31
32
|
export type ApprovalLegOutcome = FsApprovalOutcome | ToolApprovalFrameOutcome;
|
|
@@ -12,6 +12,7 @@ export const APPROVAL_UNSETTLED_CAUSES = Object.freeze([
|
|
|
12
12
|
'transport_exhausted',
|
|
13
13
|
'safety_stop',
|
|
14
14
|
'respond_failed',
|
|
15
|
+
'parking_in_progress',
|
|
15
16
|
'interrupted',
|
|
16
17
|
'orchestration',
|
|
17
18
|
'unreadable',
|
|
@@ -98,11 +99,23 @@ function fsLegResolution(outcome, kind) {
|
|
|
98
99
|
return { kind: 'unsettled', cause: 'orchestration', ...call, ...detail };
|
|
99
100
|
return { kind: 'unsettled', cause: 'unreadable', ...call, ...detail };
|
|
100
101
|
}
|
|
102
|
+
function parkingViewOf(v) {
|
|
103
|
+
const approvalId = str(pick(v, 'approvalId'));
|
|
104
|
+
if (approvalId === undefined)
|
|
105
|
+
return undefined;
|
|
106
|
+
const hint = pick(v, 'retryAfterMs');
|
|
107
|
+
const retryAfterMs = typeof hint === 'number' && Number.isFinite(hint) && hint >= 0 ? hint : undefined;
|
|
108
|
+
const decidePath = str(pick(v, 'decidePath'));
|
|
109
|
+
return { approvalId, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), ...(decidePath !== undefined ? { decidePath } : {}) };
|
|
110
|
+
}
|
|
101
111
|
function frameLegResolution(outcome) {
|
|
102
112
|
if (pick(outcome, 'retracted') === true)
|
|
103
113
|
return { kind: 'not_sent', cause: 'retracted' };
|
|
104
114
|
if (pick(outcome, 'editRefused') === true)
|
|
105
115
|
return { kind: 'not_sent', cause: 'edit_refused' };
|
|
116
|
+
const parking = parkingViewOf(pick(outcome, 'parking'));
|
|
117
|
+
if (parking !== undefined)
|
|
118
|
+
return { kind: 'unsettled', cause: 'parking_in_progress', parking };
|
|
106
119
|
if (pick(outcome, 'decision') === 'unresolved') {
|
|
107
120
|
const refusal = pick(outcome, 'respondRefusal');
|
|
108
121
|
return {
|
|
@@ -28,6 +28,9 @@ export declare const REMEMBER_NOT_APPLIED_WARN_TEXT = "this session-wide allow w
|
|
|
28
28
|
export declare const EDIT_NOT_FORWARDED_WARN_TEXT = "your edited tool input was NOT forwarded \u2014 the tool is running with the ORIGINAL input you saw before editing";
|
|
29
29
|
export declare function surfaceRememberNotApplied(): void;
|
|
30
30
|
export declare function surfaceEditNotForwarded(): void;
|
|
31
|
+
export declare const APPROVAL_PARKING_WARN_TEXT = "This approval is being parked; answer it again on the parked card when it appears.";
|
|
32
|
+
export declare function approvalParkingNoticeText(retryAfterMs?: number): string;
|
|
33
|
+
export declare function surfaceApprovalParking(retryAfterMs?: number): void;
|
|
31
34
|
export declare const REPLAYED_APPROVAL_LIST_UNREADABLE_WARN_TEXT: string;
|
|
32
35
|
export declare function surfaceReplayedApprovalListUnreadable(): void;
|
|
33
36
|
export declare const EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT: string;
|
|
@@ -72,6 +72,17 @@ export function surfaceRememberNotApplied() {
|
|
|
72
72
|
export function surfaceEditNotForwarded() {
|
|
73
73
|
surfaceSelfClearingWarn(EDIT_NOT_FORWARDED_KEY, EDIT_NOT_FORWARDED_WARN_TEXT, EDIT_NOT_FORWARDED_TIMEOUT_MS);
|
|
74
74
|
}
|
|
75
|
+
export const APPROVAL_PARKING_WARN_TEXT = 'This approval is being parked; answer it again on the parked card when it appears.';
|
|
76
|
+
const APPROVAL_PARKING_KEY = 'hitl-approval-parking';
|
|
77
|
+
const APPROVAL_PARKING_TIMEOUT_MS = 15_000;
|
|
78
|
+
export function approvalParkingNoticeText(retryAfterMs) {
|
|
79
|
+
if (retryAfterMs === undefined)
|
|
80
|
+
return APPROVAL_PARKING_WARN_TEXT;
|
|
81
|
+
return `${APPROVAL_PARKING_WARN_TEXT} (the engine suggested waiting about ${Math.ceil(retryAfterMs / 100) / 10} s)`;
|
|
82
|
+
}
|
|
83
|
+
export function surfaceApprovalParking(retryAfterMs) {
|
|
84
|
+
surfaceSelfClearingWarn(APPROVAL_PARKING_KEY, approvalParkingNoticeText(retryAfterMs), APPROVAL_PARKING_TIMEOUT_MS);
|
|
85
|
+
}
|
|
75
86
|
export const REPLAYED_APPROVAL_LIST_UNREADABLE_WARN_TEXT = "Could not read the pending-approval list, so an approval request read back from this run's event log was not raised as a question, " +
|
|
76
87
|
'and no decision was sent for it.';
|
|
77
88
|
const REPLAYED_APPROVAL_LIST_UNREADABLE_KEY = 'hitl-replayed-approval-list-unreadable';
|
|
@@ -26,12 +26,15 @@ export type FsApprovalOutcome = {
|
|
|
26
26
|
denyAttributionDropped?: true;
|
|
27
27
|
denyAttributionRenamed?: true;
|
|
28
28
|
receipt?: DecideReceiptView | undefined;
|
|
29
|
+
joinedInFlight?: true;
|
|
29
30
|
} | {
|
|
30
31
|
kind: 'aborted';
|
|
31
32
|
gatedCallId?: string | undefined;
|
|
33
|
+
joinedInFlight?: true;
|
|
32
34
|
} | {
|
|
33
35
|
kind: 'retracted';
|
|
34
36
|
gatedCallId?: string | undefined;
|
|
37
|
+
joinedInFlight?: true;
|
|
35
38
|
} | {
|
|
36
39
|
kind: 'failed';
|
|
37
40
|
stage: HitlFailureStage;
|
|
@@ -45,6 +48,7 @@ export type FsApprovalOutcome = {
|
|
|
45
48
|
currentPending?: GateCurrentPending | undefined;
|
|
46
49
|
denyAttributionRefusal?: DenyAttributionRefusalDetail | undefined;
|
|
47
50
|
editRefused?: true;
|
|
51
|
+
joinedInFlight?: true;
|
|
48
52
|
};
|
|
49
53
|
export interface FsApprovalWireDeps {
|
|
50
54
|
client: HitlClientLike;
|
|
@@ -246,6 +250,11 @@ export type RespondToolApprovalFn = (approvalId: string, decision: ToolApprovalR
|
|
|
246
250
|
export type ToolApprovalRespondAckView = ToolApprovalRespondAck;
|
|
247
251
|
export type PersistedRuleAnchor = SdkPersistedRuleAnchor;
|
|
248
252
|
export declare function readToolApprovalRespondAck(v: unknown): ToolApprovalRespondAckView | undefined;
|
|
253
|
+
export interface ToolApprovalRespondParkingView {
|
|
254
|
+
readonly approvalId: string;
|
|
255
|
+
readonly retryAfterMs?: number;
|
|
256
|
+
readonly decidePath?: string;
|
|
257
|
+
}
|
|
249
258
|
export declare function decisionAttributionKeyOf(reading: ApprovalDecidedByReading | undefined, denySettledBy: ApprovalDenySettledBy | undefined): {
|
|
250
259
|
decidedBy: 'policy';
|
|
251
260
|
} | {
|
|
@@ -262,6 +271,7 @@ export interface ToolApprovalFrameOutcome {
|
|
|
262
271
|
denyAttributionRefusal?: DenyAttributionRefusalDetail;
|
|
263
272
|
denyAttributionDropped?: true;
|
|
264
273
|
denyAttributionRenamed?: true;
|
|
274
|
+
parking?: ToolApprovalRespondParkingView;
|
|
265
275
|
}
|
|
266
276
|
interface ToolApprovalRespondRefusalFields {
|
|
267
277
|
status?: number;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { APPROVAL_CARD_PORT_KEY_MISMATCH_REASON, DEFAULT_DENY_REASON, DecideTransportRetryExhaustedError, HitlBridge, NO_APPROVAL_CARD_PORT_REASON, HitlSafetyError, denyReasonForWire, findPendingForTask, readDecideCurrentPending, readWireErrorCode, } from './hitlBridge.js';
|
|
2
2
|
import { askParkRowArm } from './askParkRowRouting.js';
|
|
3
3
|
import { hostLog } from '../host.js';
|
|
4
|
-
import { readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
|
|
4
|
+
import { readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
|
|
5
5
|
import { readAskClassPair } from './askClassPair.js';
|
|
6
6
|
import { legacyShadowedRuleTextOf, readAllowRuleShadowFromWire } from './allowRuleShadow.js';
|
|
7
7
|
import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
8
8
|
import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
|
|
9
|
-
import { observeCancelByDeny, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
|
|
9
|
+
import { observeCancelByDeny, surfaceApprovalParking, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
|
|
10
10
|
import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
|
|
11
11
|
import { isApprovalMandateWord } from '../gateVocabulary.js';
|
|
12
12
|
import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
|
|
@@ -170,11 +170,117 @@ function isParkRowInputSizeMarker(v) {
|
|
|
170
170
|
const o = v;
|
|
171
171
|
return o.truncated === true && typeof o.bytes === 'number' && Number.isFinite(o.bytes) && o.bytes >= 0;
|
|
172
172
|
}
|
|
173
|
+
const durableDecisionHolds = { inFlight: new Map(), settled: new Map(), openReads: new Set(), clock: 0 };
|
|
174
|
+
function durableHoldKey(row, callKey) {
|
|
175
|
+
return JSON.stringify([typeof row.sessionId === 'string' ? row.sessionId : null, typeof row.taskId === 'string' ? row.taskId : null, callKey]);
|
|
176
|
+
}
|
|
177
|
+
function openDurableRead() {
|
|
178
|
+
const mark = ++durableDecisionHolds.clock;
|
|
179
|
+
durableDecisionHolds.openReads.add(mark);
|
|
180
|
+
return mark;
|
|
181
|
+
}
|
|
182
|
+
function closeDurableRead(mark) {
|
|
183
|
+
const h = durableDecisionHolds;
|
|
184
|
+
h.openReads.delete(mark);
|
|
185
|
+
let oldest = Infinity;
|
|
186
|
+
for (const m of h.openReads)
|
|
187
|
+
if (m < oldest)
|
|
188
|
+
oldest = m;
|
|
189
|
+
for (const [key, s] of h.settled)
|
|
190
|
+
if (s.at <= oldest)
|
|
191
|
+
h.settled.delete(key);
|
|
192
|
+
}
|
|
193
|
+
function heldDurableDecision(holdKey, readMark) {
|
|
194
|
+
const live = durableDecisionHolds.inFlight.get(holdKey);
|
|
195
|
+
if (live !== undefined)
|
|
196
|
+
return live;
|
|
197
|
+
const recent = durableDecisionHolds.settled.get(holdKey);
|
|
198
|
+
return recent !== undefined && recent.at > readMark ? recent.hold : undefined;
|
|
199
|
+
}
|
|
200
|
+
function holdDurableDecision(holdKey, callerSignal, decide) {
|
|
201
|
+
const h = durableDecisionHolds;
|
|
202
|
+
const interruption = new AbortController();
|
|
203
|
+
let settled = false;
|
|
204
|
+
const interrupt = () => {
|
|
205
|
+
if (!settled && !interruption.signal.aborted)
|
|
206
|
+
interruption.abort();
|
|
207
|
+
};
|
|
208
|
+
if (callerSignal?.aborted === true)
|
|
209
|
+
interrupt();
|
|
210
|
+
else
|
|
211
|
+
callerSignal?.addEventListener('abort', interrupt, { once: true });
|
|
212
|
+
let resolveOutcome = () => { };
|
|
213
|
+
let rejectOutcome = () => { };
|
|
214
|
+
const outcome = new Promise((resolve, reject) => {
|
|
215
|
+
resolveOutcome = resolve;
|
|
216
|
+
rejectOutcome = reject;
|
|
217
|
+
});
|
|
218
|
+
const hold = { outcome, presented: false, interrupt, cardSignal: interruption.signal };
|
|
219
|
+
h.inFlight.set(holdKey, hold);
|
|
220
|
+
const release = () => {
|
|
221
|
+
if (h.inFlight.get(holdKey) === hold)
|
|
222
|
+
h.inFlight.delete(holdKey);
|
|
223
|
+
if (h.openReads.size > 0)
|
|
224
|
+
h.settled.set(holdKey, { at: ++h.clock, hold });
|
|
225
|
+
};
|
|
226
|
+
const settle = (give) => {
|
|
227
|
+
settled = true;
|
|
228
|
+
callerSignal?.removeEventListener('abort', interrupt);
|
|
229
|
+
const trailing = hold.trailing;
|
|
230
|
+
if (trailing === undefined) {
|
|
231
|
+
release();
|
|
232
|
+
give();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
give();
|
|
236
|
+
trailing.then(release, release);
|
|
237
|
+
};
|
|
238
|
+
decide(hold).then((o) => settle(() => resolveOutcome(o)), (e) => settle(() => rejectOutcome(e)));
|
|
239
|
+
return outcome;
|
|
240
|
+
}
|
|
241
|
+
async function joinDurableDecision(hold, deps, signal) {
|
|
242
|
+
if (signal?.aborted === true)
|
|
243
|
+
hold.interrupt();
|
|
244
|
+
else
|
|
245
|
+
signal?.addEventListener('abort', hold.interrupt, { once: true });
|
|
246
|
+
let o;
|
|
247
|
+
try {
|
|
248
|
+
o = await hold.outcome;
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
signal?.removeEventListener('abort', hold.interrupt);
|
|
252
|
+
}
|
|
253
|
+
if (hold.presented) {
|
|
254
|
+
try {
|
|
255
|
+
deps.onPresented?.();
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return { ...o, joinedInFlight: true };
|
|
261
|
+
}
|
|
173
262
|
export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signal, parkGatedCallId) {
|
|
174
263
|
const decidedByReading = decidedByReadingSnapshotOf(deps);
|
|
175
|
-
const
|
|
264
|
+
const readMark = openDurableRead();
|
|
265
|
+
let found;
|
|
266
|
+
let held;
|
|
267
|
+
try {
|
|
268
|
+
found = await findPendingForTask(deps.client, taskId, (toolName) => toolName !== undefined && (toolNameIsFsWrite(toolName) || toolNameIsShellExec(toolName)), signal ? { signal } : undefined, parkGatedCallId, (row) => askParkRowArm(row) === 'tool-gate');
|
|
269
|
+
if (found.ok)
|
|
270
|
+
held = heldDurableDecision(durableHoldKey(found.pending, approvalCallKey(found.gatedCallId, taskId)), readMark);
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
closeDurableRead(readMark);
|
|
274
|
+
}
|
|
176
275
|
if (!found.ok)
|
|
177
276
|
return { kind: 'failed', stage: 'fetch', reason: found.reason, ...(found.code !== undefined ? { code: found.code } : {}) };
|
|
277
|
+
if (held !== undefined)
|
|
278
|
+
return joinDurableDecision(held, deps, signal);
|
|
279
|
+
const callKey = approvalCallKey(found.gatedCallId, taskId);
|
|
280
|
+
const fetched = found;
|
|
281
|
+
return holdDurableDecision(durableHoldKey(fetched.pending, callKey), signal, (hold) => presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, fetched, decidedByReading, callKey, hold));
|
|
282
|
+
}
|
|
283
|
+
async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, found, decidedByReading, callKey, hold) {
|
|
178
284
|
const { pending, gatedCallId } = found;
|
|
179
285
|
const toolName = typeof pending.toolName === 'string' ? pending.toolName : '';
|
|
180
286
|
const streamArgs = gatedCallId !== undefined ? argsByCall.get(gatedCallId) : undefined;
|
|
@@ -191,18 +297,18 @@ export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signa
|
|
|
191
297
|
return { kind: 'failed', stage: 'input', gatedCallId, reason: 'gate has no tool input payload' };
|
|
192
298
|
}
|
|
193
299
|
const bridge = new HitlBridge(deps.client, taskId, deps.onDecideOperation ? { onDecideOperation: deps.onDecideOperation } : undefined);
|
|
194
|
-
const callKey = approvalCallKey(gatedCallId, taskId);
|
|
195
300
|
const ruleOffersReadOnly = readRuleOffers(pending.ruleOffers);
|
|
196
301
|
const durableProbeCause = pending.riskDescriptor?.probeCause;
|
|
197
302
|
const durableProbeReason = readProbeReason(pending.riskDescriptor);
|
|
198
303
|
const durableShadow = readAllowRuleShadowFromWire(pending, 'row');
|
|
199
304
|
const durableRuleOffersAbsence = pending.ruleOffersAbsence;
|
|
305
|
+
hold.presented = true;
|
|
200
306
|
deps.onPresented?.();
|
|
201
307
|
const card = await surfaceApprovalCard({
|
|
202
308
|
toolName,
|
|
203
309
|
args,
|
|
204
310
|
callKey,
|
|
205
|
-
|
|
311
|
+
signal: hold.cardSignal,
|
|
206
312
|
...(rowArgsGap !== undefined
|
|
207
313
|
? {
|
|
208
314
|
argsUnavailable: true,
|
|
@@ -245,7 +351,11 @@ export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signa
|
|
|
245
351
|
hostLog('debug', `liveHitlAskWire: approval card retracted without a decision for ${gatedCallId ?? '(no call)'} — nothing sent`);
|
|
246
352
|
return { kind: 'retracted', gatedCallId };
|
|
247
353
|
case 'aborted':
|
|
248
|
-
|
|
354
|
+
{
|
|
355
|
+
const cancelDeny = bridge.decideTool({ decision: 'deny', reason: 'Interrupted by user' }, gatedCallId, undefined, pending);
|
|
356
|
+
hold.trailing = cancelDeny;
|
|
357
|
+
observeCancelByDeny(cancelDeny, taskId);
|
|
358
|
+
}
|
|
249
359
|
return { kind: 'aborted', gatedCallId };
|
|
250
360
|
case 'allow':
|
|
251
361
|
try {
|
|
@@ -546,6 +656,27 @@ export function readToolApprovalRespondAck(v) {
|
|
|
546
656
|
}
|
|
547
657
|
return out;
|
|
548
658
|
}
|
|
659
|
+
function readToolApprovalRespondParking(v) {
|
|
660
|
+
if (typeof v !== 'object' || v === null)
|
|
661
|
+
return undefined;
|
|
662
|
+
const read = (fn) => {
|
|
663
|
+
try {
|
|
664
|
+
return fn();
|
|
665
|
+
}
|
|
666
|
+
catch {
|
|
667
|
+
return undefined;
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
if (read(() => readOwnDataNonEmptyString(v, 'reason')) !== 'parking_in_progress')
|
|
671
|
+
return undefined;
|
|
672
|
+
const approvalId = read(() => readOwnDataNonEmptyString(v, 'approvalId'));
|
|
673
|
+
if (approvalId === undefined)
|
|
674
|
+
return { kind: 'claimed_unreadable' };
|
|
675
|
+
const hint = read(() => readOwnDataValue(v, 'retryAfterMs'));
|
|
676
|
+
const retryAfterMs = typeof hint === 'number' && Number.isFinite(hint) && hint >= 0 ? hint : undefined;
|
|
677
|
+
const decidePath = read(() => readOwnDataNonEmptyString(v, 'decidePath'));
|
|
678
|
+
return { kind: 'parking', view: { approvalId, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), ...(decidePath !== undefined ? { decidePath } : {}) } };
|
|
679
|
+
}
|
|
549
680
|
function isNonEmptyStringArray(v) {
|
|
550
681
|
return Array.isArray(v) && v.length > 0 && v.every(x => typeof x === 'string' && x !== '');
|
|
551
682
|
}
|
|
@@ -1101,6 +1232,19 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
|
|
|
1101
1232
|
throw first;
|
|
1102
1233
|
}
|
|
1103
1234
|
}
|
|
1235
|
+
const parkingBody = readToolApprovalRespondParking(raw);
|
|
1236
|
+
if (parkingBody !== undefined) {
|
|
1237
|
+
const parking = parkingBody.kind === 'parking' && parkingBody.view.approvalId === approvalId ? parkingBody.view : undefined;
|
|
1238
|
+
if (parking !== undefined) {
|
|
1239
|
+
hostLog('debug', `liveToolApprovalWire: respond(${decision}) for ${approvalId} answered 202 parking_in_progress${parking.retryAfterMs !== undefined ? ` (retryAfterMs=${parking.retryAfterMs})` : ''} — ` +
|
|
1240
|
+
`the answer did NOT take effect${parking.decidePath !== undefined ? ' (the engine pointed at a decide path for the parked card)' : ''}; not re-sent, not reported as decided; the user is told to answer again on the parked card`);
|
|
1241
|
+
surfaceApprovalParking(parking.retryAfterMs);
|
|
1242
|
+
return { decision: 'unresolved', parking };
|
|
1243
|
+
}
|
|
1244
|
+
hostLog('error', `liveToolApprovalWire: 202 parking body for ${approvalId} is ${parkingBody.kind === 'parking' ? `for another approval (${parkingBody.view.approvalId})` : 'unreadable (approvalId is not usable)'} — ` +
|
|
1245
|
+
'reporting the answer as NOT settled (never as decided, never as parked); not re-sent');
|
|
1246
|
+
return { decision: 'unresolved' };
|
|
1247
|
+
}
|
|
1104
1248
|
const parsed = readToolApprovalRespondAck(raw);
|
|
1105
1249
|
let ack = parsed;
|
|
1106
1250
|
if (parsed !== undefined && (parsed.approvalId !== approvalId || parsed.decision !== decision)) {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **0.93.0**(本批发布版 = **minor**:到期登记物硬删八组(型面 BREAKING;根入口 −21 名;CC-431)· device 车道读器扩到车道三位与 `management` 三态字面、新判据 `deviceLaneOpen`(型面 BREAKING;CC-454)· 审批决定口出处键换名:能力位 `approvalDecidedBy` 读器 / 唯一决定函数 `decisionAttributionKeyOf` / 退役键拒绝臂 `retired_key` / 换名恰重发一次(CC-403 并 CC-451 ②)· 能力位 `permissionModes` 读器与 `dontAsk` 按位发词(CC-451 ③)· 终局 `blocked` 的机读成因 `detail` 与会话规则记录读不到句的第十六句(CC-364)· 连接失败现场判读口 `transportFailureScene`(CC-363)· 交出后台的引擎 Bash 登记 `detectEngineBgShellDetach`(CC-331)· 子代 tick 模型位与 `/health` 配置落地读器 `readEngineConfigApplyState` / 漂移判决 `configDriftVerdict`(CC-323)· 引擎装机 core 版本三态口 `coreVersionTier`(CC-355)· 停泊赎回启动失败成因词位 `startupCause`(CC-244)· workflow 子代审批决定口两只 409(CC-430)· MCP 重拨 `unsettled` 判决臂(CC-429)· 联网搜索密钥头值判臂与来源 `host`(CC-428)· 多成因措辞存量两批(CC-120 / 423 / 422)· 活卡帧键镜像 +3(CC-433)· 会话规则可送判定对空对端段名收紧(CC-437)· 场景指派悬空 503 读口(CC-451 ⑤)· 重试覆盖层 429 不再渲成额度耗尽(CC-473)· 展示出口先洗后折(CC-472)· 弃用预告一名三位(CC-309 / 431)· 开发依赖引擎 `~7.44.0` 与生成表(CC-427)· 其余 CC-242 / 301 / 295 / 365 / 374;型面 BREAKING 两处 + 四处联合各 +1 员 + 一名三位弃用预告;根公面 1483 → 1485(+23 −21);测试钩 69 → 71;peer sdk 地板 `>=12.0.1` 不动;服务端夹具现役 7.119.0(老一代 7.106.0 – 7.118.0 十一份)、sdk 17.1.0 作下一代见证位;§119)。上一版 0.92.0 = **minor**:自动答复判定收成一只 `automaticAnswerVerdict`(CC-368)· 卡面披露键两代读 `allowRuleShadow`(CC-401)· steer 档位经包 `steerBodyOf` / `fleet.steerPriority` / `readSteerReceipt`(CC-374 并 CC-353)· 能力位读器读数随代际自动失效(CC-377)· 服务端 7.116.0 / sdk 16.2.0 提货 + `CoreValuePorts` +1 必填(CC-371 / 370)· 会话规则可送判定过规则编译器与协议名段判定(CC-381)· 支持底线抬到 server 7.106.0 / core 7.35.2(CC-352 / 380)· 其余 CC-367 / 369 / 373 / 376 / 379 / 366 / 178 / 295 / 407;型面 BREAKING 四处 + 七名弃用预告;根公面 1429 → 1483(+56 −2);测试钩 68 → 69;服务端夹具现役 7.116.0(老一代 7.106.0 – 7.115.0 八份)、7.117.0 与 sdk 16.3.0 作下一代见证位;§118)。上一版 0.91.0 = **minor**:steer 拒收处置句单源 `steerRefusalAdviceOf` / `ControlSafetyError.advice` · `.status` / `steeringRefusedBeforeEngine`(CC-307)· `abortableSleep` / `isAlreadyResolvedFailure` 上根入口(CC-317)· 引擎闭集表 `ASK_EVIDENCE_ABSENCE_VALUES` / `SYSTEM_INJECTION_PRIORITIES` / `READ_DENY_BUILTIN_TIERS` · `READ_DENY_DEFAULT_TIERS` + `parseReadDenyBuiltinTiers` / `MODE_ARBITRATION` + `askSurvivesStandingAnswer`(CC-318 / 327 / 322 ①)· 会话历史 tool_use 错配一族:`_sema_provider_rejection_resend` 归合成终局行、错配键 `rewindOffered`、`readToolHistoryMismatchKey` / `ToolHistoryMismatchRowKey`、`toolHistoryBadTurnSentence`(CC-303 / 304 / 305 / 309 ②)· 投递账本记录 `by` / `share` 与 `deliveryShareOf` / `droppedKeyCount`、`attempted` 的 `{ generation }` + `undeliveredInGeneration`(`PromptDeliveryLedger` 接口 +3 必有成员 —— 型面 BREAKING 第一处;CC-293 / 334)· 崩溃遗留通告 `crashConvergedNotice` / `crashConvergedNeedsHumanSentence` / `NEEDS_HUMAN_REASON_ORDER`(CC-310)· `permissionsDeclarationReport` + `PERMISSIONS_KEPT_REASONS` 与 `PermissionsDeclarationInput.settingsRead` 必填(型面 BREAKING 第二处;CC-314)· `engineCapsSettled(url, { withinMs })` 返回型窄变 `Promise<'settled' | 'timed_out'>` + `disableSkillsDeclarationSettled`(CC-311)· `hookMatcherVerdict`(CC-306)· `sessionPolicyReadNotice`(CC-328)· `inheritEnvRefusalContent` 首段改口(CC-336)· `attachmentsSubmitVerdict`(CC-337)· 展示出口 YAML 块标量整块一枚记号(CC-340)· `mintUserAttachmentEnvelope` / `encodeHumanTurn` / `deliveredUuidsOf` / `imageVisionOf` + 附件席位能力位读器占位形(CC-315 / 297 子集)· 服务端 7.115.0 / sdk 16.1.0 提货:「只续已有会话」按码优先、`checkpointUnsupportedVersionFromError` / `checkpointUnsupportedVersionContent`、`hookMatcherRefusalFromError`、活卡帧与耐久行 `probeReason`、接线回执 `fleet` 段 + `WiringManifestFleetView`(CC-339)· 登记物整治:`permissionRuleIssueDetail` 第三参分句(CC-359)、`rewindSpecForMode` 第三参按纪元位取舍(CC-345 ①)、HITL 桥两处型面 additive 与补偿表 `retireOn` 改台账行号(CC-343)、已知限制档清账(CC-349)· 开发依赖 settings-schema `^8.0.0`(CC-308,不出包)· 根公面 1397 → 1429(+32,零删名);测试钩 63 → 64;公面类型名 964 → 997;超集键 +2(`_sema_provider_rejection_resend` / `_sema_fleet`);peer sdk 地板 `>=12.0.1` 不动;服务端夹具现役 7.115.0(老一代八份)、sdk 16.1.0 进地板见证矩阵;§117)。上一版 0.90.0 = **minor**:引擎 7.40.1 / 服务端 7.113.0 · 7.114.0 / sdk 16 探针提货(通告码册 86 → 85、`readLegacyModeSeedMigrated` 退出公面、`attachments.planModeReminder` 退役、`PromptDeliveryLedger` +2 必有成员 —— 型面 BREAKING 三处;CC-291 / 300)· 云控制面子路径五名(CC-136)· 文件历史一句五态判定与声明事实账本(CC-294)· hooks matcher 工具别名读口(CC-298)· 机读支持底线与 `engineVersionTier`(CC-299)· `settings.permissions` 三桶装配口与 allow 能力位(CC-302)· 「改了重发」错配让位与错误载体铸口(CC-309 ①)· `AttachmentsSpecRefused`(CC-316)· 能力位读数冻结;根公面 1379 → 1397、peer sdk 地板 `>=12.0.1` 不动;§116。上一版 0.89.0 = **minor**:引擎 7.38 提货(开发依赖换钉引擎 `~7.38.2`;通告码册 81 → 86、引擎铸方表接手服务端自铸码的受众,`SERVER_NOTICE_AUDIENCE` 🔧 退出公面(型面 BREAKING,逐名见 §2z);工具轮不完整读器 `readToolTurnIncomplete`、用户输入没被用上读器 `readUserInputUndrained` 与一句 `userInputUndrainedNotice`(`EngineNoticeFactsCode` +3 员,穷尽分支的端编译期红);终局服务商拒绝详情 `readRunTerminal` 的 `failed.detail` 与「改了重发」判定口 `providerRejectionResend`;steer 账本 503 `ledger_unavailable` 一张码表三条腿(`ControlSafetyCode` +1 员、子代 steer 结局联合 +1 臂,穷尽分支的端编译期红);省略成因短语口 `taskRequestOmissionCausePhrase`;CC-282);审批四面问类两位 `askClass` / `classes`(三型各 +2 可选位;CC-284);请求键 `disableSkills` 与片段口 `disableSkillsDeclaration`(车道表 45 → 46 行;CC-277);hooks 设置来源条目的唯一执行者与本端跳过口 `settingsHooksKeptLocally`(`PLUGIN_HOOK_REASONS` +5 词、`PLUGIN_HOOK_EXCLUSION_REASONS` +1 词,穷尽分支的端编译期红;CC-287);凭据被拒判官 `isReadCredentialRefusal` 上根入口(CC-289);服务端 7.111.0 两项(接线回执新段 `instructions`、子代转向成功结局 `messageId`;CC-282 余项)与展示出口无标签 `Token <值>` 形照遮(CC-290);根公面 1372 → 1379;测试钩 62 不变;公面类型名 942 → 952;超集键 +1(98 → 99,`_sema_instructions`);peer sdk 地板 `>=12.0.1` 不动;§115)。上一版 0.88.0 = **minor**:展示出口凭据面一次扫描(带凭据的输入上输出字节变、干净文本逐字节同、一轮即不动;CC-247);崩溃收敛 `cause` 认第二个词 `shutdown_before_park`(`CrashConvergedRow.cause` 型联合 +1 词,穷尽分支的端编译期红;CC-218);服务端自铸通告 `server.model_unreachable` 入受众表与事实读器 `readModelUnreachable`(CC-270 ①);开发依赖换钉引擎 `~7.37.1`、放行原因闭集镜像 `GATE_MODE_RELEASE_REASON_WORDS` / `isGateModeReleaseReasonWord`、修复通告事实读器 `readToolTurnRepaired`、通告码册 80 → 81(`EngineNoticeFactsCode` +2 员;CC-272);会话所有者自助记忆抹除 `eraseSessionMemory` / `sessionMemoryEraseOutcome` + 三只闭集镜像(CC-264);registry 同一个 409 的两义判别 `classifyRegistryConflict` / `isScopeGoneError`(CC-280);请求键 `requireExistingSession`(车道表 44 → 45 行)与被拒读口 `requireExistingSessionRefusalFromError` / 一句 `requireExistingSessionRefusalContent`(CC-281);投递事实账本 `createPromptDeliveryLedger` + 两只按消息行的读口 `promptKnownUndelivered` / `withoutUndeliveredPrompts`(判据 = 引擎为这次提交建了 run;CC-271);plan 决断台账:离门证据结掉、还没被认领的登记由投递口认领原笔(CC-278);`wiring_manifest` 帧 `fileHistory` 段(`WiringManifestChromeEvent.fileHistory?` / `WiringManifestView.fileHistory?`,超集键 `_sema_fileHistory`;CC-279);根公面 1356 → 1372;测试钩 62 不变;公面类型名 922 → 942;超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§114)。上一版 0.87.0 = **minor**:会话历史 tool_use 错配的自救出路 —— 合成终局错误行超集键 `_sema_tool_history_mismatch`、`EmitContext.offersRewind?` 声明面出路句与连续次数句、根入口两只纯函数 `classifyToolHistoryMismatch` / `resolveToolHistoryRewindTarget`(CC-268);崩溃收敛 needsHuman 行的闭集因由位 `needsHumanReason`(CC-269);停车 fail-soft 同步终帧与结果帧的真因超集键 `_sema_park_failed_reason`(CC-273);workflow 活动台账 / 监视器源的 `authToken` 收取值函数、连线身份按凭证来源认(CC-274);`armDetachCancel` 入参 `authToken` 收取值函数、取件口每调现读(CC-275);chrome 臂 `suspended_reopened`(`ChromeEvent` +1 臂,穷尽分支的端编译期红;CC-276);根公面 1354 → 1356;测试钩 62 不变;公面类型名 922 不变;超集键 +2;peer sdk 地板 `>=12.0.1` 不动;§113)。上一版 0.86.0 = **minor**:引擎 7.34.0 提货两代读法 —— 事实表第二批构建期生成、`GATE_DENIED_BY_WORDS` 两代并集十一词(元素型 `GateDeniedByWord`,`mode` 专句)、门记录权限模式两臂与读口 `gateModeRelease`、通告码册六码与六只事实读器(`EngineNoticeFactsCode` +6)、`STRUCTURED_DETAIL_TYPES` +`read_unestablished`、本人规则店读不出两代读法、`shell_gate_tighten` 改句(CC-249 / CC-245 / CC-230);服务端 7.105.0 提货 —— 会话规则写口拒名码 `rules.legacy_tool_name` 的具名结局与 `isRulesRefusalCode`(CC-251)、门前只读路 401 的 `unauthorized` 态与 `READ_CREDENTIAL_NOT_ACCEPTED_NOTICE`(CC-252);请求键 `approverPosture` 退役、构造期按名拒,两个运行期名字退出根入口(逐名见 §2z)(CC-253);`AskUnresolvableFactsView.remedy?`(CC-254);开发依赖引擎 `~7.36.0`(CC-255 换钉 7.35.0,`CONFIG_REFUSAL_CODES` 8 → 17;CC-261 再换钉 7.36.0),通告码册 73 → 80;`adapt()` 错误信封不再回落读旧名 `result`(CC-221);服务端 7.106.0 提货 —— caps `store` / `centerWiring` 窄读口、SQL 姿态两代读、计费入口 503 `fleet.lease_unavailable` 读口与一句话(CC-250),`executionLane.isolated` 与「本机无 OS 沙箱」判定(CC-256),请求键 `inheritEnv` 与版本闸片段口、两只拒按码出句(CC-257),权限规则表超帽坏项读口与一句(CC-262),工具声明拒按码认领(CC-263),请求体键形拒两张键表读口(CC-265);`-p` 首帧工具来源超集键 `_sema_tools_source` / `_sema_tools_fallback_reason` 与铸口 `printInitToolFaceSupersetKeys`(CC-266),三张估计工具表改为常驻(CC-267);根公面 1310 → 1354;测试钩 60 → 62;公面类型 891 → 922;超集键 +2;peer sdk 地板 `>=12.0.1` 不动(sdk 12.0.1 / 13.1.0 / 14.0.0 / 15.0.0 下本版 `.d.ts` 严格编译均零错误);§112)。上一版 0.85.2 = **patch**:自愈重开两只失败结局带 `errorCode`(这一次重开放弃所依据的那一发失败请求的外层 wire 码,present-iff;判定形不带),重开判决不成功臂 +`_sema_errorCode`(宿主可选铸;宿主重开口抛错时本包铸)(CC-260);自愈腿读错误对象与成功应答记录上的各位收进保护(读不出按缺席,不再 reject;`atMostOnceFailureClass` / `readSteerDelivery`(🔧 0.92.0 退出公面)/ `readSteerReceiptStatus`(🔧 0.92.0 退出公面)不再抛);根公面 1310 不变;公面类型名不变(两个已导出型各多可选位);超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§111)。上一版 0.85.1 = **patch**:请求装配回执省略成因的终端用户向句表 `TASK_REQUEST_OMISSION_CAUSE_NOTICES` 与取句口 `taskRequestOmissionCauseNotice`(与接入方那只 `taskRequestOmissionCauseDetail` 同源于同一成因闭集、逐词不同句;表外 / 读不出 ⇒ 一句通用句,不抛、不回显),接入方那张句表的字面量补挂 `satisfies`(CC-248);plan-review 重开口在「这个会话没有接能显示卡的界面」那一形上答 `{ reopened: false, _sema_noPresentationSurface: true }`,自愈结局两臂带 `noPresentationSurface`、自愈行五句补一句成因,重开前提(宿主为该会话键订阅问题帧端口)成文(CC-258);自愈腿读宿主重开判决收进保护(某一位读不出按缺席,不再 reject),宿主日志 / 探针口抛错不再改变判决;多会话宿主的按会话呈现回执登记口 `registerArmedGateFromQuestionIdFor` 回到根入口(0.72.0 退出公面的名字复活;CC-259);根公面 1307 → 1310;公面类型名不变(两个已导出型各多可选位);超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§110)。上一版 0.85.0 = **minor**:引擎事实表(通告码册 / 受众表 / MCP 注入丢弃原因 / 会话规则翻译判定内部两表)改为构建期生成,`ASK_ORIGIN_WORDS` / `APPROVAL_MANDATE_WORDS` 就是 SDK 导出的数组(不再冻结),四个思考档 / 权限模式型改为 SDK 型的别名,包内单源(CC-230);子代族八入口与两只行停止门收注入 client,写动词失败结局 +`unconfirmed`,`classifySubagentResumeFailure` 同判(CC-236);`sessionPolicyDeliverable` 收可选名册,`SessionPolicyWithheldWhy` 六词 → 七词(CC-228);过渡物退役登记与到期门,`adapt()` 不再认旧名 `attachedFiles`,三个运行期名字退出根入口(逐名见 §2z),`surfaceRememberNotApplied` 撤回退役预告(CC-221);plan-review 决断台账六口,`reopenPlanReviewCard` 按台账拒开(CC-241);会话后台任务停止口 `stopEngineSessionBackground` 与受据归类口 `engineSessionBackgroundReceiptReadingOf`(CC-246);服务端 7.104.0 会话侧:会话存档读不出三载体读口与人话 `corruptSessionContent`、`session.records_skipped` 进册(`SERVER_NOTICE_AUDIENCE` 🔧 0.89.0 退出公面前的三行)、删会话 409 读口、`/decide` 停驻挪动族读口(CC-217 / CC-243);服务端 7.104.0 能力 / 同步体侧:同步 park 新体与 park 行 `result`、`fileHistoryCaptureMode` 认 `on-optional` 与请求词片段口 `fileHistoryDeclarationField`、公钥发现读口 `projectSealedKeyCapability`、折叠粗码 `isStatusDerivedCoarseCode`(CC-243);同名影子对账门按语义判(CC-222);导出存活门读已提交历史(CC-240);根公面 1275 → 1307;测试钩 59 → 60;公面类型 +34;peer sdk 地板 `>=12.0.1` 不动;§109)。上一版 0.84.1 = **patch**:`<system-reminder>` 开标签定位口 `findSystemReminderOpenTag`(CC-210);detach durable-off 400 纯判定 `isDetachDurableOff400`,`detachDurableOffHint` 对读属性会抛的错误对象改回 `null`(CC-219);服务端自铸通告码进码册与受众表 `SERVER_NOTICE_AUDIENCE`(🔧 0.89.0 退出公面;`instructions.source_changed` 回到用户面)+ 事实读器 `readInstructionsSourceChanged`(CC-213);按码派发的通告事实口 `readEngineNoticeFacts` + 派发表 `ENGINE_NOTICE_FACT_READERS`,`readReadRootGrantNotice` 入参型放宽(CC-214);停泊审批决断 422 `parked_resume.startup_failed` 的读口 / 一句话 / 判定与码优先 `isCodeClassifiedGateFailure`(CC-225);拒启会话的窄撤销动词 `removeRefusedSessionRules` 与出路句 `legacyToolNameFailureNoteOf`,`CONFIG_REFUSAL_CODES` 七员 → 八员(CC-229);plan-review 编排三口与两只能力探针收注入 client(CC-209);CC 形 `permission_denials` 收入参只被传输层脱敏过的拒绝 + 超集位 `_sema_tool_input_redacted`(CC-235);凭据读法两处放行收口(CC-234);根公面 1260 → 1275;公面类型 +18;peer sdk 地板 `>=12.0.1` 不动;§108)。上一版 0.84.0 = **minor**:peer sdk 地板 `>=11.3.0` → `>=12.0.1`;后台代理登记读数 —— 读口 / 取代判定 / 归类口 / 登记键桥 / 补行谓词,缺席行下半场(CC-194);读目录授权结论通告读口 `readReadRootGrantNotice`(CC-185);接线回执 `hands` 段 `_sema_hands` + 读口 `handsSeamReadingOf` / `handsSeamDetail`,`handsMountedDetail` 坏入参不再抛(CC-206);陈旧逻辑清扫(CC-223):退役键 `rewind.rewindFiles` 构造期拒收、`WorkflowRunState.agentCount` 改可选、26 个内部件退出根入口、九张公面判定表换只读 Set 子类、十五张判定数组冻结、`resume_at` 文本兼容腿退役;根公面 1278 → 1260;公面类型 +10;§107)。上一版 0.83.6 = **patch**:会话规则记录的无损判定 `sessionPolicyDeliverable` 把引擎会在准备阶段拒启的两类名字(引擎退役名、含 `__` 而不以协议前缀开头的名字)改判「不写」,成因词 `legacy_tool_name`(闭集 5 → 6),引擎说「改名为 X」的退役名带 `currentName` 出路位;`peer_wide` 那句改措辞(判决不变)(CC-226);根公面 1278 不变;peer sdk 地板 `>=11.3.0` 不动;§106)。上一版 0.83.5 = **patch**:展示层出口 `displayUntrusted` 的连接符 ZWJ / ZWNJ 按语境判(🔴 默认形输出字节变)、两只可选开关 `escapeBackslashes` / `blanks` 与标记位置读口 `displayUntrustedMarks`(CC-204);凭据两网的判别视图认孤代理项,机读字节 `errors[]` / 合成终局行同批(CC-207);转义记号在凭据再扫里原子与四处凭据读法存量修复(相对 0.83.4 零新增外泄);hooks 启动模式可选词读口 `SettingsPort.hooksStartupMode()`,安全 / bare 模式下设置来源只发 managed(CC-200),设置来源里同一条 hook 只发一份(CC-208);自愈三条重发结局 +1 可选位 `releaseConfirmedByEngine`、行句按释放证据分说(CC-212);活段接入指引订正;公面类型 +3;peer sdk 地板 `>=11.3.0` 不动;根公面 1278;§105)。上一版 0.83.4 = **patch**:只增 —— plan 审批卡「用户亲手关掉的卡,自动触发不在同一道门上放回屏上」的判定归包(`reopenPlanReviewCard` 加触发者位 `trigger`、拒开位 `dismissedByUser`,409 自愈腿按提交出身替宿主传触发者、结局与整行由包出;CC-201);座位审批请求补强制位 / 强制理由词 / 报价缺席因由 / 出身词四个可选位与过境口 `toolPermissionRequestAskBits`(CC-203);`<system-reminder>` 剥离 / 解包两只口上公面并改线性时间(CC-205);两条展示层接入指引订正;开发依赖引擎 `~7.33.1`;公面类型 +2;peer sdk 地板 `>=11.3.0` 不动;根公面 1277;§104)。上一版 0.83.3 = **patch**:入参 / 来源面 —— hooks 投影加 flag 来源(`--settings` 那一层,排在 local 之后;设置来源 hooks 维持托管在前拼接);规则列举口 `listAllPersistedRules` 入参只要 `list`(`RulesListFacade`,其余四口作可选成员);模型身份认目录缺省(本机读数加宿主报位 `engineAcceptsCatalogDefault`,位 `true` 才算目录可解析);公面类型 +1;peer sdk 地板 `>=11.3.0` 不动;根公面 1273;§103)。上一版 0.83.2 = **patch**:只增 —— 审批卡一族三件(常驻姿态下的放行谓词 `askSurvivesPosture`,三态、「不知道」不折成放行;卡上 `mandate` 六词闭集 + 读口 + 每词一句说明,通告码册 +2,开发依赖引擎 `~7.32.0`;停泊卡带出身词 `origin`;CC-193 / CC-195 / CC-196)与后台子代缺席行的判定、计数、sweep 豁免、回收与措辞单源(回收只在后台代理登记确认离场时;CC-194);公面类型 +13;peer sdk 地板 `>=11.3.0` 不动;根公面 1273;§102)。上一版 0.83.1 = **patch**:只增 + 行为订正 —— 展示层安全出口三端单源 `displayUntrusted`(凭据两网 ∘ 字符三网,选项按载体选;CC-112);本包合成的终局行正文与结果帧 `errors[]` 在铸点洗凭据(`errors[]` wire 可见,方向只会更安全)、交互车道合成行带上行类旗,回决备注与子代续跑收据多收双向 / 格式字符(CC-187 / CC-112);会话规则记录的无损判定 `sessionPolicyDeliverable` + 措辞单源 `sessionPolicyWithheldNotice` + 五词成因 `SESSION_POLICY_WITHHELD_WHY`(整批可送才送,首尾带空白的名字比宿主侧更严;CC-117);插件 hook 每轮计划 `hooksWirePlan` + `SettingsPort` 可选读口 `enabledPluginHooks` + `hooksForWire({ plan })`,逐条判「投给引擎 / 本客户端执行 / 如实不跑」、开机「不会执行」清单与 `/hooks` 标注措辞单源(投给引擎那一臂候引擎能力位 `taskSettings.pluginHooks`),设置来源的 `mcp_tool` 与 exec 形 hook 条目不再上请求体、手写的 `plugin` 键剥掉(CC-174);公面类型 +26;peer sdk 地板 `>=11.3.0` 不动;根公面 1254;§101)。上一版 0.83.0 = **minor**:行为面与型面都有 BREAKING —— CC 形消息 24 项按裁定 C-R103 退役名:结果帧 `degraded` / `errorCode` / `model` 与错误信封 `result` → `_sema_model_degraded` / `_sema_error_code` / `_sema_selected_model` / `_sema_salvaged_result`,合成终局行 `isApiErrorMessage` → `_sema_api_error_message`,工具结果记录删过渡名 `toolUseResult`,system 行 `attachedFiles` → `_sema_attached_files`、到达时戳 `timestamp` 与 `isMeta` 删,print 完成通知帧十三键平铺 `_sema_*`,记忆写入改走 chrome 臂 `memory_saved`(新型 `MemorySavedChromeEvent`,`CHROME_ARMS` required);本包只铸新名、端两名并读一版 + 结果帧 CC 键 `terminal_reason` 与读口 `terminalReasonForResult`(CC-175),错误信封知道就铸 `_sema_selected_model` + 转录 id 改 UUID 形(CC-147)+ `SettingsPort` 可选合并读口 `mergedDisableAllHooks`、用户层 `disableAllHooks` 在引擎腿上生效(CC-162)+ 退化审批卡三形拒收改写、`FsApprovalOutcome` 的 `failed` 臂 +可选位 `editRefused`(CC-135)+ 注入件自愈句整族重写 + 联网搜索旧三读口 `webSearchFromEnv` / `webSearchFromSettings` / `resolveWebSearch` 退出公面,`resolveLiveInitToolFace` 可选 `opts.webSearchStamped`(`LiveInitToolFaceOptions`),endpoint userinfo 律跟服务端 7.101.0(CC-184)+ 公面类型 −4(CC-171)+ 通告码册 69 → 71 与结构化卡白名单 +`read-inbox`(CC-186,开发依赖引擎 `~7.31.0`)+ 合成终局行 `uuid` 改 UUID 形;peer sdk 地板 `>=11.3.0` 不动;根公面 1238;§100)。上一版 0.82.7 = **patch**:只增不改 —— 每请求联网搜索配置的三态判决 `judgeWebSearchSettings` / `webSearchVerdictFromEnv` / `resolveWebSearchVerdict`(与 7.100.0 及以后 server 的受理判官同序同判,认不出的 provider 判形错、不再静默丢段;settings 段凭据注入回调 `apiKeyFor`)+ 措辞单源 `webSearchVerdictMessage`(不回显任何用户配的值)+ 调试日志用 `webSearchEndpointForDisplay`;旧三读口 `webSearchFromEnv` / `webSearchFromSettings` / `resolveWebSearch` 行为不变、标过渡期,0.83.0 删(CC-182);peer sdk 地板 `>=11.3.0` 不动;根公面 1240;§99)。上一版 0.82.6 = **patch**:只增不改 —— 停泊行上选「本会话允许」却没被记住时与活卡腿同句告知(回体 `rememberApplied: false`,或 server 以会话级放行专属拒绝码拒了 remember 后回退普通批准;其余失败一律未知不告知),回执 `DecideReceiptView` +1 可选位 `rememberApplied`(CC-181);决断落定后与桥重试臂的诊断留痕不再因宿主日志口抛错回流进决断;接入文档改口:server ≥7.100.0 上 park 行卡的 `requiresRealApproval` / `approvalIsMandated` 生效(CC-180,零代码改动);peer sdk 地板 `>=11.3.0` 不动;根公面 1235;§98)。上一版 0.82.5 = **patch**:只增不改 —— print 车道 init 帧工具面名册优先:流包装器 `withPrintInitFrame`(首选接法,init 恒为首行、其后按到达序)/ 判定闸 `createPrintInitGate` / 分类口 `printInitRosterSignal` / 判定口 `decidePrintInitToolFace` / 留痕措辞 `printInitToolFaceDebugLine` + 等待上界 `PRINT_INIT_ROSTER_WAIT_MS`(150 000);回落估计表补 `ListAgents`(7.30.0 及以后的引擎上与 `SendMessage` 同条件)(CC-169);peer sdk 地板 `>=11.3.0` 不动;根公面 1235;§97)。上一版 0.82.4 = **patch**:只增不改 —— park 行审批卡新增门类位 `irreversibleParkGate`(待决行门类恰为 irreversible_ask,今天即生效,门类事实不是保证);`requiresRealApproval` 在待决行顶层带时透传(就绪,待决列表带出后才生效,今天零行为变化)(CC-180);`ApprovalCardRequest` +1 可选位;peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§96)。上一版 0.82.3 = **patch**:只增不改的公面 —— 自愈提示的「保住对话」出路槽 `keepSessionWayOut` 与交互面引擎决断入口开关 `engineDecidePath`(CC-177;两位都不给时措辞与 0.82.2 逐字节同);自愈结局两臂 +机读位 `pendingRowGone`(重开链证实待决项已不在);peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§95)。上一版 0.82.2 = **patch**:只增不改的公面 + 若干行为订正 —— 新增措辞单源 `cloudEffectiveNotices`:云控制面有效配置回体的降级告警 / 预算 / 能力上限三读数(CC-164,四态,不读成 0 或「没有预算」);本机引擎 models 文档在宿主注入本机条目判定 `entryAccepted` 时补 `default` / `tierGroups` / `activeTierGroup`,剔掉会让本机整份拒收的目录引用与判定口不收的条目,去掉 registry 注记键 `origin` / `overridesTeam`(CC-165;结果新增 `modelRefIssues`);计划复核结局机读位 `_sema_planReviewOutcome`(CC-160 ①);停泊审批决断操作起止回调 `onDecideOperation` 与操作句柄 `openDecideOperation`(CC-160 ③);新增超集键 `_sema_planReviewOutcome`;peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§94)。上一版 0.82.1 = **patch**:只增不改的公面 + 若干行为订正 —— 新增读口 15 个(续跑折叠码读口与措辞 / 文件历史捕获读口六口 / 模型身份可解析判据五口 / 自定义代理载荷作废重投口 / 决断失败码「门还在」判定)+ 宿主车道声明 `EmitContext.lane`;新增超集键 `_sema_response_model`(终帧 / 每轮用量)与 chrome 用量两臂 `responseModel`、重开判决 `_sema_decisionInFlight`、自愈结局两臂 `decisionInFlight`、内部臂 `_sema_denial_unclassified`、通知码 +1;行为订正:计划复核决断在飞不重开卡且自愈提示不再教人再决一次(CC-160 ②)、决断出口补折叠句且停泊腿不再把折叠 / 坏档误判已决(CC-154)、执行车道 `in-process` 措辞(CC-153)、`-p` 车道 Bash 良性退出与交互同判(CC-168)、`-p` 工具结果帧补结构化结果(CC-149)、被拒分类词两车道同判(CC-172)、非交互车道子代工具帧(CC-158,宿主声明车道才生效)、终帧被拒清单对账流内拒绝(CC-159)、自定义代理载荷作废重投(CC-161);peer sdk 地板 `>=11.3.0` 不动;根公面 1228;§93)。上一版 0.82.0 = **minor**:只增不改 —— 新增只读读口 17 个 + 1 常量、工具名册行一格 `mountedBy`、turn 错误判决 `http` 臂一格 `storedRowWhere`:`/rewind` 代码档与对话档能不能用由引擎能力位回答(CC-146)、云控制面额度读数三分(CC-150)、装配期「这一条腿有没有手」(CC-152)、续跑拒收按原码判(CC-154);两处既有面行为订正:自动模式分类器拒的类别词由 `permission-rule` 改为 `automode-*` 三词(CC-155,订正 0.81.1)、续跑上下文读不出时引擎点名的那一行不再丢(CC-156);0.81.0 预告的 23 键 + 1 子型删改**改到 0.83.0**(§92y ㉙);零 wire 键、零投影臂;peer sdk 地板 `>=11.3.0` 不动;§92。上一版 0.81.1 = **patch**:被拒分类词读器加第③路(CC-148):引擎「没问过就拒」的工具调用(deny 规则 / 权限模式 / hook / 分类器 / 写保护 —— 无 `settlement` 只有 `gate.disposition.deniedBy`)在 user 工具结果记录与终帧 `permission_denials[]` 上此前恒缺 `_sema_denial_kind` / `toolDenialKind`,现按层名落 `permission-rule`(其中「分类器」一项已由 0.82.0 CC-155 订正)(`ask_resolution` 无结算 / 结算段不成形 / 层名表外仍缺席不猜);交互与 `--print` 两条车道同一只读器;另钉终帧两臂 `_sema_effective_*` 键集不变量 —— 成功臂展开单铸函数、错误信封显式重发,覆盖性钉在返回对象自己的类型上(漏键 / 多键编译期即红)+ 门格判两臂键集相等且值逐字节同,给单铸函数加键时错误臂不会再静默少键(本版无键增减);零 wire 键、零投影臂、根公面 1195;§91。上一版 0.81.0 = **minor**:CC 形消息一张脸(C-R85 / CC-131):user 工具结果记录加 SDK 面键 `tool_use_result`(与过渡键 `toolUseResult` 同引用,删驼峰原定 0.82.0、已改到 0.83.0)+ DS-19 普查门升硬门(键集按语法解析、按 type/subtype 分表;23 键 + 1 子型过渡表到期窗原为 0.82.0、已改到 0.83.0,零常驻豁免)+ CC-145 `/rewind` both 臂改发 `restoreFiles:true`、`projectRewind(pending)` 单参;零 wire 键、零投影臂、根公面 1195;§90。上一版 0.80.2 = **patch**:`conflict.resume_context_unavailable` 的 `staleAfterSec` / `runId` 在真 SDK 上读不到(CC-137:sdk 11.1.0 起 `APIError` 把体上非具名键收进 `extra`,这一码映射成 `ConflictError` 无具名位,读口只读顶层 ⇒ 真调用链恒缺席)⇒ 体源结构位改「顶层有效值优先、`extra` 兜底」三只类型化读口单铸,有具名子类位的三处(`retryAfterSec` × 2 / `allowlist`)行为不变只多兜底,头源 `retryAfterMs` 只读具名位;零 wire 键、零投影臂、根公面 1195;§89。上一版 0.80.1 = **patch**:去键重发判据句按「铸」计(CC-143;§87「带键的体恰一次」作废 → 被铸恰一次,POST 几次随传输层)+ 接入文档段落自带射程限定词自 §88 起向前执法 + 模型预设表 deepseek 项改闭集真名 deepseek-flash(CC-144,C-R82 ①)+ 门里 git 兜底自陈探针(CC-142);零 wire 键、零投影臂、根公面 1195;§88。上一版 0.80.0 = **minor**:🔴 peer sdk 地板 >=11.2.1 → >=11.3.0 + 策略拒的归因上 wire(CC-133:发送面 deny+policy 带 settledBy / 读侧 policy_refused 十三词入 CC 规则桶 / 三错误码读口 / 直连门去键重发恰一次)+ 删除规则后果句归包(CC-132)+ /mcp 详情卡两腿分说归包(CC-134:六档读口 + 九句铸点,同批改口八处说满的话)+ 🔴 终帧旧拼法 `structuredOutput` 按 0.79.1 的宣告删除(只剩 CC 形 `structured_output`);根公面 1195;§87。上一版 0.79.1 = **patch**:终帧结构化产出同帧铸 CC 形 `structured_output`(旧拼法 `structuredOutput` 过渡一版,0.80.0 删;CC-130)+ 写审批 `argsOmitted` 退化卡在无受护写入部署形上重新解得出路径(CC-129)+ 云控制面十值二型经本包第二个入口 `@sema-agent/client-core/registry` 原样转口(根入口零变;CC-128 ①);根公面 1184;§86。上一版 0.79.0 = **minor**:server 7.93.0 过境批 —— peer sdk 地板 >=11.2.1 + 写口回执第六臂 unverified 与 503 体 committed 分臂(CC-124)+ 无 run 可读的 MCP 状态面(CC-74)+ 审批卡 mandated 位(CC-110)+ 请求装配第三车道 utility 与 approverPosture / maxTokens / outputRetries 三键 + print 车道 model 座(CC-116 / 118 / 123)+ 拒因两面分铸与四个机读位(CC-125)+ 模型轮边界划消息界(CC-126)+ 委派结果人类面读口按来源声明体内定位(CC-127)+ sdk 转口三件(CC-128)+ 通告码 memory.project_scope_absent(CC-122);公面 1184;§85。上一版 0.78.2 = **patch**:门的棘轮登记数字单真源 —— 五只门十一格棘轮 + 218 条沿革账搬进 scripts/registry.json、门只读不抄、负控改篡改登记物、下调通道 RATCHET-SLACK、新门 run-registry-test(CC-79 第一期)+ 两格存量松量收掉 + submit-wiring-manifest 门补 count===1 边界格;src 零改动,dist 逐字节同 0.78.1;公面 1154;§84。上一版 0.78.1 = **patch**:两辆并行车收货 + 三张跟进票 —— displayBody 人类面读口 + 围栏解析头尾配对收紧(CC-113)/ MCP 两处「没报」措辞分句(CC-115)/ 记忆治理面五动词调用口(CC-97 b)/ 非流式提交回执接线回执读口 readSubmitWiringManifest(CC-121)/ 三份失败判官抛出物读取收口(CC-119);公面 1154;§83。上一版 0.78.0 = **minor**:peer sdk 地板 >=9.8.1 → >=11.0.1(CC-106)+ 单步写口 200 体按 stillLive 判别联合改读、第五臂 revoked、三型取自 sdk、RulesFacade.write 必填、PersistedRuleLiveness 转口(CC-103)+ DeniedBy 第十词 read_boundary 专句(CC-106 ④)+ excludeAllTools 车道行;型面 BREAKING 三处、行为面同 0.77.2;公面 1143;§82。上一版 0.77.2 = **patch**:出包面结构卫生 —— 构建期 removeComments,dist js / d.ts 零注释(新门 run-dist-comments-test.mjs + 卫生门词表 32 条 + 文档向前执法;CC-100)+ gateDeniedByDetail 表外词兜底句改「本版不认识这个层名」(CC-111 ①);行为 / 型面逐字节同 0.77.1;公面 1143;§81。上一版 0.77.1 = **patch**:外部验收三件回填 —— 读器族边界残留 projectMcpReconnectCapability 只认自有键(CC-107)/ rewind 四子键恰读一次(CC-108)/ 子代输出合并按回体 output.type · retrieval_status 定处置(CC-109,server ≥7.92.0 cursorSemantics 缺席面);型面 additive 一处;公面 1143;§80。上一版 0.77.0 = **minor**:请求装配逐键去向回执 + print 车道补座 + 表外键响亮拒(CC-101,四条行为 BREAKING)/ 会话策略写端口(CC-105)/ 持久规则单步写面(CC-103)/ workflow 子代面板行代际三向恢复(CC-104,零改码)/ 能力位读器族口径整族改齐 + 外部验收 F-A / F-B 处置 + 合并树异源复审两轮处置;公面 1143;§79。上一版 0.76.2 = **patch**:制品卫生 —— 清 dist 重 build 去掉两只已撤出源码的编译产物 + dist ⇄ src 对账门;零源码 / 零型面 / 零行为改动;公面 1122;§78。上一版 0.76.1 = **patch**:能力位读器工厂(CC-75)/ MCP 活性观察读口(CC-36)/ `capabilities.peerLane` · `permissionRulesWrite` 四态读口(CC-102)/ 记忆治理面两只读口 + 三只条目面回体读口(CC-97 a)/ 主车道证明逐次新建(CC-99)+ 修 0.76.0 的 F1 / F2(身份四键一次性快照只修了投影口一侧);公面 1122;§77。上一版 0.76.0 = **minor**:六票一批 —— `prompt_assembled` 投影臂 / 审批 feed 三态(**型面 BREAKING**)/ `ApprovalResolution` 单源联合 / 记忆 spec 读口 / 终态词表上游钉 / `tasks_expand` 退役(**型面 BREAKING**),外加身份四键一次性快照(跨全部内部臂);公面 1081;§76。上一版 0.75.1 = **patch**:面板短命子代反序缓行放不出的残洞(外部复验 D1)+ 同代 running 帧三向定形(B4)+ #969 提货 `spawnName` 透传与 `agentType` 改读诚实来源(CC-95);§75。上一版 0.75.0 = **minor**:压缩的非 compacted 结局上 chrome 面 `compaction_outcome`(新内部臂 —— 自建 print 出口的端先表态)+ peer sdk 地板 `>=9.8.1`;型面 additive(ChromeEvent +1 臂)、公面 1065、零 wire 新键;§74。上一版 0.74.5 = **patch**:core 7.24.0 提货 `_sema_freed_tokens?` + 首见即终态的行零事件(幽灵完成行)+ `isNewEngineAgentPanelCycle` / `approvalOutcomeNoteOf` 上公面;型面 additive、公面 1065、peer 不动;§73。上一版 0.74.4 = **patch**:面板键「先发布的键为准」(tick 归不了一的三序不再两行)+ 前代 UUID 迟到 tick 丢弃 + `readRunCancelContext` 下钻收紧;型面 additive、公面 1061、peer 不动;§72。上一版 0.74.3 = **patch**:面板子代身份归一(tick / end 的 UUID 归到 fleet 尾段,宿主零改)+ run 记录 `cancelContext` 读口与成因四词 + workflow 行 `errorCode` + reopen 第二臂两件;型面纯 additive、公面 1061、peer 不动;§71。上一版 0.74.2 = **patch**:`capabilities.deviceExecutor.management` 四态读口(缺席 ≠ false;`deviceExecutor: false` = 车道缺席;管理动词可用性三态归包);公面 1052;§70。上一版 0.74.1 = **patch**:审批卡无决断收口 + 结局回交;§69。上一版 0.74.0 = **minor**:peer sdk 地板 >=9.7.1 + covers 过境 + 面板周期身份 + 离场读口;§68。上一版 0.73.5 = **patch**:workflow 规模告警判定上收进包(`evaluateWorkflowSize` 三态:未知的规模不当作规模正常;分母口径与帽优先级单源;env 读口纯函数);型面纯 additive、公面 1044、peer 不动;§67。上一版 0.73.4 = **patch**:终帧 `permission_denials` 第三键 ⇐ 同一条流 `tool_start` 入参按 `toolCallId` join(三道闸;join 不上留 sema 载体;🔴 更正 0.73.2「自动升级收口」一句)+ 审批 feed push 侧取件失败的欠账退避重试;型面纯 additive、公面 1033、peer 不动;§66。上一版 0.73.3 = **patch**:CC-61 sdk 9.7.1 提货 + `capabilities.approvalsStreamLive` 四态读口(缺席 = 判不出;`livePendingNeedsReconcile` 只在引擎明说会推时才让对账节拍降兜底)+ CC-60 五条模型面文案锚包侧半场(cursorSemantics 机读位 / result 行注记 / bash 首行两变体与良性槽 / 通知 seed 并集 / parked 臂);型面纯 additive、公面 1032、peer 不动;§65。上一版 0.73.2 = **patch**:CC-59 悬挂 ask 全卡 —— `livePending[].frame`(server ≥7.87.0)两道闸窄读进视图,在场即走流内帧腿同一条路(入参可见、改写可转发),缺席保持盲卡;CC-34 收口(引擎半场随 7.87.0 到货,判据交黑盒);型面纯 additive、公面 1026、peer 不动;§64。上一版 0.73.1 = **patch**:CC-57 `decidePlanReview` outcome 尾句按「决断有没有生效」四态选(单铸点 `planReviewOutcomeTail`;此前本地拒发仍让模型汇报已拒绝)+ CC-56 cancel 的 409 按机器码分家(`cancelConflictFromError` 三形 / 新安全码 `cancel_run_not_running`)与提交面 429 用量窗读口 + 人话;型面纯 additive、公面 1026、peer 不动;§63。上一版 0.73.0 = **minor,型面 BREAKING**:fleet 视图八个数值键改可选 —— CC-52 `FleetTaskView.elapsedMs` / `tokens` / `queuedCount` 与 `FleetWorkflowView.doneCount` / `totalCount` / `failedCount` / `tokens` / `elapsedMs` 不再 `?? 0`(有键 = 真值含真 0,缺键 = 不知道;逐键缺席语义见 §62b)+ 台账补偿链无基数不铸;公面导出名零增减 1019、零 wire 变化、peer 不动;§62。上一版 0.72.14 = **patch**:悬挂的流内 ask 拉半场 —— CC-55 `startApprovalsFeed` 快照加 `livePending` 段并进变化摘要(键缺席 = 未报,不铸空)+ 视图 / 去重账 / 与流内帧腿同链的决断口(入参不可见上卡明说、改写不转发)+ 宿主闸对账节拍 + 待决计数读口(不知道 = null);型面纯 additive、公面 1019、peer 不动;§61。上一版 0.72.13 = **patch**:server 7.86.0 提货 —— CC-46 plan_review `permissionModeAfter` 发口(三选卡双闸:宿主声明只读起步 ∧ 引擎 ≥7.86.0;400 field_conflict 两种处置)+ CC-54 `capabilities.executionLane` 四态读面(键缺席 ≠ 不是本机车道;`toolsRunHere` 判据归包)+ CC-53 detach 版本闸三态;型面 additive(另撤回 0.72.12 的主通道 `absent` 臂,改独立缺席订阅口)、公面 1011、peer 不动;§60;**预告 0.73.0 BREAKING**:fleet 视图数值键改可选。上一版 0.72.12 = **patch**:「缺席被折成正向终态」按类清剿 —— CC-50 M1 头条(fleet 行缺席改发 `absent` 不再铸 `end{isError:false}`)+ 六站一次改齐(缺席 ⇒ `unknown`)+ 结果边界 fail-closed 取舍 + `_sema_outcome` + `Outcome unknown:` 行 + CC-51 M6(default 臂不再谎报 running)+ 普查门 + DS-06;型面 additive、公面 993、peer 不动;行为面三处真变化见 CHANGELOG 取舍段;§59。上一版 0.72.11 = **patch**:core 7.23.0 提货 —— CC-49 通告码 66 → 67 `config.write_protection_unresolved`(operator;兄弟码 `target_view_absent` = 没有视图,这枚 = 有视图解析不出)+ `permission_denials` 自动升级腿通电(`gates[].toolCallId` ⇒ `tool_use_id`;CC-34 引擎半场);型面零变化、公面 989、peer 不动、devDep core ~7.23.0;§58。上一版 0.72.10 = **patch**:CC-41 leader run 终局 `needs_human` + `result.conflict` 三形读面(none 缺席不可分 / unreadable 在场读不懂 / conflict;`salvaged[]` 原样给落盘口;措辞单源不提重试);型面纯 additive、公面 989、peer 不动;§57。上一版 0.72.9 = **patch**:server 7.85.0 提货 —— CC-30 会话内 MCP re-dial 消费口(`reconnectMcpServer` 三态 / unsupported 恒五键 / 交易文案单源)+ CC-39② memory-status `autoConsolidationArmed` 三态 + CC-45 resume 补充句渲保留秒数;型面纯 additive、公面 985、peer 不动;§56。上一版 0.72.8 = **patch**:清账三票 —— `memory:"off"` 请求键(CC-39③,server 7.84.0 S-405)+ `runStream` 第二条中性臂 `Model output error:`(CC-43)+ 注入件撞活 run 自动 steer 零卡(CC-44);型面纯 additive、公面 977、peer 不动;§55。上一版 0.72.7 = **patch**:core 7.22.0 提货 —— 通告码 66 `mcp.server_redialed` + 读器 `readMcpServerRedialed` + `wiring_manifest.readDeny` 第九段 `_sema_readDeny`(缺席 = 没有内置行判这条腿);型面纯 additive、公面 971、peer 不动、devDep core ~7.22.0;§54。上一版 0.72.6 = **patch**:cli L-379 包侧半场 —— `steerFollowIntent` steer 后续听意图三态(tail / after-decision / after-wake)+ `activeRunSelfHealRow` 续听声明第五参;型面纯 additive、公面 969、peer 不动;§53。上一版 0.72.5 = **patch**:server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面(键缺席 = 老引擎判不了 ≠ `none`);型面纯 additive、公面 968、peer 不动;§52。上一版 0.72.4 = **patch**:core 7.21.x 三件经 server 7.82.0 提货 —— `wiring_manifest.autoConsolidation` 第八段 `_sema_autoConsolidation`(缺席 = indeterminate 不折 false);型面纯 additive、公面 962、peer 不动;§51。上一版 0.72.3 = **patch**:core #863 记忆单系统半场 ① —— `projectAgentsForWire` 投影 `agents[].memory`(user|project|local 三词同映射引擎平面 agent:<type>);型面纯 additive、公面 962、零 wire 新键、peer 不动;§50。上一版 0.72.2 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **0.93.1**(本批发布版 = **patch**:耐久停驻审批的决断口单一持有者 —— `surfaceFsApprovalAndDecide` 对同一把审批身份键(行会话 + run + `toolCallId ?? boundCallId`)同时只许一次决断在路上,后到者拿同一结局的拷贝 + `joinedInFlight: true`、自己不呈卡不发决断,任一路中止 = 这一只决断被中断(CC-491)· 活卡 respond 回 `202 parking_in_progress` 读成「停驻中、这一发没生效」:结局 `{ decision: 'unresolved', parking }`、判别口既有 `unsettled` 臂新 cause `parking_in_progress`、包替用户上屏一句、不重发不去键不换名(CC-492);零型面 BREAKING;`FsApprovalOutcome` 四臂 +1 可选位、`ToolApprovalFrameOutcome` +1 可选位、`ApprovalUnsettledCause` +1 词;根公面运行期导出 1485 不变、公面类型名 +1;peer sdk 地板 `>=12.0.1` 不动;服务端夹具现役 7.119.0 不动;§120)。上一版 0.93.0 = **minor**:到期登记物硬删八组(型面 BREAKING;根入口 −21 名;CC-431)· device 车道读器扩到车道三位与 `management` 三态字面、新判据 `deviceLaneOpen`(型面 BREAKING;CC-454)· 审批决定口出处键换名:能力位 `approvalDecidedBy` 读器 / 唯一决定函数 `decisionAttributionKeyOf` / 退役键拒绝臂 `retired_key` / 换名恰重发一次(CC-403 并 CC-451 ②)· 能力位 `permissionModes` 读器与 `dontAsk` 按位发词(CC-451 ③)· 终局 `blocked` 的机读成因 `detail` 与会话规则记录读不到句的第十六句(CC-364)· 连接失败现场判读口 `transportFailureScene`(CC-363)· 交出后台的引擎 Bash 登记 `detectEngineBgShellDetach`(CC-331)· 子代 tick 模型位与 `/health` 配置落地读器 `readEngineConfigApplyState` / 漂移判决 `configDriftVerdict`(CC-323)· 引擎装机 core 版本三态口 `coreVersionTier`(CC-355)· 停泊赎回启动失败成因词位 `startupCause`(CC-244)· workflow 子代审批决定口两只 409(CC-430)· MCP 重拨 `unsettled` 判决臂(CC-429)· 联网搜索密钥头值判臂与来源 `host`(CC-428)· 多成因措辞存量两批(CC-120 / 423 / 422)· 活卡帧键镜像 +3(CC-433)· 会话规则可送判定对空对端段名收紧(CC-437)· 场景指派悬空 503 读口(CC-451 ⑤)· 重试覆盖层 429 不再渲成额度耗尽(CC-473)· 展示出口先洗后折(CC-472)· 弃用预告一名三位(CC-309 / 431)· 开发依赖引擎 `~7.44.0` 与生成表(CC-427)· 其余 CC-242 / 301 / 295 / 365 / 374;型面 BREAKING 两处 + 四处联合各 +1 员 + 一名三位弃用预告;根公面 1483 → 1485(+23 −21);测试钩 69 → 71;peer sdk 地板 `>=12.0.1` 不动;服务端夹具现役 7.119.0(老一代 7.106.0 – 7.118.0 十一份)、sdk 17.1.0 作下一代见证位;§119)。上一版 0.92.0 = **minor**:自动答复判定收成一只 `automaticAnswerVerdict`(CC-368)· 卡面披露键两代读 `allowRuleShadow`(CC-401)· steer 档位经包 `steerBodyOf` / `fleet.steerPriority` / `readSteerReceipt`(CC-374 并 CC-353)· 能力位读器读数随代际自动失效(CC-377)· 服务端 7.116.0 / sdk 16.2.0 提货 + `CoreValuePorts` +1 必填(CC-371 / 370)· 会话规则可送判定过规则编译器与协议名段判定(CC-381)· 支持底线抬到 server 7.106.0 / core 7.35.2(CC-352 / 380)· 其余 CC-367 / 369 / 373 / 376 / 379 / 366 / 178 / 295 / 407;型面 BREAKING 四处 + 七名弃用预告;根公面 1429 → 1483(+56 −2);测试钩 68 → 69;服务端夹具现役 7.116.0(老一代 7.106.0 – 7.115.0 八份)、7.117.0 与 sdk 16.3.0 作下一代见证位;§118)。上一版 0.91.0 = **minor**:steer 拒收处置句单源 `steerRefusalAdviceOf` / `ControlSafetyError.advice` · `.status` / `steeringRefusedBeforeEngine`(CC-307)· `abortableSleep` / `isAlreadyResolvedFailure` 上根入口(CC-317)· 引擎闭集表 `ASK_EVIDENCE_ABSENCE_VALUES` / `SYSTEM_INJECTION_PRIORITIES` / `READ_DENY_BUILTIN_TIERS` · `READ_DENY_DEFAULT_TIERS` + `parseReadDenyBuiltinTiers` / `MODE_ARBITRATION` + `askSurvivesStandingAnswer`(CC-318 / 327 / 322 ①)· 会话历史 tool_use 错配一族:`_sema_provider_rejection_resend` 归合成终局行、错配键 `rewindOffered`、`readToolHistoryMismatchKey` / `ToolHistoryMismatchRowKey`、`toolHistoryBadTurnSentence`(CC-303 / 304 / 305 / 309 ②)· 投递账本记录 `by` / `share` 与 `deliveryShareOf` / `droppedKeyCount`、`attempted` 的 `{ generation }` + `undeliveredInGeneration`(`PromptDeliveryLedger` 接口 +3 必有成员 —— 型面 BREAKING 第一处;CC-293 / 334)· 崩溃遗留通告 `crashConvergedNotice` / `crashConvergedNeedsHumanSentence` / `NEEDS_HUMAN_REASON_ORDER`(CC-310)· `permissionsDeclarationReport` + `PERMISSIONS_KEPT_REASONS` 与 `PermissionsDeclarationInput.settingsRead` 必填(型面 BREAKING 第二处;CC-314)· `engineCapsSettled(url, { withinMs })` 返回型窄变 `Promise<'settled' | 'timed_out'>` + `disableSkillsDeclarationSettled`(CC-311)· `hookMatcherVerdict`(CC-306)· `sessionPolicyReadNotice`(CC-328)· `inheritEnvRefusalContent` 首段改口(CC-336)· `attachmentsSubmitVerdict`(CC-337)· 展示出口 YAML 块标量整块一枚记号(CC-340)· `mintUserAttachmentEnvelope` / `encodeHumanTurn` / `deliveredUuidsOf` / `imageVisionOf` + 附件席位能力位读器占位形(CC-315 / 297 子集)· 服务端 7.115.0 / sdk 16.1.0 提货:「只续已有会话」按码优先、`checkpointUnsupportedVersionFromError` / `checkpointUnsupportedVersionContent`、`hookMatcherRefusalFromError`、活卡帧与耐久行 `probeReason`、接线回执 `fleet` 段 + `WiringManifestFleetView`(CC-339)· 登记物整治:`permissionRuleIssueDetail` 第三参分句(CC-359)、`rewindSpecForMode` 第三参按纪元位取舍(CC-345 ①)、HITL 桥两处型面 additive 与补偿表 `retireOn` 改台账行号(CC-343)、已知限制档清账(CC-349)· 开发依赖 settings-schema `^8.0.0`(CC-308,不出包)· 根公面 1397 → 1429(+32,零删名);测试钩 63 → 64;公面类型名 964 → 997;超集键 +2(`_sema_provider_rejection_resend` / `_sema_fleet`);peer sdk 地板 `>=12.0.1` 不动;服务端夹具现役 7.115.0(老一代八份)、sdk 16.1.0 进地板见证矩阵;§117)。上一版 0.90.0 = **minor**:引擎 7.40.1 / 服务端 7.113.0 · 7.114.0 / sdk 16 探针提货(通告码册 86 → 85、`readLegacyModeSeedMigrated` 退出公面、`attachments.planModeReminder` 退役、`PromptDeliveryLedger` +2 必有成员 —— 型面 BREAKING 三处;CC-291 / 300)· 云控制面子路径五名(CC-136)· 文件历史一句五态判定与声明事实账本(CC-294)· hooks matcher 工具别名读口(CC-298)· 机读支持底线与 `engineVersionTier`(CC-299)· `settings.permissions` 三桶装配口与 allow 能力位(CC-302)· 「改了重发」错配让位与错误载体铸口(CC-309 ①)· `AttachmentsSpecRefused`(CC-316)· 能力位读数冻结;根公面 1379 → 1397、peer sdk 地板 `>=12.0.1` 不动;§116。上一版 0.89.0 = **minor**:引擎 7.38 提货(开发依赖换钉引擎 `~7.38.2`;通告码册 81 → 86、引擎铸方表接手服务端自铸码的受众,`SERVER_NOTICE_AUDIENCE` 🔧 退出公面(型面 BREAKING,逐名见 §2z);工具轮不完整读器 `readToolTurnIncomplete`、用户输入没被用上读器 `readUserInputUndrained` 与一句 `userInputUndrainedNotice`(`EngineNoticeFactsCode` +3 员,穷尽分支的端编译期红);终局服务商拒绝详情 `readRunTerminal` 的 `failed.detail` 与「改了重发」判定口 `providerRejectionResend`;steer 账本 503 `ledger_unavailable` 一张码表三条腿(`ControlSafetyCode` +1 员、子代 steer 结局联合 +1 臂,穷尽分支的端编译期红);省略成因短语口 `taskRequestOmissionCausePhrase`;CC-282);审批四面问类两位 `askClass` / `classes`(三型各 +2 可选位;CC-284);请求键 `disableSkills` 与片段口 `disableSkillsDeclaration`(车道表 45 → 46 行;CC-277);hooks 设置来源条目的唯一执行者与本端跳过口 `settingsHooksKeptLocally`(`PLUGIN_HOOK_REASONS` +5 词、`PLUGIN_HOOK_EXCLUSION_REASONS` +1 词,穷尽分支的端编译期红;CC-287);凭据被拒判官 `isReadCredentialRefusal` 上根入口(CC-289);服务端 7.111.0 两项(接线回执新段 `instructions`、子代转向成功结局 `messageId`;CC-282 余项)与展示出口无标签 `Token <值>` 形照遮(CC-290);根公面 1372 → 1379;测试钩 62 不变;公面类型名 942 → 952;超集键 +1(98 → 99,`_sema_instructions`);peer sdk 地板 `>=12.0.1` 不动;§115)。上一版 0.88.0 = **minor**:展示出口凭据面一次扫描(带凭据的输入上输出字节变、干净文本逐字节同、一轮即不动;CC-247);崩溃收敛 `cause` 认第二个词 `shutdown_before_park`(`CrashConvergedRow.cause` 型联合 +1 词,穷尽分支的端编译期红;CC-218);服务端自铸通告 `server.model_unreachable` 入受众表与事实读器 `readModelUnreachable`(CC-270 ①);开发依赖换钉引擎 `~7.37.1`、放行原因闭集镜像 `GATE_MODE_RELEASE_REASON_WORDS` / `isGateModeReleaseReasonWord`、修复通告事实读器 `readToolTurnRepaired`、通告码册 80 → 81(`EngineNoticeFactsCode` +2 员;CC-272);会话所有者自助记忆抹除 `eraseSessionMemory` / `sessionMemoryEraseOutcome` + 三只闭集镜像(CC-264);registry 同一个 409 的两义判别 `classifyRegistryConflict` / `isScopeGoneError`(CC-280);请求键 `requireExistingSession`(车道表 44 → 45 行)与被拒读口 `requireExistingSessionRefusalFromError` / 一句 `requireExistingSessionRefusalContent`(CC-281);投递事实账本 `createPromptDeliveryLedger` + 两只按消息行的读口 `promptKnownUndelivered` / `withoutUndeliveredPrompts`(判据 = 引擎为这次提交建了 run;CC-271);plan 决断台账:离门证据结掉、还没被认领的登记由投递口认领原笔(CC-278);`wiring_manifest` 帧 `fileHistory` 段(`WiringManifestChromeEvent.fileHistory?` / `WiringManifestView.fileHistory?`,超集键 `_sema_fileHistory`;CC-279);根公面 1356 → 1372;测试钩 62 不变;公面类型名 922 → 942;超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§114)。上一版 0.87.0 = **minor**:会话历史 tool_use 错配的自救出路 —— 合成终局错误行超集键 `_sema_tool_history_mismatch`、`EmitContext.offersRewind?` 声明面出路句与连续次数句、根入口两只纯函数 `classifyToolHistoryMismatch` / `resolveToolHistoryRewindTarget`(CC-268);崩溃收敛 needsHuman 行的闭集因由位 `needsHumanReason`(CC-269);停车 fail-soft 同步终帧与结果帧的真因超集键 `_sema_park_failed_reason`(CC-273);workflow 活动台账 / 监视器源的 `authToken` 收取值函数、连线身份按凭证来源认(CC-274);`armDetachCancel` 入参 `authToken` 收取值函数、取件口每调现读(CC-275);chrome 臂 `suspended_reopened`(`ChromeEvent` +1 臂,穷尽分支的端编译期红;CC-276);根公面 1354 → 1356;测试钩 62 不变;公面类型名 922 不变;超集键 +2;peer sdk 地板 `>=12.0.1` 不动;§113)。上一版 0.86.0 = **minor**:引擎 7.34.0 提货两代读法 —— 事实表第二批构建期生成、`GATE_DENIED_BY_WORDS` 两代并集十一词(元素型 `GateDeniedByWord`,`mode` 专句)、门记录权限模式两臂与读口 `gateModeRelease`、通告码册六码与六只事实读器(`EngineNoticeFactsCode` +6)、`STRUCTURED_DETAIL_TYPES` +`read_unestablished`、本人规则店读不出两代读法、`shell_gate_tighten` 改句(CC-249 / CC-245 / CC-230);服务端 7.105.0 提货 —— 会话规则写口拒名码 `rules.legacy_tool_name` 的具名结局与 `isRulesRefusalCode`(CC-251)、门前只读路 401 的 `unauthorized` 态与 `READ_CREDENTIAL_NOT_ACCEPTED_NOTICE`(CC-252);请求键 `approverPosture` 退役、构造期按名拒,两个运行期名字退出根入口(逐名见 §2z)(CC-253);`AskUnresolvableFactsView.remedy?`(CC-254);开发依赖引擎 `~7.36.0`(CC-255 换钉 7.35.0,`CONFIG_REFUSAL_CODES` 8 → 17;CC-261 再换钉 7.36.0),通告码册 73 → 80;`adapt()` 错误信封不再回落读旧名 `result`(CC-221);服务端 7.106.0 提货 —— caps `store` / `centerWiring` 窄读口、SQL 姿态两代读、计费入口 503 `fleet.lease_unavailable` 读口与一句话(CC-250),`executionLane.isolated` 与「本机无 OS 沙箱」判定(CC-256),请求键 `inheritEnv` 与版本闸片段口、两只拒按码出句(CC-257),权限规则表超帽坏项读口与一句(CC-262),工具声明拒按码认领(CC-263),请求体键形拒两张键表读口(CC-265);`-p` 首帧工具来源超集键 `_sema_tools_source` / `_sema_tools_fallback_reason` 与铸口 `printInitToolFaceSupersetKeys`(CC-266),三张估计工具表改为常驻(CC-267);根公面 1310 → 1354;测试钩 60 → 62;公面类型 891 → 922;超集键 +2;peer sdk 地板 `>=12.0.1` 不动(sdk 12.0.1 / 13.1.0 / 14.0.0 / 15.0.0 下本版 `.d.ts` 严格编译均零错误);§112)。上一版 0.85.2 = **patch**:自愈重开两只失败结局带 `errorCode`(这一次重开放弃所依据的那一发失败请求的外层 wire 码,present-iff;判定形不带),重开判决不成功臂 +`_sema_errorCode`(宿主可选铸;宿主重开口抛错时本包铸)(CC-260);自愈腿读错误对象与成功应答记录上的各位收进保护(读不出按缺席,不再 reject;`atMostOnceFailureClass` / `readSteerDelivery`(🔧 0.92.0 退出公面)/ `readSteerReceiptStatus`(🔧 0.92.0 退出公面)不再抛);根公面 1310 不变;公面类型名不变(两个已导出型各多可选位);超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§111)。上一版 0.85.1 = **patch**:请求装配回执省略成因的终端用户向句表 `TASK_REQUEST_OMISSION_CAUSE_NOTICES` 与取句口 `taskRequestOmissionCauseNotice`(与接入方那只 `taskRequestOmissionCauseDetail` 同源于同一成因闭集、逐词不同句;表外 / 读不出 ⇒ 一句通用句,不抛、不回显),接入方那张句表的字面量补挂 `satisfies`(CC-248);plan-review 重开口在「这个会话没有接能显示卡的界面」那一形上答 `{ reopened: false, _sema_noPresentationSurface: true }`,自愈结局两臂带 `noPresentationSurface`、自愈行五句补一句成因,重开前提(宿主为该会话键订阅问题帧端口)成文(CC-258);自愈腿读宿主重开判决收进保护(某一位读不出按缺席,不再 reject),宿主日志 / 探针口抛错不再改变判决;多会话宿主的按会话呈现回执登记口 `registerArmedGateFromQuestionIdFor` 回到根入口(0.72.0 退出公面的名字复活;CC-259);根公面 1307 → 1310;公面类型名不变(两个已导出型各多可选位);超集键 +1;peer sdk 地板 `>=12.0.1` 不动;§110)。上一版 0.85.0 = **minor**:引擎事实表(通告码册 / 受众表 / MCP 注入丢弃原因 / 会话规则翻译判定内部两表)改为构建期生成,`ASK_ORIGIN_WORDS` / `APPROVAL_MANDATE_WORDS` 就是 SDK 导出的数组(不再冻结),四个思考档 / 权限模式型改为 SDK 型的别名,包内单源(CC-230);子代族八入口与两只行停止门收注入 client,写动词失败结局 +`unconfirmed`,`classifySubagentResumeFailure` 同判(CC-236);`sessionPolicyDeliverable` 收可选名册,`SessionPolicyWithheldWhy` 六词 → 七词(CC-228);过渡物退役登记与到期门,`adapt()` 不再认旧名 `attachedFiles`,三个运行期名字退出根入口(逐名见 §2z),`surfaceRememberNotApplied` 撤回退役预告(CC-221);plan-review 决断台账六口,`reopenPlanReviewCard` 按台账拒开(CC-241);会话后台任务停止口 `stopEngineSessionBackground` 与受据归类口 `engineSessionBackgroundReceiptReadingOf`(CC-246);服务端 7.104.0 会话侧:会话存档读不出三载体读口与人话 `corruptSessionContent`、`session.records_skipped` 进册(`SERVER_NOTICE_AUDIENCE` 🔧 0.89.0 退出公面前的三行)、删会话 409 读口、`/decide` 停驻挪动族读口(CC-217 / CC-243);服务端 7.104.0 能力 / 同步体侧:同步 park 新体与 park 行 `result`、`fileHistoryCaptureMode` 认 `on-optional` 与请求词片段口 `fileHistoryDeclarationField`、公钥发现读口 `projectSealedKeyCapability`、折叠粗码 `isStatusDerivedCoarseCode`(CC-243);同名影子对账门按语义判(CC-222);导出存活门读已提交历史(CC-240);根公面 1275 → 1307;测试钩 59 → 60;公面类型 +34;peer sdk 地板 `>=12.0.1` 不动;§109)。上一版 0.84.1 = **patch**:`<system-reminder>` 开标签定位口 `findSystemReminderOpenTag`(CC-210);detach durable-off 400 纯判定 `isDetachDurableOff400`,`detachDurableOffHint` 对读属性会抛的错误对象改回 `null`(CC-219);服务端自铸通告码进码册与受众表 `SERVER_NOTICE_AUDIENCE`(🔧 0.89.0 退出公面;`instructions.source_changed` 回到用户面)+ 事实读器 `readInstructionsSourceChanged`(CC-213);按码派发的通告事实口 `readEngineNoticeFacts` + 派发表 `ENGINE_NOTICE_FACT_READERS`,`readReadRootGrantNotice` 入参型放宽(CC-214);停泊审批决断 422 `parked_resume.startup_failed` 的读口 / 一句话 / 判定与码优先 `isCodeClassifiedGateFailure`(CC-225);拒启会话的窄撤销动词 `removeRefusedSessionRules` 与出路句 `legacyToolNameFailureNoteOf`,`CONFIG_REFUSAL_CODES` 七员 → 八员(CC-229);plan-review 编排三口与两只能力探针收注入 client(CC-209);CC 形 `permission_denials` 收入参只被传输层脱敏过的拒绝 + 超集位 `_sema_tool_input_redacted`(CC-235);凭据读法两处放行收口(CC-234);根公面 1260 → 1275;公面类型 +18;peer sdk 地板 `>=12.0.1` 不动;§108)。上一版 0.84.0 = **minor**:peer sdk 地板 `>=11.3.0` → `>=12.0.1`;后台代理登记读数 —— 读口 / 取代判定 / 归类口 / 登记键桥 / 补行谓词,缺席行下半场(CC-194);读目录授权结论通告读口 `readReadRootGrantNotice`(CC-185);接线回执 `hands` 段 `_sema_hands` + 读口 `handsSeamReadingOf` / `handsSeamDetail`,`handsMountedDetail` 坏入参不再抛(CC-206);陈旧逻辑清扫(CC-223):退役键 `rewind.rewindFiles` 构造期拒收、`WorkflowRunState.agentCount` 改可选、26 个内部件退出根入口、九张公面判定表换只读 Set 子类、十五张判定数组冻结、`resume_at` 文本兼容腿退役;根公面 1278 → 1260;公面类型 +10;§107)。上一版 0.83.6 = **patch**:会话规则记录的无损判定 `sessionPolicyDeliverable` 把引擎会在准备阶段拒启的两类名字(引擎退役名、含 `__` 而不以协议前缀开头的名字)改判「不写」,成因词 `legacy_tool_name`(闭集 5 → 6),引擎说「改名为 X」的退役名带 `currentName` 出路位;`peer_wide` 那句改措辞(判决不变)(CC-226);根公面 1278 不变;peer sdk 地板 `>=11.3.0` 不动;§106)。上一版 0.83.5 = **patch**:展示层出口 `displayUntrusted` 的连接符 ZWJ / ZWNJ 按语境判(🔴 默认形输出字节变)、两只可选开关 `escapeBackslashes` / `blanks` 与标记位置读口 `displayUntrustedMarks`(CC-204);凭据两网的判别视图认孤代理项,机读字节 `errors[]` / 合成终局行同批(CC-207);转义记号在凭据再扫里原子与四处凭据读法存量修复(相对 0.83.4 零新增外泄);hooks 启动模式可选词读口 `SettingsPort.hooksStartupMode()`,安全 / bare 模式下设置来源只发 managed(CC-200),设置来源里同一条 hook 只发一份(CC-208);自愈三条重发结局 +1 可选位 `releaseConfirmedByEngine`、行句按释放证据分说(CC-212);活段接入指引订正;公面类型 +3;peer sdk 地板 `>=11.3.0` 不动;根公面 1278;§105)。上一版 0.83.4 = **patch**:只增 —— plan 审批卡「用户亲手关掉的卡,自动触发不在同一道门上放回屏上」的判定归包(`reopenPlanReviewCard` 加触发者位 `trigger`、拒开位 `dismissedByUser`,409 自愈腿按提交出身替宿主传触发者、结局与整行由包出;CC-201);座位审批请求补强制位 / 强制理由词 / 报价缺席因由 / 出身词四个可选位与过境口 `toolPermissionRequestAskBits`(CC-203);`<system-reminder>` 剥离 / 解包两只口上公面并改线性时间(CC-205);两条展示层接入指引订正;开发依赖引擎 `~7.33.1`;公面类型 +2;peer sdk 地板 `>=11.3.0` 不动;根公面 1277;§104)。上一版 0.83.3 = **patch**:入参 / 来源面 —— hooks 投影加 flag 来源(`--settings` 那一层,排在 local 之后;设置来源 hooks 维持托管在前拼接);规则列举口 `listAllPersistedRules` 入参只要 `list`(`RulesListFacade`,其余四口作可选成员);模型身份认目录缺省(本机读数加宿主报位 `engineAcceptsCatalogDefault`,位 `true` 才算目录可解析);公面类型 +1;peer sdk 地板 `>=11.3.0` 不动;根公面 1273;§103)。上一版 0.83.2 = **patch**:只增 —— 审批卡一族三件(常驻姿态下的放行谓词 `askSurvivesPosture`,三态、「不知道」不折成放行;卡上 `mandate` 六词闭集 + 读口 + 每词一句说明,通告码册 +2,开发依赖引擎 `~7.32.0`;停泊卡带出身词 `origin`;CC-193 / CC-195 / CC-196)与后台子代缺席行的判定、计数、sweep 豁免、回收与措辞单源(回收只在后台代理登记确认离场时;CC-194);公面类型 +13;peer sdk 地板 `>=11.3.0` 不动;根公面 1273;§102)。上一版 0.83.1 = **patch**:只增 + 行为订正 —— 展示层安全出口三端单源 `displayUntrusted`(凭据两网 ∘ 字符三网,选项按载体选;CC-112);本包合成的终局行正文与结果帧 `errors[]` 在铸点洗凭据(`errors[]` wire 可见,方向只会更安全)、交互车道合成行带上行类旗,回决备注与子代续跑收据多收双向 / 格式字符(CC-187 / CC-112);会话规则记录的无损判定 `sessionPolicyDeliverable` + 措辞单源 `sessionPolicyWithheldNotice` + 五词成因 `SESSION_POLICY_WITHHELD_WHY`(整批可送才送,首尾带空白的名字比宿主侧更严;CC-117);插件 hook 每轮计划 `hooksWirePlan` + `SettingsPort` 可选读口 `enabledPluginHooks` + `hooksForWire({ plan })`,逐条判「投给引擎 / 本客户端执行 / 如实不跑」、开机「不会执行」清单与 `/hooks` 标注措辞单源(投给引擎那一臂候引擎能力位 `taskSettings.pluginHooks`),设置来源的 `mcp_tool` 与 exec 形 hook 条目不再上请求体、手写的 `plugin` 键剥掉(CC-174);公面类型 +26;peer sdk 地板 `>=11.3.0` 不动;根公面 1254;§101)。上一版 0.83.0 = **minor**:行为面与型面都有 BREAKING —— CC 形消息 24 项按裁定 C-R103 退役名:结果帧 `degraded` / `errorCode` / `model` 与错误信封 `result` → `_sema_model_degraded` / `_sema_error_code` / `_sema_selected_model` / `_sema_salvaged_result`,合成终局行 `isApiErrorMessage` → `_sema_api_error_message`,工具结果记录删过渡名 `toolUseResult`,system 行 `attachedFiles` → `_sema_attached_files`、到达时戳 `timestamp` 与 `isMeta` 删,print 完成通知帧十三键平铺 `_sema_*`,记忆写入改走 chrome 臂 `memory_saved`(新型 `MemorySavedChromeEvent`,`CHROME_ARMS` required);本包只铸新名、端两名并读一版 + 结果帧 CC 键 `terminal_reason` 与读口 `terminalReasonForResult`(CC-175),错误信封知道就铸 `_sema_selected_model` + 转录 id 改 UUID 形(CC-147)+ `SettingsPort` 可选合并读口 `mergedDisableAllHooks`、用户层 `disableAllHooks` 在引擎腿上生效(CC-162)+ 退化审批卡三形拒收改写、`FsApprovalOutcome` 的 `failed` 臂 +可选位 `editRefused`(CC-135)+ 注入件自愈句整族重写 + 联网搜索旧三读口 `webSearchFromEnv` / `webSearchFromSettings` / `resolveWebSearch` 退出公面,`resolveLiveInitToolFace` 可选 `opts.webSearchStamped`(`LiveInitToolFaceOptions`),endpoint userinfo 律跟服务端 7.101.0(CC-184)+ 公面类型 −4(CC-171)+ 通告码册 69 → 71 与结构化卡白名单 +`read-inbox`(CC-186,开发依赖引擎 `~7.31.0`)+ 合成终局行 `uuid` 改 UUID 形;peer sdk 地板 `>=11.3.0` 不动;根公面 1238;§100)。上一版 0.82.7 = **patch**:只增不改 —— 每请求联网搜索配置的三态判决 `judgeWebSearchSettings` / `webSearchVerdictFromEnv` / `resolveWebSearchVerdict`(与 7.100.0 及以后 server 的受理判官同序同判,认不出的 provider 判形错、不再静默丢段;settings 段凭据注入回调 `apiKeyFor`)+ 措辞单源 `webSearchVerdictMessage`(不回显任何用户配的值)+ 调试日志用 `webSearchEndpointForDisplay`;旧三读口 `webSearchFromEnv` / `webSearchFromSettings` / `resolveWebSearch` 行为不变、标过渡期,0.83.0 删(CC-182);peer sdk 地板 `>=11.3.0` 不动;根公面 1240;§99)。上一版 0.82.6 = **patch**:只增不改 —— 停泊行上选「本会话允许」却没被记住时与活卡腿同句告知(回体 `rememberApplied: false`,或 server 以会话级放行专属拒绝码拒了 remember 后回退普通批准;其余失败一律未知不告知),回执 `DecideReceiptView` +1 可选位 `rememberApplied`(CC-181);决断落定后与桥重试臂的诊断留痕不再因宿主日志口抛错回流进决断;接入文档改口:server ≥7.100.0 上 park 行卡的 `requiresRealApproval` / `approvalIsMandated` 生效(CC-180,零代码改动);peer sdk 地板 `>=11.3.0` 不动;根公面 1235;§98)。上一版 0.82.5 = **patch**:只增不改 —— print 车道 init 帧工具面名册优先:流包装器 `withPrintInitFrame`(首选接法,init 恒为首行、其后按到达序)/ 判定闸 `createPrintInitGate` / 分类口 `printInitRosterSignal` / 判定口 `decidePrintInitToolFace` / 留痕措辞 `printInitToolFaceDebugLine` + 等待上界 `PRINT_INIT_ROSTER_WAIT_MS`(150 000);回落估计表补 `ListAgents`(7.30.0 及以后的引擎上与 `SendMessage` 同条件)(CC-169);peer sdk 地板 `>=11.3.0` 不动;根公面 1235;§97)。上一版 0.82.4 = **patch**:只增不改 —— park 行审批卡新增门类位 `irreversibleParkGate`(待决行门类恰为 irreversible_ask,今天即生效,门类事实不是保证);`requiresRealApproval` 在待决行顶层带时透传(就绪,待决列表带出后才生效,今天零行为变化)(CC-180);`ApprovalCardRequest` +1 可选位;peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§96)。上一版 0.82.3 = **patch**:只增不改的公面 —— 自愈提示的「保住对话」出路槽 `keepSessionWayOut` 与交互面引擎决断入口开关 `engineDecidePath`(CC-177;两位都不给时措辞与 0.82.2 逐字节同);自愈结局两臂 +机读位 `pendingRowGone`(重开链证实待决项已不在);peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§95)。上一版 0.82.2 = **patch**:只增不改的公面 + 若干行为订正 —— 新增措辞单源 `cloudEffectiveNotices`:云控制面有效配置回体的降级告警 / 预算 / 能力上限三读数(CC-164,四态,不读成 0 或「没有预算」);本机引擎 models 文档在宿主注入本机条目判定 `entryAccepted` 时补 `default` / `tierGroups` / `activeTierGroup`,剔掉会让本机整份拒收的目录引用与判定口不收的条目,去掉 registry 注记键 `origin` / `overridesTeam`(CC-165;结果新增 `modelRefIssues`);计划复核结局机读位 `_sema_planReviewOutcome`(CC-160 ①);停泊审批决断操作起止回调 `onDecideOperation` 与操作句柄 `openDecideOperation`(CC-160 ③);新增超集键 `_sema_planReviewOutcome`;peer sdk 地板 `>=11.3.0` 不动;根公面 1229;§94)。上一版 0.82.1 = **patch**:只增不改的公面 + 若干行为订正 —— 新增读口 15 个(续跑折叠码读口与措辞 / 文件历史捕获读口六口 / 模型身份可解析判据五口 / 自定义代理载荷作废重投口 / 决断失败码「门还在」判定)+ 宿主车道声明 `EmitContext.lane`;新增超集键 `_sema_response_model`(终帧 / 每轮用量)与 chrome 用量两臂 `responseModel`、重开判决 `_sema_decisionInFlight`、自愈结局两臂 `decisionInFlight`、内部臂 `_sema_denial_unclassified`、通知码 +1;行为订正:计划复核决断在飞不重开卡且自愈提示不再教人再决一次(CC-160 ②)、决断出口补折叠句且停泊腿不再把折叠 / 坏档误判已决(CC-154)、执行车道 `in-process` 措辞(CC-153)、`-p` 车道 Bash 良性退出与交互同判(CC-168)、`-p` 工具结果帧补结构化结果(CC-149)、被拒分类词两车道同判(CC-172)、非交互车道子代工具帧(CC-158,宿主声明车道才生效)、终帧被拒清单对账流内拒绝(CC-159)、自定义代理载荷作废重投(CC-161);peer sdk 地板 `>=11.3.0` 不动;根公面 1228;§93)。上一版 0.82.0 = **minor**:只增不改 —— 新增只读读口 17 个 + 1 常量、工具名册行一格 `mountedBy`、turn 错误判决 `http` 臂一格 `storedRowWhere`:`/rewind` 代码档与对话档能不能用由引擎能力位回答(CC-146)、云控制面额度读数三分(CC-150)、装配期「这一条腿有没有手」(CC-152)、续跑拒收按原码判(CC-154);两处既有面行为订正:自动模式分类器拒的类别词由 `permission-rule` 改为 `automode-*` 三词(CC-155,订正 0.81.1)、续跑上下文读不出时引擎点名的那一行不再丢(CC-156);0.81.0 预告的 23 键 + 1 子型删改**改到 0.83.0**(§92y ㉙);零 wire 键、零投影臂;peer sdk 地板 `>=11.3.0` 不动;§92。上一版 0.81.1 = **patch**:被拒分类词读器加第③路(CC-148):引擎「没问过就拒」的工具调用(deny 规则 / 权限模式 / hook / 分类器 / 写保护 —— 无 `settlement` 只有 `gate.disposition.deniedBy`)在 user 工具结果记录与终帧 `permission_denials[]` 上此前恒缺 `_sema_denial_kind` / `toolDenialKind`,现按层名落 `permission-rule`(其中「分类器」一项已由 0.82.0 CC-155 订正)(`ask_resolution` 无结算 / 结算段不成形 / 层名表外仍缺席不猜);交互与 `--print` 两条车道同一只读器;另钉终帧两臂 `_sema_effective_*` 键集不变量 —— 成功臂展开单铸函数、错误信封显式重发,覆盖性钉在返回对象自己的类型上(漏键 / 多键编译期即红)+ 门格判两臂键集相等且值逐字节同,给单铸函数加键时错误臂不会再静默少键(本版无键增减);零 wire 键、零投影臂、根公面 1195;§91。上一版 0.81.0 = **minor**:CC 形消息一张脸(C-R85 / CC-131):user 工具结果记录加 SDK 面键 `tool_use_result`(与过渡键 `toolUseResult` 同引用,删驼峰原定 0.82.0、已改到 0.83.0)+ DS-19 普查门升硬门(键集按语法解析、按 type/subtype 分表;23 键 + 1 子型过渡表到期窗原为 0.82.0、已改到 0.83.0,零常驻豁免)+ CC-145 `/rewind` both 臂改发 `restoreFiles:true`、`projectRewind(pending)` 单参;零 wire 键、零投影臂、根公面 1195;§90。上一版 0.80.2 = **patch**:`conflict.resume_context_unavailable` 的 `staleAfterSec` / `runId` 在真 SDK 上读不到(CC-137:sdk 11.1.0 起 `APIError` 把体上非具名键收进 `extra`,这一码映射成 `ConflictError` 无具名位,读口只读顶层 ⇒ 真调用链恒缺席)⇒ 体源结构位改「顶层有效值优先、`extra` 兜底」三只类型化读口单铸,有具名子类位的三处(`retryAfterSec` × 2 / `allowlist`)行为不变只多兜底,头源 `retryAfterMs` 只读具名位;零 wire 键、零投影臂、根公面 1195;§89。上一版 0.80.1 = **patch**:去键重发判据句按「铸」计(CC-143;§87「带键的体恰一次」作废 → 被铸恰一次,POST 几次随传输层)+ 接入文档段落自带射程限定词自 §88 起向前执法 + 模型预设表 deepseek 项改闭集真名 deepseek-flash(CC-144,C-R82 ①)+ 门里 git 兜底自陈探针(CC-142);零 wire 键、零投影臂、根公面 1195;§88。上一版 0.80.0 = **minor**:🔴 peer sdk 地板 >=11.2.1 → >=11.3.0 + 策略拒的归因上 wire(CC-133:发送面 deny+policy 带 settledBy / 读侧 policy_refused 十三词入 CC 规则桶 / 三错误码读口 / 直连门去键重发恰一次)+ 删除规则后果句归包(CC-132)+ /mcp 详情卡两腿分说归包(CC-134:六档读口 + 九句铸点,同批改口八处说满的话)+ 🔴 终帧旧拼法 `structuredOutput` 按 0.79.1 的宣告删除(只剩 CC 形 `structured_output`);根公面 1195;§87。上一版 0.79.1 = **patch**:终帧结构化产出同帧铸 CC 形 `structured_output`(旧拼法 `structuredOutput` 过渡一版,0.80.0 删;CC-130)+ 写审批 `argsOmitted` 退化卡在无受护写入部署形上重新解得出路径(CC-129)+ 云控制面十值二型经本包第二个入口 `@sema-agent/client-core/registry` 原样转口(根入口零变;CC-128 ①);根公面 1184;§86。上一版 0.79.0 = **minor**:server 7.93.0 过境批 —— peer sdk 地板 >=11.2.1 + 写口回执第六臂 unverified 与 503 体 committed 分臂(CC-124)+ 无 run 可读的 MCP 状态面(CC-74)+ 审批卡 mandated 位(CC-110)+ 请求装配第三车道 utility 与 approverPosture / maxTokens / outputRetries 三键 + print 车道 model 座(CC-116 / 118 / 123)+ 拒因两面分铸与四个机读位(CC-125)+ 模型轮边界划消息界(CC-126)+ 委派结果人类面读口按来源声明体内定位(CC-127)+ sdk 转口三件(CC-128)+ 通告码 memory.project_scope_absent(CC-122);公面 1184;§85。上一版 0.78.2 = **patch**:门的棘轮登记数字单真源 —— 五只门十一格棘轮 + 218 条沿革账搬进 scripts/registry.json、门只读不抄、负控改篡改登记物、下调通道 RATCHET-SLACK、新门 run-registry-test(CC-79 第一期)+ 两格存量松量收掉 + submit-wiring-manifest 门补 count===1 边界格;src 零改动,dist 逐字节同 0.78.1;公面 1154;§84。上一版 0.78.1 = **patch**:两辆并行车收货 + 三张跟进票 —— displayBody 人类面读口 + 围栏解析头尾配对收紧(CC-113)/ MCP 两处「没报」措辞分句(CC-115)/ 记忆治理面五动词调用口(CC-97 b)/ 非流式提交回执接线回执读口 readSubmitWiringManifest(CC-121)/ 三份失败判官抛出物读取收口(CC-119);公面 1154;§83。上一版 0.78.0 = **minor**:peer sdk 地板 >=9.8.1 → >=11.0.1(CC-106)+ 单步写口 200 体按 stillLive 判别联合改读、第五臂 revoked、三型取自 sdk、RulesFacade.write 必填、PersistedRuleLiveness 转口(CC-103)+ DeniedBy 第十词 read_boundary 专句(CC-106 ④)+ excludeAllTools 车道行;型面 BREAKING 三处、行为面同 0.77.2;公面 1143;§82。上一版 0.77.2 = **patch**:出包面结构卫生 —— 构建期 removeComments,dist js / d.ts 零注释(新门 run-dist-comments-test.mjs + 卫生门词表 32 条 + 文档向前执法;CC-100)+ gateDeniedByDetail 表外词兜底句改「本版不认识这个层名」(CC-111 ①);行为 / 型面逐字节同 0.77.1;公面 1143;§81。上一版 0.77.1 = **patch**:外部验收三件回填 —— 读器族边界残留 projectMcpReconnectCapability 只认自有键(CC-107)/ rewind 四子键恰读一次(CC-108)/ 子代输出合并按回体 output.type · retrieval_status 定处置(CC-109,server ≥7.92.0 cursorSemantics 缺席面);型面 additive 一处;公面 1143;§80。上一版 0.77.0 = **minor**:请求装配逐键去向回执 + print 车道补座 + 表外键响亮拒(CC-101,四条行为 BREAKING)/ 会话策略写端口(CC-105)/ 持久规则单步写面(CC-103)/ workflow 子代面板行代际三向恢复(CC-104,零改码)/ 能力位读器族口径整族改齐 + 外部验收 F-A / F-B 处置 + 合并树异源复审两轮处置;公面 1143;§79。上一版 0.76.2 = **patch**:制品卫生 —— 清 dist 重 build 去掉两只已撤出源码的编译产物 + dist ⇄ src 对账门;零源码 / 零型面 / 零行为改动;公面 1122;§78。上一版 0.76.1 = **patch**:能力位读器工厂(CC-75)/ MCP 活性观察读口(CC-36)/ `capabilities.peerLane` · `permissionRulesWrite` 四态读口(CC-102)/ 记忆治理面两只读口 + 三只条目面回体读口(CC-97 a)/ 主车道证明逐次新建(CC-99)+ 修 0.76.0 的 F1 / F2(身份四键一次性快照只修了投影口一侧);公面 1122;§77。上一版 0.76.0 = **minor**:六票一批 —— `prompt_assembled` 投影臂 / 审批 feed 三态(**型面 BREAKING**)/ `ApprovalResolution` 单源联合 / 记忆 spec 读口 / 终态词表上游钉 / `tasks_expand` 退役(**型面 BREAKING**),外加身份四键一次性快照(跨全部内部臂);公面 1081;§76。上一版 0.75.1 = **patch**:面板短命子代反序缓行放不出的残洞(外部复验 D1)+ 同代 running 帧三向定形(B4)+ #969 提货 `spawnName` 透传与 `agentType` 改读诚实来源(CC-95);§75。上一版 0.75.0 = **minor**:压缩的非 compacted 结局上 chrome 面 `compaction_outcome`(新内部臂 —— 自建 print 出口的端先表态)+ peer sdk 地板 `>=9.8.1`;型面 additive(ChromeEvent +1 臂)、公面 1065、零 wire 新键;§74。上一版 0.74.5 = **patch**:core 7.24.0 提货 `_sema_freed_tokens?` + 首见即终态的行零事件(幽灵完成行)+ `isNewEngineAgentPanelCycle` / `approvalOutcomeNoteOf` 上公面;型面 additive、公面 1065、peer 不动;§73。上一版 0.74.4 = **patch**:面板键「先发布的键为准」(tick 归不了一的三序不再两行)+ 前代 UUID 迟到 tick 丢弃 + `readRunCancelContext` 下钻收紧;型面 additive、公面 1061、peer 不动;§72。上一版 0.74.3 = **patch**:面板子代身份归一(tick / end 的 UUID 归到 fleet 尾段,宿主零改)+ run 记录 `cancelContext` 读口与成因四词 + workflow 行 `errorCode` + reopen 第二臂两件;型面纯 additive、公面 1061、peer 不动;§71。上一版 0.74.2 = **patch**:`capabilities.deviceExecutor.management` 四态读口(缺席 ≠ false;`deviceExecutor: false` = 车道缺席;管理动词可用性三态归包);公面 1052;§70。上一版 0.74.1 = **patch**:审批卡无决断收口 + 结局回交;§69。上一版 0.74.0 = **minor**:peer sdk 地板 >=9.7.1 + covers 过境 + 面板周期身份 + 离场读口;§68。上一版 0.73.5 = **patch**:workflow 规模告警判定上收进包(`evaluateWorkflowSize` 三态:未知的规模不当作规模正常;分母口径与帽优先级单源;env 读口纯函数);型面纯 additive、公面 1044、peer 不动;§67。上一版 0.73.4 = **patch**:终帧 `permission_denials` 第三键 ⇐ 同一条流 `tool_start` 入参按 `toolCallId` join(三道闸;join 不上留 sema 载体;🔴 更正 0.73.2「自动升级收口」一句)+ 审批 feed push 侧取件失败的欠账退避重试;型面纯 additive、公面 1033、peer 不动;§66。上一版 0.73.3 = **patch**:CC-61 sdk 9.7.1 提货 + `capabilities.approvalsStreamLive` 四态读口(缺席 = 判不出;`livePendingNeedsReconcile` 只在引擎明说会推时才让对账节拍降兜底)+ CC-60 五条模型面文案锚包侧半场(cursorSemantics 机读位 / result 行注记 / bash 首行两变体与良性槽 / 通知 seed 并集 / parked 臂);型面纯 additive、公面 1032、peer 不动;§65。上一版 0.73.2 = **patch**:CC-59 悬挂 ask 全卡 —— `livePending[].frame`(server ≥7.87.0)两道闸窄读进视图,在场即走流内帧腿同一条路(入参可见、改写可转发),缺席保持盲卡;CC-34 收口(引擎半场随 7.87.0 到货,判据交黑盒);型面纯 additive、公面 1026、peer 不动;§64。上一版 0.73.1 = **patch**:CC-57 `decidePlanReview` outcome 尾句按「决断有没有生效」四态选(单铸点 `planReviewOutcomeTail`;此前本地拒发仍让模型汇报已拒绝)+ CC-56 cancel 的 409 按机器码分家(`cancelConflictFromError` 三形 / 新安全码 `cancel_run_not_running`)与提交面 429 用量窗读口 + 人话;型面纯 additive、公面 1026、peer 不动;§63。上一版 0.73.0 = **minor,型面 BREAKING**:fleet 视图八个数值键改可选 —— CC-52 `FleetTaskView.elapsedMs` / `tokens` / `queuedCount` 与 `FleetWorkflowView.doneCount` / `totalCount` / `failedCount` / `tokens` / `elapsedMs` 不再 `?? 0`(有键 = 真值含真 0,缺键 = 不知道;逐键缺席语义见 §62b)+ 台账补偿链无基数不铸;公面导出名零增减 1019、零 wire 变化、peer 不动;§62。上一版 0.72.14 = **patch**:悬挂的流内 ask 拉半场 —— CC-55 `startApprovalsFeed` 快照加 `livePending` 段并进变化摘要(键缺席 = 未报,不铸空)+ 视图 / 去重账 / 与流内帧腿同链的决断口(入参不可见上卡明说、改写不转发)+ 宿主闸对账节拍 + 待决计数读口(不知道 = null);型面纯 additive、公面 1019、peer 不动;§61。上一版 0.72.13 = **patch**:server 7.86.0 提货 —— CC-46 plan_review `permissionModeAfter` 发口(三选卡双闸:宿主声明只读起步 ∧ 引擎 ≥7.86.0;400 field_conflict 两种处置)+ CC-54 `capabilities.executionLane` 四态读面(键缺席 ≠ 不是本机车道;`toolsRunHere` 判据归包)+ CC-53 detach 版本闸三态;型面 additive(另撤回 0.72.12 的主通道 `absent` 臂,改独立缺席订阅口)、公面 1011、peer 不动;§60;**预告 0.73.0 BREAKING**:fleet 视图数值键改可选。上一版 0.72.12 = **patch**:「缺席被折成正向终态」按类清剿 —— CC-50 M1 头条(fleet 行缺席改发 `absent` 不再铸 `end{isError:false}`)+ 六站一次改齐(缺席 ⇒ `unknown`)+ 结果边界 fail-closed 取舍 + `_sema_outcome` + `Outcome unknown:` 行 + CC-51 M6(default 臂不再谎报 running)+ 普查门 + DS-06;型面 additive、公面 993、peer 不动;行为面三处真变化见 CHANGELOG 取舍段;§59。上一版 0.72.11 = **patch**:core 7.23.0 提货 —— CC-49 通告码 66 → 67 `config.write_protection_unresolved`(operator;兄弟码 `target_view_absent` = 没有视图,这枚 = 有视图解析不出)+ `permission_denials` 自动升级腿通电(`gates[].toolCallId` ⇒ `tool_use_id`;CC-34 引擎半场);型面零变化、公面 989、peer 不动、devDep core ~7.23.0;§58。上一版 0.72.10 = **patch**:CC-41 leader run 终局 `needs_human` + `result.conflict` 三形读面(none 缺席不可分 / unreadable 在场读不懂 / conflict;`salvaged[]` 原样给落盘口;措辞单源不提重试);型面纯 additive、公面 989、peer 不动;§57。上一版 0.72.9 = **patch**:server 7.85.0 提货 —— CC-30 会话内 MCP re-dial 消费口(`reconnectMcpServer` 三态 / unsupported 恒五键 / 交易文案单源)+ CC-39② memory-status `autoConsolidationArmed` 三态 + CC-45 resume 补充句渲保留秒数;型面纯 additive、公面 985、peer 不动;§56。上一版 0.72.8 = **patch**:清账三票 —— `memory:"off"` 请求键(CC-39③,server 7.84.0 S-405)+ `runStream` 第二条中性臂 `Model output error:`(CC-43)+ 注入件撞活 run 自动 steer 零卡(CC-44);型面纯 additive、公面 977、peer 不动;§55。上一版 0.72.7 = **patch**:core 7.22.0 提货 —— 通告码 66 `mcp.server_redialed` + 读器 `readMcpServerRedialed` + `wiring_manifest.readDeny` 第九段 `_sema_readDeny`(缺席 = 没有内置行判这条腿);型面纯 additive、公面 971、peer 不动、devDep core ~7.22.0;§54。上一版 0.72.6 = **patch**:cli L-379 包侧半场 —— `steerFollowIntent` steer 后续听意图三态(tail / after-decision / after-wake)+ `activeRunSelfHealRow` 续听声明第五参;型面纯 additive、公面 969、peer 不动;§53。上一版 0.72.5 = **patch**:server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面(键缺席 = 老引擎判不了 ≠ `none`);型面纯 additive、公面 968、peer 不动;§52。上一版 0.72.4 = **patch**:core 7.21.x 三件经 server 7.82.0 提货 —— `wiring_manifest.autoConsolidation` 第八段 `_sema_autoConsolidation`(缺席 = indeterminate 不折 false);型面纯 additive、公面 962、peer 不动;§51。上一版 0.72.3 = **patch**:core #863 记忆单系统半场 ① —— `projectAgentsForWire` 投影 `agents[].memory`(user|project|local 三词同映射引擎平面 agent:<type>);型面纯 additive、公面 962、零 wire 新键、peer 不动;§50。上一版 0.72.2 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
|
|
23
23
|
| peer:wire 契约 | `@sema-agent/sdk` **>=12.0.1**(value-level,非 type-only;**0.84.0 抬版**:12.x 声明每会话后台登记列表 `sessions.background`、能力位 `capabilities.background.listFace` 与七词闭集的后台状态型,本包三者都读(登记读口的端点门与归类口的编译期穷举),按 12.0.1 编译,11.3.0 失去物料见证;0.84.1 / 0.85.0 / 0.85.1 / 0.85.2 / 0.86.0 / 0.87.0 / 0.88.0 / 0.89.0 / 0.90.0 不动(0.86.0:sdk 14 的三处型面 BREAKING 本包已按结构读覆盖,本版 `.d.ts` 在 sdk 12.0.1 / 13.1.0 / 14.0.0 / 15.0.0 下严格编译零错误,§112y;0.90.0:地板见证矩阵改为路径列表 —— 开发依赖 12.0.1 + 15.0.0 / 15.2.0 / 15.3.0 / 16.0.0 探针树逐份验,`.d.ts` 对 sdk 16.0.0 严格编译零错,§116 SD-1)。此前 **0.80.0 曾抬到 >=11.3.0**:11.3.0 在两条回决口体上声明 `settledBy?: "policy"`、`Settlement.kind` 第十三词 `policy_refused` 与三错误码(0.80.0 至 0.83.6 都在这条地板上);**0.79.0 曾抬到 >=11.2.1**:11.2.x 声明 `capabilities.mcpProbe`、`mcpCapabilities` / `probeMcp` + `McpProbeFace`、写回执第三支 `stillLive: "unknown"`,11.2.1 再补 `TaskRequest.approverPosture` 与审批帧键 `mandated`(型面 + 运行期键锚),本包按 11.2.1 编译,11.0.1 失去物料见证;**0.78.0 曾抬到 >=11.0.1**:11.x 声明 `DeniedBy` 第十词 `read_boundary`、`rules.write` 200 体按 `stillLive` 判别联合、`RemovalLiveness` / `RuleWriteRequest` / `RuleWriteResult` / `RuleWriteBehavior` 包根导出、`TaskRequest.excludeAllTools`,本包按 11.0.1 编译,9.8.1 失去物料见证;**0.75.0 曾抬到 >=9.8.1**:9.8.x 声明 `Capabilities.deviceExecutor.management?`,9.7.1 失去物料见证;**0.74.0 曾抬到 >=9.7.1**:9.7.x 追平的六处型面是本包 0.73.3 起的编译基线,且 9.6.0 失去物料见证;**0.71.0 曾抬到 >=9.6.0**:`tool_disclosure` / `tool_progress` 两帧型与 `ToolApprovalFrame.readRootCandidate` 自 9.6.0 起;0.69.0 曾抬到 >=9.4.0(`reasoning_end` / `lastLegMcp`),0.60.0 抬到 >=8.4.0;地板由 `scripts/run-sdk-floor-test.mjs` 的 `FLOOR` 与 public-surface 门 C-CC-3「不低于见证到的最低实装版」双钉)| `package.json` `peerDependencies` |
|
|
24
24
|
| peer:会话词汇表 | `@sema-agent/agent-types` **>=0.3.0**(type-only,零运行时;0.71.0 抬版:devDep 与 peer 同步,type-superset 门 ④ 撞名预警对着 0.3.0 的 .d.ts 求值) | 同上 |
|
|
25
25
|
| runtime dep | `diff` ^9.0.0(**唯一**一条;portability 门按**等值**钉死) | `package.json` `dependencies` |
|
|
@@ -9655,6 +9655,104 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
9655
9655
|
|
|
9656
9656
|
**包侧缺口:** ① 出包面注释存量(别仓名 / 票号 / 帖号 / 过程词)与卫生门判据太窄(CC-100)—— 方案候拍板(dist 去注释 vs 手清),0.77.2 · ② `DeniedBy` 第十词 `read_boundary` / `teamName` / `stillLive` 三词随 sdk 10 型面在 0.78.0 吸收(CC-106)· ③ `capabilities.mcpProbe` 候 core 7.26.0 #951 → server 7.93.0(CC-74)。
|
|
9657
9657
|
|
|
9658
|
+
## §120 🆕 0.93.1(2026-10-09)— 耐久停驻审批的决断口单一持有者(`FsApprovalOutcome.joinedInFlight`)· 活卡 respond 回 202 的停驻中结局(`unsettled` / `parking_in_progress`)
|
|
9659
|
+
|
|
9660
|
+
> **同一只停驻审批两个持有者(SH 行;CC-491;外部验收 [9516])**:耐久停驻卡由本包 `surfaceFsApprovalAndDecide` 铸(取件 → 交宿主卡口 → 等答 → 发决断)。引擎换代之后,终端的重摆路与停驻解析器对**同一行**各调它一次;宿主卡口按 `callKey` 只呈一张、只答一个 Promise,另一路零超时永远等(卡停屏、下一张卡不来)。本版起同一把审批身份键在进程里同时只有一次决断在路上:先到者持有,后到者拿同一个结局的拷贝(`joinedInFlight: true`)、自己不呈卡不发决断不重发;没有并发的调用与 0.93.0 逐字节同(处置表 SH-1;判据 G-SH1 … G-SH11)。
|
|
9661
|
+
|
|
9662
|
+
> **活卡 respond 回 202 `parking_in_progress`(PK 行;CC-492;外部验收 [9533])**:引擎上这张卡的行正在转停驻(卡窗到期或排空那一拍)时,用户按下的答复**没有生效** —— 服务端回 `202 { approvalId, askId, reason: "parking_in_progress", retryAfterMs, … }`(体上没有 200 回执的 `delivery` 键;引擎不预存这次答复,不重答就等于没答)。修前本包的回执读器只认 `delivery: "applied"`,这个 202 体被读成「没有回执」,活卡路径的结局落成用户按的那个词(已批准),终端据此注销卡、屏上不说话。本版起结局是 `{ decision: 'unresolved', parking }`,判别口读成既有 `unsettled` 臂的新 cause `parking_in_progress`(`kind` 联合仍三臂),包替用户上屏一句;包不重发(处置表 PK-1;判据 G-PK1 … G-PK9)。
|
|
9663
|
+
|
|
9664
|
+
### 120a. 处置表
|
|
9665
|
+
|
|
9666
|
+
| 键 / 口 | 来源 | 处置 | 变化 | cli | web-admin | web-client | desktop | 判据 | 缺席语义 |
|
|
9667
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
9668
|
+
| **SH-1** `surfaceFsApprovalAndDecide` 单一持有者 + `FsApprovalOutcome` 四臂 `joinedInFlight?: true` | 本包(CC-491;外部验收 [9516]);身份 = 取件那一行的会话 + run + `toolCallId ?? boundCallId`(缺席退 `taskId`),call 部分与卡口 `callKey` 同一把(`approvalCallKey` 唯一铸口),会话与 run 两段保证不同 run 同名的 call 不被并成一次决断 | changed(🔴 行为面:只在同一把键上有并发调用时)+ added(四臂各 +1 可选位) | 前:两条路各呈一张卡、各发一次决断;宿主只答一个 ⇒ 另一路永远等。后:先到者持有整次决断;后到者(在持有者在路上时进来,或取件开始于持有者落定之前)交回持有者结局的浅拷贝 + 位,零卡零发;持有者落定当拍清登记(中断拒绝即发即弃:那一发落定之后才清);任一路的信号中止 = 这一只决断被中断(持有者撤卡 + 恰一发中断拒绝,两路同 `aborted`;谁持有不改 Esc 的效果);卡口每次决断恰收一次请求,请求恒带 `signal`;没有并发的调用逐字节同 | 🔴 换钉同批删工具门行的「拒开第二张」判读(120d);join 结局上重摆链不发结局行、不起跟跑 | 不涉及(本机 origin/main 对本口零读点) | 不涉及(同左) | 不涉及(同左;不装审批卡口) | G-SH1 … G-SH11 | 120b SH-1 |
|
|
9669
|
+
| **PK-1** `ToolApprovalFrameOutcome.parking?` + `ApprovalUnsettledCause` 新词 `parking_in_progress` + `ApprovalResolutionUnsettled.parking?` | 本包(CC-492;外部验收 [9533]);202 体形来自服务端铸点(`case "PARKING"`:`approvalId` / `askId` / `reason: "parking_in_progress"` / `retryAfterMs`〔常量 250〕),逐代钉在 G-PK9;`decidePath` 是服务端预告的新键([9537]),契约位候服务端登清单,本包按键名读 | consumed + added(🔴 行为面:只在引擎真回 202 时) | 前:202 体读成「没有回执」,结局 `{ decision: <用户按的词> }`,归因旗位与「审批本身过了」一类伴随通知照 200 的路径铸出。后:结局 `{ decision: 'unresolved', parking: { approvalId, retryAfterMs?, decidePath? } }`,无 `ack`,归因各位与伴随通知不铸,上屏一句;respond 恰一发,不重发 / 不去键 / 不换名 / 不等 `retryAfterMs`;判别口 `{ kind: 'unsettled', cause: 'parking_in_progress', parking }`;结局便签 `settled: false`。200 回执及其余非回执 200 体的读法一字未动 | 🔴 换钉同批改 respond 包装处(120d 第一条);对 `ApprovalUnsettledCause` 做 `never` 穷举的写法编译红一次,按 `kind` 的写法与既有 `unsettled` 有界重呈不受影响 | 🔴 必改:直调 respond 的调用点把 202 当成已提交(120d) | 零必改(已有本地判读,换钉后可换读这一 cause;[9540]) | 🔴 必改:直调 respond 的调用点把 202 当成已提交(120d) | G-PK1 … G-PK9 | 120b PK-1 |
|
|
9670
|
+
|
|
9671
|
+
### 120a′. 成文改口
|
|
9672
|
+
|
|
9673
|
+
- **§119 勘误(三)(0.93.0 外部验收 [9596] 指出接入文档五处;旧判据眼作废 → 新判据眼;🔴 已发的 §119 不回改)**:① G-RT2 的「`TOOL_APPROVAL_FRAME_KEYS_MIRROR` 长度 34」作废 → 0.93.0 发布件实读 **37**(同批 RT-1 −2 与 FK-1 +3 一并算;按字面 34 判会把正确产物判红);新眼 = 「不含 `ruleStoreUnreadable` / `ruleSuggestions`、含 FK-1 三键」,不钉总长 ② G-PM8 第五句「读数读不出」的触发面限定:`{ kind: 'present', modes: 42 }`(`modes` 不是数组)落的是「does not include」那一句;「could not be read」只在读数为 `null` / 字符串 / 认不出的 `kind` / 读取时抛这四形出现(0.93.1 实跑坐实)③ G-DX4 的「三位上的取值器抛 ⇒ 整格删」只在读口工厂路径(`noteEngineCapsForDeviceExecutorManagement` 的 tee 落点)成立;直调 `projectDeviceExecutorManagementCapability` 遇取值器抛会抛出,同族 `projectPermissionModesCapability` 同形却吞成 `undefined` —— 同族两条处置律是缺陷不是判据(CC-507,0.94.0 收成单律),收口前该眼限定到读口工厂路径 ④ G-DB4 与 G-DB10 的 AST 半场(src 里恰一只 `decisionAttributionKeyOf` 声明 / 恰两个调用点 / 桥白名单拷贝单源)是包侧门(`run-approval-decided-by-capability-test.mjs`),发布件无 src,外部验收不核这半场;两格的行为半场(deny 体按位选键、`HitlBridge.decideTool` 实跑)照核 ⑤ 119a WD2-1 行「无型面变化」漏了限定:`RULE_NOT_SENT_REJECTED_WARN_TEXT` 的声明由三因并列的字面类型变为 `string`(119a′ WD2 ④ / 119y WD2 已写),该行读作「除此一处外无型面变化」。
|
|
9674
|
+
|
|
9675
|
+
### 120b. 缺席语义
|
|
9676
|
+
|
|
9677
|
+
**单一持有者(SH-1;CC-491)**
|
|
9678
|
+
- **`joinedInFlight` 缺席** ⇒ 本次调用自己持有那一次决断(或根本没走到登记那一步,如取件失败)。**不等于** `false`,本包永不铸 `false`。
|
|
9679
|
+
- **在场(严格 `true`)** ⇒ 这只结局是另一路持有的那一次决断的拷贝:本路没呈卡、没发决断、没重发、没上屏告知(会话授权没记住 / 盲卡编辑拒发两句只由持有者说一次)。`denied` / `receipt` / `denySettledBy` / `denyReason` / `denyAttributionDropped` / `denyAttributionRenamed` / 失败各位(`stage` / `errorCode` / `retriable` / `safetyCode` / `retryExhausted` / `currentPending` / `editRefused`)说的都是持有者那一次决断,原样搬;后到者自己的能力位读数(`approvalDecidedBy`)不读不用。
|
|
9680
|
+
- **中断拒绝的尾随期**:持有者被中止时照旧立即交回 `aborted`、那一发中断拒绝在后台落定;落定之前进来的调用方同样拿这次的 `aborted`(带位),不会在拒绝落地之前再呈一张卡、再发一次批准。
|
|
9681
|
+
- **`aborted` 臂上在场** = 这一只决断被中断了:持有者那一路或本路的信号中止都算(本路中止 ⇒ 持有者撤卡、发恰一发中断拒绝);中断拒绝只由持有者发、只发一次。持有者已落定之后本路才中止 ⇒ 不中断,本路拿已落定的结局(不是 `aborted`)。卡已答、决断正在发时中断不打断那一发。结局判别口 `approvalResolutionOf` 两形同读 `unsettled` / `interrupted`(不承诺零字节,也不说已决)。
|
|
9682
|
+
- **持有者抛** ⇒ 后到者以**同一只**抛出物拒绝(不是一只新错误)。
|
|
9683
|
+
- **回调**:后到者的 `onDecideOperation` 恒不报;`onPresented` 只在持有者真把卡交给了卡口时回调一次(持有者没交卡 ⇒ 不回调),回调抛错不改后到者的结局。
|
|
9684
|
+
- **读起点**:每次调用在取件发出之前取一枚读起点;取件回来时这把键的上一次决断若在读起点之后才落定 ⇒ 按后到者处置(那份行快照对这把键是陈旧的);读起点晚于落定 ⇒ 新决断。
|
|
9685
|
+
|
|
9686
|
+
**活卡 respond 的停驻中结局(PK-1;CC-492)**
|
|
9687
|
+
- **`parking` 位缺席** ⇒ 这次 respond 不是 202 停驻体(含:200 回执、非回执 200 体〔赎回 `accepted` / 幂等回放 `idempotent`〕、void 返回、respond 抛错、202 体自称停驻却认不出这张卡〔缺 / 空 / 非串 `approvalId`,或点名别的卡:这两形结局是 `{ decision: 'unresolved' }`,见下〕)。**不等于** `false`,本包永不铸 `false`。
|
|
9688
|
+
- **在场** ⇒ 这一发**没有生效**:`decision` 恒为 `'unresolved'`(不是已批准也不是已拒绝)、没有 `ack`、`denySettledBy` / `denyReason` / `denyAttributionDropped` / `denyAttributionRenamed` 不铸、不上屏「审批本身过了」一类伴随通知;包已替用户上屏一句。判别口 `approvalResolutionOf` 读成 `{ kind: 'unsettled', cause: 'parking_in_progress', parking }` —— `kind` 联合仍三臂,不是新臂;`parking` 位只在这一 cause 上在场(present-iff);三个判官 `isApprovalDecided` / `approvalNotSentCause` / `approvalUnsettledCause` 对它依次答 `false` / `undefined` / `'parking_in_progress'`。**这一 cause 与其它 `unsettled` 的差别**:字节已出站、引擎答了,答的是「停驻中、这一发没生效」,卡会以停驻卡的形再回来;壳据此**不注销卡、不说已批准**,既有的有界重呈路径(`unsettled` → 稍后重呈)对它默认安全;其余 `unsettled` 因由多半是「没落定、引擎按自己的窗结算」,不是这一句。判别序:撤卡、编辑被拒(零字节事实)压过它,它压过决断词;结局上的 `parking` 位 `approvalId` 缺 / 坏 ⇒ 当缺席。
|
|
9689
|
+
- **`retryAfterMs`**:缺席 = 服务端没给(不是 0);`0` 是合法值、原样带;在场必须是自有数据位上的有限非负数 —— 负数 / 串 / NaN / Infinity / null / 对象 / 布尔 / 访问器**只丢这一键**(无该键,不是 0),停驻照认、句子无句尾;读它抛(宿主注入的代理)同样只丢这一键。本包不据它重发、不替宿主等。
|
|
9690
|
+
- **`decidePath`**:服务端预告在 202 体上带的停驻卡决定口路径(契约位候服务端登清单,本包按 202 体的键名读)。缺席 = 老服务端没给:**不猜、不拼路径**(不据 `approvalId` 自铸);在场须是自有数据位上的非空串,原字节随结局交回宿主;空串 / 非串 / 原型链 / 访问器 / 读它抛**只丢这一键**、停驻照认。🔴 不上屏(用户面一句不含它);🔴 它是应答体上的文本,宿主拿去发请求前自行核对,本包不判形、不替宿主发。
|
|
9691
|
+
- **停驻事实的承载**:只由自有数据位 `reason` 恰是 `parking_in_progress`(只有 `delivery` 键、大小写不同、前导空格、原型链上的 `reason`、访问器 `reason` 都不算)∧ `approvalId` 非空串且与这张卡一致承载。读不出 `approvalId`(缺 / 空 / 非串 / 原型链 / 访问器)或点名别的卡 ⇒ **不落 parking**(不伪造),但也不落回「没有回执 ⇒ 已批准」:结局恰 `{ decision: 'unresolved' }`(无 `parking`、无 `ack`;判别口 `unsettled` / `respond_failed`,便签 `settled: false`;零通知、不重发)并响亮留痕。读它抛〔代理陷阱〕⇒ 当不是停驻体。
|
|
9692
|
+
- **用户面一句**(包铸,唯一铸点,不含服务端文本):`This approval is being parked; answer it again on the parked card when it appears.`;`retryAfterMs` 在场时句尾补 ` (the engine suggested waiting about N s)`(N 以秒计、向上取到 0.1:250 → `0.3`、30000 → `30`、0 → `0`)。warning 级、立即顶替、15 秒自清、同 key 连发只顶替;无宿主口 ⇒ 静默,结局不变。
|
|
9693
|
+
- **悬挂 ask(盲卡)**与流内帧是同一条路,同判。耐久停驻路径的决断口是 `/v1/approvals/:id/decide`,不会回这个 202,**没有**这一 cause(与 SH-1 的 join 无交点:join 拷贝的是耐久结局)。
|
|
9694
|
+
|
|
9695
|
+
### 120c. 黑盒判据(G 骨架)
|
|
9696
|
+
|
|
9697
|
+
> 纯包层,走根入口公面:`import { surfaceFsApprovalAndDecide, installApprovalCardPort, bridgeAskUserQuestionGates, approvalResolutionOf } from '@sema-agent/client-core'`。宿主卡口取「按 `callKey` 只认最后一张」的形(只呈一张、只答一个);假服务端一张待决行 `{ sessionId: 's-1', taskId: 't-1', toolCallId: 'call-1', boundCallId: 'call-1', boundInputHash: 'h-1', toolName: 'Write', input: { file_path: '/x' } }`,决断后行消失(G-SH3 / G-SH6 留行)。标「本版证明」的格在 0.93.0 上 FAIL、在 0.93.1 上 PASS;等待一律有界(1 秒),不真等。
|
|
9698
|
+
|
|
9699
|
+
- **G-SH1**(本版证明):同一行两次调用先后相隔 10 ms(都传 `parkGatedCallId: 'call-1'`),答卡 allow ⇒ 卡口恰被调 1 次、decide 恰 1 次、两路都在 1 秒内落定且都是 `decided`、`denied` 同值、后到者 `joinedInFlight === true`、先到者没有这一键;deny 同判且 `denyReason` 两路同(0.93.0:卡 2 张、先到者 1 秒挂住)。
|
|
9700
|
+
- **G-SH2**(本版证明;两序):真解析器 `bridgeAskUserQuestionGates`(同步段 `tool_start` → `tool_end` 中止 → `done{ paused, gate: irreversible_ask Bash }`,续读段 `tool_end` ok → `done{ completed }`)× 终端重摆形直调(自有 client、决断操作观察器、空 `argsByCall`、无信号、传行的 call id);解析器先 / 重摆路先各一跑 ⇒ 卡口恰 1 次、decide 恰 1 次、解析器那条流读到末帧 `done`、重摆调用 `decided`;后到者带位,重摆路后到时它的观察器零回调、先到时恰 `start` / `end` 一对(0.93.0:后到者的卡被答、先到者挂住 —— 解析器先时正是那条流挂住)。
|
|
9701
|
+
- **G-SH3**(本版证明):decide 回 500(带 `errorCode`)⇒ 卡 1、decide 1、两路同 `failed` / `stage: 'decide'` / 同 `errorCode` / 同 `reason`、后到者带位;随后同键再调一次 ⇒ 新卡、新 decide、无位。卡口自己抛 ⇒ 卡口恰被调 1 次、两路以同一只抛出物拒绝;再调一次 ⇒ 卡口第 2 次被调。
|
|
9702
|
+
- **G-SH4**(本版证明):后到者的信号在等待中中止 ⇒ 持有者那张卡收到中止(宿主答 `aborted`)、decide 恰 1 次且是 `deny` + `Interrupted by user`、持有者 `aborted` 无位、后到者 `{ kind: 'aborted', gatedCallId: 'call-1', joinedInFlight: true }`;后到者进来时信号已中止 ⇒ 同一组读数。真解析器 `bridgeAskUserQuestionGates`(传 `{ signal }`)× 终端重摆形直调,两序各一跑,中止解析器那只 turn 信号 ⇒ 两序读数逐字相同(卡 1 张且已收口、决断恰一发 `deny`、重摆调用 `aborted`、流收口;0.93.0 / 修中间态:重摆路持有时卡留屏、零拒绝、重摆调用挂住)。持有者已落定之后后到者才中止(取件回包被拖到落定之后、信号已中止)⇒ 零中断拒绝、后到者 `decided` 带位。两路同一拍中止 ⇒ 仍恰一发 `deny`。持有者的信号中止 ⇒ 两路都是 `aborted`(后到者带位)、decide 恰 1 次且是 `deny` + `Interrupted by user`(0.93.0:后到者中止时自己发一发中断拒绝)。把那一发中断拒绝的回包拖住,持有者交回 `aborted` 之后再调一次 ⇒ 交回 `aborted` 带位、卡口不再被调、决断仍只有那一发 `deny`;放开回包、行消失之后再调 ⇒ `failed` / `stage: 'fetch'` / `code: 'no_pending'`、无位(0.93.0:第三路再呈一张卡、答卡后补发一发 `approve`)。
|
|
9703
|
+
- **G-SH5**(回归):两条不同行(`call-1` / `call-2`)并发 ⇒ 两张卡、两次 decide、各自结局、都没有位。
|
|
9704
|
+
- **G-SH6**(回归):同键一个接一个调两次(行留着)⇒ 两张卡、两次 decide、都没有位。
|
|
9705
|
+
- **G-SH7**(本版证明):后到者的取件在持有者呈卡之后发出、回包被拖到持有者落定之后 ⇒ 卡口不再被调、decide 不再发、后到者 `decided` 带位;取件在持有者落定之后才发出(同样拖住回包)⇒ 新卡、新 decide、无位。
|
|
9706
|
+
- **G-SH8**(本版证明):两路各带 `onPresented` / `onDecideOperation` ⇒ 持有者 `onPresented` 1 次、后到者 1 次(后到者的回调抛错时它仍交回 `decided` + 位);持有者 `onDecideOperation` 恰 `start` / `end`、后到者 0 次。行上 `input` 不是对象(持有者在入参段失败、没交卡)⇒ 两路 `onPresented` 都是 0、两路同 `failed` / `stage: 'input'`、后到者带位。后到者带 `onPresented` 并在等待中被自己的信号中止、之后持有者才落定 ⇒ 后到者的 `onPresented` 恰 1 次(不在持有者落定时再报)。
|
|
9707
|
+
- **G-SH9**(本版证明):后到者的结局对象 `!==` 持有者的;持有者对象上没有这一键;后到者键集 = 持有者键集 + `joinedInFlight`;`receipt` 值同;任何结局上这一键要么缺席要么严格 `true`;`approvalResolutionOf({ kind: 'aborted', gatedCallId: 'call-1', joinedInFlight: true })` ⇒ `{ kind: 'unsettled', cause: 'interrupted', gatedCallId: 'call-1' }`。
|
|
9708
|
+
- **G-SH10**(本版证明):新一代服务端(体带 `settledBy` ⇒ 400 `request.body_shape` + `field: 'settledBy'`),答卡 policy deny ⇒ decide 恰两发(首发 `settledBy`、换名重发 `decidedBy`,都由持有者发)、两路 `denyAttributionRenamed === true`、后到者 `denySettledBy === 'policy'` 且带位(后到者自己给了 `approvalDecidedBy` 读数也不读)。
|
|
9709
|
+
- **G-SH12**(回归;0.93.0 与 0.93.1 都 PASS —— 钉的是登记不许跨 run 合并):两条行同一个 call id、不同会话 / run(`s-A` / `t-A` 与 `s-B` / `t-B`),两次调用各传自己的 run ⇒ 两张卡、两次决断分别落在 `s-A` / `s-B`、两路都没有位。
|
|
9710
|
+
- **G-SH12c**(回归;盯登记键里的会话位):同一个 run(`t-C`)、同一个 call id,两行分属两个取件范围(会话 `s-C1` / `s-C2` 各自的待决表),两次调用并发 ⇒ 两张卡、两次决断各落在自己的会话上、两路都没有位(会话位去掉时:卡 1 张、后到者带位拿另一个会话的结局)。
|
|
9711
|
+
- **G-SH11**(包层源码结构,端不复跑):决断口里 join 与登记的代码路径对呈卡 / 决断 / 告知零引用,呈卡与决断只在持有者体里、持有者体恰一个调用点;登记表与它的读写口不在根入口。
|
|
9712
|
+
|
|
9713
|
+
> **PK 行的判据**(纯包层,走根入口公面:`import { surfaceToolApprovalFrameAndRespond, installApprovalCardPort, installHitlHostSurface, approvalResolutionOf, approvalOutcomeNoteOf, approvalUnsettledCause } from '@sema-agent/client-core'`)。宿主卡口恒答 allow(另测 allow_session / deny / policy 拒绝);respond 注入 `async (id, decision, opts) => 体`;帧 `{ type: 'tool_approval', approvalId: 'ap-1', toolName: 'Bash', args: { command: 'ls' } }`;宿主面记通知。标「本版证明」的格在 0.93.0 上 FAIL、在 0.93.1 上 PASS。
|
|
9714
|
+
|
|
9715
|
+
- **G-PK1**(本版证明):respond 回 `{ approvalId: 'ap-1', askId: 'ask-1', reason: 'parking_in_progress', retryAfterMs: 250 }` ⇒ 结局恰 `{ decision: 'unresolved', parking: { approvalId: 'ap-1', retryAfterMs: 250 } }`(0.93.0:`{ decision: 'allow' }`);respond 恰 1 次、卡口恰 1 次、通知恰 1 条且正文恰为停驻句 + ` (the engine suggested waiting about 0.3 s)`(warning / immediate);`approvalResolutionOf` ⇒ `{ kind: 'unsettled', cause: 'parking_in_progress', parking: { approvalId: 'ap-1', retryAfterMs: 250 } }`;`approvalOutcomeNoteOf` ⇒ `{ approvalId: 'ap-1', settled: false }`。`retryAfterMs` 缺席 ⇒ 位上无该键、句子无句尾;`retryAfterMs: 0` ⇒ 原样带 0。三种决断词与 policy 拒绝同判,policy 拒绝的结局键集恰 `decision,parking`(0.93.0:多 `denySettledBy` / `denyReason`)。持久臂被丢(表外规则文本)+ 202 ⇒ 不上屏「审批本身过了」一类伴随句(0.93.0 照说)。真消费路径 `routeFrame` 与悬挂 ask 盲卡同判。体带 `decidePath` ⇒ 位与判别口原字节带该键、句子不变且不含路径、respond 仍恰一发;缺席 ⇒ 无该键。
|
|
9716
|
+
- **G-PK2**(回归):respond 回 200 回执 `{ approvalId, delivery: 'applied', decision }` ⇒ `decision` 为用户按的词、`ack` 在场、无 `parking`、无通知、判别口 `decided`;赎回 200 / 幂等回放 200 / void / `{}` 都不被读成停驻(既有读法不变)。
|
|
9717
|
+
- **G-PK3**(两格):① `approvalId` 缺 / 空 / 非串 / 原型链 / 访问器 / 读抛 / 对不上这张卡 ⇒ 结局恰 `{ decision: 'unresolved' }`、判别口 `unsettled` / `respond_failed`(不是 `parking_in_progress`)、便签 `settled: false`、零通知(持久臂被丢时也不说「审批本身过了」)、respond 仍恰一发;② `retryAfterMs`(负 / 串 / NaN / Infinity / null / 对象 / 布尔 / 访问器 / 读抛)与 `decidePath`(空串 / 非串 / 原型链 / 访问器 / 读抛)坏值 ⇒ 停驻照认、结局只丢各自那一键,句子是基句(`retryAfterMs` 坏时无句尾)。`reason` 表外 / 大小写 / 前导空格 / 非串 / 缺席、只有 `delivery: 'parking_in_progress'`、原型链 `reason`、访问器 `reason`、抛错代理、非对象 ⇒ 根本不是停驻体,既有路径不变。访问器代码一次不跑。
|
|
9718
|
+
- **G-PK4**(回归):与 SH-1 的交互 —— 耐久路径两路并发(join)而 decide 回包形如停驻体时,恰一张卡、恰一次 decide、结局仍是 `decided`(后到者带 `joinedInFlight`)、两路都无 `parking`;活卡路径同一 `approvalId` 并发两路 + 202 ⇒ 两路各自停驻、没有任何一路读成已批准、respond 至多每路一发。
|
|
9719
|
+
- **G-PK5**(本版证明):202 之后零重发 / 去键 / 换名 —— 位认的 policy 拒绝(`decidedBy`)恰一发;位不认(`settledBy`)恰一发、不换名;首发撞退役键、换名那一发返 202 ⇒ 恰两发、停驻、归因旗位不铸(0.93.0 铸 `denyAttributionRenamed`);首发撞直连门、去键那一发返 202 ⇒ 恰两发、停驻、不铸 `denyAttributionDropped`;`retryAfterMs: 30000` 的 202 立即交回结局、没有定时重发。
|
|
9720
|
+
- **G-PK6**:停驻句逐字;句尾八形(`250 → 0.3`、`100 → 0.1`、`1 → 0.1`、`1500 → 1.5`、`30000 → 30`、`12345 → 12.4`、`0 → 0`、`3600000 → 3600`);无宿主口 ⇒ 静默不抛、结局不变;句中不含服务端体上的任何文本(`askId` / `decidePath` / 额外键)。
|
|
9721
|
+
- **G-PK7**:`APPROVAL_UNSETTLED_CAUSES` 含 `parking_in_progress`、联合仍三臂(d.ts 里没有 `kind: 'parking'` 臂)、`ApprovalResolutionUnsettled.parking?` 在场;判别序 —— 撤卡 / 编辑被拒压过停驻,停驻压过决断词(`{ decision: 'allow', parking }` 不说 decided),`approvalId` 缺 / 坏的 parking 位当缺席;判别口产物键集恰 `kind` / `cause` / `parking`,`parking` 位只带 `approvalId` / `retryAfterMs` / `decidePath`;`retryAfterMs` / `decidePath` 坏值只丢各自那一键。
|
|
9722
|
+
- **G-PK8**(包层源码结构,端不复跑):判停驻的读器(包内件)恰一只声明、恰一个调用点且在活卡路径内;`parking_in_progress` 字面量在包源里只在三处 —— 线上 `reason` 词在读器里 1 处,cause 词在判别口模块里 2 处(词表 + 判别口),别处零(植入违例自证);停驻句的铸口、文案常量与读器都不在根入口。
|
|
9723
|
+
- **G-PK9**(服务端夹具在场时):服务端各代(7.106.0 – 7.119.0 共 12 份)`case "PARKING"` 回 202,体键 ⊇ `approvalId` / `askId` / `reason` / `retryAfterMs`,`reason` 字面 `parking_in_progress`,`retryAfterMs` 常量 250,体上没有 `delivery` 键;这些代的体上都还没有 `decidePath`。
|
|
9724
|
+
|
|
9725
|
+
### 120d. 端上要动的读点
|
|
9726
|
+
|
|
9727
|
+
坐标来自本机克隆的只读检索;本机克隆可能落后远端,行号会漂,合并前请各端对自己的最新主干重看一遍。
|
|
9728
|
+
|
|
9729
|
+
**终端(origin/main `b43004f0`)**
|
|
9730
|
+
- `sema/askParkReopen.ts:996`(`armPendingRow` 里 `[armedKey, rowBoundCallId].some(k => durableDecideInFlight(k, …))` 的拒开判读):对**工具门行**,本版起「这把键有没有一次决断在路上、或在你开始读之后才落定」由本包决断口单源回答 —— 工具门行上这一判读是第二份真源,换钉 `^0.93.1` 同批删(把判读挪进问答臂,或只对问答行判)。**问答臂照留**:问答卡由终端自己铸、`HitlBridge.decideTool` 直发,不经本口,本包登记管不到。
|
|
9731
|
+
- `sema/askParkReopen.ts:1543` / `:1596`(工具门整链 `surfaceFsApprovalAndDecide` 的调用与 `chainDecideOperationObserver`):调用不改;链拿到带 `joinedInFlight` 的结局 = 这一步由在路上的那一路(通常是停驻解析器)决的、那一路在跟续跑 ⇒ 不发结局行、不起跟跑、不说「没做」;上一条删掉之后,本链的决断操作观察器随之复核去留(退役登记 RL-78)。
|
|
9732
|
+
- `sema/askParkExpiry.ts:1235-1262`(`already-following` 臂):不改。修前重摆路在这里收场、解析器那一路永远等;本版起两路同结局,解析器那条流照常往下读、下一张卡由它呈。
|
|
9733
|
+
- `sema/liveClient.ts:1614`(`onDecideOperation: durableDecideOperationObserver()`):问答臂的决断仍要记账,照留。
|
|
9734
|
+
|
|
9735
|
+
**网页端(本机 origin/main `8bfc1a7`)/ 管理台(`17d6a3c5`)/ 桌面端(`a4fdc9d`)**:产品源码对 `surfaceFsApprovalAndDecide` / `bridgeAskUserQuestionGates` / `FsApprovalOutcome` 零命中,不涉及。
|
|
9736
|
+
|
|
9737
|
+
**PK-1(CC-492)的读点**
|
|
9738
|
+
|
|
9739
|
+
**终端(1.0.144 参照树 `dd838c9b`;本机克隆可能落后远端,行号会漂)**
|
|
9740
|
+
- `sema/liveClient.ts:1541-1546`(`respondToolApproval` 包装:`respondToolApprovalInner` 返回后不论回体即 `noteSuspendedAskDecided(approvalId)`):202 停驻体也走到这一行 ⇒ 卡被注销。这一行在包读回体**之前**,壳在这里自己判 202 就是第二条读法;换钉后把「记已决断」挪到拿到包的结局之后(只在结局是 `decided` 时记),这一行删。
|
|
9741
|
+
- `sema/suspendedSubagentAskWire.ts:445-499`(`approvalResolutionOf(outcome)` 之后依次判 `not_sent` / `unsettled`,最后无条件 `noteSuspendedAskDecided`):停驻落在 `unsettled` 分支(:488)里 —— 走既有有界重呈 `retryLater`,**不会**掉进最后那一行「本端已决断」,默认安全。可选:按 `resolution.cause === 'parking_in_progress'` 细分措辞(`detail` 缺席时现句是「the engine did not confirm it」),以及按 `retryAfterMs` 有界重试 / `decidePath` 在场时改走停驻卡的决定口 —— 是壳的事,包零自动重试。
|
|
9742
|
+
- `sema/liveClient.ts:1686`(`onToolApprovalOutcome` → `approvalOutcomeNoteOf`):便签对停驻给 `settled: false`、无 `retracted`、无 `detail`(与旧口径 `decision !== 'unresolved'` 同值),按 `settled === false` 走的既有分支会把它当「没落定」;核对那一分支的文案不把它说成「引擎没收到」。
|
|
9743
|
+
|
|
9744
|
+
**网页端**:已有的本地判读(只认 `reason` 词,[9540])可在换钉后换成这一 cause 并退掉;零必改。
|
|
9745
|
+
|
|
9746
|
+
**管理台与桌面端(🔴 必改)**:两处直调点都不经本包的活卡路径、不看回体是不是停驻 —— 管理台 `lib/chat/transport/engine-transport.ts:2330`(远端主线 `0552587f`,2026-10-09:`await clientFor(…).toolApprovals.respond(…)` 之后立即删登记,回体只交回执两位的通知口)与桌面端 `main/session-host.ts:3219`(远端主线 `dbafa0b`,2026-10-09,已钉本包 0.93.0:`await this.deps.client.toolApprovals.respond(…)` 之后不看返回体、直接把卡标为已允许 / 已拒绝):引擎回 202 时同样把没生效的答复当成已提交(两端远端主线读码,未实跑)。必改:停驻不得记为已提交 —— 换成经包的活卡路径取结局(`surfaceToolApprovalFrameAndRespond`,读 `approvalResolutionOf(…)` 的 `unsettled` / `parking_in_progress`);本包不导出判停驻的读器,直调点自己判 202 就是第二条读法 —— 要不要一只公面读口(根公面 +1,接入档 §0a / §2 / §2b 的计数同批动)另议。两端的表态由各端给。
|
|
9747
|
+
|
|
9748
|
+
### 120y. 🔴 三端升级必读(固定段式)
|
|
9749
|
+
|
|
9750
|
+
1. **换钉 `^0.93.1` 之前**:零编译红(只在 `FsApprovalOutcome` 四臂各加一个可选位;对结局整只做键集等值断言、或把结局整只展开进别的对象的测试替身,在同一把键并发调用时多一键)。终端同批删工具门行上的「拒开第二张」判读(120d 第一条),join 结局上不发结局行、不起跟跑;网页端 / 管理台 / 桌面端零动作。**PK-1**:`ApprovalUnsettledCause` 多一词 `'parking_in_progress'` —— 对 cause 做 `never` 穷举的写法编译红一次;`kind` 联合仍三臂,按 `kind` 读的写法不受影响,既有对 `unsettled` 的有界重呈把它当「没落定」处理,默认安全(终端 `unsettled` → `retryLater`);`ToolApprovalFrameOutcome` 多可选位 `parking?`(对结局整只做键集等值断言的测试替身,在 202 形上多一键);管理台与桌面端的直调点必改(120d)。
|
|
9751
|
+
2. **零改的面**:0.93.0 §119 全部内容原样适用;没有并发的调用与 0.93.0 逐字节同;宿主卡口、`surfaceApprovalCard`、`FsApprovalWireDeps` 的形不变;流内活卡帧口与问答口不变。**PK-1**:200 回执及其余非回执 200 体的读法、`readToolApprovalRespondAck` 的每条纪律不变;耐久路径的结局型与 SH-1 的 join 不变;`ApprovalResolution` 联合的臂数不变。
|
|
9752
|
+
3. **成文改口**:① `FsApprovalWireDeps.onPresented`「这一次调用真把卡交给卡口时回调一次」补一臂 —— 本次调用 join 了另一路持有的决断时,持有者真交过卡 ⇒ 本路也回调一次(交回的就是那张卡的结局);② 「同一行被两条路各调一次 ⇒ 各呈一张卡、各发一次决断」作废(本版起同键单一持有);③ 「`aborted` = 本包发了一发中断拒绝」照旧成立,补一句:带 `joinedInFlight` 的 `aborted` 说的是同一只决断那一发中断拒绝(由持有者发);任一路的信号中止都中断这一只决断;④ 耐久口的卡请求恒带 `signal`(此前调用方没给信号时不带)—— 对卡请求做键集等值断言的测试替身多一键;⑤ **PK-1**:「活卡 respond 返回体不是 200 回执 ⇒ 没有回执、决断词即用户按的词」对 202 停驻体作废 —— 那是「没生效」,不是「已决断」;⑥ **PK-1**:「`unsettled` 一律不承诺字节已出站」对新 cause `parking_in_progress` 不成立 —— 它是「字节已出站、引擎答了停驻」,其余因由的成文不变。
|
|
9753
|
+
|
|
9754
|
+
**包侧缺口:** ① 问答类停驻(终端问答卡 + `HitlBridge.decideTool` 直发)不经本口,本登记管不到;终端的在飞台账在问答臂上照留,同形问题后续单独处理 · ② 流内活卡帧口(`hitl-frame:` 前缀的键)不进本登记:两个包内来路(流内帧 / 悬挂 ask)按引擎铸法互斥(推断,未实证),有复现再接同一张表 · ③ 匿名行(无 `toolCallId` / `boundCallId`,支持底线之下才有)身份键退 `taskId`,同 run 两条匿名行会被并成一把键(少做方向;KL-607)· ④ 同一进程装两份本包 ⇒ 两张登记表互不相见(KL-608)· ⑤ 持有者那张卡的卡口 Promise 永不落定(宿主撤卡不回 `retracted`、界面重挂丢了卡,也不理会卡上的中止信号)⇒ 同键后到者一并等、不再另呈一张(修前后到者会再呈一张);出路是任一路的信号中止(卡上的中止信号触发)或宿主按卡口契约回 `retracted` —— 卡口契约本来就要求每张卡都落定(KL-610) · ⑥ 卡口 `callKey` 本身在行有 call id 时不带 run:两个 run 恰好同名的 call 同时呈卡时,按 `callKey` 去重的宿主会把两张卡当一张(登记已按会话 + run 分开 —— 会话位是防御位,G-SH12c 盯;卡口键形本版不动)· ⑦ **PK-1**:活卡帧的消费与卡呈现仍串在同一个循环里(队头阻塞):停驻帧要等前面那张活卡落定才被处理,所以这一 cause 只在卡落定、respond 返回之后才读到 —— 解耦在 0.94.0 另行设计(CC-493)· ⑧ **PK-1**:非回执 200 体(赎回 `accepted` / 幂等回放 `idempotent`)仍读成「没有回执」,结局的决断词是用户按的词 —— 幂等回放的首决可能与之相反,以回体里的 `decision` 为准(推断;本版未改)· ⑨ **PK-1**:`decidePath` 的契约位候服务端登清单([9537] 预告;按键名读,不判形)· ⑩ **PK-1**:直调 `respond` 的宿主调用点(管理台 / 桌面端,120d)没有公面读口可用 —— 读器是包内件,上根入口要同批改接入档 §0a / §2 / §2b 的导出计数。
|
|
9755
|
+
|
|
9658
9756
|
## §119 🆕 0.93.0(2026-10-09)— 到期登记物硬删与 device 车道读器三态(型面 BREAKING)· 服务端 7.119.0 提货与一批新读口
|
|
9659
9757
|
|
|
9660
9758
|
> **开发依赖引擎换钉 `~7.44.0` 与生成表重生成(UP 行;CC-427,并为 CC-365 / CC-374 先放事实钉)**:构建期,不出包;包根导出差 +6 −1(`USER_STEER_UNDRAINED_CAUSES` 改名 `USER_INPUT_UNDRAINED_CAUSES`),`MODE_ARBITRATION` 多第 24 类 `classifier_no_ruling`;新常量先进生成表作事实钉,消费读口分别随 CC-365(`approvalReach`)/ CC-374(`detail.differs`)(处置表 UP-1;判据 G-UP1)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.1",
|
|
4
4
|
"description": "Client-side session runtime shared by every sema human client (TUI / web / desktop): sema wire frames (AgentEvent) -> CC session vocabulary (SDKMessage) with dual-plane output (transcript/chrome), deterministic transcript ids, lane discipline as a type, and the notification/dedup ledgers. Every CC-skin shape is collected here so the wire itself stays neutral. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|