@sema-agent/client-core 0.85.1 → 0.85.2
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 +34 -0
- package/README.md +2 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +3 -0
- package/dist/adapter/activeRunSelfHeal.js +126 -36
- package/docs/INTEGRATION-CLIENTS.md +139 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,40 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.85.2(2026-09-30)
|
|
53
|
+
|
|
54
|
+
> 主题:**patch**,一件 + 一处同族修复 —— 自愈重开的两只失败结局(`plan-review-reopen-failed` / `ask-reopen-failed`)带上**这一次重开放弃所依据的那一发失败请求的外层 wire 码**(CC-260,终端的请托);另把自愈腿读**错误对象与成功应答记录**上的各位收进保护(见 Fixed),注入形交接行在投递方式未知时改说实话(见 Changed)。零型面 BREAKING;根公面运行期导出 1310 不变;测试钩 60 不变;公面类型名不变(两个已导出型各多一个可选位:`ReopenCardVerdict` 不成功臂 `_sema_errorCode` · `SelfHealOutcome` 两只失败臂 `errorCode`);超集键 +1(`_sema_errorCode`);`activeRunSelfHealRow` 不引用 `errorCode`,只在注入形交接行、投递方式未知那一形换两句(见 Changed);零投影臂;peer sdk 地板 `>=12.0.1` 不动;开发依赖不变。
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **自愈失败结局的 `errorCode`**(CC-260):`SelfHealOutcome` 的 `plan-review-reopen-failed` 与 `ask-reopen-failed` 各 +1 可选键 `errorCode?: string` —— 这一次重开**因为一发请求失败而放弃**时,那一发的外层 wire 码。present-iff(只在有码时在场,值恒为非空串)。读法与本包按码分诊的各处同一只:折叠码 `resume_blocked_by_policy` 在时答 `blockedBy` 那个原码,否则答 `errorCode`(服务端没给具体码时是按状态派生的粗码,例 `request.rejected`)。接入文档 **§111 EC-1 / 111a-1**。
|
|
59
|
+
- 口径是「放弃所依据的那一发」:带的是**放弃所依据**那一发的码;之后的请求若**改变了放弃的依据**(例:轮询终于答上了、待决行出现了)⇒ 不带;只作确认的读(例:决断 POST 失败之后确认待决行仍在)不改依据,照带那一发 POST 的码。放弃所依据的那一发没有 wire 码(断连 / 截止 / 中止 / 客户端自己的错)⇒ 不带,不回溯更早的码;调用方已中止(放弃的依据是中止)⇒ 不带;因判定拒开(决断在路上 / 卡是用户关的 / 会话没有接界面)⇒ 不带 —— 按判决本身答的拒开,两只失败结局在这三形上恒不带 `errorCode`(本包保证;ask 臂认判决上的用户关卡位来丢码,结局不加这一位);ask 判决带 `pendingRowGone` 且不在飞时改道陈旧 park 那条路,本包自己那一发读 run 状态失败照口径带码(放弃所依据的那一发是它,判决上别的判定位不拦)。本包自己的来路上,`pendingRowGone` 与它同在只有一形:待决项已证不在、紧接着本包复核那条 run 的状态时请求失败;宿主判决自带 `pendingRowGone` 与 `_sema_errorCode`(不合口径的组合)时,计划臂原样透传两位。
|
|
60
|
+
- 码的三条来路:宿主重开口(`reopenPlanReview` / `reopenAskPark`)抛错 ⇒ 抛出物的码;宿主重开判决上的 `_sema_errorCode`(下一条);待决项已证不在时本包自己的三发 —— 呈卡前、呈卡后两次读那条 run 的状态,开枪前再问一次属主待决行数 —— 失败即收口,带那一发的码(只认请求本身失败:请求答了、答回的记录上 `status` 读不出不算,按读不到状态处置、不铸码)。
|
|
61
|
+
- 出句不引用它:`activeRunSelfHealRow` 的每一句与不带码时逐字节同;要说成因的端自己读这一键。
|
|
62
|
+
- **重开判决的失败码位**(CC-260):`ReopenCardVerdict` 不成功臂 +1 可选位 `_sema_errorCode?: string`,宿主自带的重开口按同一口径**可选**铸(只在 `reopened: false` 上读,只认非空串;读不出按缺席,与判决其余各位同一读法)。宿主重开口抛错时(调用方未中止),本包在保护内把抛出物的码铸到判决上 —— 两只失败结局与 steer `queued` 结局的 `reopened` 读的是同一个位;`queued` 结局的 `reopened` 是宿主判决的原样拷贝,宿主判决上判定位与码两样都给了就两样都在(丢码只在两只失败结局上做)。包内计划复核重开口 `reopenPlanReviewCard` 在重开这一步不发任何 wire 请求,不铸这一位。接入文档 **§111 EC-2 / 111a-1**。
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- CC-260 在已发导出上的可观察变化:宿主重开口**抛出一个带 wire 码的错误**(调用方没中止)时,两只失败结局多 `errorCode`,steer `queued` 结局的 `reopened` 从 `{ reopened: false }` 变为 `{ reopened: false, _sema_errorCode: <码> }`;抛出物没有 wire 码(普通 `Error`、断连、非对象)时与 0.85.1 逐字节同。另:待决项已证不在、本包复核请求失败的那几形,`ask-reopen-failed` 多 `errorCode`。其余结局、判决、出句与 0.85.1 逐字节同(错误对象 / 应答记录读不出的那几形见 Fixed)。
|
|
67
|
+
- 注入形(`activeRunSelfHealRow(…, 'injected', follow)`)的交接行:`running-steered` 的投递方式缺席 / 读不出 / 表外词时,修前与 `applied` 同句(「was passed to the reply already in progress … instead of starting a new one」,宿主声明续听时还说「nothing for you to do now」,替引擎断言消息已交给正在进行的那一轮),本版改说投递方式未知 —— 两种续听声明下都不说「不用动手」:
|
|
68
|
+
- 未声明续听 —— `A follow-up message sema sent on its own (not one you typed) was accepted for the reply already in progress (id <id>), but how it will be delivered was not reported, so sema cannot tell whether that reply will pick it up — watch that reply before deciding whether anything needs to be sent again.`
|
|
69
|
+
- 声明续听 —— `A follow-up message sema sent on its own (not one you typed) was accepted for the reply already in progress (id <id>), but how it will be delivered was not reported, so sema cannot tell whether that reply will pick it up. sema is following that reply and will show whatever it asks for next; check what it does before deciding whether anything needs to be sent again.`
|
|
70
|
+
- `applied` 那两句、用户形(本就说「the engine did not say how it will be delivered … before sending it again」)、处置档(`handed-off`)与续听意图(投递方式未知仍按保守当活 ⇒ `tail`)都不变。接入文档 **§111 EC-7 / 111a-2**。
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- `attemptActiveRunSelfHeal` 读**错误对象与成功应答记录上的**各位收进保护(CC-260 同族修复;0.85.1 把宿主重开判决各位收进了保护,这是另外两半)。错误对象:自愈腿里 `runs.get` / `runs.steer` / `runs.cancel` 抛出的错误对象,`status` / `message` 是会抛的取值器、或整个是读就抛的 Proxy(`get` / `has` 陷阱)⇒ 按那一位缺席处置,结局照常落定。修前(0.85.1 实测)这几形 `attemptActiveRunSelfHeal` 直接 reject,抛出的就是取值器那个错:待决项已证不在时本包读 run 状态、`running` 三选卡出卡前的存活对账(两处都读 `status === 404`);kind 与状态都缺席时补读 run 状态失败、steer / cancel 失败腿(细节句读 `'message' in e` / `.message`);steer / cancel 的至多一次失败分类(读 `status`)。这几处读法分别自 0.29.0 / 0.30.0 / 0.37.0 起就是裸读(按源码历史;早于 0.85.1 的产物没有实跑)。修后:读不出 `status` ⇒ 不当 404(不判幽灵)、至多一次失败分类答 `unknown`(送达未知,不断言「没送到」);读不出 `message` ⇒ 细节句 `the engine gave no detail`;`errorCode` / `blockedBy` 读不出按缺席同样落定(取码口原本就在保护内,本版补格钉回归)。公面 `atMostOnceFailureClass` 对这类对象答 `'unknown'`、不再抛;公面 `readSteerDelivery` / `readSteerReceiptStatus` 同样收进保护:回执上那一位读不出(取值器 / Proxy 抛)⇒ 答 `null`(与缺那一位同答)、不再抛(0.85.1 及更早直接抛)—— 自愈 steer 腿随之:回执读不出 ⇒ 落 `running-steered`(投递方式读作缺席),用户形说「sema handed your message to run …, but the engine did not say how it will be delivered … watch that run before sending it again」,注入形说投递方式未知那一句(见 Changed)。修前(0.85.1 实测)落 `running-steer-failed`:取值器抛普通错误 ⇒ 送达未知那一句,细节句是那条取值异常;取值器抛出的是带 422 形状态码的对象 ⇒ `delivery: 'rejected'`,用户形说「Your message was NOT sent; send it again if you still want it.」—— 而引擎其实已经收下了那一枪,这句话诱导用户把一条非幂等指令再发一次。成功应答记录:kind 与状态都缺席时那一次补读 run 状态,`runs.get` 答回的记录上 `status` 读不出(会抛的取值器 / 读 `status` 就抛的 Proxy)⇒ 与读不出状态同处置,落 `state-unknown`「the engine reported no status for that run」(不把那条异常当成引擎给的细节);修前(0.85.1 实测)reject,这一读自 0.29.0 起就在保护外(按源码历史)。待决项已证不在时两次读状态与 `running` 存活对账:请求答了、记录上 `status` 读不出 ⇒ 同样按读不到状态处置(不铸码、不判幽灵);修前(0.85.1)这一读与请求共用一处保护,读抛按「那一发没答上来」处置 —— 结局相同,只差一形:取值器抛出的恰是 404 形错误时,修前被当成引擎说「查无此 run」(落 `ask-run-not-found` / `running-not-found`),修后按读不到状态收口。cancel 之后的释放轮询不变(读抛按那一发没答上来)。普通错误对象与普通记录(SDK 给的那一类)的结局与 0.85.1 逐字节同。接入文档 **§111 EC-6**。
|
|
75
|
+
|
|
76
|
+
### Gates
|
|
77
|
+
|
|
78
|
+
- 扩门 `scripts/run-selfheal-reopen-test.mjs`(595 → 704 格)。G14(+22,CC-260):宿主重开口抛 503 / 409 ⇒ 结局带那个码、其余键逐字节同;折叠码按 `blockedBy`(顶层 / `extra` 两处),`blockedBy` 缺席答折叠码本身;客户端错 / 断连 / 空串码 / 只有状态码 / 抛非对象 ⇒ 无键、与 0.85.1 逐字节同;steer `queued` 时重开口抛错 ⇒ 结局的判决带 `_sema_errorCode`、结局形不加键、两形行句不变;宿主判决位透传,坏形(非串 / 空串 / 数组 / `null` / `undefined`)不带,只在 `reopened` 严格 `false` 上读,挂在原型链上的取值器与不可枚举的自有键照读;带码结局的用户形 / 注入形 / 带保会话出路三句与处置档与去掉码的同一结局逐字同;判定形(在飞 / 用户关卡 / 无界面)宿主带了码也丢;包内计划复核重开口无界面、关卡后门实例读失败 ⇒ 判定形、零码;待决项已证不在时本包三发:呈卡前读状态失败 ⇒ `pendingRowGone` 与码同在、宿主早先的码被这一发的码盖掉,断连 ⇒ 不带且不回溯,读状态成功后按判定收口(无呈卡口 / 表外状态词 / 奇形记录 / 读口缺席)⇒ 不带(宿主判决上的码不沿用),呈卡后读状态 / 开枪前复证失败 ⇒ 带码、不带 `pendingRowGone`、零 cancel,复证答非 0 / 非 wire 错 / 呈卡口抛错 ⇒ 不带,404 ⇒ `ask-run-not-found` 不加键,读到计划停驻转计划臂 ⇒ 只看计划重开口的判决。G15(+47,同族修复):错误对象七形(`status` / `errorCode` / `blockedBy` / `message` 取值器抛、Proxy `get` / `has` / 全陷阱抛)× 五条路(陈旧 park 卡前复核 / `running` 存活对账 / kind 与状态都缺席时的补读 / steer 失败腿 / cancel 失败腿)⇒ 不 reject、结局照常落定;公面至多一次失败分类口对七形不抛、答 `'unknown'`(折叠码那一形 409 照答 `'rejected'`),正常形逐格同旧;宿主重开口抛这些对象 ⇒ 两臂照常落定;成功应答记录两形(`status` 取值器抛 / 只在读 `status` 时抛的 Proxy)× kind 与状态都缺席时的补读 ⇒ 落 `state-unknown`、细节句是「读不出状态」那一句,另三条读记录的路(陈旧 park 复核 / `running` 存活对账 / cancel 后释放轮询)与全陷阱都抛的 Proxy 记录(`await` 探 `then` 即抛,按读口失败处置)钉回归。G16(+16):成功答回的记录上 `status` 取值器 / Proxy 抛带码错 ⇒ 卡前 / 卡后复核都不带码(卡后零 cancel)、抛 404 形错误不判幽灵,请求本身 reject 照旧铸码 / 404 照旧判幽灵;调用方中止后重开口抛带码错 ⇒ 两臂与 steer `queued` 路径都不带码,没中止照旧带;ask 判决带用户关卡位与码 ⇒ 不带码、结局不加位;用户关卡那一刻门实例读失败 ⇒ 此刻那一次读不发、答用户关卡、不带码;steer 回执两只公面读口遇读不出的回执答 `null`、不抛,自愈 steer 腿落 `running-steered`。G17(+18):回执整只不可读 / 只投递方式不可读 × 两种续听声明 ⇒ 注入形走投递方式未知那一句、不说「nothing for you to do」,用户形同说「引擎没说怎样送达、先看那一轮」;投递方式缺席 / 表外词 / 空串同句;`applied` 两句照旧,续听意图与处置档不变。判决读取保护那一组(G2⑧u–⑧x)的位名单加第九位 `_sema_errorCode`(+6)。
|
|
79
|
+
- 登记物:超集台账 `docs/type-superset.json` 92 → 93 条(`_sema_errorCode`:判决形声明、读口与抛错铸点同在一处);扩门 `scripts/run-terminal-identity-copy-test.mjs`(1041 → 1077 条):注入形事实表 15 → 17 句(投递方式未知的两句),样本补缺席 / 空串 / 表外词三形;「nothing for you to do」只许在续听已挂且投递方式为 `applied` 的交接档与重投档出现。门清单 `scripts/gates-manifest.json` 自愈重开门的说明与 README「Guards」派生表同批更新;门数 158 不变。
|
|
80
|
+
|
|
81
|
+
### Known limits(本版新增)
|
|
82
|
+
|
|
83
|
+
- 包内计划复核重开口在自动触发、撞上用户关卡记号时要读两次门实例(用户关卡那一刻起读的那一次、此刻那一次),任一次失败都按「证不出是新门」答用户关卡:结局带 `dismissedByUser`、不带 `errorCode` —— 由请求失败推出的判定形(0.83.4 起如此);读失败若是因为引擎在排空,端拿不到那个码(KL-287)。
|
|
84
|
+
- 完整台账见接入文档 §111 末行「包侧缺口」。
|
|
85
|
+
|
|
52
86
|
## 0.85.1(2026-09-30)
|
|
53
87
|
|
|
54
88
|
> 主题:**patch**,三件 —— 请求装配回执的省略成因补一张**给终端用户看**的句表与取句口(CC-248);plan-review 重开口在「这个会话没有接能显示卡的界面」那一形上带机读成因位、自愈行补一句成因(CC-258);多会话宿主在自己的会话键上登记呈现回执的口 `registerArmedGateFromQuestionIdFor` 回到根入口(CC-259)。零型面 BREAKING;已发导出的可观察变化:「没有接界面」那一形(见 Changed),另有两处修复 —— 宿主重开判决某一位读不出时自愈不再 reject、宿主日志 / 探针口抛错不再改变判决(见 Fixed);根公面运行期导出 1307 → 1310(+3:`taskRequestOmissionCauseNotice` / `TASK_REQUEST_OMISSION_CAUSE_NOTICES` / `registerArmedGateFromQuestionIdFor`);测试钩 60 不变;公面类型名不变(两个已导出型各多可选位:`ReopenCardVerdict` 不成功臂 `_sema_noPresentationSurface` · `SelfHealOutcome` 两臂 `noPresentationSurface`;一个已导出函数的返回型 `void` → `boolean`:`hostLog`,见 Fixed);超集键 +1(`_sema_noPresentationSurface`);成因闭集 `TASK_REQUEST_OMISSION_CAUSES` 不变;接入方那只 `taskRequestOmissionCauseDetail` 逐字不变;零投影臂;peer sdk 地板 `>=12.0.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.85.
|
|
38
|
+
**Version:** 0.85.2
|
|
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
|
|
@@ -371,7 +371,7 @@ guard still cross-checks the table by name).
|
|
|
371
371
|
| `scripts/run-type-superset-ledger-test.mjs` | The type/wire **superset ledger** (`docs/type-superset.json`): positions this package adds on top of a CC-shaped contract, each carrying the evidence for what CC's own type surface does or does not have there. Completeness is deliberately uneven and the ledger says so. The `_sema_*` private-key class is checked in **both** directions (a key in the source that never entered the ledger is red, naming key and file; a ledger row whose key left the source is red) — but only for keys written as literals, which is the convention the ledger mandates. A key assembled by string arithmetic is beyond what any static rule can enumerate, so the guard fails closed on every shape it *can* decide (a bare `_sema_` prefix is red wherever it appears, save one pinned guard site) and leaves the rest as a convention violation for review to catch, rather than claiming a completeness it does not have. The two hand-surveyed classes are only checked for coordinate and evidence integrity, never discovered. Both directions read the source through the **TypeScript AST**, not a text scan, and they read two different sets out of it. A *key site* is an identifier, or a string whose whole value is the key — so `'_sema_decision-v2'` is carried whole rather than truncated at the first non-identifier character into some *other* key that happens to be registered. A *mention* is the key appearing inside a longer string, which is prose, not usage. The staleness direction counts key sites only: a comment or a doc sentence left behind after the last real mint site is deleted must not keep the row alive (mutation-proven — with both the comment and the prose string untouched, removing the one real site turns the guard red). And because a prefix can be concatenated or interpolated into a key no static set will ever see, the bare `_sema_` literal is refused outright rather than traced: every occurrence is red except the single inline `startsWith` guard the sanitizer needs, because the set of expressions a bare prefix can travel through on its way to a concatenation is open-ended and enumerating it is always one form behind. Every row's `host` must still resolve, with the key being a real **member of that declaration** rather than a string occurring somewhere in the same file — `governanceForced`/`delegation` each live on two different shapes in one file, and a member commented out is a member deleted, which a text-shaped check happily reads as still present. And the direction worth the most: each machine-form `ccAbsenceEvidence` is re-derived from the row's own `key` — the ledger's recorded string must match that derivation verbatim, since a row quietly witnessing `\bnever_present\b` is green forever while watching nothing (mutation-proven: the same edit passes the unbound form and is caught by the bound one) — and the check runs against the names the installed `@sema-agent/agent-types` `.d.ts` set actually declares, parsed with the TypeScript AST rather than grepped, so a name CC merely mentions in a comment cannot force the row into the manual escape hatch and thereby retire the very witness that was supposed to fire the day CC declares that name for real. That escape hatch is gated by an allowlist living **in the guard**, not the ledger, so claiming it costs a reviewed diff. Missing material never reads as a pass, and the verdict splits by *why* it is missing: no TypeScript parser skips the suite before it starts; a missing `agent-types` still runs and prints the first three directions, then exits **1** when `package.json` declares the mirror but it is not installed — a broken install must not retire the repository's only "the day CC declares this name" alarm, and reporting it as a skip would leave "never evaluated" and "evaluated, no drift" indistinguishable to the runner — and exits 3 only when nothing declares the mirror at all, which is the one case where the direction genuinely does not apply. Either way a run that evaluated no witness is never counted as one that did. When the mirror *is* present its **installed version** is witnessed too (the two declared floors must agree with each other and the installed copy must meet them), since four preflight probes are satisfied by an arbitrarily stale mirror — they prove the extractor speaks, not that it is current. Every direction carries a positive control — known-present CC symbols, a comment-only sample proving the extractor distinguishes declaration from mention, and synthetic corpora fed through the **same** discriminator function the real verdict uses, so a verdict quietly rewritten to return nothing takes its own control down with it |
|
|
372
372
|
| `scripts/run-rules-side-test.mjs` | The persisted-permission-rules lane's shared decision half. The two capability bits are checked as **two independent gates** — a worker can honestly advertise the rules lane while predating the revoke routes, and that shape must *hide* the governance surface rather than render a dead entry. Failure classification is by **disposition, not cause**: the two 404s (route missing vs. dead ticket) never share a bucket, a 503 `rule_import_retry` means *the ticket is still alive* (the opposite handling of a dead one), and a stale-cursor 400 drops the cursor and re-lists from the top exactly once — never resuming a stale keyset, never surfacing a partial governance list, and never paging past the hard cap. The persist-ack reader is **merged into** `readToolApprovalRespondAck`: the three-state verdict (`persisted` / `refused` / `unknown`) is derived only from an ack that passed the package's structural narrowing, and a half-shaped object such as `{rulePersisted: true}` with no `delivery` reads as `unknown` — the pre-merge shell read would have said `persisted`, which is precisely the double-ledger drift this file closes, so that case is pinned in reverse. The local-allow-rule skeleton pins all five narrowings (whole-tool, tool-name match, literal anchor with the escaped-star counter-example, bare interpreter prefix consulted only for Bash, and the canonical dangerous-pattern overlay) **with their refusal strings byte-for-byte** — the cli's 128-assertion suite anchors the same strings, so a one-character edit here changes observable behaviour on three clients — and asserts the parse is a pure function of its input, because the same call backs both "render the option" and "resolve the selected value" `listAllPersistedRules` needs only `list` (`RulesListFacade`; the other four methods are known to the parameter type as optional members): a synthetic consumer compiled against the built declarations passes a two-method object, a list-only literal, a `Pick` slice, the named type, the full facade, and the full or two-method facade written as an inline object literal — including arrow functions with untyped parameters — all with zero diagnostics, while a misspelled method name in such a literal is still reported. |
|
|
373
373
|
| `scripts/run-park-decision-layer-test.mjs` | The decision layer behind the "stuck behind a card" family, shared by every client. A pending row that is **not in the queue** is three states, not one: a bounded, interruptible re-probe loop distinguishes *a decidable row*, *not born yet* (no positive evidence that anything settled — an empty queue proves nothing) and *settled elsewhere*, always probes at least once so a zero budget keeps the pre-fix semantics verbatim, cuts a hung read face off at the window rather than only noticing afterwards, and reports the honest failure when the window is spent instead of inventing a decision. The decision-note reader is likewise three-state: an explicit `noteRecorded: false` outranks an echoed note body, absence renders **no line at all**, and untrusted note text is flattened and bounded before it ever reaches a renderer. Row routing anchors on the deciding quantity — a row carrying `gateKind: "human"` with `toolName: "Write"` is a tool gate, because `human` is the engine's *generic* "someone must decide", not a synonym for a question — and the queue scan refuses to surface a row it cannot positively prove belongs to this session. A chain that fails after the row vanished is split by whether a card was ever presented: decided-elsewhere, or not-its-turn-yet. A row-level single-flight makes "at most one card per pending item" structural rather than incidental. The resume three-way card pins the option **order** (the zero-effect choice sits at index 0, because the frame carries no default-focus field and a stray Enter must not attach or cancel), renders only options the wired verbs can honour, collapses every ambiguous answer to zero action, omits the liveness line entirely when the engine gave no evidence, and — when there is no card lane at all — prints three real routes and exits on a dedicated code rather than reporting success |
|
|
374
|
-
| `scripts/run-selfheal-reopen-test.mjs` | The 409 active-run self-heal decision chain: `governanceForced` narrows on strict `true` only; triage prefers the wire's `pendingGate.kind` and falls back to the status table (an off-table kind is never guessed into a card arm — hands-off plus the honest wording); a first-sight card makes zero closed/reopened claims and a host presentation receipt of `presented: false` demotes the outcome to reopen-failed; park-row ownership is a fail-closed positive proof (own-run ledger or session id — unprovable is not owned); the three gate-identity key literals live in exactly one mint (`hitl/gateIdentity.ts`, AST string-token scan); the armed-gate presentation ledger is per-session; and the `plan_review` reopen arm shares the arm arm's card body, three-state verdict and delivery pipe, consuming the presentation history once a decision is delivered. The same chain also carries the `running` three-way card: both plan-family gate kinds route to the plan arm and all four ask-family kinds to the ask arm (an off-table kind still never gets guessed into either); the card is offered only for verbs that can actually be honoured and a missing presenter means zero action rather than a silent cancel; a steer is sent **exactly once** with its three delivery outcomes worded apart (a `queued` receipt is the wire correcting the triage input, so the named park word decides which card gets reopened, and an unrecognised park word drives neither arm), and a steer failure is split into *provably not delivered* (4xx) and *delivery unknown*, because telling a user to resend a non-idempotent instruction that may already have landed is how duplicates get made. After a user-chosen cancel, "the session is free" is asserted only from a whitelist of terminal states — park states hold the claim, an unrecognised state word is not a release, a failed read is *unknown* rather than a release, and only a 404 counts as one — and the honest timeout line quotes how long it really waited. The two "card could not be reopened" rows can carry a host-declared way to keep the conversation, which says the card comes back on resume only if it is still waiting: it is placed before the route that abandons it, never offered for an injected submission, while a decision is still on its way, or once the pending approval has been proven gone (the outcome then carries a flag saying so; the proof only counts before the cleanup card is shown, so a fallback after the card carries no flag unless a fresh read finds the run finished, and a recheck that finds the approval back clears it), the host function is not even called in those cases, and it is treated as unavailable when it throws or returns an empty value; a host can also switch off the engine decide route on the interactive rows while the cancel route stays, and with neither given all four rows are pinned byte-for-byte to the text the previous release produced. When the plan reopen refuses because the user closed that card (`dismissedByUser`), the outcome carries the flag and one package-owned line says so — you closed it, a message brings it back — in the typed, the injected and the queued-steer forms, with no way-to-keep and no engine decide route; the reopen port receives `{ trigger }` mapped from the submission origin (typed ⇒ `user`, injected ⇒ `automatic`, absent ⇒ the old single-argument call). When the reopen refuses because no view is subscribed to question frames for that session (`_sema_noPresentationSurface`), the plan and ask outcomes carry `noPresentationSurface`, and the five lines that talk about the card not coming back — both arms' typed line, the queued-steer typed and injected lines, and the injected not-delivered line — add one package-owned clause saying the session has no view that can show decision cards, byte-identical to the plain refusal otherwise; loose values and the other refusals (answer in flight, user-closed card, plain refusal) carry neither the flag nor the clause. For a host that reopens under its own session key with a presentation receipt, the suite drives the whole sequence end to end: subscribing for that key, reopening, and registering the receipt through the per-session call `registerArmedGateFromQuestionIdFor` gives `reopened: true` with the right first-sight reading, a second reopen reads as seen before, a decisive answer (with no extra bookkeeping from the host) makes the next reopen read as first sight again, and a dismissal does not; registering through the default-session call instead leaves the receipt window to run out with `{ reopened: false }`. Every bit the package reads off a host's reopen verdict is read once, inside the guard: a bit whose getter throws (or a proxy that throws) is treated as absent, so the self-heal still settles — with exactly the outcome it would give if that bit were missing — and the rows never throw, including for an outcome the host built itself; a plain verdict lands in the queued-steer outcome byte for byte, key order and any extra keys the host added included, a key whose getter throws is the only one left out, and an own key literally named `__proto__` is copied as a key rather than changing the copy's prototype; symbol keys are copied too and a verdict with a null prototype stays one (compared key by key, value by value and by prototype, not through JSON); and an outcome whose `reopened` property itself cannot be read is phrased as if it had none. |
|
|
374
|
+
| `scripts/run-selfheal-reopen-test.mjs` | The 409 active-run self-heal decision chain: `governanceForced` narrows on strict `true` only; triage prefers the wire's `pendingGate.kind` and falls back to the status table (an off-table kind is never guessed into a card arm — hands-off plus the honest wording); a first-sight card makes zero closed/reopened claims and a host presentation receipt of `presented: false` demotes the outcome to reopen-failed; park-row ownership is a fail-closed positive proof (own-run ledger or session id — unprovable is not owned); the three gate-identity key literals live in exactly one mint (`hitl/gateIdentity.ts`, AST string-token scan); the armed-gate presentation ledger is per-session; and the `plan_review` reopen arm shares the arm arm's card body, three-state verdict and delivery pipe, consuming the presentation history once a decision is delivered. The same chain also carries the `running` three-way card: both plan-family gate kinds route to the plan arm and all four ask-family kinds to the ask arm (an off-table kind still never gets guessed into either); the card is offered only for verbs that can actually be honoured and a missing presenter means zero action rather than a silent cancel; a steer is sent **exactly once** with its three delivery outcomes worded apart (a `queued` receipt is the wire correcting the triage input, so the named park word decides which card gets reopened, and an unrecognised park word drives neither arm), and a steer failure is split into *provably not delivered* (4xx) and *delivery unknown*, because telling a user to resend a non-idempotent instruction that may already have landed is how duplicates get made. After a user-chosen cancel, "the session is free" is asserted only from a whitelist of terminal states — park states hold the claim, an unrecognised state word is not a release, a failed read is *unknown* rather than a release, and only a 404 counts as one — and the honest timeout line quotes how long it really waited. The two "card could not be reopened" rows can carry a host-declared way to keep the conversation, which says the card comes back on resume only if it is still waiting: it is placed before the route that abandons it, never offered for an injected submission, while a decision is still on its way, or once the pending approval has been proven gone (the outcome then carries a flag saying so; the proof only counts before the cleanup card is shown, so a fallback after the card carries no flag unless a fresh read finds the run finished, and a recheck that finds the approval back clears it), the host function is not even called in those cases, and it is treated as unavailable when it throws or returns an empty value; a host can also switch off the engine decide route on the interactive rows while the cancel route stays, and with neither given all four rows are pinned byte-for-byte to the text the previous release produced. When the plan reopen refuses because the user closed that card (`dismissedByUser`), the outcome carries the flag and one package-owned line says so — you closed it, a message brings it back — in the typed, the injected and the queued-steer forms, with no way-to-keep and no engine decide route; the reopen port receives `{ trigger }` mapped from the submission origin (typed ⇒ `user`, injected ⇒ `automatic`, absent ⇒ the old single-argument call). When the reopen refuses because no view is subscribed to question frames for that session (`_sema_noPresentationSurface`), the plan and ask outcomes carry `noPresentationSurface`, and the five lines that talk about the card not coming back — both arms' typed line, the queued-steer typed and injected lines, and the injected not-delivered line — add one package-owned clause saying the session has no view that can show decision cards, byte-identical to the plain refusal otherwise; loose values and the other refusals (answer in flight, user-closed card, plain refusal) carry neither the flag nor the clause. For a host that reopens under its own session key with a presentation receipt, the suite drives the whole sequence end to end: subscribing for that key, reopening, and registering the receipt through the per-session call `registerArmedGateFromQuestionIdFor` gives `reopened: true` with the right first-sight reading, a second reopen reads as seen before, a decisive answer (with no extra bookkeeping from the host) makes the next reopen read as first sight again, and a dismissal does not; registering through the default-session call instead leaves the receipt window to run out with `{ reopened: false }`. Every bit the package reads off a host's reopen verdict is read once, inside the guard: a bit whose getter throws (or a proxy that throws) is treated as absent, so the self-heal still settles — with exactly the outcome it would give if that bit were missing — and the rows never throw, including for an outcome the host built itself; a plain verdict lands in the queued-steer outcome byte for byte, key order and any extra keys the host added included, a key whose getter throws is the only one left out, and an own key literally named `__proto__` is copied as a key rather than changing the copy's prototype; symbol keys are copied too and a verdict with a null prototype stays one (compared key by key, value by value and by prototype, not through JSON); and an outcome whose `reopened` property itself cannot be read is phrased as if it had none. The two reopen-failed outcomes carry `errorCode` only when the reopen gave up because a request failed — the outer wire code of that request (a folded policy code is read through `blockedBy`), taken from a reopen port that threw, from the host verdict's `_sema_errorCode`, or from the stale-park arm's own three requests; a later request that changed what the reopen gave up on (the poll finally answered, the row appeared), a failure with no wire code, a reopen port that failed after the caller had already aborted, and the three judgment refusals (answer in flight, user-closed card, no view) all leave it absent, while a read that only confirms (the row is still pending after a failed decision) keeps it; only a request that failed counts, never a field that cannot be read on a record that did come back; and every row is byte-identical with or without it. The error objects the self-heal leg reads (thrown by the run lookup, the steer and the cancel) are read inside the guard too: a `status` or `message` whose getter throws, or a proxy that throws on any read, is treated as absent, so the self-heal still settles instead of rejecting, and the at-most-once failure class reads such an error as delivery unknown; the same goes for the run record a successful lookup returns — when its `status` cannot be read, the self-heal treats it as a record without a status rather than rejecting — and for a steer receipt, whose two readers answer `null` for a field they cannot read. When the delivery of a steer is missing, unreadable or an unknown word, the injected-submission line says the message was accepted but its delivery was not reported and to watch that reply before deciding whether anything needs sending again, instead of the handed-over wording, and it never says nothing is needed, with or without a follow declaration. |
|
|
375
375
|
| `scripts/run-terminal-identity-copy-test.mjs` | Terminal-state **identity**, in both lanes where a stop gets a name. A run stopped by this deployment's own governance knobs — the open-set `limits.*` family, `output.invalid`, and the `blocked` contract terminal a ReportBlocked agent produces — is not a provider failure, and labelling it `API Error:` sends the reader to check the network, the key and the quota when the handle is the `--max-turns` they passed themselves. Those terminals now render a neutral row; the reverse direction is guarded just as hard, because asserting "this is *not* an API error" on a code the package does not recognise is the same misfiling pointed the other way — a real `gateway HTTP 502`, a `conflict.session_active_run` and any unknown code all keep the `API Error:` prefix, and the row keeps its `_sema_api_error_message` class flag (spelled `isApiErrorMessage` before 0.83.0) so brief-mode visibility filtering does not silently drop it. The second half is who the rejected submission belonged to: the self-heal copy told every caller "Your message was NOT sent … send it again", which is three separate untruths for a system injection (a plan-review outcome, a cron wake-up, a task notification) — not the user's message, and not re-sendable, since a host queue marks those non-editable and non-recallable. The injected form says so instead, and the one sentence that promises re-delivery is pinned to the single disposition that earns it: `selfHealSubmissionDisposition` is the same function the host consults before putting the item back on its queue, so the promise and the behaviour cannot drift apart, and the arms where no card could be surfaced state plainly that nothing was delivered and nothing will retry. Since 0.72.6 the same gate pins the **follow intent** after a steer (): a message handed to a live run only pays off if someone tails that run's own event stream, so `steerFollowIntent` decides from the delivery word whether to tail now, after the pending decision, or only after a wake — and the "watch that run" sentence ("watch that reply" on the rows about follow-up messages sema sent on its own) turns into a factual "sema is following that run" ("… that reply") **only** when the host declares it attached that tail, so a shell that did not wire it can never claim it did. Since 0.83.0 the rows about follow-up messages sema sent on its own carry no engine-internal words and say what happened per delivery shape, promising a resend or "nothing for you to do" only where the code guarantees it |
|
|
376
376
|
| `scripts/run-additive-key-passthrough-test.mjs` | The one disease shape behind two legs: a **closed whitelist / flattening arm** dropping a fact that is already on the wire, while both sides of the seam look correct. (1) The `task_progress` projection carries a registered **key ledger** — a frame populated with every key the service really projects is pushed through the shipped `eventToSdkMessage`, and the set of wire keys that survive must equal the registered pass-through list **name for name in both directions**, so quietly forwarding one more key is as red as quietly dropping one. `model` (the child run's model id, minted by core as `prepared.model.id` and projected by the server since 7.52.1) is the key this batch adds, with the same conditional the server itself applies: a non-empty string or no key at all — an empty string is neither a model id nor "unknown". The ledger is also checked against the fenced list in `docs/INTEGRATION-CLIENTS.md` §3d, so a doc that still says seven keys while the code forwards eight is red rather than merely stale. (2) The decide-failure arms carry the server's S-02 `currentPending` pointer key from a 409 `approval_stale` refusal onto the outcome the host reads. The reader is structural rather than `instanceof`, because the client is host-injected and the class identity is not this package's to assume; a half triple never mints (half a pointer cannot relocate anything), an empty string is not presence, and `checkpointToken` never transits. Both the allow and the deny leg are driven end to end through the real durable approval path — as is the accept-session leg, where a refusal carrying the pointer key must now re-raise instead of silently re-sending the human's answer for the **old** card as a plain approve (one decide call, pointer preserved), while a legacy 400 still falls back exactly as before — and all three flattening points must call the one shared reader — the same-shape residue check that makes "fixed one arm and left the twin" red instead of invisible. (3) The same disease growing on the REQUEST side: the `.mcp.json` → server-spec projection rebuilds each server key by key, and the settings schema deliberately leaves some keys parse-transparent — whatever JSON the file carries reaches the engine untouched, because validating them where the whole domain parses all-or-nothing would let one bad declaration take every server down silently. The whitelist had no row for the newest of them, so an operator's per-tool declarations — the ones the write fence reads — were stripped at the package boundary while both sides looked correct. The criterion is not "is that key handled" but the transparent-key table read out of the INSTALLED schema at runtime, reconciled name-for-name against this leg's ledger, so the day upstream adds a third one this turns red and forces an explicit decision. Behaviour is pinned on both transports, by object identity rather than deep equality (a rebuild would be a second judge), and malformed values must transit UNCHANGED rather than be refused here — the engine refuses them loudly and names the server, whereas a package-side judge can only swallow a declared protection quietly. Absence still mints no key, unknown keys still never reach the wire (the fix is the dropped key, not the gate), and the one transparent key this leg deliberately does not forward is a ledger entry with its own exit condition: it belongs to the deployment plane, and the day the request-plane type declares it the entry's premise is gone and the gate says so |
|
|
377
377
|
| `scripts/run-esc-halt-plan-test.mjs` | The Esc stop decision every client shares: fire the **turn-level** halt first, and escalate to a **run-level** cancel in exactly two cases — the engine itself answered with a 409 from the closed code set (it is saying "there is no in-flight turn here; use cancel for a run-level stop"), or that shot came back with no verdict at all *and* the shell can independently prove a permission card was on screen. Everything else does not escalate. The asymmetry is the whole point and every negative control guards the same direction — deciding *not* to escalate costs the user one more choice on a busy-session card (recoverable), deciding to escalate wrongly tears down a run that was alive and takes every in-flight tool with it (not). So: the closed code set is a **frozen** value, not a `ReadonlySet` — type-level immutability does not stop a consumer's `.add()`, and the guard proves it by really trying to mutate the exported value and then checking the verdict did not drift; the escalation gate is the **conjunction** of that closed set and the 409 status, since honouring the code alone lets a 500 that merely quotes it drive a destructive call; `interrupt.not_held` and `steering.not_running` are deliberately outside the set (the first means *this replica* has no live face — the run may be perfectly alive on another); an unreadable code falls to the no-escalation side; a `parked` flag never overrides a verdict the engine did give, and only strict `true` counts when it did not. The first shot is unconditional by construction — it does not consult `parked`, because the 409 it earns is exactly the verdict the gate wants — and the verdict itself is a closed machine-readable reason word, not display copy. A third escalating case was added once tearing the stream stopped reaping the run: with detach armed, a shot that never lands leaves the run going all the way to the end of the turn, so the Esc the user pressed has no effect at all and nothing on screen says so — the old behaviour had a silent backstop (tearing the stream ended the run) and that backstop is gone. The new fact is held to the same three disciplines as `parked`: it is read only where the engine gave no verdict, it is judged **after** `parked` so an existing host's reason word does not change under it, and only strict `true` counts. Absence is proven to be a no-op rather than asserted — the guard carries its own reference implementation of the previous version's table, runs the full grid through both, requires zero divergence when the new field is omitted, and first shows the comparison really does report a difference on the one cell where the two versions are meant to differ |
|
|
@@ -36,6 +36,7 @@ export type ReopenCardVerdict = {
|
|
|
36
36
|
_sema_decisionInFlight?: true;
|
|
37
37
|
dismissedByUser?: true;
|
|
38
38
|
_sema_noPresentationSurface?: true;
|
|
39
|
+
_sema_errorCode?: string;
|
|
39
40
|
} | {
|
|
40
41
|
reopened: true;
|
|
41
42
|
firstSight: boolean;
|
|
@@ -88,6 +89,7 @@ export type SelfHealOutcome = {
|
|
|
88
89
|
pendingRowGone?: true;
|
|
89
90
|
dismissedByUser?: true;
|
|
90
91
|
noPresentationSurface?: true;
|
|
92
|
+
errorCode?: string;
|
|
91
93
|
} | {
|
|
92
94
|
kind: 'not-parked';
|
|
93
95
|
taskId: string;
|
|
@@ -111,6 +113,7 @@ export type SelfHealOutcome = {
|
|
|
111
113
|
decisionInFlight?: true;
|
|
112
114
|
pendingRowGone?: true;
|
|
113
115
|
noPresentationSurface?: true;
|
|
116
|
+
errorCode?: string;
|
|
114
117
|
} | {
|
|
115
118
|
kind: 'ask-decided-without-card';
|
|
116
119
|
taskId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { abortableSleep } from '../abortableSleep.js';
|
|
2
|
-
import { corruptStoredRowContent, corruptStoredRowWhere } from '../wireErrorTriage.js';
|
|
2
|
+
import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
|
|
3
3
|
export const PLAN_REVIEW_GATE_KIND = 'plan_review';
|
|
4
4
|
export const PLAN_REVIEW_GATE_KINDS = Object.freeze([PLAN_REVIEW_GATE_KIND, 'dry_run_review']);
|
|
5
5
|
export const ASK_PARK_GATE_KINDS = Object.freeze(['human', 'irreversible_ask', 'policy_ask', 'tool_approval']);
|
|
@@ -45,20 +45,42 @@ function sessionOpts(deps) {
|
|
|
45
45
|
const sessionId = deps?.sessionId;
|
|
46
46
|
return typeof sessionId === 'string' && sessionId.length > 0 ? { session: sessionId } : {};
|
|
47
47
|
}
|
|
48
|
+
function errorSlot(e, key) {
|
|
49
|
+
if (e === null || e === undefined)
|
|
50
|
+
return undefined;
|
|
51
|
+
try {
|
|
52
|
+
return e[key];
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
48
58
|
function describeFailure(e) {
|
|
49
59
|
const where = corruptStoredRowWhere(e);
|
|
50
60
|
const rowNote = where === undefined ? '' : ` — ${corruptStoredRowContent(where)}`;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return `${m.length > 200 ? `${m.slice(0, 200)}…` : m}${rowNote}`;
|
|
61
|
+
let m;
|
|
62
|
+
try {
|
|
63
|
+
m = typeof e === 'object' && e !== null && 'message' in e ? e.message : undefined;
|
|
55
64
|
}
|
|
65
|
+
catch {
|
|
66
|
+
m = undefined;
|
|
67
|
+
}
|
|
68
|
+
if (typeof m === 'string' && m.length > 0)
|
|
69
|
+
return `${m.length > 200 ? `${m.slice(0, 200)}…` : m}${rowNote}`;
|
|
56
70
|
return `the engine gave no detail${rowNote}`;
|
|
57
71
|
}
|
|
58
72
|
function readStatus(record) {
|
|
59
73
|
const st = record?.status;
|
|
60
74
|
return typeof st === 'string' && st.length > 0 ? st : null;
|
|
61
75
|
}
|
|
76
|
+
function readStatusGuarded(record) {
|
|
77
|
+
try {
|
|
78
|
+
return readStatus(record);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
62
84
|
function readClaimHolder(record) {
|
|
63
85
|
if (record === null || typeof record !== 'object')
|
|
64
86
|
return 'unknown';
|
|
@@ -88,6 +110,7 @@ const REOPEN_VERDICT_KEYS = [
|
|
|
88
110
|
'_sema_decisionInFlight',
|
|
89
111
|
'dismissedByUser',
|
|
90
112
|
'_sema_noPresentationSurface',
|
|
113
|
+
'_sema_errorCode',
|
|
91
114
|
];
|
|
92
115
|
function snapshotReopenVerdict(raw) {
|
|
93
116
|
if (raw === null || raw === undefined)
|
|
@@ -179,6 +202,29 @@ function reopenRefusedForNoPresentationSurface(verdict) {
|
|
|
179
202
|
return false;
|
|
180
203
|
}
|
|
181
204
|
}
|
|
205
|
+
function reopenErrorCodeOf(verdict) {
|
|
206
|
+
try {
|
|
207
|
+
if (verdict.reopened !== false)
|
|
208
|
+
return undefined;
|
|
209
|
+
const v = verdict._sema_errorCode;
|
|
210
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function failureWireCode(e) {
|
|
217
|
+
try {
|
|
218
|
+
return effectiveWireErrorCode(e);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function thrownReopenVerdict(e) {
|
|
225
|
+
const code = failureWireCode(e);
|
|
226
|
+
return code !== undefined ? { reopened: false, _sema_errorCode: code } : { reopened: false };
|
|
227
|
+
}
|
|
182
228
|
function planReviewReopenTriggerFor(origin) {
|
|
183
229
|
if (origin === 'user')
|
|
184
230
|
return 'user';
|
|
@@ -214,20 +260,30 @@ function reopenedOfOutcome(outcome) {
|
|
|
214
260
|
}
|
|
215
261
|
}
|
|
216
262
|
export function atMostOnceFailureClass(e) {
|
|
217
|
-
const status = e
|
|
263
|
+
const status = errorSlot(e, 'status');
|
|
218
264
|
return typeof status === 'number' && status >= 400 && status < 500 ? 'rejected' : 'unknown';
|
|
219
265
|
}
|
|
220
266
|
export function readSteerDelivery(receipt) {
|
|
221
|
-
|
|
267
|
+
try {
|
|
268
|
+
if (typeof receipt !== 'object' || receipt === null || !('delivery' in receipt))
|
|
269
|
+
return null;
|
|
270
|
+
const d = receipt.delivery;
|
|
271
|
+
return typeof d === 'string' && d.length > 0 ? d : null;
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
222
274
|
return null;
|
|
223
|
-
|
|
224
|
-
return typeof d === 'string' && d.length > 0 ? d : null;
|
|
275
|
+
}
|
|
225
276
|
}
|
|
226
277
|
export function readSteerReceiptStatus(receipt) {
|
|
227
|
-
|
|
278
|
+
try {
|
|
279
|
+
if (typeof receipt !== 'object' || receipt === null || !('status' in receipt))
|
|
280
|
+
return null;
|
|
281
|
+
const s = receipt.status;
|
|
282
|
+
return typeof s === 'string' && s.length > 0 ? s : null;
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
228
285
|
return null;
|
|
229
|
-
|
|
230
|
-
return typeof s === 'string' && s.length > 0 ? s : null;
|
|
286
|
+
}
|
|
231
287
|
}
|
|
232
288
|
const CANCEL_RELEASE_WAIT_MS = 10_000;
|
|
233
289
|
const RUNNING_LIVENESS_RECHECK_TIMEOUT_MS = 4_000;
|
|
@@ -345,11 +401,14 @@ async function readOwnedPendingCount(read, deps) {
|
|
|
345
401
|
claimPollSleep(OWNED_PENDING_RECHECK_TIMEOUT_MS, recheckCtl.signal).then(() => null),
|
|
346
402
|
]);
|
|
347
403
|
if (deps?.signal?.aborted === true)
|
|
348
|
-
return null;
|
|
349
|
-
return typeof count === 'number' ? count : null;
|
|
404
|
+
return { count: null };
|
|
405
|
+
return { count: typeof count === 'number' ? count : null };
|
|
350
406
|
}
|
|
351
|
-
catch {
|
|
352
|
-
|
|
407
|
+
catch (e) {
|
|
408
|
+
if (deps?.signal?.aborted === true)
|
|
409
|
+
return { count: null };
|
|
410
|
+
const errorCode = failureWireCode(e);
|
|
411
|
+
return errorCode !== undefined ? { count: null, errorCode } : { count: null };
|
|
353
412
|
}
|
|
354
413
|
finally {
|
|
355
414
|
deps?.signal?.removeEventListener('abort', onCallerAbort);
|
|
@@ -366,7 +425,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
|
366
425
|
}
|
|
367
426
|
const callerAborted = () => deps?.signal?.aborted === true;
|
|
368
427
|
if (pending && typeof deps?.listOwnedPendingApprovals === 'function' && !callerAborted()) {
|
|
369
|
-
const count = await readOwnedPendingCount(deps.listOwnedPendingApprovals, deps);
|
|
428
|
+
const { count } = await readOwnedPendingCount(deps.listOwnedPendingApprovals, deps);
|
|
370
429
|
if (count === 0 && !callerAborted())
|
|
371
430
|
pending = false;
|
|
372
431
|
}
|
|
@@ -397,7 +456,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
|
397
456
|
catch (e) {
|
|
398
457
|
return { kind: 'state-unknown', taskId, detail: describeFailure(e) };
|
|
399
458
|
}
|
|
400
|
-
status =
|
|
459
|
+
status = readStatusGuarded(record);
|
|
401
460
|
}
|
|
402
461
|
if (status === null) {
|
|
403
462
|
return { kind: 'state-unknown', taskId, detail: 'the engine reported no status for that run' };
|
|
@@ -419,30 +478,39 @@ async function planVerdict(taskId, deps) {
|
|
|
419
478
|
const verdict = trigger === undefined ? deps?.reopenPlanReview?.(taskId) : deps?.reopenPlanReview?.(taskId, { trigger });
|
|
420
479
|
return snapshotReopenVerdict(await verdict);
|
|
421
480
|
}
|
|
422
|
-
catch {
|
|
423
|
-
|
|
481
|
+
catch (e) {
|
|
482
|
+
if (deps?.signal?.aborted === true)
|
|
483
|
+
return { reopened: false };
|
|
484
|
+
return thrownReopenVerdict(e);
|
|
424
485
|
}
|
|
425
486
|
}
|
|
426
487
|
async function askVerdict(taskId, deps) {
|
|
427
488
|
try {
|
|
428
489
|
return snapshotReopenVerdict(await deps?.reopenAskPark?.(taskId));
|
|
429
490
|
}
|
|
430
|
-
catch {
|
|
431
|
-
|
|
491
|
+
catch (e) {
|
|
492
|
+
if (deps?.signal?.aborted === true)
|
|
493
|
+
return { reopened: false };
|
|
494
|
+
return thrownReopenVerdict(e);
|
|
432
495
|
}
|
|
433
496
|
}
|
|
434
497
|
async function planReviewArm(taskId, signal, deps) {
|
|
435
498
|
const verdict = await planVerdict(taskId, deps);
|
|
436
499
|
if (reopenDelivered(verdict))
|
|
437
500
|
return { kind: 'plan-review-reopened', taskId, firstSight: verdict.firstSight === true };
|
|
501
|
+
const inFlight = reopenRefusedForDecisionInFlight(verdict);
|
|
502
|
+
const dismissed = reopenRefusedForUserDismissal(verdict);
|
|
503
|
+
const noView = reopenRefusedForNoPresentationSurface(verdict);
|
|
504
|
+
const errorCode = inFlight || dismissed || noView ? undefined : reopenErrorCodeOf(verdict);
|
|
438
505
|
return {
|
|
439
506
|
kind: 'plan-review-reopen-failed',
|
|
440
507
|
taskId,
|
|
441
508
|
decidePath: signal.pendingGate?.decidePath ?? null,
|
|
442
|
-
...(
|
|
509
|
+
...(inFlight ? { decisionInFlight: true } : {}),
|
|
443
510
|
...(verdict.pendingRowGone === true ? { pendingRowGone: true } : {}),
|
|
444
|
-
...(
|
|
445
|
-
...(
|
|
511
|
+
...(dismissed ? { dismissedByUser: true } : {}),
|
|
512
|
+
...(noView ? { noPresentationSurface: true } : {}),
|
|
513
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
446
514
|
};
|
|
447
515
|
}
|
|
448
516
|
async function askParkArm(taskId, signal, runs, deps) {
|
|
@@ -477,30 +545,41 @@ async function askParkArm(taskId, signal, runs, deps) {
|
|
|
477
545
|
if (verdict.reopened === false && verdict.decidedWithoutCard !== true && verdict.pendingRowGone === true && !inFlight) {
|
|
478
546
|
return staleParkArm(taskId, signal, runs, deps);
|
|
479
547
|
}
|
|
548
|
+
const noView = reopenRefusedForNoPresentationSurface(verdict);
|
|
549
|
+
const errorCode = inFlight || noView || reopenRefusedForUserDismissal(verdict) ? undefined : reopenErrorCodeOf(verdict);
|
|
480
550
|
return {
|
|
481
551
|
kind: 'ask-reopen-failed',
|
|
482
552
|
taskId,
|
|
483
553
|
decidePath: signal.pendingGate?.decidePath ?? null,
|
|
484
554
|
...(inFlight ? { decisionInFlight: true } : {}),
|
|
485
555
|
...(verdict.pendingRowGone === true ? { pendingRowGone: true } : {}),
|
|
486
|
-
...(
|
|
556
|
+
...(noView ? { noPresentationSurface: true } : {}),
|
|
557
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
487
558
|
};
|
|
488
559
|
}
|
|
489
560
|
async function probeRunStatusOnce(taskId, durable, durableGet, deps) {
|
|
490
561
|
let status = null;
|
|
491
562
|
let ghost = false;
|
|
563
|
+
let errorCode;
|
|
564
|
+
let record = null;
|
|
565
|
+
let answered = false;
|
|
492
566
|
const lease = claimProbeLease(deps?.signal, RUNNING_LIVENESS_RECHECK_TIMEOUT_MS);
|
|
493
567
|
try {
|
|
494
|
-
|
|
568
|
+
record = await durableGet.call(durable, taskId, { signal: lease.signal, ...sessionOpts(deps) });
|
|
569
|
+
answered = true;
|
|
495
570
|
}
|
|
496
571
|
catch (e) {
|
|
497
|
-
if (e
|
|
572
|
+
if (errorSlot(e, 'status') === 404)
|
|
498
573
|
ghost = true;
|
|
574
|
+
else
|
|
575
|
+
errorCode = failureWireCode(e);
|
|
499
576
|
}
|
|
500
577
|
finally {
|
|
501
578
|
lease.release();
|
|
502
579
|
}
|
|
503
|
-
|
|
580
|
+
if (answered)
|
|
581
|
+
status = readStatusGuarded(record);
|
|
582
|
+
return errorCode !== undefined ? { status, ghost, errorCode } : { status, ghost };
|
|
504
583
|
}
|
|
505
584
|
async function staleParkArm(taskId, busy, runs, deps) {
|
|
506
585
|
const reopenFailed = {
|
|
@@ -514,6 +593,7 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
514
593
|
taskId,
|
|
515
594
|
decidePath: busy.pendingGate?.decidePath ?? null,
|
|
516
595
|
};
|
|
596
|
+
const withFailureCode = (base, code) => code !== undefined ? { ...base, errorCode: code } : base;
|
|
517
597
|
if (runs === undefined || typeof runs.get !== 'function')
|
|
518
598
|
return reopenFailed;
|
|
519
599
|
const durableGet = runs.get;
|
|
@@ -527,7 +607,7 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
527
607
|
return reopenFailed;
|
|
528
608
|
const fresh = first.status;
|
|
529
609
|
if (fresh === null)
|
|
530
|
-
return reopenFailed;
|
|
610
|
+
return withFailureCode(reopenFailed, first.errorCode);
|
|
531
611
|
if (RUNNING_STATES.includes(fresh))
|
|
532
612
|
return runningChoiceArm(taskId, fresh, busy, false, runs, deps);
|
|
533
613
|
if (PLAN_REVIEW_STATES.includes(fresh))
|
|
@@ -566,12 +646,14 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
566
646
|
return { kind: 'ask-run-not-found', taskId };
|
|
567
647
|
if (callerAborted())
|
|
568
648
|
return reopenFailedAfterCard;
|
|
569
|
-
if (afterCard.status === null
|
|
570
|
-
return
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
649
|
+
if (afterCard.status === null)
|
|
650
|
+
return withFailureCode(reopenFailedAfterCard, afterCard.errorCode);
|
|
651
|
+
if (!ASK_PARK_STATES.includes(afterCard.status)) {
|
|
652
|
+
return !CLAIM_HELD_STATES.includes(afterCard.status) ? reopenFailed : reopenFailedAfterCard;
|
|
653
|
+
}
|
|
654
|
+
const recheck = await readOwnedPendingCount(recheckOwnedPending, deps);
|
|
655
|
+
if (recheck.count !== 0)
|
|
656
|
+
return withFailureCode(reopenFailedAfterCard, recheck.errorCode);
|
|
575
657
|
const verdict = await cancelAndConfirmRelease(taskId, runs, durableGet, deps);
|
|
576
658
|
if (verdict.outcome === 'released') {
|
|
577
659
|
return { kind: 'stale-park-cancelled', taskId, ...(verdict.engineStatedRelease ? { releaseConfirmedByEngine: true } : {}) };
|
|
@@ -816,6 +898,14 @@ function injectedSubmissionRow(outcome, following = false) {
|
|
|
816
898
|
return (`${lead} has not reached the model: the earlier reply${id} had already finished, so the message was set aside on it ` +
|
|
817
899
|
`instead of starting a new reply, and sema did not retry it.`);
|
|
818
900
|
}
|
|
901
|
+
if (outcome.kind === 'running-steered' && outcome.delivery !== 'applied') {
|
|
902
|
+
const unknown = `${lead} was accepted for the reply already in progress${id}, but how it will be delivered was not reported, ` +
|
|
903
|
+
`so sema cannot tell whether that reply will pick it up`;
|
|
904
|
+
return following
|
|
905
|
+
? `${unknown}. sema is following that reply and will show whatever it asks for next; check what it does ` +
|
|
906
|
+
`before deciding whether anything needs to be sent again.`
|
|
907
|
+
: `${unknown} — watch that reply before deciding whether anything needs to be sent again.`;
|
|
908
|
+
}
|
|
819
909
|
switch (selfHealSubmissionDisposition(outcome)) {
|
|
820
910
|
case 'held-for-decision':
|
|
821
911
|
return (`${lead} is on hold: this session is busy with an earlier reply${id} that is waiting on a decision. ` +
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **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` 三行)、删会话 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`(`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
|
-
| 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.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` |
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **0.85.2**(本批发布版 = **patch**:自愈重开两只失败结局带 `errorCode`(这一次重开放弃所依据的那一发失败请求的外层 wire 码,present-iff;判定形不带),重开判决不成功臂 +`_sema_errorCode`(宿主可选铸;宿主重开口抛错时本包铸)(CC-260);自愈腿读错误对象与成功应答记录上的各位收进保护(读不出按缺席,不再 reject;`atMostOnceFailureClass` / `readSteerDelivery` / `readSteerReceiptStatus` 不再抛);根公面 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` 三行)、删会话 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`(`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
|
+
| 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.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` |
|
|
26
26
|
| 公开导出面 | **1310** 个运行期符号(+ **60 个测试钩,两种拼法**:36 个 `__*ForTests` + 24 个单下划线开头(22 个 `_*ForTest` + `_resetLiveQuestionStore` / `_resetUltracodePreset`) —— 两种都在 `public-export-baseline.json` 的 `testHookNames` 里、各自受棘轮管,**不在** `names` 的 1310 里。运行期 `Object.keys(dist/index.js)` 的全量 = 1310 + 60 = **1370**;只剔双下划线那 36 个会多数出 24 个来,那不是棘轮盲区;最简单的剔法是去掉所有以 `_` 开头的名字(公面运行期名没有一个以 `_` 开头);= 下一版(未发布)的值:相对 0.75.1 **+16**,两票合计 —— **CC-77 ①** 审批决断结局单源判别联合 6 件:`approvalResolutionOf` / `isApprovalDecided` / `approvalNotSentCause` / `approvalUnsettledCause` + 两张 cause 词表 `APPROVAL_NOT_SENT_CAUSES` / `APPROVAL_UNSETTLED_CAUSES`(域 3);**CC-96** 记忆 spec 读面 10 件:`readAgentMemorySpec` / `unknownMemorySpecKeys` / `unknownMemorySpecKeysNote` / `memoryConfigRefusalNoteOf` / `KNOWN_AGENT_MEMORY_SPEC_KEYS` / `PENDING_MEMORY_SPEC_KEYS` / `MAX_UNKNOWN_MEMORY_SPEC_KEYS` / `CONFIG_MEMORY_PROJECT_KEY_SPELLING` / `CONFIG_MEMORY_WRITE_SCOPE_MISMATCH` + 判别形型(域 6 / 16)。CC-89 / CC-91 / CC-92 / CC-98 四票**零值导出增减**(新臂走 `ChromeEvent` 联合与内部臂表,`tasks_expand` 退役删的是联合成员不是导出名);1065 = 0.74.5 / 0.75.0 / 0.75.1 的值:相对 0.74.4 +4 —— `isNewEngineAgentPanelCycle`(CC-87,域 4)+ `approvalOutcomeNoteOf` 与两句固定文案常量(CC-88,域 3);1065 = 0.74.5 / 0.75.0 的值:相对 0.74.4 +4 —— `isNewEngineAgentPanelCycle`(CC-87,域 4)+ `approvalOutcomeNoteOf` 与两句固定文案常量(CC-88,域 3);1061 = 0.74.3 / 0.74.4 的值:相对 0.74.2 +9 —— CC-70 / CC-71 / CC-72 / CC-73 八件 + CC-80 `lastFlagValue`,见 §2b 域 3 / 4 / 10 / 15;1052 = 0.74.2 的值:相对 0.74.1 +6 —— CC-69 六件,见 §2b 域 9;1046 = 0.74.1 的值:相对 0.74.0 +1 —— `RETRACTED_CARD_DECISION_KIND`,见 §2b 域 3;1045 = 0.74.0 的值:相对 0.73.5 +1 —— `isStaleEngineAgentPanelEnd`,见 §2b 域 4;1044 = 0.73.5 的值:相对 0.73.4 +11 —— CC-58 规模告警十一件,名单见 §2b 域 12;1033 = 0.73.4 的值:相对 0.73.3 +1 —— `TOOL_INPUT_JOIN_MAX_CALLS`,见 §2b 域 1;1032 = 0.73.3 的值:相对 0.73.2 +6 —— CC-61 六件,名单见 §2b 域 9;1026 = 0.73.2 的值(导出名零增减);= 0.73.1 的值:相对 0.73.0 +7 —— CC-56 六件 / CC-57 一件,名单见 §2b 域 3 / 15;1019 = 0.73.0 的值(导出名零增减,BREAKING 在类型面);= 0.72.14 的值:相对 0.72.13 +8 —— CC-55 八件,名单见 §2b 域 3;1011 = 0.72.13 的值:相对 0.72.12 +18 —— CC-46 八件 / CC-54 六件 / CC-53 两件 / CC-50 缺席口两件,名单见 §2b 域 3 / 4 / 9 / 10;993 = 0.72.12 的值(测试钩 45):相对 0.72.11 +4 —— CC-50 `OUTCOME_UNKNOWN_ROW_PREFIX` / `isOutcomeUnknownRowText` / `TASK_NOTIFICATION_TERMINAL_STATUSES` / `isTaskNotificationTerminalStatus`;989 = 0.72.10 的值:相对 0.72.9 +4 —— CC-41 `LEADER_RUN_STATUSES` / `LEADER_REJ_HEAD_DISPLAY_MAX` / `projectLeaderConflict` / `leaderConflictDetail`;985 = 0.72.9 的值:相对 0.72.8 +8 —— CC-30 `MCP_RECONNECT_OUTCOMES` / `MCP_RECONNECT_TRANSACTION_NOTICE` / `projectMcpReconnectResult` / `classifyMcpReconnectFailure` / `reconnectMcpServer` / `projectMcpReconnectCapability` / `mcpReconnectOutcomeDetail`、CC-39② `readAutoConsolidationArmed`;977 = 0.72.8 的值:相对 0.72.7 +6 —— CC-39③ `MEMORY_OFF` / `memoryOffDeclarationField` / `memoryOffDeclared`、CC-43 `MODEL_OUTPUT_ERROR_PREFIX` / `isModelOutputErrorText` / `isModelOutputErrorRowText`;971 = 0.72.7 的值:相对 0.72.6 +2 —— CC-42 core 7.22.0 提货 `MCP_REDIAL_OUTCOMES` / `readMcpServerRedialed`;969 = 0.72.6 的值:相对 0.72.5 +1 —— CC-40 `steerFollowIntent`;968 = 0.72.5 的值:相对 0.72.4 +6 —— CC-31 server 7.82.1 提货 `capabilities.webSearch.backend` 四态读面:`WEB_SEARCH_BACKEND_NONE` / `projectWebSearchBackendCapability` / `observedWebSearchBackend` / `noteEngineCapsForWebSearchBackend` / `forgetWebSearchBackendReading` / `webSearchBackendDoctorDetail`;962 = 0.72.3 的值:相对 0.72.2 +1 —— CC-39① `AGENT_MEMORY_WORDS`;0.72.2 相对 0.72.1 +1 —— CC-37 `noteOwnWorkflowRun`;0.72.1 相对 0.72.0 +4 —— CC-33 server 7.80.1 提货:`RESUME_CONTEXT_UNAVAILABLE` / `resumeContextUnavailableFromError` / `resumeContextUnavailableContent` / `skillBaseDirOf`;0.72.0 相对 0.71.4 −39 —— CC-32 退役批删 export-liveness 登记 retire 的 39 个零消费导出(23 常量 + 16 函数,名单见 §47);995 = 0.71.3 的值:相对 0.71.2 +9 —— CC-06 `readEffectiveReasoning` / `readEffectiveMemoryScopes` / `resumeReopenFromError` / `resumeReopenContent` / `routePairingVerdict` 五函数 + `RESUME_REOPEN_CODES` / `RESUME_ENV_FAILED` / `RESUME_TOOL_UNAVAILABLE` / `RESUME_TOOL_CONTRACT_MISMATCH` 四常量;986 = 0.71.0 的值:相对 0.70.2 −`MAX_AGENT_SKILLS` −`DECIDE_WORKFLOW_HOST_NOT_PARKED` +`projectToolRosterDelta` +`mcpEngineLegPresence`;986 = 0.70.0 的值:相对 0.69.2 **一件 additive(`readSkillsListingTruncated`,§39)、零删除**;985 = 0.69.2 的值:相对 0.69.1 **三件 additive、零删除**(CC-13 `isSubFlowSegmentEnd` / `SEGMENT_END_IDENTITY_KEYS` / `droppedWhySentence`,§38);982 = 0.69.0 未发布版的值(原排 0.68.3,因 peer 地板抬升改 minor)= 相对 0.68.2 **十七件 additive、零删除**:`fetchMcpPanel`(CC-03 补件,§36e)+ `readWorkflowResumeAdmissionIncomplete`(CC-05 core 7.18.0 #755)+ `installCoreValuePorts`/`hasCoreValuePorts`/`hasCoreValuePort`/`coreValuePortMisses`/`CORE_VALUE_PORT_NAMES` + 十读口(CC-07 core 值级端口,§36d);0.68.2 相对 0.68.1 十三件 additive:`SEMA_SEGMENT_ID_KEY`(CC-01 段身份键,§35f)/ `projectMcpPanel`+`mcpPanelLastLegDetail`+`projectMcpSection`(CC-03 `/mcp` 面板读视图,§35g)/ `resolveTextSegmentAuthority`/`createTextSegmentLedger`(L-318 `text_end` 权威段替换的判决单源 + print 形段账,详见 §35b/§35c)/ `memoryCaptureDeclarationField`/`MEMORY_CAPTURE_OFF`(L-316 会话级隐私声明的字面唯一铸点,§35d)/ `engineUrl`/`probeHealth`(L-61 件④ SDK 纯工具面原样转口,§35d)/ `AgentClient`/`isApprovalRequestFrameV1`/`isApprovalRevokeFrameV1`(L-61 存量清零:SDK **wire 面**原样转口,§35e)。`0.68.1`/`0.68.0` 是 **952**,那批是相对 0.67.2 **二十件 additive、🔴 两件删除(BREAKING)**:additive = `TERMINAL_CAUSE_KINDS`/`isTerminalCauseKind`/`RUN_TERMINAL_NOT_SUCCESS_STATUSES`/`RUN_TERMINAL_STATUSES`(L-247 终态词两表分源,详见 §33b)/ `SEMA_SUBAGENT_USAGE_PARTIAL_KEY`/`subagentUsageIsPartial`(L-244 子代下界位自有名,§33g)/ `ASK_UNRESOLVABLE_CAUSES`/`readAskUnresolvable`/`DURABLE_MANDATE_SOURCES`/`readDurableGateUnavailable`(core 7.17.0 #709 ①② 两只通告事实窄读器,§33c)/ `WORKFLOW_PARK_TRUTH_UNREADABLE`/`WORKFLOW_PARK_NOT_PENDING`/`WORKFLOW_PARK_BINDING_BROKEN`/`WORKFLOW_PARK_REQUIRES_RUN_STORE`(四个单码常量 🔧 0.72.0 退役)/`WORKFLOW_PARK_REFUSAL_CODES`/`isWorkflowParkRefusalCode`/`readWorkflowParks`(core 7.17.0 #652 park 真相四码 + parks 三键读器,§33d)/ `ENGINE_STOP_REASONS`/`engineStopReasonToCc`(L-246 A13 停止原词映射下沉,§33g)/ `readCancelRequested`(L-230 读面,§33f);🔴 **删除两件** `TERMINAL_NOT_SUCCESS_STATUSES`/`TERMINAL_STATUSES`(随 L-247 两表分源更名成 `RUN_TERMINAL_*`,clean-cut **不留别名** —— 留一个别名等于让端可以继续按合起来的那张表读,分源就白做了,详见 §33b)。`0.67.0` 是 **934**,那批是相对 0.66.0 **七件 additive、🔴 两件删除**:additive = `CLASSIFIER_DENY_CAUSES`/`isClassifierDenyCause`/`classifierDenyCauseOf`/`classifierDenyCauseDetail`(core 7.14.0 退役 `classifierUnavailable` 之后的**拒绝面**继任读器与措辞,详见 §32b)/ `RULE_STORE_UNREADABLE_KINDS`/`isRuleStoreUnreadableKind`/`ruleStoreUnreadableDetail`(core 7.14.0 #688 C3 的规则店机制位三件,详见 §32d);🔴 **删除两件** `classifierUnavailableOf`/`classifierUnavailableDetail`(随 core 7.14.0 的 Retired keys 表整族退役,clean-cut 不留别名,详见 §32b;同批删的还有**型** `ClassifierUnavailableView`、卡位与帧位 `classifierUnavailable`、以及一条恒真的型面钉 `_askOriginWordsPin`)。`0.66.0` 是 **929**,那批是一件 additive、零删除:`readRunCostFacts`(终局成本事实的唯一读器:`costBreakdown` / `nested` 窄读 + 对账三段与两个判别位,终帧超集键与 chrome 对账臂共用它;详见 §31c);已发的 **0.65.x 十一件 additive、两件删除**:additive = `DECIDE_WORKFLOW_HOST_UNKNOWN`/`DECIDE_WORKFLOW_HOST_NOT_PARKED`/`DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED`/`DECIDE_WORKFLOW_LANE_CODES`/`readDecideReceipt`/`decideAcceptedNotResolved`/`decideRefusalFromError`(B-070 `/decide` 回执读面与三码人话,详见 §30h)/ `TERMINAL_NOT_SUCCESS_STATUSES`/`isTerminalNotSuccess`/`TERMINAL_STATUSES`/`isTerminalStatus`(L-215② 终局词汇单铸谓词,详见 §30j);🔴 **删除两件** `AUTO_MODE_BREAKER_CAUSES`/`classifierBreakerOf`(熔断族随 core 7.12.0 的 Removed(BREAKING) 整只退役,clean-cut 不留别名,详见 §30k②;同批删的还有**型** `ClassifierBreakerView` 与 `ClassifierStatusView.breaker` 一位)。`0.64.2` 是 **919**,那批是一件 additive、零删除:`readDenialLimitFallback`(限额回落卡的窄读器上公面,壳侧同判据副本退役,详见 §29③);`0.64.0` 是 **918**,那批是件①+件② 十三件 additive、零删除:`CLASSIFIER_STATUS_STATES`/`classifierBreakerOf`/`classifierStatusOf`/`classifierStatusDetail`(分类器状态面,详见 §28②)/ `THINKING_FORMATS`/`THINKING_FORMAT_WIRE_TWINS`/`THINKING_DISABLE_PROBE_ORDER`/`MODEL_PROBE_VERDICTS`/`PROBE_PROMPT`/`PROBE_MAX_TOKENS`(两个探针常量 🔧 0.72.0 退役)/`probeRequestBody`/`probeModelCapability`/`applyProbeToEntry`(模型思考能力探测,详见 §28①);`0.63.0` 是 **905**,那批是八件 additive、零删除:`projectServerGateKnobs`/`postureKnobSourceOf`/`postureSourceIsOperatorPinned`/`postureKnobDetail`/`POSTURE_SOURCE_WORDS`(S-178 三根 posture 旋钮读数,详见 §27b)/ `PERSISTED_RULE_BEHAVIORS`/`PERSISTED_RULE_BEHAVIOR_UNKNOWN`/`persistedRuleBehaviorOf`/`persistedRuleBehaviorLabel`/`revokeTargetFromPersistedRule`(三态规则身份,§27c)/ `engineIdentityOf`/`engineIdentityVerdict`/`engineIdentityChanged`/`engineIdentityChangedBy`/`ENGINE_IDENTITY_ANCHORS`(S-179 代际锚,§27d)/ `GATE_DENIED_BY_WORDS`/`gateDeniedByDetail`/`ASK_ORIGIN_WORDS`/`askOriginDetail`(门词汇 +2,§27e)/ `PERMISSION_RULE_ISSUE_CODES`/`RETIRED_PERMISSION_RULE_ISSUE_CODES`/`permissionRuleIssueDetail`(规则 lint 码表,§27f)/ `projectToolRoster`/`toolRosterNames`/`toolShimFromRoster`/`applyToolRosterDelta`(L-161 工具名册,§27g)/ `ENGINE_NOTICE_CODES`/`ENGINE_NOTICE_AUDIENCE`/`noticeAudienceOf`/`engineNoticeInCatalog`/`MCP_INJECTION_DROP_REASONS`/`readMcpInjectionDrop`(L-167 通告码册,§27h)/ `AUTO_MODE_UNAVAILABLE_CAUSES`/`AUTO_MODE_BREAKER_CAUSES`/`classifierUnavailableOf`/`classifierUnavailableDetail`(件⑧ 分类器不可用事实,§27h2);`0.62.0` 是 **869**,那批是五件 additive、**零删除**:`capForDisplay`(呈前消毒 + 封长的共用铸点,详见 §26⑦)/ `SEAT_SEND_MESSAGE_KEY_ORIGINS`(座位载荷逐键出身表,详见 §26③)/ `configureSubagentContentStore`+`subagentContentStoreConfig`+`SUBAGENT_CONTENT_STORE_DEFAULTS`(子代内容账本字节预算,测试钩 `__resetSubagentContentStoreConfigForTests` +1,详见 §26②);`0.61.0` 是 **864**,那批是三件 additive、**零删除**:`projectReadFacePosture`/`readFacePostureDetail`/`readFaceDisagreement`(S-167 READ 容纳面 operator 读器,详见 §25);`0.60.0` 是 **861**,那批是二十五件 additive、**零删除**:`readRunTerminal`/`runTerminalCode`/`runTerminalGateKind`/`runTerminalGateToolName`/`isReviewPark`/`REVIEW_PARK_GATE_KINDS` 六件终局因由读器 + `gateOutcomeOf`/`isDeniedGate`/`gateDeniedBy`/`gateApprover`/`isApprovalWindowExpiredGate`/`isDenialLimitAutoDeniedGate`/`isParkSlaExpiredGate`/`isHumanSettledGate` 八件门记录读器 + `projectWriteProtectionCapability`/`noteEngineCapsForWriteProtection`/`observedWriteProtection`/`forgetWriteProtectionReading`/`writeProtectionDoctorDetail`/`projectWriteProtectionPosture`/`writeProtectionPostureDetail` 七件写保护读面(测试钩 `__resetWriteProtectionReadingsForTests` +1)+ `readWireErrorCode` + 真机边界①的两件 `isGateParkedToolEnd`/`GATE_PARKED_ERROR_CODE` + 异源复审逼出的 `engineCapsGeneration`;`0.59.0` 是 **836**,那批是八件 additive:`RULE_OFFERS_ABSENCE_REASONS`/`DENIAL_LIMIT_KINDS`(后者 🔧 0.85.0 退出公面)两张闭词表再导出 + `engineCapValue` 能力位四态通用读口 + `projectSqlEngineCapability`/`observedSqlEngine`/`noteEngineCapsForSqlEngine`/`forgetSqlEngineReading`/`sqlEngineDoctorDetail` 五件 SQL 姿态读面(测试钩 `__resetSqlEngineReadingsForTests` +1);`0.58.0` 是 **828**,那批是三件 additive:`RULE_OFFER_MATCHES`/`RULE_OFFER_BATCH_MEMBER_KINDS`/`RULE_OFFER_UNCOVERED_REASONS` 三张闭词表再导出 + `RESUME_REFUSAL_CODES`/`RESUME_PLACEMENT_MISMATCH`/`resumeRefusalFromError`/`resumeRefusalContent` 四件文案铸点;`0.57.0` 是 **821**;`0.56.0`/`0.55.0` 是 **815**;已发 `0.54.0`(design/385 十件 additive 含 `AUTHORITY_ENVELOPE_TAGS` 🔧 0.72.0 退役);`0.52.0` 是 **805**(L-69⑨ 两件);`0.51.0` 是 **803**;`0.50.0` 是 **800**(S-81 五件);`0.49.0` 是 **795**;`0.48.0` 是 **794**;npm `0.47.0` 是 **790**,`0.46.0` 是 **787**,`0.44.0` 是 **783**,`0.43.1`/`0.43.0` 是 **776**,`0.42.0` 是 **771**,`0.41.0` 是 **767**,`0.39.0` 是 **766**,`0.38.0` 是 **764**;`0.37.0` 是 **753**,见 `CHANGELOG.md`) | `scripts/public-export-baseline.json` 的 `count` / `testHookCount` —— **别手抄进别处,以该文件为准** |
|
|
@@ -924,6 +924,7 @@ type ReopenCardVerdict =
|
|
|
924
924
|
_sema_decisionInFlight?: true // §93:这道门的决断还在路上
|
|
925
925
|
dismissedByUser?: true // §104:用户关卡 × 自动触发
|
|
926
926
|
_sema_noPresentationSurface?: true // §110:这个会话没有接能显示卡的界面
|
|
927
|
+
_sema_errorCode?: string // §111:放弃所依据的那一发失败请求的外层 wire 码
|
|
927
928
|
}
|
|
928
929
|
| { reopened: true; firstSight: boolean; presented?: boolean }
|
|
929
930
|
```
|
|
@@ -1717,6 +1718,7 @@ reason 里写明「枚举器盲区形」。已知两形:
|
|
|
1717
1718
|
- [ ] durable 腿:**按意图**选动词 —— 否掉这一道门用 **deny**(run 继续),终结整条 run 用 **`runs.cancel`**(server [868] 起对 suspended/needs_review 就地取消;409 只剩 CAS race)。⚠️ 0.36.0 修:原行写的「取消 suspended 必须用 deny、绝不 cancel」已被 SDK 7.1.0 标 stale,详见 §4 「cancel vs deny」行
|
|
1718
1719
|
- [ ] `HitlSafetyError` 按 **`.code` 结构化判型**,`instanceof` 只作加强(跨 realm / 双实例)
|
|
1719
1720
|
- [ ] `ReopenCardVerdict.presented`:要用这个位就自己在呈现层实现回执;不实现就**缺席**(缺席不降级),**别填 `false` 当占位**
|
|
1721
|
+
- [ ] `ReopenCardVerdict._sema_errorCode`(0.85.2,可选):自带重开口因为一发请求失败而交回 `{ reopened: false }` 时,按 §111 111a-1 铸那一发的外层 wire 码(读法 `effectiveWireErrorCode`);因判定拒开(在飞 / 用户关卡 / 无界面 / 窗尽没行)与调用方已中止**不铸**
|
|
1720
1722
|
|
|
1721
1723
|
**F. 多会话宿主(desktop)额外项**
|
|
1722
1724
|
- [ ] 每会话一个真 `sessionKey`,**不拿 `DEFAULT_SESSION_KEY` 当会话 id**
|
|
@@ -9638,6 +9640,141 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
9638
9640
|
|
|
9639
9641
|
**包侧缺口:** ① 出包面注释存量(别仓名 / 票号 / 帖号 / 过程词)与卫生门判据太窄(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)。
|
|
9640
9642
|
|
|
9643
|
+
## §111 🆕 0.85.2(2026-09-30)自愈重开失败结局带「放弃所依据的那一发」失败请求的外层 wire 码 + 自愈腿读错误对象与成功应答记录上的各位收进保护(patch;根公面运行期导出 1310 不变;公面类型名不变;`ReopenCardVerdict` 不成功臂 +1 可选位 `_sema_errorCode`〔超集键 +1〕;`SelfHealOutcome` 两只失败臂 +1 可选键 `errorCode`;`activeRunSelfHealRow` 不引用 `errorCode`,注入形交接行在投递方式未知时换两句;`atMostOnceFailureClass` / `readSteerDelivery` / `readSteerReceiptStatus` 遇读不出的对象不再抛;零投影臂;peer sdk 地板 `>=12.0.1` 不动)
|
|
9644
|
+
|
|
9645
|
+
> **patch**,一件 + 一处同族修复。
|
|
9646
|
+
> **CC-260**(应终端的请托;本版 **consumed**):自愈重开没能把卡放回来时,两只失败结局只说「重开不了」和几个判定位(`decisionInFlight` / `pendingRowGone` / `dismissedByUser` / `noPresentationSurface`),说不出「是不是一发请求失败了、引擎答的是什么」—— 引擎在排空(`503 draining`)时,终端只能给一句通用的「could not reopen」。修前码丢在三处:宿主重开口抛错时本包按「没能重开」收口、不看抛出物;宿主自带重开口吞掉请求失败后只交回 `{ reopened: false }`,没有位可递码;待决项已证不在时本包自己读 run 状态 / 复证待决行失败,只收口不留码。本版给两只失败结局一个 `errorCode`,给重开判决一个同源的 `_sema_errorCode`。
|
|
9647
|
+
> **口径**:码是这一次重开**放弃所依据的那一发**失败请求的外层 wire 码(111a-1)—— 不是「途中出过的任何一个码」。
|
|
9648
|
+
> **同族修复**(EC-6):0.85.1 把宿主重开判决各位收进了保护;自愈腿读**错误对象**(`runs.get` / `runs.steer` / `runs.cancel` 的抛出物)各位、与读**成功应答记录**(`runs.get` 答回的 run 记录,kind 与状态都缺席时那一次补读)上 `status` 的两半还在保护外 —— 某一位是会抛的取值器、或整个是读就抛的 Proxy 时,`attemptActiveRunSelfHeal` 直接 reject;steer 回执的两只公面读口(`readSteerDelivery` / `readSteerReceiptStatus`)遇读不出的回执直接抛。本版一并收进保护。
|
|
9649
|
+
> **注入形交接行**(EC-7):投递方式缺席 / 读不出 / 表外词时,注入形修前与 `applied` 同句(说消息已交给正在进行的那一轮,续听已挂时还说「不用动手」);本版改说投递方式未知(111a-2)。
|
|
9650
|
+
> **到货点名**:终端 —— 零改动即得(本包三发与抛错两条来路;EC-6);要让自带的 ask 重开口也递码,按 111d 在那一处铸 `_sema_errorCode`(非必改)。网页端 —— 零改动即得(待决项已证不在时本包读 run 状态失败那一形;EC-6);自带重开口铸不铸按 111d。管理台 —— EC-6 零改动即得,其余零读点。桌面端 —— 零读点,零改动。
|
|
9651
|
+
|
|
9652
|
+
### 111a. 处置表
|
|
9653
|
+
|
|
9654
|
+
各端列的词同 §110a(`pending` / `n/a` / 「零改动即得」/「回归约束」/ `—`)。
|
|
9655
|
+
|
|
9656
|
+
| # | 面 | 包处置 | 旧 → 新 | 终端 | 网页端 | 桌面端 | 管理台 | 验收方 | 本节 |
|
|
9657
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
9658
|
+
| EC-1 | `SelfHealOutcome`:`plan-review-reopen-failed` / `ask-reopen-failed` 的 `errorCode?: string` | added(终端请托 consumed) | 无 → 放弃所依据的那一发失败请求的外层 wire 码,present-iff(111a-1) | 零改动即得(本包三发与抛错两条来路;要说成因时读它,见 111d) | 零改动即得(同左;自渲行时读它) | n/a | n/a(两只重开口都不装,走不到有码的形) | pending(G-EC1–G-EC6) | 111a-1 · G-EC1–G-EC6 |
|
|
9659
|
+
| EC-2 | `ReopenCardVerdict`(`reopened: false` 臂)`_sema_errorCode?: string` | added(超集键 +1) | 无 → 宿主自带重开口可选铸(同一口径);宿主重开口抛错时本包在保护内铸 | pending(非必改:ask 重开口按 111d 铸) | pending(非必改:同左,见 111d) | n/a | n/a | pending(G-EC3) | 111a-1 · 111d |
|
|
9660
|
+
| EC-3 | steer `queued` 结局(`running-steered`)的 `reopened` | changed(抛错形多一键) | 宿主重开口抛带码的错 ⇒ `{ reopened: false }` → `{ reopened: false, _sema_errorCode: <码> }`;其余形逐字节同 0.85.1 | 零改动即得 | 零改动即得 | n/a | n/a | pending(按「恰 `{ reopened: false }`」断言这一形的格改锚,111a′ ②) | 111a′ ② · G-EC2 |
|
|
9661
|
+
| EC-4 | `activeRunSelfHealRow` | 不变 | 每一句与不带码时逐字节同 | 回归约束 | 回归约束 | — | 回归约束 | 回归约束 | G-EC6 |
|
|
9662
|
+
| EC-5 | `reopenPlanReviewCard` | 不变 | 重开这一步零 wire 请求,不铸 `_sema_errorCode`;判决与 0.85.1 逐字节同 | 回归约束 | 回归约束 | — | — | 回归约束 | G-EC4 |
|
|
9663
|
+
| EC-7 | `activeRunSelfHealRow` 注入形:`running-steered` 投递方式缺席 / 读不出 / 表外词 | changed(换两句) | 与 `applied` 同句(「was passed to the reply already in progress …」,续听已挂时「nothing for you to do now」)→ 投递方式未知两句(111a-2);`applied` 两句、用户形、处置档、续听意图不变 | 零改动即得(测试格按旧句断言这一形的改锚,111a′ ④) | 零改动即得(不用注入形时无读点) | n/a | n/a | pending(G-EC9) | 111a-2 · G-EC9 |
|
|
9664
|
+
| EC-6 | `attemptActiveRunSelfHeal` 读错误对象(`runs.get` / `runs.steer` / `runs.cancel` 的抛出物)与成功应答记录(`runs.get` 答回的 run 记录)上的各位;公面 `atMostOnceFailureClass` / `readSteerDelivery` / `readSteerReceiptStatus` | fixed | 错误对象 `status` / `message` 读不出(会抛的取值器 / Proxy `get` / `has` 陷阱抛)、或 kind 与状态都缺席时补读答回的记录上 `status` 读不出 ⇒ 修前 reject(0.85.1 实测;公面分类口直接抛)→ 按缺席处置、结局照常落定:错误对象读不出 `status` ⇒ 不当 404、分类答 `'unknown'`;读不出 `message` ⇒ 细节句 `the engine gave no detail`;记录读不出 `status` ⇒ `state-unknown`「the engine reported no status for that run」(陈旧 park 复核与存活对账同按读不到状态,取值器抛出 404 形错误也不再判幽灵 run);steer 回执读口读不出 ⇒ 答 `null`(修前抛;自愈 steer 腿随之落 `running-steered`、投递方式缺席,修前落 `running-steer-failed`);普通错误对象与普通记录逐字节同 0.85.1 | 零改动即得 | 零改动即得 | n/a | 零改动即得 | pending(G-EC7) | 111b · G-EC7 |
|
|
9665
|
+
|
|
9666
|
+
#### 111a-1 · 口径:什么时候带码、带哪个码
|
|
9667
|
+
|
|
9668
|
+
**码的读法**:这一发失败请求(抛出物)的外层 wire 码 = 本包按码分诊处处同一只读法 —— 折叠码 `resume_blocked_by_policy` 在时答 `blockedBy` 那个原码(顶层优先,`extra` 兜底;`blockedBy` 缺席答折叠码本身),否则答抛出物上的 `errorCode`;非空串才算。服务端没给具体码时 SDK 按状态派生的粗码(§109 起,例 `request.rejected`)照样是码。
|
|
9669
|
+
|
|
9670
|
+
**带码 = 这一次重开因为一发请求失败而放弃**,带的是那一发的码:
|
|
9671
|
+
|
|
9672
|
+
| 来路 | 哪一发 | 结局 |
|
|
9673
|
+
|---|---|---|
|
|
9674
|
+
| 宿主重开口(`reopenPlanReview` / `reopenAskPark`)抛错 / reject | 抛出物本身(调用方已中止 ⇒ 不带:放弃的依据是中止) | 所在那一臂的失败结局带码;判决带 `_sema_errorCode`(steer `queued` 时结局的 `reopened` 就是这一份) |
|
|
9675
|
+
| 宿主重开口交回的判决带 `_sema_errorCode` | 宿主自己那条链上放弃所依据的那一发(宿主按本口径铸,111d) | 所在那一臂的失败结局带码(判定位在场时丢,见下) |
|
|
9676
|
+
| 待决项已证不在(判决带 `pendingRowGone`)之后本包自己的三发 | 呈卡前读 run 状态 / 呈卡后读 run 状态 / 开枪前再问一次属主待决行数(`listOwnedPendingApprovals`),哪一发失败即收口于哪一发(只认请求本身失败:请求答了、答回的记录上 `status` 读不出按读不到状态,不铸码) | `ask-reopen-failed` 带码;呈卡前那一发时同带 `pendingRowGone`(待决项已证不在、紧接着读 run 状态失败 —— 本包自己的来路上 `pendingRowGone` 与码同在只有这一形;宿主判决自带两位时计划臂原样透传,见下);后两发时不带 `pendingRowGone`(与 0.85.1 同) |
|
|
9677
|
+
|
|
9678
|
+
**放弃所依据的那一发**:之后的请求若**改变了放弃的依据**(轮询终于答上、待决行出现、run 状态读到了而按它另作判定)⇒ 依据换了,不再带先前那一发的码;**只作确认的读不改依据** —— 例如决断 POST 失败之后回读队列确认待决行仍在,放弃所依据的仍是那一发 POST,照带它的码(宿主铸法见 111d)。
|
|
9679
|
+
|
|
9680
|
+
**不带码**:
|
|
9681
|
+
|
|
9682
|
+
- 之后的请求改变了放弃的依据:宿主判决上的码只在本包没有再发请求时沿用 —— 待决项已证不在之后本包读 run 状态、再按判定收口(读到了但没有呈卡口 / 表外状态词 / 读回奇形记录;或没有 `runs.get` 可读)⇒ 放弃的依据换成了本包那一次读与判定 ⇒ 不带(宿主判决上的码不沿用);读到 run 转去等计划复核 ⇒ 转计划臂,只看计划重开口的判决(ask 重开口的码不跨口)。
|
|
9683
|
+
- 放弃所依据的那一发没有 wire 码:断连、截止、调用方中止、客户端自己的错、抛非对象 ⇒ 不带,也**不回溯**更早的码(那是一次更旧的读数,不是这一次放弃的成因)。开枪前复证读口窗尽(本包的有界等待到点)同样不带;宿主重开口抛错时调用方已中止 ⇒ 同样不带(放弃的依据是中止)。
|
|
9684
|
+
- 因判定拒开:按判决本身答的拒开(判决带 `_sema_decisionInFlight` / `dismissedByUser` / `_sema_noPresentationSurface`),两只失败结局**恒不带**(本包保证,宿主判决上两样都给了也丢码;ask 臂认用户关卡位来丢码,结局不加这一位)。射程:ask 判决带 `pendingRowGone` 且不在飞时改道陈旧 park 那条路(上表第 3 行),本包自己那一发读 run 状态 / 复证失败照口径带码 —— 放弃所依据的那一发是它,判决上的其余判定位不拦。那几形的成因是判定:答案在路上、卡是用户关的、会话没有接界面。保证只在两只失败结局上:steer `queued` 结局的 `reopened` 是宿主判决的原样拷贝,宿主两样都给了就两样都在。
|
|
9685
|
+
- 其余判定形:回执窗没落定、待决行没出生窗就尽了(宿主读面答了但没有行)、`presented: false` 降级、呈卡口抛错、复证答出非 0(行回来了)、404(结局是 `ask-run-not-found`,不是失败臂)。
|
|
9686
|
+
- 🔴 由请求失败推出的判定形:包内计划复核重开口自动触发、撞上用户关卡记号时要读两次门实例(宿主读口 `readGateInstanceKeys`:用户关卡那一刻起读的那一次、此刻那一次),任一次失败 ⇒ 证不出是新门 ⇒ 答用户关卡(`dismissedByUser`),**不带码**(成因是用户关卡记号,读失败只是没证出例外;0.83.4 起如此;KL-287)。关卡那一刻那一次失败时,此刻那一次读根本不发。
|
|
9687
|
+
|
|
9688
|
+
**出句**:`activeRunSelfHealRow` 不引用 `errorCode`,每一句与不带码时逐字节同。端要把成因说给用户时自己读这一键;措辞上只说「引擎答了 X」这一件事,不要替它补「因此卡永远回不来」之类的断言 —— 码说的是那一发请求,不是那道门的去向。
|
|
9689
|
+
|
|
9690
|
+
#### 111a-2 · 注入形交接行:投递方式未知(EC-7;逐字,`<id>` 为任务号)
|
|
9691
|
+
|
|
9692
|
+
| 条件 | 整句 |
|
|
9693
|
+
|---|---|
|
|
9694
|
+
| `running-steered`,投递方式缺席 / 读不出 / 表外词,宿主未声明续听 | `A follow-up message sema sent on its own (not one you typed) was accepted for the reply already in progress (id <id>), but how it will be delivered was not reported, so sema cannot tell whether that reply will pick it up — watch that reply before deciding whether anything needs to be sent again.` |
|
|
9695
|
+
| 同上,宿主声明续听(`{ following: true }`) | `A follow-up message sema sent on its own (not one you typed) was accepted for the reply already in progress (id <id>), but how it will be delivered was not reported, so sema cannot tell whether that reply will pick it up. sema is following that reply and will show whatever it asks for next; check what it does before deciding whether anything needs to be sent again.` |
|
|
9696
|
+
|
|
9697
|
+
措辞纪律:只说「收下了、没说怎样送达、说不准会不会被用上」—— 不说「交给了正在进行的那一轮」(没证出),两形都不说「不用动手」(续听意图仍是 `tail`,但那只决定谁去听);与用户形同一件事(用户形那一句本就在,不变)。`applied` 两句不变。
|
|
9698
|
+
|
|
9699
|
+
### 111a′. 成文改口
|
|
9700
|
+
|
|
9701
|
+
- ① **改读**(§110b 不回改,以本条为准):§110b「列不出宿主判决的键 ⇒ 只按本包读的八位读」与「本包读的八位除外:它们照读」—— 本版起是**九位**,多 `_sema_errorCode`;读不出按缺席的纪律对它同样成立(取值器抛 ⇒ 结局与判决只缺这一位时逐字节同)。
|
|
9702
|
+
- ② **改读**(EC-3):按「宿主重开口抛错 ⇒ 结局恰 `{ kind, taskId, decidePath }`」或「steer `queued` 结局的 `reopened` 恰 `{ reopened: false }`」逐键断言的格:抛出物带 wire 码时各多一键(`errorCode` / `_sema_errorCode`);抛普通 `Error` 的格照旧成立。
|
|
9703
|
+
- ③ **补读**:§110a-2「不带这一位的拒开形」与 §110b 对 `_sema_noPresentationSurface` 的缺席语义照旧;本版的 `errorCode` 与它在两只失败结局上互斥(判定形丢码),不改变那一位的任何一形;steer `queued` 结局的 `reopened` 判决原样透传宿主给的位,不保证互斥。
|
|
9704
|
+
- ④ **改读**(EC-7;§100 不回改,以本条为准):§100 100a-3 第 1 / 2 句的条件列「`delivery` 为 `applied` / 读不出 / 表外词」自本版起只剩 `applied`;读不出 / 缺席 / 表外词改说 111a-2 两句。按旧句断言这一子形的格改锚。
|
|
9705
|
+
- 新增 G-EC1–G-EC9(111c)。
|
|
9706
|
+
|
|
9707
|
+
### 111b. 缺席语义(逐键)
|
|
9708
|
+
|
|
9709
|
+
- `errorCode`(结局):在场 = 这一次重开放弃所依据的那一发失败请求带着这个外层 wire 码(非空串)。**缺席不等于「没有请求失败」**:放弃所依据的那一发没有 wire 码、之后的请求改变了放弃的依据、调用方已中止、放弃是判定、或宿主自带重开口吞掉了失败而没铸位,都缺席。
|
|
9710
|
+
- 结局层:`errorCode` 与 `decisionInFlight` / `dismissedByUser` / `noPresentationSurface` 不同在(本包保证;ask 判决带 `pendingRowGone` 而改道陈旧 park 的那几形,结局本就不带这几位)。与 `pendingRowGone` 同在:本包自己的来路只有 111a-1 表第 3 行那一形;宿主判决自带 `pendingRowGone` 与 `_sema_errorCode`(不合口径)时,计划臂原样透传两位。
|
|
9711
|
+
- `_sema_errorCode`(判决):只在 `reopened` 严格 `false` 上读;非串 / 空串 / 数组 / `null` 按缺席;读不出(会抛的取值器 / Proxy)按缺席。宿主不铸 ⇒ 缺席(老宿主行为不变)。
|
|
9712
|
+
- 本包在判决上铸这一位只有一处:宿主重开口抛错时。包内计划复核重开口不铸(重开这一步零 wire 请求)。
|
|
9713
|
+
- `running-steered` 结局没有 `errorCode` 键;它的 `reopened` 判决上可以有 `_sema_errorCode`(同一个判决位;是宿主判决的原样拷贝,宿主铸了不合口径的组合照样在)。
|
|
9714
|
+
- 错误对象上读不出的位(EC-6)按缺席:读不出 `status` = 没有状态码(不是 404、不是 4xx);读不出 `message` = 没给细节;读不出 `errorCode` / `blockedBy` = 没有码(按上面的码读法)。成功应答记录上读不出 `status` = 读不到状态(与记录没带 `status` 同处置;补读、陈旧 park 两次复核、存活对账同判 —— 取值器抛出什么错都不当请求失败:不铸码、不判幽灵);记录读到 `then` 就抛(`await` 那一步就失败)按读口失败处置。steer 回执上读不出的位 = 缺那一位(`null`)。
|
|
9715
|
+
|
|
9716
|
+
### 111c. 黑盒判据骨架
|
|
9717
|
+
|
|
9718
|
+
> 🔴 标「本版证明」的格在 **0.85.1** 产物上必须 FAIL、在 0.85.2 上必须 PASS;标「回归约束」的格两版都 PASS。请记下两次跑的产物标识(版本 + tarball shasum)。以下 `S_plan = { activeTaskId: 'T', activeTaskStatus: 'needs_review', pendingGate: { kind: 'plan_review' } }`,`S_ask = { activeTaskId: 'T', activeTaskStatus: 'suspended', pendingGate: { kind: 'human' } }`;`E(s, c, x)` = `Object.assign(new Error('x'), { status: s, errorCode: c }, x)`。
|
|
9719
|
+
|
|
9720
|
+
- **G-EC1**(本版证明,纯包层):`attemptActiveRunSelfHeal(S_plan, undefined, { reopenPlanReview: () => { throw E(503, 'draining') } })` ⇒ 恰 `{ kind: 'plan-review-reopen-failed', taskId: 'T', decidePath: null, errorCode: 'draining' }`;`S_ask` + `reopenAskPark: async () => { throw E(409, 'resume_blocked_by_policy', { blockedBy: 'scenario.not_allowed' }) }` ⇒ `ask-reopen-failed` 且 `errorCode === 'scenario.not_allowed'`;`blockedBy` 只放在 `extra` 里同答;不带 `blockedBy` ⇒ `'resume_blocked_by_policy'`。0.85.1 上无键 ⇒ FAIL。
|
|
9721
|
+
- **G-EC2**(本版证明,纯包层):信号 `{ activeTaskId: 'T', activeTaskStatus: 'running', pendingGate: null }`,`runs = { steer: async () => ({ delivery: 'queued', status: 'needs_review' }), get: async () => ({ status: 'running' }), cancel: async () => ({}) }`,deps `{ offerRunningChoice: async () => 'steer', deniedMessage: 'x', reopenPlanReview: () => { throw E(503, 'draining') } }` ⇒ 结局 `running-steered`,`reopened` 的 JSON 恰 `{"reopened":false,"_sema_errorCode":"draining"}`,结局上没有 `errorCode` 键;`activeRunSelfHealRow` 用户形 / 注入形与 `reopened: { reopened: false }` 时逐字同。
|
|
9722
|
+
- **G-EC3**(纯包层;第一格本版证明,其余格两版同答):`reopenPlanReview: () => ({ reopened: false, _sema_errorCode: 'draining' })` ⇒ `errorCode === 'draining'`(`reopenAskPark` 同形 ⇒ ask 臂同答);`_sema_errorCode` 换成 `123` / `true` / `{}` / `null` / `''` / `['x']` ⇒ 无键;判决 `{ reopened: true, firstSight: true, presented: false, _sema_errorCode: 'x' }`(降级成失败)/ `{ _sema_errorCode: 'x' }`(`reopened` 缺席)⇒ 无键;判决同时带 `_sema_decisionInFlight: true` / `dismissedByUser: true` / `_sema_noPresentationSurface: true` 之一(不带 `pendingRowGone`)⇒ 结局带那个判定位、**无** `errorCode`;ask 臂同判(ask 臂认 `_sema_decisionInFlight` / `_sema_noPresentationSurface`,另认 `dismissedByUser` 来丢码)。射程:ask 判决带 `pendingRowGone` 且不在飞时改道陈旧 park,那几形按 G-EC5 判(本包那一发失败照带码)。
|
|
9723
|
+
- **G-EC4**(回归约束,纯包层):`reopenPlanReview: (tid, o) => reopenPlanReviewCard(tid, { ...o, deliverDecision: () => {}, readGateInstanceKeys, presentationReceiptMs: 300 })`(包内计划复核重开口;`o` 是本包按提交出身传的 `{ trigger }`)。① 会话没有问题帧订阅者 ⇒ 结局 `noPresentationSurface: true`、无 `errorCode`。② `onQuestionFrame(f => { if (f.type === 'question') registerArmedGateFromQuestionId(f.questionId) })` 订阅;`readGateInstanceKeys` 第一次答 `new Set(['g1'])`、之后 reject `E(503, 'draining')`;先以 `submissionOrigin: 'user'` 撞一次(卡上屏),对那张卡 `respondToQuestion(id, { answers: [] })` 关掉,再以 `submissionOrigin: 'injected'` 撞 ⇒ 结局 `dismissedByUser: true`、无 `errorCode`,读口被调恰两次(关卡那一刻 + 此刻;KL-287 的判据格)。
|
|
9724
|
+
- **G-EC5**(本版证明 + 回归约束,纯包层):`S_ask` + `runs = { get, cancel: async () => ({}) }`(`get` 按下列各格给)+ `reopenAskPark: async () => ({ reopened: false, pendingRowGone: true })` + `offerStaleParkChoice: async () => 'cancel'` + `listOwnedPendingApprovals: async () => 0`:
|
|
9725
|
+
① `runs.get` reject `E(503, 'draining')` ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null, pendingRowGone: true, errorCode: 'draining' }`(本版证明);
|
|
9726
|
+
② 判决另带 `_sema_errorCode: 'early'`、`runs.get` reject `E(502, 'upstream.bad_gateway')` ⇒ `errorCode === 'upstream.bad_gateway'`;`runs.get` reject 一个断连错误(`Object.assign(new Error('fetch failed'), { cause: new Error('ECONNRESET') })`)⇒ 带 `pendingRowGone`、无 `errorCode`(不回溯 `'early'`);
|
|
9727
|
+
③ `runs.get` 第一次答 `{ status: 'suspended' }`、第二次 reject `E(503, 'draining')` ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null, errorCode: 'draining' }`,`runs.cancel` 零次;
|
|
9728
|
+
④ `runs.get` 恒答 `{ status: 'suspended' }`、`listOwnedPendingApprovals` reject `E(503, 'approval.store_unavailable')` ⇒ 恰 `{ …, errorCode: 'approval.store_unavailable' }`(无 `pendingRowGone`),`runs.cancel` 零次;
|
|
9729
|
+
⑤(回归约束)判决带 `_sema_errorCode: 'early'`,`runs.get` 答 `{ status: 'suspended' }` 而不给 `offerStaleParkChoice` ⇒ 带 `pendingRowGone`、无 `errorCode`;`listOwnedPendingApprovals` 答 `2` ⇒ 无 `errorCode`;`runs.get` reject `E(404, 'not_found.run')` ⇒ 恰 `{ kind: 'ask-run-not-found', taskId: 'T' }`。
|
|
9730
|
+
- **G-EC6**(回归约束,纯包层):带码结局 `o` 与去掉 `errorCode` 的同一结局,`activeRunSelfHealRow(o, S)` / `activeRunSelfHealRow(o, S, undefined, 'injected')` / 带 `keepSessionWayOut` 的一形与 `selfHealSubmissionDisposition(o)` 逐字同(两臂各一次)。
|
|
9731
|
+
- **G-EC7**(本版证明,纯包层;EC-6):`X = Object.defineProperty(new Error('x'), 'status', { get() { throw new Error('g') }, enumerable: true })`,`P = new Proxy(new Error('x'), { get() { throw new Error('g') } })`。① `S_ask` + `runs = { get: async () => { throw X }, cancel: async () => ({}) }` + `reopenAskPark: async () => ({ reopened: false, pendingRowGone: true })` ⇒ 落定为 `ask-reopen-failed` 且 `pendingRowGone: true`;② 信号 `{ activeTaskId: 'T', activeTaskStatus: null, pendingGate: null }` + `runs = { get: async () => { throw P } }` ⇒ 落定为 `state-unknown`,`detail === 'the engine gave no detail'`;③ 信号 `{ activeTaskId: 'T', activeTaskStatus: 'running', pendingGate: null }` + `runs = { get: async () => ({ status: 'running' }), steer: async () => { throw X }, cancel: async () => ({}) }` + `{ offerRunningChoice: async () => 'steer', deniedMessage: 'x' }` ⇒ 落定为 `running-steer-failed`,`delivery: 'unknown'`;④ `atMostOnceFailureClass(X) === 'unknown'`、`atMostOnceFailureClass(P) === 'unknown'`(不抛);⑤ 信号 `{ activeTaskId: 'T', activeTaskStatus: null, pendingGate: null }` + `runs = { get: async () => Object.defineProperty({}, 'status', { get() { throw new Error('g') }, enumerable: true }) }`(应答成功、记录上 `status` 读不出)⇒ 恰 `{ kind: 'state-unknown', taskId: 'T', detail: 'the engine reported no status for that run' }`。⑥ `R = Object.defineProperty(Object.defineProperty({}, 'delivery', { get() { throw new Error('g') }, enumerable: true }), 'status', { get() { throw new Error('g') }, enumerable: true })`:`readSteerDelivery(R) === null`、`readSteerReceiptStatus(R) === null`(不抛;`new Proxy({ delivery: 'applied' }, { has() { throw new Error('g') } })` 同答);③ 的布置改为 `steer: async () => R` ⇒ 恰 `{ kind: 'running-steered', taskId: 'T', delivery: null, status: null, reopened: null }`,注入形(`{ following: false }` / `{ following: true }`)逐字等于 111a-2 两句(不含 `nothing for you to do`),用户形含 `the engine did not say how it will be delivered`;⑦ `S_ask` + `runs = { get: async () => Object.defineProperty({}, 'status', { get() { throw E(404, 'not_found.run') }, enumerable: true }), cancel: async () => ({}) }` + `reopenAskPark: async () => ({ reopened: false, pendingRowGone: true })` ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null, pendingRowGone: true }`(请求答了,不判幽灵)。0.85.1 上 ①②③⑤ reject、④⑥ 抛(⑥ 的自愈腿落 `running-steer-failed`;回执取值器抛带 422 形状态码的对象时还是 `delivery: 'rejected'`、用户形说「Your message was NOT sent; send it again」)、⑦ 落 `ask-run-not-found` ⇒ FAIL。
|
|
9732
|
+
- **G-EC8**(回归约束,两版同答;纯包层):① deps 带 `signal: ctl.signal`,`reopenPlanReview: () => { ctl.abort(); throw E(503, 'draining') }` ⇒ 恰 `{ kind: 'plan-review-reopen-failed', taskId: 'T', decidePath: null }`;`reopenAskPark` 同形 ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null }`;G-EC2 的 steer `queued` 布置同形 ⇒ `reopened` 恰 `{ reopened: false }`。② `reopenAskPark: async () => ({ reopened: false, dismissedByUser: true, _sema_errorCode: 'draining' })` ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null }`。③ G-EC5 的布置,`runs.get` 答回 `Object.defineProperty({}, 'status', { get() { throw E(503, 'draining') }, enumerable: true })` ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null, pendingRowGone: true }`;第一次答 `{ status: 'suspended' }`、第二次答那只记录 ⇒ 恰 `{ kind: 'ask-reopen-failed', taskId: 'T', decidePath: null }`,`runs.cancel` 零次。④ G-EC4 ② 的布置,`readGateInstanceKeys` 第一次(用户关卡那一刻)就 reject `E(503, 'draining')` ⇒ 自动触发那一次结局 `dismissedByUser: true`、无 `errorCode`,读口只被调一次(此刻那一次读不发)。
|
|
9733
|
+
- **G-EC9**(本版证明,纯包层;EC-7):结局 `{ kind: 'running-steered', taskId: 'T', delivery: D, status: 'running', reopened: null }`,`D` 取 `null` / `'brand_new_delivery'` / `''` ⇒ `activeRunSelfHealRow(结局, null, undefined, 'injected', { following: false })` 与 `{ following: true }` 分别逐字等于 111a-2 两句,都不含 `nothing for you to do`;`D = 'applied'` ⇒ 两句与 0.85.1 逐字同(续听已挂那一句仍含 `nothing for you to do now`,回归约束);`steerFollowIntent(结局)` 仍为 `tail`、`selfHealSubmissionDisposition(结局)` 仍为 `handed-off`(回归约束)。0.85.1 上前三形答 `applied` 那两句 ⇒ FAIL。
|
|
9734
|
+
|
|
9735
|
+
### 111d. 端上要动的读点
|
|
9736
|
+
|
|
9737
|
+
坐标来自本机克隆的只读检索,读的提交:终端 `origin/main` 6e050ef7 · 网页端 `origin/main` 0fb6df39 · 管理台 `origin/main` 21b89514 · 桌面端 `origin/main` 5c996117(冻结)。产品源码坐标省去开头的 src 目录;行号会漂,以各端现状为准。
|
|
9738
|
+
|
|
9739
|
+
**终端**(6e050ef7)
|
|
9740
|
+
|
|
9741
|
+
- EC-1 零改动即得:两只失败结局在「待决项已证不在、本包复核请求失败」与「重开口抛带码的错」两条来路上带 `errorCode`;终端的两只重开外壳(`sema/seamQuery.ts:2737` 的 `reopenPlanReview` / `:2751` 的 `reopenAskPark`)今天吞掉一切失败、交回普通判决,所以抛错那条来路今天走不到。要在「could not reopen」那一行说出成因(引擎在排空等),读结局的 `errorCode`;包行不变。
|
|
9742
|
+
- EC-2(非必改):要让自带的 ask 重开口也递码,在它放弃的那一处按 111a-1 同一口径铸 `_sema_errorCode`,读法用 `effectiveWireErrorCode(抛出物)`(本包导出,折叠码按 `blockedBy`)—— 不另写读码:
|
|
9743
|
+
- 出生窗的轮询(`sema/askParkReopen.ts` `probeOwnedAskRow` `:597`,`approvals.list` `:616`,失败落 `unborn` `:622`):**最后一拍失败才铸**。每一拍失败记下这一拍的码(没有码就记「无码」),答上了就清掉(答上了 = 放弃的依据变了);窗尽收口(`:800`)时只在最后一拍是失败、且带码时铸 —— 窗尽于「答了但没有行」不铸(`pendingRowGone` 那一形同样不铸)。
|
|
9744
|
+
- tool 门无卡链(`:1475` 起的整链,`:1506` outcome 形失败 / `:1520` 抛出形失败):**以决断 POST 失败收口才铸** —— 链没呈卡、也没决断成功(`:1602` 那一次 `{ reopened: false }`)时,铸最后一发决断失败的码(整链重跑一次的,取第二发的);决断失败之后那一次「行还在不在」的队列回读只作确认、不改放弃的依据,不清码。链因呈现回执窗尽、熔断、已呈台账闸、决断在路上等判定收口 ⇒ 不铸。
|
|
9745
|
+
- 问答臂:决断在作答之后才发(重开这一步之外),没有可铸的码。
|
|
9746
|
+
- 调用方已中止(用户按了 Esc)⇒ 不铸(放弃的依据是中止)。
|
|
9747
|
+
- 外层兜底 catch(`:826`):不铸(那里接住的不是某一发请求的失败)。或者把一个 wire 失败原样抛出去 —— 本包在保护内按抛出物铸同一位(111a-1 表第 1 行);两种做法端上看到的结局相同,择一。
|
|
9748
|
+
- plan 重开外壳(`sema/planReviewReopen.ts:165`,用户关卡判定 `:177` 读待决队列、失败即拒开)答的是用户关卡 / 决断在路上两种判定形 —— 按 111a-1 不铸;交给包口(`:193`)之后的判决本包不铸。
|
|
9749
|
+
- EC-6 零改动即得:终端交给自愈腿的 `runs` 动词是 SDK 客户端的方法,抛的是普通错误对象、答的是普通记录,结局与 0.85.1 逐字节同;只有外壳自己包一层、交出读不出的对象时才走到修复那一形。
|
|
9750
|
+
- 自渲句:终端经 `rowFor` 覆写失败结局那几行时,码的措辞按 111a-1「出句」一条。
|
|
9751
|
+
- EC-7 零改动即得:注入件撞活 run 折成 steer、回执没给投递方式(或读不出)时,注入形交接行换成 111a-2 那两句;终端现有按「was passed to the reply already in progress」断言这一子形的格改锚(`applied` 形不变)。
|
|
9752
|
+
|
|
9753
|
+
**网页端**(0fb6df39)
|
|
9754
|
+
|
|
9755
|
+
- EC-1 零改动即得:`ui/lib/engine/engine-self-heal.ts` 的两只重开口(`reopenViaParkSurface`)在 `approvals.list` 失败时呈降级卡(答 `reopened: true`),走不到带码的失败形;判决带 `pendingRowGone`(`row-not-found`)之后,本包读 run 状态(`runs.get`)失败的那一形 `ask-reopen-failed` 带 `errorCode`。`renderSelfHealMessage` 按处置档出句,不读新键也不受影响。
|
|
9756
|
+
- EC-2(非必改):自带重开口里若有一处「因为一发请求失败而交回 `{ reopened: false }`」,按终端那一条同一口径铸。
|
|
9757
|
+
- EC-6 零改动即得(同终端)。
|
|
9758
|
+
|
|
9759
|
+
**桌面端 / 管理台**
|
|
9760
|
+
|
|
9761
|
+
- 管理台(21b89514,`lib/chat/transport/engine-transport.ts` 的 `attemptActiveRunSelfHeal`)两只重开口都不装:结局恒是不带码的失败形,零改动;EC-6 零改动即得(它把 SDK 客户端的 `runs` 交给自愈腿)。桌面端零读点。
|
|
9762
|
+
|
|
9763
|
+
**验收方**
|
|
9764
|
+
|
|
9765
|
+
- 新增 G-EC1–G-EC9;按 111a′ ② / ④ 改锚。
|
|
9766
|
+
|
|
9767
|
+
### 111y. 🔴 三端升级必读(固定段式)
|
|
9768
|
+
|
|
9769
|
+
1. **换钉 `^0.85.2` 之前**:零前置改动。对调用方非破坏的增量:两个已导出型各多一个可选位(`ReopenCardVerdict` 不成功臂 `_sema_errorCode` · `SelfHealOutcome` 两只失败臂 `errorCode`),根入口运行期名与公面类型名不变,`activeRunSelfHealRow` 不引用 `errorCode`,peer sdk 地板 `>=12.0.1` 不动。已发导出的可观察变化:(a)「宿主重开口抛出带 wire 码的错」与「待决项已证不在之后本包复核请求失败」两类形上多一键(111a′ ②);(b)修复(EC-6):自愈腿遇到读不出的错误对象或成功应答记录不再 reject;`atMostOnceFailureClass` / `readSteerDelivery` / `readSteerReceiptStatus` 遇读不出的对象不再抛(分别答 `'unknown'` / `null`),自愈 steer 腿遇读不出的回执落 `running-steered`(投递方式缺席);(c)注入形交接行在投递方式缺席 / 读不出 / 表外词时换成 111a-2 两句(EC-7;修前与 `applied` 同句)。0.85.1 的必读三条(§110y)原样适用。
|
|
9770
|
+
2. **逐面**:
|
|
9771
|
+
- **自愈失败行**(CC-260):按 kind 渲包行的端零改动(行不变);要说成因的端读 `errorCode`,只说「引擎答了 X」,不据它断言卡的去向(111a-1「出句」)。
|
|
9772
|
+
- **自带重开口**(终端的 ask 重开口 / 网页端的两只):非必改;要递码就按 111a-1 口径铸 `_sema_errorCode`、读法用 `effectiveWireErrorCode`(111d)。
|
|
9773
|
+
- 桌面端 / 管理台 —— 零读点(管理台 EC-6 零改动即得)。
|
|
9774
|
+
3. **成文改口**:见 111a′ —— ① 改读(§110b 本包读的判决位八 → 九)/ ② 改读(抛带码错时结局与 steer `queued` 判决各多一键)/ ③ 补读(与 `_sema_noPresentationSurface` 在两只失败结局上互斥)/ ④ 改读(§100 注入件句表第 1 / 2 句只剩 `applied` 形);新增 G-EC1–G-EC9;已发段(§110)不回改,以本段为准;活段 §0a / §4c / §8 同批改。
|
|
9775
|
+
|
|
9776
|
+
**包侧缺口:** ① 由请求失败推出的判定形 —— 包内计划复核重开口自动触发时两次门实例读(用户关卡那一刻 / 此刻)任一次失败 ⇒ 答用户关卡、不带码;读失败若因引擎排空,端拿不到那个码(KL-287)· ② 宿主自带重开口吞掉的请求失败,本包看不见;宿主不铸 `_sema_errorCode` 时两只失败结局在那几形上不带码(终端 / 网页端今天都不铸,见 111d)· ③ 码的读法随本包按码分诊的那一只(`effectiveWireErrorCode`)走:服务端不带具体码时答的是按状态派生的粗码,说不出比它更细的成因 · ④ 宿主判决上不合口径的组合(`pendingRowGone` 与码、判定位与码)本包在计划臂 / steer `queued` 结局上原样透传,不代宿主纠正;丢码只在两只失败结局的判定形上做。
|
|
9777
|
+
|
|
9641
9778
|
## §110 🆕 0.85.1(2026-09-30)请求装配回执省略成因的终端用户向句表 + 取句口 + plan-review 重开口「没有接能显示卡的界面」成因位与重开前提成文补 + 多会话宿主的按会话呈现回执登记口回到根入口(patch;根公面运行期导出 +3,1307 → 1310〔`taskRequestOmissionCauseNotice` / `TASK_REQUEST_OMISSION_CAUSE_NOTICES` / `registerArmedGateFromQuestionIdFor`(0.72.0 退出公面的名字复活)〕;公面类型名不变;`ReopenCardVerdict` 不成功臂 +1 可选位 `_sema_noPresentationSurface`〔超集键 +1〕;`SelfHealOutcome` 两臂 +1 可选键 `noPresentationSurface`;`activeRunSelfHealRow` 五句在这一形上补一句成因;自愈腿读宿主重开判决收进保护(某一位读不出按缺席,不再 reject);宿主日志 / 探针口抛错不再改变判决;成因闭集不变;接入方那只 `taskRequestOmissionCauseDetail` 逐字不变;零投影臂;peer sdk 地板 `>=12.0.1` 不动)
|
|
9642
9779
|
|
|
9643
9780
|
> **patch**,三件同发,另带两处修复(PS-6 / PS-7)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.85.
|
|
3
|
+
"version": "0.85.2",
|
|
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",
|