@sema-agent/client-core 0.86.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +18 -12
  3. package/dist/adapt/arms.js +9 -0
  4. package/dist/adapter/downstream/eventToSdkMessage.js +14 -1
  5. package/dist/adapter/downstream/terminalToSdkResult.js +4 -1
  6. package/dist/adapter/downstream/wiringManifestView.d.ts +2 -0
  7. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  8. package/dist/adapter/runStream.js +75 -2
  9. package/dist/adapter/types.d.ts +3 -0
  10. package/dist/decideReceipt.d.ts +1 -1
  11. package/dist/decideReceipt.js +1 -1
  12. package/dist/detachWire.d.ts +6 -1
  13. package/dist/detachWire.js +22 -1
  14. package/dist/displayUntrusted.d.ts +4 -0
  15. package/dist/displayUntrusted.js +1657 -573
  16. package/dist/engineErrorCodes.d.ts +2 -0
  17. package/dist/engineErrorCodes.js +1 -0
  18. package/dist/engineNoticeCodes.d.ts +20 -0
  19. package/dist/engineNoticeCodes.js +71 -0
  20. package/dist/engineWireFor.d.ts +1 -0
  21. package/dist/engineWireFor.js +1 -1
  22. package/dist/gateOutcome.d.ts +4 -0
  23. package/dist/gateOutcome.js +5 -0
  24. package/dist/generated/engineFactTables.d.ts +1 -0
  25. package/dist/generated/engineFactTables.js +3 -0
  26. package/dist/generated/engineNoticeTables.js +2 -0
  27. package/dist/hitl/crashConverged.d.ts +2 -1
  28. package/dist/hitl/crashConverged.js +23 -3
  29. package/dist/hitl/hitlBridge.d.ts +4 -0
  30. package/dist/hitl/hitlBridge.js +6 -0
  31. package/dist/hitl/parkResolver.js +17 -12
  32. package/dist/hitl/planReviewWire.js +30 -10
  33. package/dist/hitl/suspendedReopen.d.ts +7 -0
  34. package/dist/hitl/suspendedReopen.js +38 -7
  35. package/dist/hitl/toolApprovalWire.js +4 -5
  36. package/dist/index.d.ts +7 -0
  37. package/dist/index.js +4 -0
  38. package/dist/promptDelivery.d.ts +20 -0
  39. package/dist/promptDelivery.js +153 -0
  40. package/dist/registryConflict.d.ts +3 -0
  41. package/dist/registryConflict.js +44 -0
  42. package/dist/request/taskRequest.d.ts +1 -0
  43. package/dist/request/taskRequest.js +25 -1
  44. package/dist/resumeRefusalCopy.d.ts +8 -6
  45. package/dist/resumeRefusalCopy.js +41 -19
  46. package/dist/rewindArchiveCapability.js +5 -0
  47. package/dist/seam.d.ts +12 -1
  48. package/dist/seam.js +7 -0
  49. package/dist/sessionMemoryErase.d.ts +76 -0
  50. package/dist/sessionMemoryErase.js +432 -0
  51. package/dist/subagent/engineSubagentResume.js +2 -1
  52. package/dist/toolHistoryMismatch.d.ts +63 -0
  53. package/dist/toolHistoryMismatch.js +425 -0
  54. package/dist/workflowClient.d.ts +3 -2
  55. package/dist/workflowClient.js +3 -3
  56. package/docs/INTEGRATION-CLIENTS.md +598 -13
  57. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -49,6 +49,134 @@
49
49
  > 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
50
50
  > commit 漏转在发布前就红,不再靠人记。
51
51
 
52
+ ## 0.88.0(2026-10-02)
53
+
54
+ > 主题:**minor** —— 十票同发(按票序)。① **展示出口凭据面一次扫描**(CC-247):`displayUntrusted` / `displayUntrustedMarks`(与本包合成终局行 / 结果帧 `errors[]` 铸点共用的凭据面)此前是几张识别网**串行改写同一份文本、再洗到不动点**;本版改为在一份只读的判别视图上一遍收齐全部候选(URL 结构 / 无 scheme 的 userinfo / 标签与方案词的值 / PEM 块 / 参数表 / 已知凭据字面形 / 控制串内容),按写死的优先序归并、落地;带凭据的输入在出口内部对落地结果再过一遍,到输出不再变为止(按改写遍数计、帽 8 次;实测遍数(含确认输出不再变的那一遍):差分门的随机 / 穷举 / 文法池与两条已知构造链至多 3 遍,非定向的自造文法串也见到 4 遍(门池收了一只),定向搜索构造的串至多 6 遍,都在帽内;干净文本一遍、逐字节同),一轮即不动对**帽内收敛的输入**由这只循环保证(定向构造可让改写遍数随长度增长;到帽交最后一次改写的输出,再过一遍只多遮不多露;KL-355)。带凭据的输入上输出字节变(凭据位上「多遮 / 记号位置变」,非凭据位上几形少遮);对上一发布产物做五池 × 十五出口全池差分,凭据位(= 本包认得的凭据标签 / 方案词的值位,与 URL 结构位:userinfo / query 值 / 片段)上「上一版遮、本版露」为 0(射程:差分门五池与门内追加的最小形之内;池外仍有上一版遮、本版原样的几形,逐形见 Known limits 口令禁字一条;本包铸点洗过再经展示出口的复合路径另见 KL-317)。② **崩溃收敛 `cause` 认第二个词 `shutdown_before_park`**(CC-218):服务端 7.108.0 起,有序关停截断了一条还没闭的腿时照列收敛行,修前这些行整行计入 `dropped`,本版照常分桶;同版服务端对未被追踪腿的 pending 孤儿改给 `resumeSafe:false`(本包零代码,分桶读数随之变)。③ **`server.model_unreachable` 用户面通告入册**(CC-270 ①):服务端自铸码受众表 +1 行(user)+ 事实读器 `readModelUnreachable`,修前按受众分发的端看不到它。④ **开发依赖换钉引擎 `~7.36.0` → `~7.37.1`**(CC-272):构建期事实表按 7.37.1 重生(通告码册 +1 `context.tool_turn_repaired`,运维面)、放行原因闭集镜像 `GATE_MODE_RELEASE_REASON_WORDS` 与判词谓词 `isGateModeReleaseReasonWord`、修复通告事实读器 `readToolTurnRepaired`。⑤ **会话所有者自助记忆抹除**(CC-264):调用口 `eraseSessionMemory` + 结局判定口 `sessionMemoryEraseOutcome` + 三只闭集镜像。⑥ **registry 写冲突的两种 409 分得开**(CC-280):`classifyRegistryConflict` / `isScopeGoneError`。⑦ **请求装配认得 `requireExistingSession`**(CC-281):车道表 +1 行 + 被拒读口 `requireExistingSessionRefusalFromError` 与一句 `requireExistingSessionRefusalContent`。⑧ **投递事实判定归包**(CC-271):提交事实账本 `createPromptDeliveryLedger` + 两只按消息行的读口;判据 = 引擎为这次提交**建了 run**。⑨ **plan 决断台账**(CC-278):被离门证据结掉、还没被投递口认领的那一笔登记,由随后到达的投递口认领原笔(不另铸刻度)。⑩ **`wiring_manifest` 帧的 `fileHistory` 段**(CC-279):这条腿捕不捕文件历史,可选成员 + 超集键。**为什么是 minor**:十六只新顶层导出;`CrashConvergedRow.cause` 型联合 +1 词、`EngineNoticeFactsCode` +2 员 / `EngineNoticeFacts` +2 臂(对它们做穷尽 `switch` / `Record` 的 TypeScript 端编译红一次,见 Changed 第 2 / 5 / 6 条);`WiringManifestChromeEvent.fileHistory?` / `WiringManifestView.fileHistory?` / `TaskRequestInput.requireExistingSession?` 三只可选位(对构造方 additive);展示出口输出字节、`SERVER_NOTICE_AUDIENCE` 行数、通告码册长度、`latestPlanReviewDecisionMark` 刻度等**已发导出的可观察变化**在 Changed 逐条单列(写明谁要跟)。型面 BREAKING 零处(对构造方)。根公面运行期导出 1356 → 1372(+16);测试钩 62 不变;公面类型名 922 → 942(+20);超集键 +1(`_sema_fileHistory`);零新投影臂(chrome `wiring_manifest` 臂多一只可选成员);请求装配车道表 44 → 45 行;`ENGINE_NOTICE_CODES` 80 → 81;`SERVER_NOTICE_AUDIENCE` 三行 → 四行;peer sdk 地板 `>=12.0.1` 不动;开发依赖引擎 `~7.36.0` → `~7.37.1`(构建期,不进运行期依赖)。
55
+
56
+ ### Added
57
+
58
+ - **`readModelUnreachable(notice)`** ⇒ `ModelUnreachableFactsView | undefined`(CC-270 ①;接入文档 **§114 MU-2**):服务端 7.108.0 起,一条 run 腿上某次模型调用以错误收场、且它最后一条请求在**建连**时就失败了(拒连 / DNS / 建连超时 …)时,给这条腿的用户发一条 `engine_notice`,码 `server.model_unreachable`(每腿每目标一次)。读器交出五位:`code`(建连失败的底层码,服务端今天六词:`UND_ERR_CONNECT_TIMEOUT` / `ECONNREFUSED` / `ENOTFOUND` / `EAI_AGAIN` / `EHOSTUNREACH` / `ENETUNREACH`;开集原样透传)、`targetHost`(够不着的模型端点 `host:port`)、`proxyInUse?`(这一跳走了代理时代理取自哪个环境变量 —— 只是**变量名**;直连缺席)、`remedy`(服务端给的一句补救话,原样)、`sessionId`。`code` / `targetHost` / `remedy` / `sessionId` 任一读不出(只认 `detail` 的自有属性,原型链上的同名键不算)⇒ 整只 `undefined`;`proxyInUse` 读不出只省这一键。每一位恰读一次,读点不抛。按码派发口 `readEngineNoticeFacts` 同批多认这一码(`audience: 'user'`)。本包不抄服务端的通告句与补救句 —— 要渲给人时用服务端给的 `message` / `remedy` 原句。
59
+ - **放行原因的闭集镜像**(CC-272;**§114 RR-1**):`GATE_MODE_RELEASE_REASON_WORDS`(冻结数组,今天一词 `rule_unreadable`)就是构建期从引擎包入口生成的那张表本身(不手抄);`isGateModeReleaseReasonWord(v)` 答「这个词本版认不认得」,与引擎自己的成员判定逐值同答;成员型 `GateModeReleaseReasonWord` 由同一张表派生。🔴 它们只给端判词:`gateOutcomeOf` / `gateModeRelease` 读出的 `released.reason` 仍按开集透传 —— 比本包新的引擎加的词原样带回,不折成 `rule_unreadable`、不丢、不让整只放行账缺席;谓词对它答 `false`,端原样显示或走通用句。
60
+ - **`context.tool_turn_repaired` 的事实读器 `readToolTurnRepaired(notice)`**(CC-272;**§114 TT-2**)⇒ `{ repairs: [{ form, toolCallIds }], sessionId, runId } | undefined`,挂进 `readEngineNoticeFacts`(受众 `operator`)。`form` 按开集透传(引擎今天四词 `trailing_text` / `late_result` / `missing_result` / `duplicate_result`;引擎没有从包入口导出这张词表);`toolCallIds` 是引擎的调用 id、按调用序、非空。`repairs` 缺席 / 空表、任一条读不出(`form` 非空串、`toolCallIds` 非空的非空串名单)、`sessionId` / `runId` 缺席 ⇒ 整只 `undefined`(半张修复清单比没有更坏);只认自有属性、每格只读一次、永不抛;名单与每一条都冻结。
61
+ - **会话所有者自助记忆抹除:调用口 `eraseSessionMemory` + 结局判定口 `sessionMemoryEraseOutcome`**(CC-264;**§114 SE-1 … SE-6**):
62
+ - `eraseSessionMemory({ sessionId, requestId, allowUnevidenced? }, wire, opts?)` 发**一次** `POST /v1/sessions/:id/memory/erase`(不重发:5xx / 429 / 503 同样只发一次),交回传输层事实 `SessionMemoryEraseAnswer`:`not_sent`(可证一个字节都没送出:入参坏 / 没有可用连线或连接阶段就失败 / 调用前已取消)、`answered`(HTTP 状态 + JSON 体)、`no_answer`(可能已送到、没拿到可读答复:截止 / 连接中途断 / 发出之后取消 / 说不出没送出)。永不抛。
63
+ - 体由本包新铸:恰好 `{ requestId }`;调用方对象**自有**的布尔 `allowUnevidenced` 才带上(原型链上继承来的不算),缺席时**不补** `false`;调用方对象上别的键(包括 `select`)一个都不上 wire。`requestId` 由宿主铸(一次抹除动作 × 一个会话一只),本包不铸、不改、不去空白。会话 id 是 `.` / `..`、或含未配对的代理码元(路径段编码不了)时本地拒、零请求(URL 解析会把点段吃掉,请求会被改投到别的路径)。
64
+ - `wire` 是与 `makeEngineWireClient` 同一份的连线配置(`baseUrl` / `token`〔串、每发读一次的取值函数、或 `{ mode: 'same-origin-relay' }`〕/ `principal` / `timeoutMs`〔缺省 60 s〕/ `fetchImpl`);出站头与 `makeEngineWireClient` 造的 client 逐字节同(凭证三态、principal 归一、浏览器宿主里带凭证的形不发、同源中继形零 `Authorization`)。已装目标(`EngineWireTarget`)直接可用。凭证不进答复、不进结局、不记日志。
65
+ - `sessionMemoryEraseOutcome(answer)` 是纯函数,结局闭集四档:`erased`(收执 `status: "complete"`)/ `partial`(`"partial"`)/ `refused`(**确知什么都没抹**:没送出,或引擎在门序里 / 改动之前按具名码拒)/ `unconfirmed`(**说不清抹没抹**:没答复、收执读不出或不是这一次的、一码两义的拒、未分类的拒、没有引擎机读码的非 2xx)。每档带一句单源英文人话 `text`(拒档恒以 `Nothing was erased` 起头,没法确认档恒以 `Not confirmed` 起头;不复述服务端原句)与重发姿势 `retry` + `retryText`(七值闭集:`not_needed` / `same_request_id` / `new_request_id` / `needs_operator` / `needs_consent` / `human_decision` / `pointless`)。引擎答了时带 `status` / `errorCode`(诊断用)。已抹 / 部分两档带收执(`readMemoryEraseReceipt` 的读数,数几条走 `memoryEraseCounts`)。永不抛,读不了的入参落 `unconfirmed`,绝不落「没做」。
66
+ - 三只冻结闭集镜像:`SESSION_MEMORY_ERASE_REFUSAL_REASONS`(12)/ `SESSION_MEMORY_ERASE_UNCONFIRMED_WHYS`(9)/ `SESSION_MEMORY_ERASE_RETRIES`(7)。两代服务端逐码 → 档见接入文档 §114a-2(服务端 7.108.0 起把三只 409 与控制面 500 逐码转发;更老的服务端同四形落 500 `internal.error` ⇒ `unconfirmed` / `engine_fault`,如实,不是本包少认)。
67
+ - **registry 写冲突的两种 409 分得开**(CC-280;**§114 RC-1 … RC-3**):registry 的配置写门 / 回滚门在同一个 HTTP 409 上答两件相反的事 —— 普通的乐观锁冲突(重读、改基线、再写一次即可),与「写的目标空间在途中被删、或删了又同名重建」(机器码 `scope_gone`:什么都没写;重读读到的是替身空间,原样重发会把旧草稿写进一个没人审过的空间)。`classifyRegistryConflict(status, body)` 返回三词闭集 `RegistryConflictClass` —— `'gone'`(409 且机器码是 scope-gone)/ `'conflict'`(其余任何 409)/ `'none'`(不是 409),与新版 SDK 子路径里的同名函数同名同形、逐例同答(机器码读法三步:`errorCode` → 对象形 `error.code` → `error` 串)。`isScopeGoneError(err)` 对 catch 到的错误答布尔:带原样响应体的 registry 错误按体判,新版 SDK 的两只 scope-gone 错误类按类名 + 409 认;本包不出错误类。本包支持的 SDK 版本(peer `>=12.0.1`)上没有这两名,所以是包内实现而不是转口;peer 地板不动。「逐例同答」的射程是 JSON 解析出来的体;与 SDK 刻意不同的两处都只在宿主自造的对象上出现:① 409 上读不出机器码(体上取值器 / 代理抛)时不抛、答 `'gone'`(停下不重发的那一边);② 体上的取值器每次读答不同时,本包每一位只读一次、按那一次读数判,SDK 同一位读多次,两边可能不同答。`isScopeGoneError` 对新版 SDK 的两只错误类按类名认,类名被打包器改写或子类改了 `name` 时判不出(答 `false`;KL-339)。`'conflict'` = 「不是 scope-gone 的 409」,不等于「重试必过」。
68
+ - **请求装配认得 `requireExistingSession`**(CC-281;**§114 RE-1 … RE-3**):`TaskRequestInput.requireExistingSession?: boolean`(型取自 SDK `TaskRequest.requireExistingSession`):`true` = 只续已有会话,会话不在时服务端在任何东西跑起来之前拒,而不是静默新开一个同 id 的空会话。车道表 +1 行:interactive / print 有座、live 门后;utility 无座(那条车道每次提交都用自己的独立会话 id)。本层只发字面 `true`(`false` 与缺席同义、不发、不进回执);非布尔坏值装配期拒;`true` 而 `sessionId` 缺席 / null / 空串 / 非串 ⇒ 装配期按名拒(错误文本写明「没有可续的会话」),不留给服务端。
69
+ - **「只续已有会话」被拒的读口与一句话**(CC-281;**§114 RF-1 / RF-2**):服务端对这一键的两种拒绝(会话不在 ⇒ 404;要求续却没给会话 id ⇒ 422)今天都不带专属码 —— wire 上 `errorCode` 是按状态补的通用码(`not_found.resource` / `request.unprocessable`),专属码只出现在消息末尾的括注 `(resume.session_not_found)` 里;引擎侧同步提交那一形带专属码、404。`requireExistingSessionRefusalFromError(err)` ⇒ `{ code, form: 'session_not_found' | 'session_id_missing' } | null`(三形都认;子代续跑面同码的 409 不归它);`requireExistingSessionRefusalContent(detail)` 两形各一句(都说明没有新开会话),表外形给两形都为真的通用句。
70
+ - **投递事实判定归包**(CC-271;**§114 PD-1 … PD-3**):`createPromptDeliveryLedger()`(提交事实账本出厂口)、`promptKnownUndelivered(ledger, message)` / `withoutUndeliveredPrompts(ledger, messages)`(按消息行的两只读口);型 `PromptDeliveryLedger` / `PromptDeliveryRecord`。账本两只**只增不删**的集合(attempted / delivered),按消息 uuid 记、一次记整批:`attempted(batch)` 记在提交路径第一拍,`deliveredByFrame(batch, event)` 吃引擎流上的原样 `AgentEvent`,`deliveredBySteerReceipt(batch, outcome)` 吃 409 自愈结局;`isAttempted` / `isDelivered` / `knownUndelivered`(= attempted ∧ ¬delivered)/ `batchOf` 四只查询;`toRecords()` / `fromRecords(records)` 的记录形 `{u, s:'a'|'d'}` 逐行 JSON 可落盘、可读回。判据:引擎为这次提交**建了 run** 的帧才算交出去 —— 🔴 409「会话已有在跑的 run」那一帧不算;**durable 腿流首帧 `meta`、开流审批卡 preamble 重放(`approval_request`)与撤卡帧(`approval_revoke`)也不算**(服务端在建 run 之前就写它们,会话被占时 409 帧跟在它们后面);拒收之后自愈把消息递进在跑 run、处置分类为 `handed-off` 的结局算。没走过提交路径的行两判皆假(不知道)。每个写口返回本次新增的记录。零 IO、零文案:提交批怎么从自己的消息表里划、落盘、渲染归宿主。
71
+ - **`wiring_manifest` 帧的 `fileHistory` 段**(CC-279;**§114 FH-1 … FH-3**):`WiringManifestChromeEvent` / `WiringManifestView`(非流式提交回执 `readSubmitWiringManifest` 同一张)多一只可选成员 `fileHistory?: string` —— **这条腿捕不捕文件历史**,今天两词 `"on"` / `"disabled"`,开集原字节透传(第三个词原样交给端,按未知处理)。帧上该键是**自有**非空串才在场;非串 / 空串 ⇒ 段缺席(与服务端上 wire 前丢键同尺);原型链上的同名键不算。🔴 缺席 = 老服务端 / 老引擎 / 外部 derive 没报,不折 `"disabled"`、也不当「在捕获」;`"disabled"` 也**不等于**「不能还原」(部署捕获位关时已存历史照常服务还原;部署形看能力位 `fileHistoryCapture`,本位答的是这一条腿)。内部臂超集键 `_sema_fileHistory`。只此一段的帧也成臂(修前整帧 `not_in_slice`)。子流帧照旧断闸。0.85.0 起登记的「这一段不投」(KL-245)收口。
72
+ - 公面合计:根入口运行期导出 +16(CC-270 ① `readModelUnreachable`;CC-272 `GATE_MODE_RELEASE_REASON_WORDS` / `isGateModeReleaseReasonWord` / `readToolTurnRepaired`;CC-264 `eraseSessionMemory` / `sessionMemoryEraseOutcome` / `SESSION_MEMORY_ERASE_REFUSAL_REASONS` / `SESSION_MEMORY_ERASE_UNCONFIRMED_WHYS` / `SESSION_MEMORY_ERASE_RETRIES`;CC-280 `classifyRegistryConflict` / `isScopeGoneError`;CC-281 `requireExistingSessionRefusalFromError` / `requireExistingSessionRefusalContent`;CC-271 `createPromptDeliveryLedger` / `promptKnownUndelivered` / `withoutUndeliveredPrompts`);测试钩不变;公面类型名 +20(`ModelUnreachableFactsView`;`GateModeReleaseReasonWord` / `ToolTurnRepairedFactsView` / `ToolTurnRepairView`;`SessionMemoryEraseWire` / `SessionMemoryEraseCall` / `SessionMemoryEraseOptions` / `SessionMemoryEraseSent` / `SessionMemoryEraseNotSentWhy` / `SessionMemoryEraseJson` / `SessionMemoryEraseAnswer` / `SessionMemoryEraseRefusalReason` / `SessionMemoryEraseUnconfirmedWhy` / `SessionMemoryEraseRetry` / `SessionMemoryEraseOutcome`;`RegistryConflictClass`;`RequireExistingSessionRefusalForm` / `RequireExistingSessionRefusalDetail`;`PromptDeliveryLedger` / `PromptDeliveryRecord`);`CrashConvergedRow.cause` +1 词;`EngineNoticeFactsCode` +2 员;`WiringManifestChromeEvent` / `WiringManifestView` +1 可选成员;`TaskRequestInput` +1 可选位;超集键 +1。
73
+
74
+ ### Changed
75
+
76
+ 🔴 **已发导出的可观察变化(逐条;按旧行为断言过的测试请按接入文档 §114a′ 改锚)**:
77
+
78
+ 1. **展示出口的凭据面输出字节**(CC-247;**§114 DU-1 … DU-6**):`displayUntrusted` / `displayUntrustedMarks` 与本包合成终局行 / 结果帧 `errors[]` 上的凭据洗法,在下列各类带凭据的输入上与上一版字节不同(每类一例;`<口令>` / `<值>` / `<尾>` 代表凭据样的字串;干净文本逐字节同、全部出口一轮即不动 —— 带凭据的输入由出口内部的不动点循环在帽内保证(按改写遍数计、帽 8 次;实测遍数(含确认那一遍):差分门的随机 / 穷举 / 文法池与两条已知构造链至多 3 遍、非定向的自造文法串也见到 4 遍、定向搜索构造的串至多 6 遍;定向构造可让遍数随长度增长、到帽,KL-355),`escapeBackslashes` 开着时除外,与此前同)。**谁要跟**:按字节断言凭据输出的测试格改成「不含值 ∧ 含 `«redacted:`」两条独立断言(§114a′ 第 1 条);按产物字节登记锚的门换钉当天重跑(§114d)。
79
+ - 标签 / 方案词后的引号值头上是带主机的 `user:<口令>@host`:键、标签、引号留在原处,userinfo 记号落在引号里,地址后隔空白的尾巴换 `secret` 记号 —— `{"password":"u:<口令>@host/ <尾>"}` ⇒ `{"password":"«redacted:userinfo»@host/ «redacted:secret»"}`(此前 JSON 键与开引号被吞进 userinfo 记号、尾巴原样;KL-193 收口)。标签值读成无 scheme userinfo 地址时,最后一枚 `@` 的主机[:端口]之后紧贴、却不是路径 / query / 片段起头的尾巴是这只值的余下部分,照遮到值末(`"password":"To:<…>admin:<<口令>@db:5432&x=<值>` ⇒ `"password":"«redacted:userinfo»@db:5432«redacted:secret»`;上一版两只值都露 —— `To:<…>` 那一截被读成 userinfo,口令与 `<值>` 原样);只剩标点 / 引号的尾巴不动。
80
+ - 引号值是 `scheme://` 地址、地址后隔空白还有文字:空白之后到闭引号换 `secret` 记号(此前尾巴原样;KL-233 收口)。尾巴里又以一只地址起头(`token:"u:<口令>@h https://h/x <尾>`)时,那只地址同样只到空白为止,之后的文字照遮(此前整截按「像地址」放过);里层标签紧贴外层引号值的闭引号(`"<地址> token":<值>`)时,闭引号与分隔留在记号外,洗过的产物再洗一遍不变。无标签、单引号包着的 `user:<口令>@host`:口令换记号(此前原样;KL-234 收口);反引号包着的同形此前也遮,但开头的反引号被吞进记号,本版反引号留在原处;「口令以 `'` 起头 ∧ 主机右界恰是 `'`」的单引号串(`email:'bob@example.com'`)不算 userinfo。用户名整枚是一枚记号(`«redacted:query»:<口令>@host`)⇒ `«redacted:userinfo»@host`(此前口令原样;KL-235 收口)。
81
+ - 无 scheme userinfo 的用户名不再向左吞过定界字符(空白与 `" ' ` ( ) [ ] { } < > | \ ^ , ; =`):`token=u:<口令>@host.example/x` ⇒ `token=«redacted:userinfo»@host.example/x`(此前 `token=` 也进记号);`x(a:<口令>@host/p)` ⇒ `x(«redacted:userinfo»@host/p)`。标签左边紧贴、无标签无形状的裸串按原文显示(此前随用户名落进记号,是向左吞的副作用;KL-318)。空用户名的 `:<口令>@host` 无 scheme 也遮。口令段含双引号 / 反引号 / 尖括号的无 scheme `[用户名]:口令@主机` 默认不算 userinfo(`{"a":"b@c"}`、`To:<bob@example.com>` 不读成 userinfo);用户名紧跟凭据标签 / 方案词(`password=admin:"<口令>"@db`、`Authorization: Basic admin:"<口令>"@db`),或用户名是裸词、主机成形、地址不被引号包着(`connect failed: admin:p"<口令>@db:5432`、`ssh root:"<口令>"@10.0.0.5`、`admin:<<口令>@db`)照遮为 userinfo,与上一版同;用户名本身就是凭据标签或方案词 + 冒号(`token:u<<口令>@db`、`password:<<口令>>@db`、`auth_token:"pass"<口令>@db`、`Authorization:Basic"<口令>"@db`、`bearer:u<<口令>@db>`)照遮为 userinfo —— 只有词级网开着、且这枚标签的值真盖到 `@`(引号值闭在 `@` 之后 / 裸值一路没有停字符)才让给词级网,只开 URL 结构面的出口同遮,与上一版同字节;标签 / 方案词的裸值停在口令禁字上、其后到 `@主机` 没有断字也没有下一枚标签(`secret=u<<口令>@db`、`Authorization: Bearer u<<口令>@db`)⇒ 遮到 `@` 前(上一版也原样);其余几形仍原样(相对上一版少遮,KL-323 逐形列出);`email:"bob@example.com tail"` 一类与上一版同字节多遮(KL-351)。
82
+ - 片段里的标签值伸出未编码的停字符:片段与尾巴取并、整只按 `secret`(`https://h:1/v1#api_key=AB|<尾>` ⇒ `https://h:1/v1#«redacted:secret»`;KL-68 的这一形收口)。值的遮盖之后隔着不可见单元再紧贴词字符 ⇒ 遮盖续到那一截词的末尾(`Authorization:N<ESC>response=h(<ESC>c` ⇒ `Authorization:«redacted:secret»`)。带 scheme 地址的 query 值 / 片段在 `,` / `;` 后紧跟「凭据标签 + 分隔 + 空白」或「方案词 + 空白」时断开、让给词级网(`?k=',api_key: <值>` ⇒ `?k=«redacted:query»,api_key: «redacted:secret»`,此前值原样);这里的空白只认 ASCII 空白 / 控制符(片段扫描自己在那里止),分隔之后是不换行空格 / 表意空格 / 各宽空格 / 谚文填充 / 盲文空点时不断 —— 它们是片段值里的字,整只值照按结构遮(与上一版同字节,只开 URL 结构面的出口同遮);`;token=<值>` / `,token=<值>` / `,password:<值>` 是 URL 自己的参数语法、值在片段里,不断,照按路径段参数 / query / 片段 / userinfo 遮(与上一版同字节)。
83
+ - 上游预先带记号的输入:值以一枚记号起头、记号后不紧贴词字符 ⇒ 这只值就是那枚记号,后面隔着非词字符的明文不再并进(`token=«redacted:query»&<值> done` 原样;此前第二遍把它并成 `token=«redacted:secret» done`;KL-317)。紧贴词字符、或隔不可见单元再紧贴的照旧遮;记号后紧跟凭据名字而名字后不是分隔(`password=«redacted:secret»password!<值>`)、或名字与分隔之间隔着点而分隔后还有明文,照旧遮。URL 的 userinfo 位只有整段是记号才不动(`https://***:<口令>@<主机>/` 照遮);退役占位 `***` 本版不再铸,占位后还有内容(`"***@<值>"`、`***:<值>`)照遮。query 值 / 片段 / 路径段参数值是「记号 + 尾标点 + 屏上画成点 / 转义记号的空白控制符或不可见单元 + 值」时照遮(本包机读口按真空白断开交出的 `?k=«redacted:query»:<CR><值>`,再过点形 / 转义形出口时与值粘成一截;与上一版同遮);复合路径的其余形见 KL-317。
84
+ - 不再插入记号、不再把「记号 + 下一枚标签」再吞一遍(`Credential://'e://@` ⇒ `Credential:«redacted:secret»'e://@`,此前在 `@` 前插一枚 userinfo 记号;`Authorization:tp://#>Authorization:` ⇒ `Authorization:tp://#«redacted:fragment»Authorization:`,此前第二遍把 `>Authorization:` 并进片段记号);此前要调用方再洗一遍才稳定的形,本版在出口内部的一次调用里给出终形;标签值与 userinfo 候选取并、值伸得更远时记号种类是 `secret`(端不要按记号种类分支)。PEM 块体整段是一个控制串时,控制串里的标签值照遮、块体不再另铸一枚记号;块头在读面上认不出(裸 ESC / C1 CSI 紧贴 `-----BEGIN`,判别视图把它读进一段序列)的块不划不透明区,块里的标签值照遮(与上一版同)。块头在读面上认:头行词间的空格换成零宽空格 / 软连字符 / RLM / BEL 等不可见单元时与空格同读,块体照遮、不透明区照划(`-----BEGIN<U+200B>PRIVATE KEY-----\n<主体>\n-----END PRIVATE KEY-----` ⇒ 主体一枚记号;上一版只在默认形 / 转义形遮,机读口与字符面全关 / 点形 / 保排版出口原样)。
85
+ - 点形 / 转义形载体上:值左邻被画成 `.`(或写成转义形)的不可见单元留在记号左侧(`api_key: <ESC>M<值>` 点形 ⇒ `api_key: .«redacted:secret»`);空主机 userinfo 前面隔换行的上一行末的词随用户名进记号(点形 / 转义形上换行不再断开用户名;机读口、默认形照旧按换行断开;KL-181 形变)。
86
+ - 链接后紧跟结构终止符、再往后才有 `@` 的干净文本不再并进 userinfo(少遮方向,非凭据位):带 scheme 的地址片段只在「停字符恰在 `://` 之后,或 `://` 与停字符之间有一枚冒号」时跨过 `" < > | \ ^ { }` 与反引号(闭形记号里、开头闭合方括号主机字面里的冒号不算;口令位上的停字符照旧整段进记号:`https://u:p"w@host/x`、`https://u.v:"<口令>@h/` ⇒ `https://«redacted:userinfo»@…`,与上一版同)。`{"url":"https://example.com","email":"bob@example.com"}`、`<a href="https://[2001:db8::1]">bob@example.com</a>`、`url=https://[::1]|owner=bob@example.com` 原样(此前链接主机到邮箱用户名整段换进 userinfo 记号)。带端口的链接后紧跟停字符再有邮箱(`<a href="https://example.com:8080">bob@example.com</a>`)与上一版同样多遮(authority 里有冒号,停字符可能在口令位,取遮的一侧;KL-325);链接后紧跟 `)` `[` `,` `;` 再有邮箱同样(KL-324)。
87
+ - 不变的:干净文本逐字节同;字符面(控制符 / 双向与格式字符 / 行折平 / 名字位空白)、封长与标记位置读口不变;诊断词闭集、`max_tokens` 计量单位、方案词后的普通英文词等误洗收窄各形不变;`DisplayUntrustedOptions` 各位语义不变。
88
+ 2. **`projectCrashConverged` 认 `cause: 'shutdown_before_park'`**(CC-218;**§114 SB-1 / SB-2**):服务端 7.108.0 起,有序关停(SIGTERM / 排空宽限窗满)截断了一条还没闭的腿时,下一次启动照列一条收敛行,`cause` 是 `shutdown_before_park`(进程崩了仍是 `crashed_before_park`)。修前本包把这一词当「别族的行」整行计入 `dropped`;本版这些行照常分桶。**分桶与 `needsHumanReason` 一字未改、也不看 `cause`**:常态是人已批、工具可能执行到一半(`decided` ∧ `resumeSafe:false`)⇒ needsHuman / `approved_then_interrupted`,与崩溃截断的已批腿同一句因由;罕见的 `pending` 形(关停时那张卡的结清写入挂住)按 `resumeSafe` 照旧分桶。`cause` 原样交到端上(本包不把新词折成旧词),**措辞归端:这类行是有序关停后的结清,不要说成「引擎崩了」**。词表外的 `cause` 仍整行 `dropped`(闭集)。**类型面**:`CrashConvergedRow.cause` 由 `'crashed_before_park'` 放宽为 `'crashed_before_park' | 'shutdown_before_park'` —— 对 `cause` 做穷尽 `switch`(带 `never` 兜底)或穷尽 `Record` 的 TypeScript 端**编译红一次**,补 `shutdown_before_park` 一臂;按 if 链读、或只把 `cause` 原样转述的端不受影响。**谁要跟**:按「这类行计入 `dropped`」断言的格改锚(§114a′ 第 5 / 6 条);崩溃遗留通告措辞写死「crash」的端改句(§114d)。
89
+ 3. **崩溃收敛的分桶读数随服务端变**(本包零代码;服务端 7.108.0;**§114 RS-1**):服务端对**未被追踪的腿**(零窗口 / 后台 run 腿 / 委派子代)上的 pending 孤儿改给 `resumeSafe:false`(没有腿上的证据就不断言「工具零执行」;被追踪腿的 pending 孤儿仍是 `true`)。`projectCrashConverged` 照旧只信 `resumeSafe` ⇒ 这些行从 `resumeSafe[]` 挪到 `needsHuman[]`、因由 `pending_unsafe`。端上表现:后台 run 崩溃后要人确认的行变多、可自动重跑的行变少 —— 这是服务端要的方向。更老的服务端上同一形照旧落 `resumeSafe[]`。`contradictory` 判据(`decided` ∧ `resumeSafe:true`)不变。
90
+ 4. **`SERVER_NOTICE_AUDIENCE` 三行 → 四行**(CC-270 ①;**§114 MU-1 / MU-3**):+`server.model_unreachable: 'user'`。随之 `engineNoticeInCatalog('server.model_unreachable')` 由 `false` 改答 `true`、`noticeAudienceOf` 由 `'operator'`(表外保守缺省)改答 `'user'`、`readEngineNoticeFacts` 由 `undefined` 改答 `{ code, audience: 'user', facts }`;派发表用户面码 12 → 13。**谁要跟**:按受众分发通告的端零改动即得(这一码从运维面 / 册外兜底挪到用户面);按「`SERVER_NOTICE_AUDIENCE` 恰三行」或「派发表用户面码恰十二个」断言的格改锚(§114a′ 第 7 / 8 条)。
91
+ 5. **通告码册 80 → 81**(CC-272;**§114 TT-1 / TT-3**):`ENGINE_NOTICE_CODES` +`context.tool_turn_repaired`(紧跟 `route.tool_call_id_folded`);`engineNoticeInCatalog('context.tool_turn_repaired')` false → **true**;`noticeAudienceOf` 答 `'operator'`(修前册外码按保守缺省同答 `'operator'`,答案不变、出处改为受众表);`ENGINE_NOTICE_AUDIENCE` 多这一键;`readEngineNoticeFacts` 对这一码由 `undefined` 改为 typed 读数(`audience: 'operator'`);派发表运维面码 3 → 4。这一条通告引擎铸给宿主,已发布的服务端只写进运维日志、**不放上**客户端的事件流 —— 三端经服务端承载的会话今天收不到它。**谁要跟**:对 `EngineNoticeFactsCode` 做穷尽 `Record` / `switch` 的 TypeScript 端补两行(本条与第 4 条各一码,否则编译红;按 `if (f.code === …)` 只认已知几码的端不受影响);按「码册恰 80 员」/「运维面 typed 码恰三个」断言的格改口(§114a′ 第 9 条)。
92
+ 6. **会话历史错配的出现频次随引擎变**(本包零代码;CC-272;**§114 TT-5**):0.87.0 的判型 `classifyToolHistoryMismatch` 与合成终局行键 `_sema_tool_history_mismatch` 一字未改。引擎 ≥ 7.37.1 在请求出门前修掉四形(调用之后跟着别的块 / 结果记在更后面 / 调用没有结果 / 同一调用两条结果),这几形不再让 provider 回那句 `tool_use ids were found without tool_result blocks immediately after`;转录不改写,之前写坏的会话在下一次请求自愈(那时一次成功的结局把连续次数清零,宿主不用做任何事)。仍会出 400 的形照旧被判型认出、照旧给出路句:同一条助手消息里两只同 id 的调用、宿主经旁路查询自带的历史里的孤儿 / 先于调用的结果、以及引擎 < 7.37.1 上的全部三形。用户拿到这一修复要等宿主所接的服务端带上引擎 ≥ 7.37.1。修复通告不上客户端的流 ⇒ 端不能据它抑制这只键(KL-308 射程句同批补)。
93
+ 7. **开发依赖引擎 `~7.36.0` → `~7.37.1`**(CC-272;构建期,不进运行期依赖):构建期生成的引擎事实表按 7.37.1 重生成(既有表值不变;码册 +1 见第 5 条;第四批生成放行原因表)。生成器自本版起要求开发依赖引擎 ≥ 7.37.0(更老的引擎包入口没有放行原因表 ⇒ 生成器拒生成并点名缺的那一张,不回落去读私有路径)。
94
+ 8. **`buildTaskRequest` / `assembleTaskRequest` 对 `requireExistingSession`**(CC-281;**§114 RE-1 … RE-5**):修前这一键是表外键 ⇒ 装配口抛 `TypeError`「入参带了本包不认识的键」;本版 interactive / print 有座(live 门后,非 live ⇒ 回执 `not_live`)、utility ⇒ 回执 `off_lane`(带 `sessionId` 时;`true` 而无会话 id 不分车道一律装配期拒);`true` 而无可续会话 id ⇒ 专句拒;坏值 ⇒ 专句拒。不带这一键的装配逐字节同 0.87.0。**谁要跟**:按「交这一键会被拒」断言的格改锚(§114a′ 第 12 条)。
95
+ 9. **plan 决断台账:离门证据结掉的「已交出、未认领」决断由投递口认领原笔**(CC-278;**§114 DL-1 … DL-3**):宿主经 `notePlanReviewDecisionHandedOver` 登记了一次决断、本包投递口还没认领它的那一段里(宿主等这道门的实例快照读回来的窗内,或快照放行之后、投递调用到达本包之前的那串微任务里),宿主若调了 `notePlanReviewGateLeft`(409 体指名别的门 / 状态词不再是 `needs_review`),修前这一笔被结掉、随后到达的投递口找不到可认领的登记而另铸一笔,`latestPlanReviewDecisionMark` 随之前进 —— 宿主按登记刻度记下的门实例快照与「没生效」告知都对不上这一发(同一道门仍待决、POST 失败时那一句告知整个不出)。本版投递口的认领顺序是:未结算的登记 > **最近一笔**被离门证据结掉、还没被认领的登记 > 另铸 —— 那一发仍是登记的那一笔,交出刻度不变;认领那一拍撤回离门那次结算(连同它留下的「没生效」注脚),从认领到投出结局重新算在飞(与修前另铸的那一笔同判:POST 在飞时重开口拒开,读起点早于结局的快照判陈旧),结局投出时由本包结算。只有被离门证据结掉的登记会被再认领:在离门证据**之前**宿主自己 `settle()` 过的、`revoke()` 掉的,以及已投过结局的、已被认领过的都不会;离门证据之后句柄两口是空动作,那一笔仍可被认领(KL-348);新的一次决断照旧拿新刻度。不变:离门证据本身(照旧结算这条 run 名下全部未结算的笔)、投递口闩、容量规则、结局正文与机读位(三种失败形与不登记时逐字节同)。**谁要跟**:按「登记 → 离门 → 投递之后刻度前进」断言的格改锚(§114a′ 第 16 条);用 `notePlanReviewGateLeft` 充当「本包已结算」的测试替身改用登记句柄的 `settle()`(§114d)。
96
+ 10. **`wiring_manifest` 帧的 `fileHistory` 段投影**(CC-279;**§114 FH-1 … FH-3**):`eventToSdkMessage` / `adapt()` / `runStream` 的 chrome `wiring_manifest` 事件在帧带这一段时多一键 `fileHistory`,内部臂多超集键 `_sema_fileHistory`;只带这一段的帧由 `not_in_slice` 改为成臂;`readSubmitWiringManifest` 对只带这一段的回执由 `unreadable` 改答 `manifest`。**谁要跟**:按「`wiring_manifest` 事件键集恰为 …」断言的格加这一键(present-iff;§114a′ 第 17 条)。
97
+
98
+ ### Gates
99
+
100
+ - 新门 `scripts/run-display-untrusted-baseline-diff-test.mjs`(常驻;CC-247):凭据面对**上一发布产物**逐字节差分。基线 = 上一版 tarball(`SEMA_DU_BASELINE_TGZ` 指路径;缺席 ⇒ 差分段报 SKIPPED-SECTION、整门 PARTIAL,不当绿)。五池(定种子随机串两池 + 引号值 / userinfo 穷举形两池 + URL 参数分隔池:`;` / `,` 分隔的「名 = 值」落在路径段参数 / query / 片段 / userinfo 位)加一只最小回归形池,去重后 71 411 串 × 十五出口 = 1 071 165 格。B1 凭据位「上一版遮、本版露」= 0(无角色的随机池按整串预建的结构区间判位,不设固定回看窗);B2 只开 URL 结构面的出口按它自己的射程判;B3 包内三份文档的干净行过机读口与字符面全关出口逐字节不变;B4 一轮即不动(十四出口,含封长;另并进一只 64 512 串的全积文法池,只进本格与 B6);B6 凭据面不动点循环在全部池 × 五只出口上到帽 0 次(帽按改写遍数计 8 次;到帽 = 改写到帽之后另给的那一遍确认仍在变);B5 常见干净形不多遮(HTML 链接 / markdown 链接 / JSON 链接 + 邮箱 / 管道表 / CSV / 版本库远端地址 / CSS `url()` / `<br>` 分隔手写 23 形 × 十四出口 = 322 格逐字节不变;上一版也多遮的 6 形按 KL-324 / KL-325 豁免、不算绿,有基线时核「本版多遮的出口上一版也多遮」);B0 判别力自证。对 0.87.0 的读数(本版最后一次实跑):差异 188 261 格 · 旧露新遮 84 519 · 露出同字节异 102 505 · 旧遮新露 凭据位 0 / 只开 URL 结构面出口射程内 0 / 非凭据位(标签之前的裸串 1 032 · 被裸串粘住认不出的标签的值尾 24 · 非凭据头的尾巴 120 · 随机池结构判非凭据位 189 · 裁定形 13 · 只开 URL 结构面出口射程外 461);幂等 0 / 1 902 922 格;到帽 0 / 679 615 格,凭据面遍数直方(含确认那一遍)1 遍 212 349 · 2 遍 462 786 · 3 遍 4 454 · 4 遍 3 · 5 遍 5 · 6 遍 18(4 遍一档是门池里收的一只非定向自造文法串,5 / 6 遍两档全是门池里收的定向搜索构造串,KL-355);干净语料 100%;常见干净形 322/322(豁免 6 形 78 格,上一版同出口也多遮)。
101
+ - 扩门 `scripts/run-display-untrusted-projection-test.mjs`(414 → 479 格;CC-247):Y 段(一次扫描的优先序与记号原子、逐族钉住的形;链接 + 停字符 + 邮箱七形负控、口令位停字符正控、带端口链接形与上一版同字节多遮的现状钉、带点用户名 + 停字符口令、记号后名字不成可独立消费的一对照遮、URL userinfo 位与 query / 片段 / 段参数的记号后明文、PEM 头行与块体里控制串的标签值、退役占位后还有内容、口令段含完整记号的冒号;口令段含禁字的无 scheme userinfo 在前有凭据标签 / 裸词用户名 + 主机形时照遮的八形、包着地址的开引号与引号键收尾的十三形负控、与上一版同字节多遮的两形现状钉、用户名本身是凭据标签时标签不进记号;里层标签紧贴外层闭引号与引号值里地址后的缝以地址起头的十形一轮即不动;凭据面不动点循环到帽 0 次、干净文本凭据面恰一遍、文法池抽样一轮即不动、标记位置读口对最终输出自洽)、K49b 线性(无 scheme userinfo 两形与引号标签链三形)、K70b / K70c、K30 / K31 定向形先跑;按上面 Changed 第 1 条改口 U33 / K48 / K70 / X46 / Y6。另一批(U41 – U41c / Y22 – Y28):URL 片段不在「`;` / `,` + 凭据词」处提前断、原意形(凭据词 + 分隔 + 空白)仍断;用户名恰是凭据标签 + 口令含禁字(含只开 URL 结构面与单开词级网的出口)与无冒号三形不露、负控八形逐字节、裸值延伸不吃包着的地址也不跨下一枚标签;两条「每遍只推进一格」的构造链 k / n = 1…12 一遍到终形、定向搜索构造的多遍串帽内收敛;头在读面上认不出的 PEM 块不划不透明区;标签值地址形主机之后紧贴的尾巴照遮;多遍改写时标记位置来源表的复合(门内把 dist 叶子经数据 URL 派生一份带内部件读口的副本直验,不进包);到帽读数的口径(帽压到 1 的派生副本:恰在帽上落定不报到帽);机读口洗过再过展示出口(记号 + 尾标点 + 软位 + 值照遮)。再一批(U41d / Y29 – Y32):片段在「`;` / `,` + 凭据词 + 分隔 + 非 ASCII 空白」处不断(五种空白 × query / 片段 / 路径段参数 / userinfo 位,只开 URL 结构面逐字节与上一版同);地址值路径标签之后引号里夹控制串(OSC / DCS / APC / PM / SOS,含 C1 形)照遮;PEM 头行词间的空格换成不可见单元时各出口块体照遮、不透明区与块体同一次认头;用户名是方案词 + 冒号、地址被包着时照认 userinfo;标签值覆盖判的精确字节格(地址被包着 / 引号值闭在 `@` 之前)。
102
+ - 扩门 `scripts/run-crash-converged-projection-test.mjs`(138 → 166 格,带两代服务端夹具;不带夹具时 154 格、两代段标为未跑;CC-218):成文改口格(新词读得出、因由与旧词同);新词 decided / pending 两形、32 种组合 × 两词桶与因由逐格同(`cause` 不进判据)、词表外(近形词 / 大小写 / 尾空白 / 空串 / 原型键 / 非串)仍整行 `dropped`、本模块产物零句子且不改写 `cause`;只认旧词的穷尽 `switch` ⇒ TS2322;两代夹具 —— 服务端审计店真铸五形经 JSON 过境:新一代(≥7.108.0)两行新词全读得出、未被追踪腿的 pending 孤儿 `resumeSafe:false` ⇒ `needsHuman` / `pending_unsafe`;老一代(<7.108.0,按服务端版本认代)无新词、同一形落 `resumeSafe[]`。
103
+ - 扩门 `scripts/run-engine-notice-catalog-test.mjs`(→ 1193 格,带新一代与两份老一代服务端夹具;不带夹具时真铸点与对账段标为未跑;CC-270 ① / CC-272):服务端自铸表三行 → 四行;`readModelUnreachable` 段(四格必填且只认自有属性 / `proxyInUse` 可选 / `code` 与 `remedy` 开集原样 / 每格恰读一次 / 敌意取值器不抛 / 经派发口 user / 服务端两句不进产物;可选腿直驱服务端真铸点);`context.tool_turn_repaired` 段(新码在册、受众运维面、位置同源;读器逐格透传、冻结;`form` 开集透传、公面无修复形词表;十五种坏形整只缺席;开发依赖腿 —— 引擎修复律对四种坏转录真修、通告座真铸帧过派发口逐格同,合法转录零修复零通告;可选腿 —— 服务端发布包的用户流白名单里没有这一码);派发表用户面 12 → 13、运维面 3 → 4;码册 80 → 81;服务端发布包对账两代(新一代 / 老一代夹具各对一遍,本包领先老夹具的那一行要求老夹具的受众表与用户流白名单都没有它)。
104
+ - 扩门 `scripts/run-mode-release-projection-test.mjs`(→ 82 格;CC-272):公面词表就是生成物那个对象(引用相等、冻结、与引擎包入口的表逐词逐序同);谓词与引擎谓词逐值同答;表外 `reason` 原样带回、处置照读、谓词答 false;开发依赖引擎的模式裁决口真铸一只带原因的放行账 ⇒ 过引擎不变式筛 ⇒ 本包读回逐格同。扩门 `scripts/run-upstream-tables-test.mjs`(143 → 161 格):第四批放行原因表生成、与引擎逐词逐序同、源码初始化式就是生成物、原因词在源码里零串字面量;加词 ⇒ 生成物不同,坏形 ⇒ 拒生成;老引擎形点名缺的那一张。
105
+ - 新门 `scripts/run-session-memory-erase-projection-test.mjs`(335 格;CC-264,包侧投影门):调用口恰一发、体恰 `{requestId}`(+ 自有键上的显式布尔;原型链上继承来的不上 wire)、点段会话 id 与含未配对代理码元的会话 id 本地拒(零请求、不抛)、鸭子形信号答 `bad_input`;出站头与工厂造的 client 逐字节对拍;两代夹具真服务端(7.108.0 / 7.106.0)门序 400 → 401 → 501 → 404 → 501 → 400 ×4 → 200 逐码 → 档,两代差五形;结局四档、单源句、七值重发姿势、敌意入参不抛。
106
+ - 新门 `scripts/run-registry-conflict-projection-test.mjs`(96 格;CC-280):三词闭集与谓词;对新版 SDK 同名函数逐例对拍(状态 × 体组合与错误对象两组,零不一致;敌意体刻意分歧);registry 服务源码里的 scope-gone 铸点与乐观锁铸点逐处读(`SEMA_WEB_ADMIN_ROOT` / `SEMA_SDK15_ROOT` 缺席 ⇒ SKIPPED-SECTION)。扩门 `scripts/run-task-request-omission-receipt-test.mjs`(535 格;车道表 45 行)与 `scripts/run-resume-refusal-copy-test.mjs`(210 格;两代夹具真铸点腿;CC-281)。
107
+ - 新门 `scripts/run-prompt-delivery-projection-test.mjs`(111 格;CC-271):三条不变量(只增不删 / 建了 run 的帧才算 / 没走过提交路径两判皆假;服务端幂等重放臂的 409 冲突体不算)+ 时序 / 并发 / 失败分类三维 + 夹具服务端两代按写序真铸帧(`meta` → `approval_request` → 409)经真 SDK 解析端到端;同名影子门新登记两行(终端两只同名读口,`divergent-copy`,差分格 `cc271-prompt-delivery`,retireBy 0.89.0);重启恢复一格(三只写口的返回逐条落盘 → 丢掉账本 → 读回 ⇒ 交出去的行仍是交出去;只落 attempted 的返回 ⇒ 读回成确知没交出去,判别半;接入文档 §114 G-PD10)。扩门 `scripts/run-wiring-manifest-projection-test.mjs`(→ 219 格;CC-279):Q 段 `fileHistory`(两代夹具 core 派生 → server 投影真铸;这一段的取值器抛 ⇒ 段缺席、同帧别段照交,流式与非流式两口各一格)。
108
+ - 扩门 `scripts/run-plan-review-decision-ledger-test.mjs`(97 → 125 格;CC-278):K 段(时序 / 判别负控 / 并发 / 失败分类 / 终端两形端到端 r1 / r2 / arm 卡形;认领那一拍撤回离门结算、清「没生效」注脚、posting 笔不复用)。
109
+ - 扩门 `scripts/run-integration-doc-freshness-test.mjs`(1 624 → 1 626 格):已知限制档 `docs/KNOWN-LIMITS.md` 每张表每行(按未转义 `|` 切格)格数与表头相等 —— 行内代码里的 `|` 会被 Markdown 表格当格界拆开(修前五行被拆成 6 / 8 格、触发条件与升级判据两栏错位),一律写 `\|`;自证一格。
110
+ - 扩门 `scripts/run-package-hygiene-test.mjs`:出包面任一文件(全文,不按冻结基线切段)含行首合并冲突标记(`<<<<<<< ` / `=======` / `>>>>>>> ` / `||||||| `)即红,自检构造样本双向(正样本四形命中、非行首与八连符号不命中)。另加本仓本地四条过程说法(开发分支与评审轮次一类;不并进与上游同步的共用禁表),接入文档 §114 起、CHANGELOG 本段起向前执法(已发段冻结),自检正反样本双向。
111
+ - 登记物:根公面基线 1356 → 1372(+16);测试钩 62 不变;超集台账 `docs/type-superset.json` 97 → 98 条(`_sema_fileHistory`);门清单 `scripts/gates-manifest.json` 167 → 171 条(新门四道;扩门说明同批更新),README「Guards」与负控文档派生表同批重生;棘轮 `typeshape.unknownExport` 452 → 458、`portability.index` 229 → 232(registry.json 账 322 → 328 条);单例清单 573 → 595 条,高风险上限 133 不变;缺席折正向词普查登记 7 → 9 条(两只谓词的 catch ⇒ true 收紧向);过渡物退役登记 +2 行(服务端自铸码受众手写表:开发依赖引擎 ≥ 7.38.0 即到期;「只续已有会话」粗码形读消息尾括注:retireBy 0.90.0 到期重看)。
112
+
113
+ ### Known limits(本版新增)
114
+
115
+ - 展示出口(CC-247):上游预先带记号、记号后隔非词字符紧跟明文时明文不并进(记号原子的代价;本包铸点洗过再经展示出口的复合路径同样触发,余形读数见 KL-317);凭据面不动点循环只对帽内收敛的输入保证一轮即不动,定向构造可让改写遍数随长度增长、到帽(交最后一次改写的输出;KL-355);裸 ESC / C1 CSI 紧贴 `-----BEGIN` 的 PEM 块体在非点形出口原样(三版同;块里的标签值照遮;KL-356);PEM 头行词间是制表符 / 不换行空格(真空白)、出口不把它折平成空格 / 画成点时块体原样(三版同;KL-356);凭据标签左边紧贴、无标签无形状的裸串按原文显示(KL-318);非凭据头(`"url":` / `max_tokens=`)值里地址之后的文字不遮(KL-319);封长后帽内本来可见的字不再被一枚插入的记号挤出帽外(KL-320);只开 URL 结构面时标签值 / 引号值地址之后的尾巴不遮(KL-321);随机拼接串里的四条裁定形(KL-322);口令段含双引号 / 反引号 / 尖括号的无 scheme userinfo 默认不算、前有凭据标签或裸词用户名 + 主机形时照遮,其余几形相对上一版少遮(差分门五池之外;KL-323),`email:"bob@example.com tail"` 一类与上一版同字节多遮(KL-351);标签 / 方案词 + 冒号后以 `<` 起头的占位文本(`key: <id>@scope`;只开词级网的出口上另含无空格的 `key:<id>@scope`)相对上一版新多遮成 `«redacted:secret»@…`(不含凭据,方向是多遮;KL-351);不在本包凭据标签族里的 JSON 键(`passphrase` / `pwd` / `auth` …)值里带 `@` 的串按原样显示(上一版只在值里带 `@` 时被宽松的 userinfo 网顺带遮住,同时把 `{"email":"bob@example.com"}` 的键也吞进记号;KL-354);链接后紧跟 `)` `[` `,` `;` 或(带端口时)停字符再有邮箱的干净文本整段换进 userinfo 记号(与上一版同形多遮;KL-324 / KL-325)。
116
+ - 崩溃收敛 / 服务端自铸通告(CC-218 / CC-270 ①):`shutdown_before_park` 的 `pending` 形与旧词同按 `resumeSafe` 分桶(KL-326);没收到 `server.model_unreachable` 不等于模型端点够得着 —— 同步非流式提交口、leader 车道、无会话的模型调用、代理在而上游不通、Bun 运行时上服务端不发(KL-327);它的 `code` 开集透传(KL-328);服务端自铸码受众仍是本包手写一张小表,引擎码册登记服务端自铸码的那一版(引擎 7.38.0)经下一次换钉接入后逐行退役(KL-329)。
117
+ - 引擎换钉(CC-272):`context.tool_turn_repaired` 不上客户端的事件流(KL-330);修复形词表本包不出镜像(KL-331);审批卡上的问类两位 `askClass` / `classes` 本版不接 —— 已发布的服务端卡帧不带这两位(KL-332);本版码册来自引擎 7.37.1,服务端若内嵌引擎 7.38.0,它新增的五码(四只服务端码入册 + `task.tool_turn_incomplete`)在本包码册外 ⇒ `readEngineNoticeFacts` 答 `undefined`、受众按保守缺省,到下一版换钉前经本包分发的端看不到这五码的 typed 事实(`server.model_unreachable` 本版经手写表可见,不受影响;KL-333)。
118
+ - 会话记忆抹除(CC-264):说不出没送出的传输失败一律落 `no_answer`(KL-334);会话存储层读错在本面落 `unconfirmed` / `engine_fault`(服务端落 500;KL-335);老一代服务端四形落 500 ⇒ `same_request_id`,其中两形同 id 重发不会成功(安全但没用;KL-336);点段会话 id 只在本口本地拒,同形存量(经 SDK 动词拼路径的别的口)另议(KL-337)。
119
+ - registry / 只续已有会话(CC-280 / CC-281):409 读不出机器码 ⇒ `'gone'`(与 SDK 分歧;KL-338);`isScopeGoneError` 判不出不保留体与码的错误对象(KL-339);`'conflict'` 含不可重试的 409(KL-340);兜底层删 mock 会话 id 时保留 `requireExistingSession: true`(KL-341);粗码形读消息尾括注,服务端改措辞即退化为 `null`(KL-342);流式提交上的同码失败帧不归读口(KL-343)。
120
+ - 投递判定(CC-271):判据是「建了 run」不是「模型处理了」(KL-344);开流先于建 run 的帧型是按服务端写序列的枚举(KL-345);steer 送达未知按没交出去记(KL-346);账本不判帧归属(KL-347);公面 409 判别口 `activeRunBusySignal` 对服务端幂等重放臂的 409 冲突体仍答 `null`(与上一版同,账本另认;KL-353)。
121
+ - 决断台账(CC-278):离门证据结掉的登记在宿主 `revoke()` / 自带路径 `settle()` 之后仍可被认领(KL-348);「登记 → 投递口认领」之间离门证据照旧结掉那一笔,这一小段里重开口不因它拒开(KL-349)。`fileHistory` 开集第三个词本包无措辞(CC-279;KL-350;`fileHistory` 段读抛只省这一段,既有段取值器抛仍整帧抛,与上一版同:KL-352)。
122
+ - 登记物按既定裁定改窗(本版对这些物零改动):同名影子对账门豁免表剩下的两行 —— 重开口外层(本包读点 0.83.4 起在,候终端换读)期限 0.88.0 → 0.90.0;回执成因词表(终端到期重看、下一版换读)期限 0.88.0 → 0.89.0;其余登记物本版零到期。
123
+ - 完整台账见接入文档 §114 末行「包侧缺口」。
124
+
125
+ ## 0.87.0(2026-10-01)
126
+
127
+ > 主题:**minor** —— 六票同发(按票序)。① **会话历史 tool_use 错配的自救出路**(CC-268;终端的请托):provider 因为会话历史里一只工具调用对不上结果而拒掉这一会话的每一次请求时,合成终局错误行带机读超集键 `_sema_tool_history_mismatch`;本面真有 `/rewind` 命令的宿主钉 `EmitContext.offersRewind`(`true`,或对象形 `{ engineBaseUrl }` —— 那台引擎明说没有对话锚时不加句)后,行尾另起一行出路句(与 CC 同句),同一会话连续第二次起再补一句次数;另出两只根入口纯函数 —— 判型 `classifyToolHistoryMismatch` 与回退节点解析 `resolveToolHistoryRewindTarget`。② **崩溃收敛 needsHuman 桶的因由位**(CC-269):`projectCrashConverged` 的 needsHuman 行带闭集四词 `needsHumanReason`,分桶判据一字未改。③ **停车 fail-soft 真因超集键**(CC-273):HITL 桥在同步腿终帧在场时 fail-soft 收场,那只终帧照旧原样回吐、顶层多 `_sema_park_failed_reason`(与 durable 腿合成终帧的 `errorMessage` 逐字相等),结果帧透传同名键。④ **workflow 活动台账与监视器源的凭证位收取值函数**(CC-274):连线身份改按凭证来源认,宿主持同一只取值函数时令牌轮换不再清账。⑤ **detach 取消兜底的 arm 口收取值函数**(CC-275):取件口每调一次现读。⑥ **chrome 臂 `suspended_reopened`**(CC-276):流上 `suspended{reopened}` 投成一条 chrome 事件(读数 + reopen 族单源句 + 幂等键)。**为什么是 minor**:两只新顶层导出(`classifyToolHistoryMismatch` / `resolveToolHistoryRewindTarget`)+ `ChromeEvent` 新臂 `suspended_reopened`(对 `ChromeEvent['kind']` / `ChromeArmKind` 做穷尽 `Record` / `switch` 的 TypeScript 端编译红,与 0.86.0 同口径)+ 四处可选位 / 入参放宽(`EmitContext.offersRewind?`、`CrashConvergedRow.needsHumanReason?`、`LiveWorkflowConfig.authToken` / `WorkflowActivityLedgerConfig.authToken` 收取值函数、`armDetachCancel` 入参 `authToken` 收取值函数;对构造方均 additive)。型面 BREAKING 零处(对构造方;读那两只配置位 `authToken` 并按「串 / 中继」二分的宿主代码会编译红,见 Changed 第 5 条)。根公面运行期导出 1354 → 1356(+2);测试钩 62 不变;公面类型名 922 不变(两只新口的入参 / 出参型名不上入口,宿主按结构传;chrome 新臂是 `ChromeEvent` 联合的内联成员);超集键 +2(`_sema_tool_history_mismatch` / `_sema_park_failed_reason`);投影臂 +1(chrome `suspended_reopened`;`CHROME_ARMS` +1 行,`required:false`);另有**已发导出的可观察变化**在 Changed 逐条单列(第 1–6 条,写明谁要跟;第 7 条是公面零变化的内部搬家)。peer sdk 地板 `>=12.0.1` 不动;开发依赖不变。
128
+
129
+ ### Added
130
+
131
+ - **会话历史对不上时的自救出路**(CC-268;接入文档 **§113 TH-1 / TH-5 / TH-6**):provider 因为会话历史里一只工具调用没有对应的结果(或一只结果没有对应的调用、或一只调用 id 重复)而拒掉这一会话的每一次请求时,合成终局错误行(`API Error: …`)多一只机读键 `_sema_tool_history_mismatch: { kind, toolUseId?, consecutive? }`。`kind` 取 `tool_use_without_result` / `orphan_tool_result` / `duplicate_tool_use_id` 之一;`toolUseId` 是 provider 点名的第一只 id(provider 那句话没点名、或读不出时缺席);`consecutive`(只从第二次起在场)= 同一会话连续几次 run 撞上同一错配。这只键只铸在那一行上,且只在失败是三句 provider 模板之一时铸;别的终局行与 0.86.0 逐字节同。`adapt()` 重建这一行时接力这只键;原样转发这一行的宿主(例如 print 车道的 JSON 流)也带着它。
132
+ - 判型从不读 assistant 正文。别的状态(401 / 404 / 429)、别的 400(例如模型名无效)与引用这句话的形都不认。provider 回体是 JSON 时只认错误信封上的那句话(顶层 `message` 或 `error.message`;回体须从开头就是这个对象,宿主直接交 SDK 错误对象时的 `400 {…}` 形同认),请求回显、数组成员、更深一层对象里的同名键都不认。宿主直接交 SDK 错误对象、回体不是 JSON 时的 `400 <provider 原话>` 形同认(只剥一个状态词)。
133
+ - `toolUseId` 按整只读:带字符集外字符(例如 `/`)、后接截断标记 `…`、或顶在失败文本末尾(被截断)时整只缺席,不取前缀。token 后面紧跟列表分隔符(`,` / `;`)时整只就是 id、一个字符都不剥(带尾冒号的 `call_1:` 照收);后面是空白或结尾时至多剥一个句末 `.`,剥完仍以 `.` / `:` 收尾 ⇒ 分不清 id 后缀与句末标点 ⇒ 缺席。孤儿结果那一句在 `` `tool_result` `` 之后带 `blocks`、`block` 或直接接冒号都认。
134
+ - 连续次数按进程、按会话记(键是引擎回显的会话 id),只数不同的 run(同一次 run 被重看不加码)。回放的终局、不带 run id 的终局(含失败文本为空的失败事件帧)与结局读不出的终局不记次数,但与这一次错配不同时照样清零;这一会话的任何别的结局清零。先开后收的老流晚到的终局**只许清零、不许加码**:与行上指纹不同(别的结局 / 别的错配)⇒ 本段到此为止、不答次数;同指纹 ⇒ 不改账;较新的流收到的任何终局(包括不改次数的那几形)都推水位。终局上没有引擎回显的会话 id 时(失败事件帧、会话占锁的 409 拒绝、结局读不出的 done)按宿主开流时钉的 id 记;那只 id 从没被引擎回显过(宿主每轮现铸会话 id)时这一终局认不出属于哪一只会话,本进程里每一只会话正在数的连续都按被打断处理(下一次从 1 起)。拿不准时不报次数,不多说。
135
+ - **`EmitContext.offersRewind?: boolean | { engineBaseUrl: string }`**(CC-268;**§113 TH-2 / TH-3**):本面有 `/rewind` 命令的宿主钉它;错配那一行随之在行尾另起一行 `Run /rewind to recover the conversation.`(与 CC 同句),从连续第二次起再多一句,给出次数并说明 `/rewind` 是恢复这一会话的唯一出路(` The same error has now happened N times in a row; /rewind is the only way to recover this conversation.`)。缺席、`false`、`print` 车道与 `utility` 车道都不加句。结果帧 `errors[]` 恒是引擎原文。
136
+ - 对象形 `{ engineBaseUrl }`(推荐):本包按那台引擎查自己的「只回退对话」判据(与 `/rewind` 菜单同一只 `rewindConversationAvailability`)。引擎明说没有对话锚时两句都不加,键照铸;引擎说有、或判不出(没报、读不出、没观测过)时照加。`true` 不查这只判据,由宿主自己担保。
137
+ - **`classifyToolHistoryMismatch({ code, status, message })`** ⇒ `{ kind, toolUseId? } | null`(CC-268;**§113 TH-7**):与那一行同一只判型,给手里握着失败本身(run 的失败码、provider 状态、失败文本)的宿主。只认 HTTP 400(状态 `400`,或失败文本以 `<标签> HTTP 400:` 起头);给了码时只认 `invalid_request`;且 provider 那句话须在 provider 消息的开头(JSON 回体里是顶层 `message` 或 `error.message` 的开头)。永不抛。
138
+ - **`resolveToolHistoryRewindTarget(rows, mismatch)`** ⇒ `{ target } | { rootReopen: true } | { undecidable: reason }`(CC-268;**§113 TH-8**):交进宿主自己的转录行(每行可带 `toolUseIds` / `toolResultIds` / `prompt` / `engineHandle` / `local` / `sessionRoot`),找最早提到那只 id 的一行,再回溯到那一轮的 prompt:答那只 prompt 行本身(回退到它之前);那只 prompt 是会话第一轮时答从头开始;判不了时答六个理由之一(`no-mismatch` / `no-tool-use-id` / `id-not-found` / `prompt-not-found` / `prompt-without-handle` / `unreadable-rows`)。跳过宿主本地行,绝不越过没有引擎句柄的 prompt,不改入参,永不抛(`mismatch` 的位读不出 ⇒ `no-mismatch`;行读不出 ⇒ `unreadable-rows`)。
139
+ - **崩溃收敛 needsHuman 桶的因由位**(CC-269):`projectCrashConverged` 产出的 `needsHuman[]` 每一行多一位 `needsHumanReason`(`CrashConvergedRow` 上的可选位,闭集四词):`approved_then_interrupted`(`decided` ∧ `resumeSafe:false`:人当时批了、执行窗内引擎断了)/ `pending_unsafe`(`pending` ∧ 无已批证据 ∧ `resumeSafe:false`)/ `unstable_row`(载体带取值器或自带原型)/ `contradictory`(`pending` 却带已批证据,或 `decided` 却 `resumeSafe:true`)。优先序:载体不可信 > 判据位冲突 > 人已批 > pending 却不安全。与分桶出自**同一次读**;`resumeSafe[]` 的行不带;供给行上碰巧有同名位 ⇒ needsHuman 行被覆盖、resumeSafe 行被摘掉。分桶判据一字未改。接入文档 **§113 N-1 / 113a′ 第 4 条**。
140
+ - **停车 fail-soft 真因超集键 `_sema_park_failed_reason`**(CC-273):HITL 桥(`bridgeAskUserQuestionGates`)在一张卡决不成、fail-soft 收场时,若这张 park 来自同步腿终帧 `done{suspended}`,那只终帧**照旧原样**回吐(不造第二只终帧,`type` / `id` / `result` 同一只对象),但顶层多一位 `_sema_park_failed_reason` = 真因 + 出路那一句,与 durable 腿同一失败合成的 `failed{errorCode:'hitl_unanswered'}` 的 `errorMessage` 逐字相等;结果帧投影(`terminalToSdkResult` / `runStream`)把它透传到 CC 结果信封同名键,出口与 `errors[]` 过同一只凭据洗消(句中 URL 的 userinfo / 查询串换成记号;帧上那一位是原句),`errors[]` / `subtype` / `is_error` 一字不动。触顶收场两形(连续非进展轮 / 决了又停回来 `hitl_stalled`)与宿主撤卡收场同样带各自那一句。缺席 = 没有能给用户的真因:用户 Esc、普通终帧,以及这一端没有决断面(宿主没装审批卡口、卡口装在别的会话键上、问答腿没有 overlay —— 真因是装配诊断,「卡再出现时在卡上决」在这一端不成立;durable 腿合成终帧照旧带那一句)。接入文档 **§113 P-1 / P-2**。
141
+ - **chrome 臂 `suspended_reopened`**(CC-276):`runStream` 对流上一帧 `suspended{reopened:<码>}` 发一条 chrome 事件(与该帧同一拍、按流序;转录面仍零行):`{ kind, laneProof, reopen, content?, eventId?, taskId? }` —— `reopen` = `suspendedReopenOf` 读数(恒 `reopened` 臂,原码开集);`content` = reopen 族单源句 `resumeReopenContent`(与决断回执那一路逐字同句;码不在 reopen 族闭集内 ⇒ 缺席);`eventId` = 帧的 durable id;`taskId` 只在帧上自带时在场(帧上 `taskId` 键原样 —— 服务端用这个键、且值按 run 唯一时它才等于 run id)。明说没重开 / 老引擎缺键 / 坏形 / 帧上的位读不出(取值器抛)⇒ 一条不发、流照走。同一条流上的重放按既有 durable 幂等只报一次。`CHROME_ARMS` +1 行(`required:false`)。接入文档 **§113 R-1**。
142
+ - 公面合计:根入口运行期导出 +2(CC-268:`classifyToolHistoryMismatch` / `resolveToolHistoryRewindTarget`);测试钩不变;公面类型名不变;`EmitContext` +1 可选成员(`offersRewind`)、`CrashConvergedRow` +1 可选成员(`needsHumanReason`)、`ChromeEvent` +1 臂(`suspended_reopened`)。
143
+
144
+ ### Changed
145
+
146
+ 🔴 **已发导出的可观察变化(逐条;按旧行为断言过的测试请按接入文档 §113a′ 改锚)**:
147
+
148
+ 1. **合成终局错误行**(CC-268):错配形那一行多 `_sema_tool_history_mismatch`(宿主不改代码也会看到);宿主钉 `offersRewind: true`(或对象形,且那台引擎没明说没有对话锚)时行尾另起一行出路句、连续时再加次数句;`adapt()` 重建的行同带这只键;终端 `-p` stream-json 输出的合成行照出这只键、不加句。非错配行与结果帧 `errors[]` 与 0.86.0 逐字节同。**谁要跟**:按「行恰等于 `API Error: <原句>`」或「合成行键集恰为 …」断言的格改锚(§113a′ 第 1 / 2 条)。
149
+ 2. **`projectCrashConverged`**(CC-269):needsHuman 行多一位 `needsHumanReason`;供给行上碰巧有同名位 ⇒ needsHuman 行被覆盖、resumeSafe 行被摘掉;分桶不变。**谁要跟**:按「needsHuman 行键集恰等于供给行键集」断言的格改锚(§113a′ 第 4 条)。
150
+ 3. **`bridgeAskUserQuestionGates`**(CC-273):在上述收场形上吐出的同步终帧是一只**新信封**(多一位,`result` 仍是同一只对象;按对象同一性比对终帧的宿主注意);结果帧在上述收场形上多一位超集键。**谁要跟**:按 `===` 比对回吐终帧、或按「帧键集恰等于引擎那一帧」断言的格改锚(§113a′ 第 5 条)。
151
+ 4. **`runStream`**(CC-276):有 `emitChrome` 时多发一种 chrome kind `suspended_reopened`;转录面不变。**谁要跟**:对 `ChromeEvent['kind']` / `ChromeArmKind` 做穷尽 `Record` / `switch` 的 TypeScript 端补一行(否则编译红);「`runStream` 发出的 chrome kind 恰为某集合」的判据加这一词(§113a′ 第 6 条)。按端:终端必改两处(臂登记表补一行;臂对账要求每条已知臂有在场的消费点 ⇒ `consumeChrome` 补一条零行为 `case 'suspended_reopened':`,或 `hostSink` 补一支判别);网页端必改三处(chrome 臂台账补一行;臂 parity 测试正控臂数 35 → 36;同一测试的 `SAMPLES` 补一条合成事件)。另:`suspendedReopenOf` 读 `reopened` 时取值器抛错(或入参是已撤销的 Proxy)由外抛改答 `unstated`(兑现「永不抛」;流驱动主循环也读它)。
152
+ 5. **workflow 活动台账与监视器源的凭证位收取值函数**(CC-274):`LiveWorkflowConfig.authToken` 与 `WorkflowActivityLedgerConfig.authToken` 由 `string | { mode: 'same-origin-relay' }` 放宽为 `WireAuthTokenSource | { mode: 'same-origin-relay' }`(`WireAuthTokenSource` = 串或 `() => string | undefined`,与 `makeEngineWireClient` 同一形)。取值函数原样交给 wire client,**每发一次请求读一次**(活动流的每次开流 / 断流重连、监视器源的每次 list / get),构造期零读。放宽对**构造方** additive;**读**这两只配置位、按 `typeof c.authToken === 'string' ? … : c.authToken.mode` 二分的 TypeScript 宿主代码会编译红(TS2339)—— 要补函数那一支(运行期函数形落进「串」那一支会把函数源码当令牌拼进头里)。
153
+ - **连线身份改按凭证来源认**:活动台账判「同一 workflow 的新请求是不是同一条连线」时,串按值比、取值函数按**函数引用**比、同源中继声明形按 `mode` 比;形不同恒不等(串 → 取值函数算换了来源,顶掉一次,之后稳定)。比较时**从不调用**取值函数。结果:宿主持同一只取值函数时,令牌轮换不再把同一台引擎、同一 principal 的台账当成另一条连线顶掉 —— 修前宿主只能每次现读一个串塞进来,每一次轮换都让台账被换成空账、已收的运行期活动事实清零。
154
+ - 🔴 宿主要持**同一只**函数(建一次,各入口 spread 同一份连线对象):每次调用现造一只箭头函数 = 每次都是另一连线身份,台账会被顶掉,监视器源随之停手退回只读快照轮询(接入文档 §113a′ 第 7 条)。
155
+ - 串形 / 中继形:判法与 0.86.0 逐格同(串的值就是它的来源)。
156
+ - `authToken` 缺席(`undefined`,JS 宿主漏传):同一 workflow 第二次 `ensureWorkflowActivityLedger` 由抛 `TypeError` 变为复用同一台账(两次来源相同);`null` 两版都抛。
157
+ 6. **detach 取消兜底的 arm 口收取值函数**(CC-275):`armDetachCancel` 入参的 `authToken` 另收 `() => string | undefined`。arm 时零读;取件口 `detachCancelArm()` **每调一次读一次**,读到的值过与 wire client 同一只三态解析(`resolveWireAuth`)后,仍以 `string | { mode: 'loopback-unauthed' }` 两形之一交出 —— 宿主发射腿(按「是不是串」分两支)的读法一字不变,发送前同步取件即拿到发送那一刻的凭证。`DetachCancelArm` 型本身不变(它是取件形)。
158
+ - 取不到(`undefined` / 空串 / 非串 / 抛错)⇒ 回环地址答 `{ mode: 'loopback-unauthed' }`(发射腿零 Authorization 头,绝不伪造),非回环答 fail-closed 匿名身份;取值函数抛错时取件口**不抛**(它跑在信号处理路径上)。
159
+ - 串 / 回环免鉴权声明形:取件口照旧给回 arm 进来的**同一个对象**,与 0.86.0 逐字节同。取值函数形每次取件给一个新对象:原型与 arm 相同(类实例 arm 原型上的 `getTaskId` 照样可达),自有位按属性描述符整份拷(含不可枚举的自有位;`getTaskId` 等同一引用);副本不是同一实例,方法读类的 `#private` 字段时在副本上仍抛(KL-316)。
160
+ 7. 内部搬家(公面零变化;CC-276):`ResumeReopenDetail` / `resumeReopenFromError` / `resumeReopenContent` 的定义从 `resumeRefusalCopy` 模块逐字搬到 `suspendedReopen` 模块(为 chrome 臂与决断回执两路共用一句,且不把前者的依赖拖进流驱动);原模块留同一绑定的转口(已发文档写的坐标照旧找得到),包根经两条星号导出拿到的是同一个函数对象,公面名单与个数不变。只走包根入口的端零感知。
161
+
162
+ ### Gates
163
+
164
+ - 新门 `scripts/run-tool-history-mismatch-projection-test.mjs`(212 格,带两代服务端夹具;不带时 204 格、夹具腿标为未跑;CC-268,包侧投影门):S0 两只口在根入口上、与实现模块同一函数对象、在公面基线里,账本 / 两句文案 / 锚表 / 测试钩不上入口;D1 判型 —— 三句 provider 模板单源锚表(冻结、三行三 kind),真端点 / 用户报案 / 兼容端点 / 无反引号 / 原始与截断 JSON 体都认,孤儿结果 / 重复 id(不带 id ⇒ 键缺席)也认;K5 401 / 404 / 429 / 模型名无效 / 无任何 HTTP 400 证据 / 治理码 ⇒ `null`;K6 句中引用 / JSON 消息以别的话开头 / 半句 ⇒ `null`;会抛的取值器不抛;id 窄读(控制字符 / 超 128 字 ⇒ 缺席);用开发依赖引擎包的真铸终局喂入。D2 `runStream` 终局行:错配形挂键、宿主声明 `offersRewind` 才在行尾另起一行补句(缺省 / `false` / `-p` / 工具车道不补)、`errors[0]` 原文;401 / 模型名无效行逐字节同旧、无键;治理拒绝理由复述 / 模型输出问题行 / 模型正文逐字复述 ⇒ 无键无句;`adapt()` 重建行接力同键(坏 kind 整键丢、坏成员逐个丢、模型行不接力)。D5 会话级连续同指纹:不同 run 第 2 / 3 次 ⇒ 次数句、`consecutive` 2 / 3;同一 run 重看不加码;回放帧与无 run id 帧不记账也不打断;成功一轮清零;换指纹从 1 起;别的失败打断;别的会话各记各的;键是引擎回显的会话 id;开流代际(先开后收的老流不改账);有界 64 只会话、挤出后从 1 起。D3 节点解析:坏轮 prompt 行本身(本地行跳过)/ 会话第一轮 ⇒ 从头开始 / 结果晚到取最早提到 id 的那一轮 / 判不了六理由闭集(prompt 无句柄不越级)/ 敌意行不抛。D1 另钉三件:JSON 回体只认错误信封(请求回显 / 兄弟对象 / 数组成员 / 更深一层 / 体是数组 / 顶层 `message` 非串 / 回体前有别的文字 ⇒ `null`;真信封 / 顶层 `message` / 转义引号在前 / 截在首只 id 里 / 闭合值里最后一只 / SDK `400 {…}` 形照认);id 按整只读(带 `/` / 后接 `…` / 服务端截断标记 / 顶在末尾 ⇒ 缺席,逗号 / 句点 / 分号 / 点号冒号形照读,带 `/` 的那一只交节点解析 ⇒ `no-tool-use-id`);孤儿结果 `blocks` / `block` / 直接冒号三形都认。D2x `offersRewind` 对象形:引擎明说没有对话锚 ⇒ 两句都不加、键照铸(含 `consecutive`);引擎说有 / 没观测过 / 读不出 / 读数失效后 / 地址不是串 / 取值器抛 ⇒ 照加;`true` 不查判据;print 车道不加;非错配行不变;类型面对象形可赋值、老形照过。D5x 连续账本:同一会话 17 次后重看第 1 次不报次数、第 17 次仍 17、下一次 18;两次错配之间夹不带 run id 的别的失败 / 结局读不出的 done / 不带 run id 的另一只错配 / 回放的成功 / 409 会话占锁拒绝 ⇒ 清零;同指纹的无 run id 帧与回放帧不打断;成功清零后重看上一段的 run 不开新段;换指纹再换回、重看第一段的 run 不加码。D1 另钉 SDK 错误对象的非 JSON 形 `400 <原话>`(认、id 取首只;重复 id 那一句认、不带 id;`400 ` 后面是别的话 / 句中才引用 / 两个状态词 / 状态 429 ⇒ `null`)。D3 另钉敌意入参不抛(`mismatch.kind` / `toolUseId` 取值器抛、`mismatch` 是已撤销的 Proxy ⇒ `no-mismatch`;`rows` 是已撤销的 Proxy ⇒ `unreadable-rows`)。D5y 代际水位:同指纹无 run id 的较新终局与较新流重看认得的 run 都把老流挡在外面(两条交错序列逐项读数 + 两条真开流的 `runStream` 交错);同 run 接管重放照答原次数、水位不回退。D5z 会话键无从归属:宿主每轮现铸会话 id、两次错配之间夹失败事件帧 / 体无会话 id 的 409 占锁拒绝 ⇒ 第三次无次数;宿主钉的 id 等于引擎回显 id 时夹 429 清零 / 同指纹无 run id 不打断 / 成功清零三形逐字同修前;取舍格(另一只从没被回显过的会话里的一帧失败 ⇒ 这一会话下一次从 1 起,少报);段被打断后重看最近那只 run 不报次数。H 出路句与 CC 同句逐字、次数句过卫生禁表且零机器码。X 夹具腿(服务端 7.106.0 / 7.104.0):夹具自带的引擎包铸终局 → 夹具服务端上 wire 前洗消 → 本包:键与出路句在、run id 原样上 wire ⇒ 第二次加码、401 无键。
165
+ - 新门 `scripts/run-park-failed-reason-projection-test.mjs`(55 格):P1 同步腿 + 409 `resume_blocked_by_policy` 折叠码 ⇒ 恰一只终帧、帧上带句;P2 含折叠句与出路、与 durable 腿合成终帧 `errorMessage` 逐字相等;P3 原样吐(`result` 同一只对象、调用方那一帧不被就地改写);P4 结果帧透传、`errors[]` / `subtype` / `is_error` 与未带键的同一帧投影逐字同;P5 缺席三形;P6 触顶收场两腿;P7 durable 腿不变;P8 宿主撤卡收场同样带句;P9 凭据洗消 —— 决断失败的原话里嵌着带 userinfo 与 `?token=` 的 URL,409 折叠码 / 422 续跑起不来 / 403 三形:帧上那一位与 durable 腿合成终帧同句(原句)、结果信封上这只键无明文且与 durable 腿结果信封 `errors[0]` 逐字相等、其余位与不带键的同一帧投影逐字同;P5′ 没有决断面的收场 —— 宿主没装审批卡口 / 卡口装在别的会话键上 / 问答腿没有 overlay ⇒ 同步终帧与结果帧都不铸、`errors[0]` 不变、durable 腿合成终帧照旧带句,宿主装了卡口而卡口自己报失败 ⇒ 照铸。
166
+ - 扩门 `scripts/run-crash-converged-projection-test.mjs`(118 → 138 格):G8 四因由各一形 + 优先序 + resumeSafe 行不带 + 供给同名位覆盖 / 摘除 + 32 格全组合分桶与 §12c 五项合取逐格一致 + 值形(自有可枚举数据位)+ 旧词 `crashed_before_park` 带因由 / 新词 `shutdown_before_park` 今天仍整行 dropped + 混合表账不混;G7a 编译语料加两行(因由位可赋闭集四词、不带它的老字面量照样可赋值),G7c 表外词赋值恰为 TS2322。
167
+ - 扩门 `scripts/run-suspended-reopen-projection-test.mjs`(15 → 55 格):C 段形(臂表登记、载荷键集、三码单源句、非重开零事件、开集码不带句、`taskId` 只取帧上、车道证明逐条新建);E 段端到端序列:重放(同 id 一次、第二次按既有幂等留 `duplicate_seq` 痕 / 不同 id 各一)· 接管(从第一帧重放:报在流序里自己的位置,晚于之前那一帧的转录、先于之后的正文与终局;前台腿与接管腿幂等键相同)· 迟订阅(游标在重开之后 ⇒ 零事件;停在重开上才接 ⇒ 照报)· 宿主没接 / sink 同步抛 / 返回被拒 Promise ⇒ 转录逐形不变、零未处理拒绝 · 从 HITL 桥一路到 chrome 回调;另钉帧上的位读不出(`reopened` / `taskId` 取值器抛、已撤销的 Proxy)⇒ 读口答 `unstated`、零事件、流不断、转录与不带 `reopened` 的同一条流逐形相同、零未处理拒绝。
168
+ - 扩门 `scripts/run-wire-auth-source-test.mjs`(30 → 83 格)。G8t / G9t:类型面 additive,真跑 tsc(取值函数形可赋值;老形 —— 串 / 中继 / 回环免鉴权 / 老宿主手里的 `DetachCancelArm` 变量 —— 照过;取件口仍只收窄成两形,`arm.authToken.mode` 那一支照编得过;非法形负控恰两条)。G8(CC-274):同一只取值函数两次预热之间轮换 ⇒ 不开第二条流、台账帧数与已收 beat 原样、未收口;断流重连与监视器源 GET 每发带当下的值;取值函数读取次数 = 出站请求数(身份比较零读);负控:换另一只函数(同值)⇒ 按新来源另开一条流、旧账被顶掉、持旧函数的监视器源停手不抢回;串按值 / 中继按 mode 与 0.86.0 逐格同、串 → 同值取值函数与中继 → 取值函数都算换来源。G9(CC-275):arm 期零读、台账读口(`isDetachArmed` / `detachedTaskId` / 400 分诊)零读;arm 后换值 ⇒ 取件口给取件那一刻的值且恰读一次;宿主发射腿冻结副本一字未改,发出去的取消请求头上是发送那一刻的值、凭证只在 Authorization 头;三态(回环 `undefined` / 空串 / 非串 ⇒ 免鉴权声明形且零 Authorization 头;非回环 ⇒ 匿名身份);取值函数抛错取件口不抛;串 / 回环声明形给回同一个对象;类实例 arm(`getTaskId` 在原型上)取值函数形取件后方法可达、宿主发射腿照发,串形类实例仍给回同一个对象。
169
+ - 登记物:根公面基线 1354 → 1356(+2);测试钩 62 不变;超集台账 `docs/type-superset.json` 95 → 97 条(`_sema_tool_history_mismatch` / `_sema_park_failed_reason`);门清单 `scripts/gates-manifest.json` 165 → 167 条(两道新门;崩溃收敛 / 重开挂起 / 凭证取值三道扩门的说明同批更新),README「Guards」与负控文档派生表同批重生;棘轮 `portability.kernel` 20 → 22、`portability.adapt` 36 → 37、`portability.index` 228 → 229(registry.json 追四条账:内核闭包新边 `src/hitl/suspendedReopen.ts`〔CC-276,值级 import 只有已在内核里的 `engineErrorCodes`〕与零 import 叶子 `src/toolHistoryMismatch.ts`〔CC-268,经流驱动与 `adapt()` 进内核 / A 层 / 根入口闭包〕);单例清单 561 → 573 条,高风险上限 133 不变。
170
+
171
+ ### Known limits(本版新增)
172
+
173
+ - 会话历史错配(CC-268):判型只认三句 Anthropic 形 provider 模板,OpenAI 兼容车道的同病不出键、不出出路句;JSON 回体只认从开头起的错误信封(宿主直接交的 SDK 错误对象形 `400 {…}` / `400 <原话>` 同认;KL-308);`toolUseId` 读不出的几形(字符集外、超过 128 字、失败句被截在 id 中间)键里不带 id、节点解析随之判不了(KL-309);连续次数账本在进程内、按会话、上界 64 只会话,重启 / 挤出后从 1 重数;宿主开流时钉的会话 id 从没被引擎回显过时,没有回显会话 id 的终局(失败事件帧、409 拒绝等)认不出属于哪一只会话,本进程里每一只会话正在数的连续都按被打断处理 —— 少报,不多报(KL-310);没有 run id 的终态、回放终态与结局读不出的终态不记次数(与这一次错配不同时清零),这些形上只有出路句、没有次数句;段外只认得最近 16 只 run,更早的 run 被重看会被当成新的一次(KL-311);重复 id 那一句模板不带 id,节点解析判不了,次数的指纹只剩 kind(KL-312);节点解析信宿主交进来的行序(KL-313);孤儿结果 / 重复 id 两句的报文全形是照 provider 错误体形构造的,只有锚串有出处(KL-314);连续账本是可写的会话级模块单例,同一进程里有两份本包实例时各记各的 —— 各从 1 数起(少加一句次数),另一份经过的别的结局这一份看不见、不会清零(可能多报一次「连续」)(KL-315)。
174
+ - 崩溃收敛 / 重开挂起(CC-269 / CC-276):`suspended_reopened.taskId` 今天恒缺席 —— 服务端的重开挂起帧不带 `taskId` 键,本包不从同一条流的首帧代用;将来在场时是帧上 `taskId` 键原样,只有服务端用这个键、且值按 run 唯一时它才等于 run id(KL-305);接管 / 从头重放的腿上本臂按流序报每一次重开(含已成历史的那次),「此刻还成立吗 / 还属于这块屏」由宿主判(KL-306);`decided` ∧ `resumeSafe:true` 判 `contradictory`,不判 `approved_then_interrupted`(KL-307)。
175
+ - 取值函数形的连线身份按函数引用认:宿主每次现造一只函数会让活动台账每次都被顶掉、监视器源停手退回快照轮询。按值比会重新引入本版要去掉的形(令牌轮换即清账),按形比会让同址同 principal 的两只不同凭证来源共用一条台账 —— 两害取轻,口径成文(KL-303)。
176
+ - 监视器源在 401 之后的 60 s 长退避不变:取值函数形下,若某一发恰好落在引擎换代、新令牌还没写回的窗口里答了 401,即使取值函数随后已给出新值,下一次重试仍要等到长退避到点(KL-304)。
177
+ - 登记物按既定裁定改窗(本版对这些物零改动):同名影子对账门豁免表对终端 1.0.139 集成分支跟表后剩下的两行(重开口外层 / 回执成因词表),期限 0.87.0 → 0.88.0;装配 / 宿主扩展类十行对终端 1.0.139 集成分支重看判词不变,重看期 → 0.89.0;过渡物退役登记 RL-11 … RL-14 到期重看 —— 上游契约那一节与同名常量仍未出、本包支持的引擎 / 服务端底线仍未越过 —— 重看期 0.87.0 → 0.89.0(本版距上一版一天,重看期实质未过)。
178
+ - 完整台账见接入文档 §113 末行「包侧缺口」。
179
+
52
180
  ## 0.86.0(2026-10-01)
53
181
 
54
182
  > 主题:**minor** —— 八件同发,另有开发依赖两步换钉。① **引擎 7.34.0 提货,两代读法**(CC-249 / CC-245 / CC-230 第二批;老引擎照旧、新引擎按新形,缺席读作老引擎、不折成否定):引擎包入口导出的六张事实表与本批碰到的三张闭集改为构建期生成;门处置「谁拒的」改为两代并集(新引擎的 `mode` 有了专句,老引擎仍发的 `plan_mode` 照认);门记录上权限模式两臂进视图并给具名读口 `gateModeRelease`;通告码册 +6 且各有事实读器;读站判不出读什么时的专属卡 `read_unestablished` 进结构化卡型全集;本人规则店读不出在新引擎上改为「跳过 + 一条通告」,老引擎那张卡照读;粗 shell 档那一句改成两代都成立的说法。② **服务端 7.105.0 提货**(CC-251 / CC-252):会话规则写口拒「写进去就跑不了」的工具名(`400 rules.legacy_tool_name`)投成三只写面的具名结局;配了服务凭据的部署上,门前只读路(workflow 读路、fleet 流)的 `401 auth.unauthorized` 投成具名态与一句话。③ **请求键 `approverPosture` 退役**(CC-253):引擎按名拒收、服务端 7.106.0 起整条 400,本包停发;宿主仍给 ⇒ 构造期按名响亮拒,不改发 `permissionMode`。④ **委派判不出通告带补救话**(CC-254):`delegation.ask_unresolvable` 视图 +可选 `remedy`,原样透传。⑤ **开发依赖换钉引擎 `~7.35.0` 再到 `~7.36.0`**(CC-255 / CC-261):生成物重生成、既有表一个值都没变;引擎工具声明门的九个拒码登记进配置拒绝识别表(`CONFIG_REFUSAL_CODES` 8 → 17,只登记不分派);通告码册再 +1 `route.tool_call_id_folded`(受众运维面,只登记)。⑥ **`adapt()` 在错误信封上不再回落读旧名 `result`**(CC-221):0.83.0 两名并读的收口;现役流零变化,只有宿主把 0.83.0 之前的原始输出落盘再喂回 `adapt()` 那一形看得见。⑦ **服务端 7.106.0 提货**(CC-250 / CC-256 / CC-257 / CC-262 / CC-263 / CC-265):caps `store` / `centerWiring` 两只窄读口、SQL 姿态两代读、计费入口 503 `fleet.lease_unavailable` 的读口与一句话;caps `executionLane.isolated` 与「本机无 OS 沙箱」判定;请求键 `inheritEnv` 的构造、版本闸片段口与两只拒按码出句;权限规则表超帽 / 坏项的机读读口与一句;工具声明拒按码认领「不是暂时故障」;请求体键形拒的两张键表读口;强制卡值变零改动实证。⑧ **`-p` 首帧带出工具清单的来源**(CC-266 / CC-267):`withPrintInitFrame` 放出的首帧多两只超集键;三张估计工具表改为常驻(零行为)。根公面运行期导出 1310 → 1354(+46 −2);测试钩 60 → 62;公面类型 891 → 922(+31);超集键 +2(`_sema_tools_source` / `_sema_tools_fallback_reason`);通告码册 73 → 80;零新投影臂(既有 `tool_end` 臂上的门记录视图多两组可选位);开发依赖引擎 `~7.33.1` → `~7.36.0`。peer sdk 地板 `>=12.0.1` 不动 —— sdk 14 的三处型面 BREAKING(`TaskRequest.approverPosture` 删、`Capabilities.taskApproverPosture` 删、顶层 `Capabilities.sql` 搬进 `store.sql`)本包已按结构读覆盖:本版全部 `.d.ts` 在 sdk 12.0.1 / 13.1.0 / 14.0.0 / 15.0.0 下严格编译(不跳过库检查)都零错误,消费方先升 sdk 14 或先升本包都不编译红;服务端 7.105.0 / 7.106.0 与 sdk 13 / 14 的新形一律按码 / 按结构读,不 import 只有新版 sdk 才有的型 / 值。🔴 **型面 BREAKING 三处**(`TaskRequestInput.approverPosture` 删;两个运行期名字退出根入口,见 Removed;`SemaPermissionDenial.deniedBy` 闭集 +`mode`:型由 SDK `DeniedBy` 换成 `GateDeniedByWord`,对它穷尽 `switch` 的端编译红,见 Changed 第 4 条);另有**已发导出的可观察变化**在 Changed 逐条单列(第 1–34 条与第 36 条,写明谁要跟;第 35 条是零行为的重分类);对下列联合做穷尽 `switch` 的端编译期红:`EngineNoticeFactsCode`(+6 员)、`SessionPolicyFailure` / `SessionPolicyTightenOutcome` / `SessionPolicyRemovalOutcome` / `WorkflowResolution`(各 +1 臂)、`BackgroundSourceHealth`(+1 词)、`SemaPermissionDenial` 的 `deniedBy`(+`mode`)。