@sema-agent/client-core 0.72.0 → 0.72.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 CHANGED
@@ -49,6 +49,24 @@
49
49
  > 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
50
50
  > commit 漏转在发布前就红,不再靠人记。
51
51
 
52
+ ## 0.72.2(2026-09-17)
53
+
54
+ > 主题:**workflow 视图两票**(cli [7468] ②③ 点名;本包 CC-38 / CC-37)。**patch**:型面纯 additive(公面 960 → 961;`LiveWorkflowController` +1 方法;零 wire 键;peer 不动)。接入面 §49。
55
+
56
+ ### Added
57
+
58
+ - **`LiveWorkflowController.resolution(): WorkflowResolution`**(CC-38):把 `snapshot()` 的 `null` 三义拆成六态 —— `pending{lastError}`(首发 get 未答,含纯连接错误退避中)/ `degraded{code: 501|404}`(引擎明说不可用 / run 不存在)/ `empty`(未配 workflowId 且 owner 零 run)/ `unavailable`(client 造不出来,永不会答)/ `live{state}` / `stale{state, code}`(曾 live 后引擎又说 501/404)。纯读、`snapshot()` / `status()` 契约不变;壳侧「问了 3 s 还是 null」的宽限窗可撤。`empty` 只对刚刚那次空表成立:之后任何失败退回 `pending{lastError}`、名单从空变非空也先回 `pending`(发车前复审实抓:此前空表后的连接故障会一直被报成「零 run」)。pure 门 CC-38 段 13 格(含同一 source 的两条相位转换),变异「empty 折成 pending」红。
59
+ - **`noteOwnWorkflowRun(runId)`** + adapter workflow lane 门同拍登记(CC-37):`task_progress` 帧带 `workflowRunId` ∧ 父是本会话见过的 Workflow 工具卡(own-run 正向证明)时,铸行那一拍即登 own 台账,不再等 run_workflow 回执(此前 fleet 行已渲 13 s 而 `listOwnWorkflowRuns()` 仍空);只有 `workflowRunId` 无父卡或父是别的卡 ⇒ 不登。回执登记点保留。pure 门 CC-37 段 5 格,变异「去掉同拍登记」红。
60
+
61
+ ## 0.72.1(2026-09-17)
62
+
63
+ > 主题:**server 7.80.1 提货**(发车帖 [7430] @client-core 三条;本包 CC-33)。**patch**:型面纯 additive(公面 956 → 960;零 `_sema_` 键;peer 不动)。接入面 §48。
64
+
65
+ ### Added
66
+
67
+ - **`resumeContextUnavailableFromError(err) → { code, staleAfterSec?, runId? } | null`** + **`resumeContextUnavailableContent(d)`** + 码常量 **`RESUME_CONTEXT_UNAVAILABLE`**(`conflict.resume_context_unavailable`):批准等太久、发起它的会话已不保留上下文 —— server 7.80.1 起体带 `staleAfterSec`(整数秒 = 部署当下的会话保留时长真值)。读口 duck-typed 只认 `errorCode`;`staleAfterSec` 窄读域整数 ≥1、坏值降缺席不降 0;`runId` 非空串才在场;码不进 `RESUME_RETRY_LATER_CODES` / `RESUME_REFUSAL_CODES`(不可等,也不是换参数);三句人话零内部车道词、不铸秒数(保留时长由端按 `staleAfterSec` 单独渲,缺席不渲);**只凭码不推断原因**(server 在上下文被回收或读取失败时都发本码 ⇒ 第一句只说「当前没有可用的上下文」),第三句按 `runId` 在场与否给恢复指引、调大保留时长只作预防不作恢复承诺(发车前异源对抗复审两条 medium 实抓)。**sdk 9.6.0 的 `ConflictError` 尚未把这两个体键带上来 ⇒ 经 sdk 的端今天恒缺席**,sdk 出键之日自动填满。门 `run-resume-refusal-copy-test` ⑧ 段 +11 格。
68
+ - **`SkillSpec.baseDir`(server ≥7.80.1 / core 7.20.0 #799)**:`skillCommandsToSpecs(cmds, resolveBody, { toolsRunHere })` 第三参 —— 只在工具跑在本机的车道带 `baseDir = command.skillRoot`,缺席 = fail-closed(沙箱 / 远端车道上本机路径不存在;引擎不加首行不做 `${SKILL_ROOT}` 替换,结果与此前逐字节相同);`skillBaseDirOf(root, platform = 'posix')` 窄读 = server 顶层门同一只结构判据(「绝对」按 **server 所在平台**的 `node:path.isAbsolute` 判:posix 只认 `/…`,`win32` 才收盘符与 UNC(win32 分支比 server 严:`/a` / `\\a` / `//host/share` 不发)—— 复审实抓:盘符路径在 posix server 上送出去必 400;无 `..` 段、无 NUL、≤ 4096,不做存在性检查);第三参 `{ toolsRunHere, platform? }`;出口型 `SkillSpecOnWire = SkillSpec & { baseDir?: string }`。`..` 段两个平台都按 `/` 与 `\\` 拆(server `isValidCwd` 同律)。pure 门 skills 段 +8 格。
69
+
52
70
  ## 0.72.0(2026-09-17)
53
71
 
54
72
  > 主题:**退役批**(CC-32;[7419] §45 预告 → cli [7422] 同意 → web-client / desktop 过节拍沉默 = 同意)。**minor,型面 BREAKING**:39 个零消费导出退出公面(995 → 956);运行期零 BREAKING;peer 不动。接入面 §47。
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.72.0
38
+ **Version:** 0.72.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
@@ -1,6 +1,6 @@
1
1
  import { isSubFlowSegmentEnd } from '../adapter/types.js';
2
2
  import { classifyPeerNotification, renderPeerFrameTranscriptText } from '../peerFrames.js';
3
- import { dropQueuedNotificationsForRun, isEngineWorkflowNotified, isWorkflowCompletionCardEnqueued, markEngineWorkflowNotified, normalizeTaskNotification, noteWorkflowCompletionCardEnqueued, renderTaskNotificationXml, taskNotificationDedupKey } from '../notifications.js';
3
+ import { dropQueuedNotificationsForRun, isEngineWorkflowNotified, isWorkflowCompletionCardEnqueued, markEngineWorkflowNotified, noteOwnWorkflowRun, normalizeTaskNotification, noteWorkflowCompletionCardEnqueued, renderTaskNotificationXml, taskNotificationDedupKey } from '../notifications.js';
4
4
  import { mapBrainStatusToRetry } from '../retryStatus.js';
5
5
  import { steeringInjectedToAttachments } from '../steering.js';
6
6
  import { projectDiagnosticsFrame } from '../diagnostics.js';
@@ -748,6 +748,10 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
748
748
  // footer task 树。🔴 写者在本包、读者(isKnownWorkflowAgentTaskId)也在本包 = R4 纪律,
749
749
  // 做成 chrome 臂反而会让「宿主没接线 ⇒ Set 恒空 ⇒ 判据④ 静默失效」复活。
750
750
  recordWorkflowAgentTaskId(taskId);
751
+ // CC-37(0.72.2):own 台账同拍登记 —— 只在「帧带 workflowRunId ∧ 父是本会话见过的 Workflow 卡」这一形
752
+ // (own-run 正向证明);光有 workflowRunId 不够(老引擎对 fleet 行帧广播,别的会话的 run 也会带它)。
753
+ if (workflowRunId !== undefined && explicitParent !== undefined && inst.isWorkflowCard(explicitParent))
754
+ noteOwnWorkflowRun(workflowRunId);
751
755
  ctx.probe?.('tick', JSON.stringify({
752
756
  t: ctx.now(),
753
757
  taskId,
@@ -218,6 +218,18 @@ export declare const RESUME_PREFLIGHT_REJECTED = "resume.preflight_rejected";
218
218
  * (「有人话可补」的拒绝),两个闭集刻意分家 —— 一个回答「能不能等」,一个回答「该对人说什么」。
219
219
  */
220
220
  export declare const RESUME_PLACEMENT_MISMATCH = "resume.placement_mismatch";
221
+ /**
222
+ * 409 `conflict.resume_context_unavailable`(server ≥7.80.1 S-376 起体带结构位;码本身更早就有):**这个批准无处投递** ——
223
+ * 发起这条 run 的会话当前没有可用的上下文来继续它。常见原因是部署按 `REAP_RUN_STALE_SEC` 回收了无活动会话,但 server 在
224
+ * **上下文读取失败**(如存储故障)时也发同一个码,wire 上没有判别位 ⇒ 本包只报事实不推断原因。什么都没被决定,卡仍 pending。
225
+ * 🔴 它不在 `resume.*` 族(前缀是 `conflict.`),也不进 {@link RESUME_RETRY_LATER_CODES} / `RESUME_REFUSAL_CODES`:
226
+ * 能不能等 wire 上没有判别位(回收了就等不回来,读取失败则可能恢复)⇒ 不进「可等」集;出路是「用体上的 `runId` 自己恢复这条 run」,
227
+ * 调大保留时长只能避免以后再发生。
228
+ * 🔴 体上的 `staleAfterSec`(整数秒 = 该部署当下的 `REAP_RUN_STALE_SEC` 真值)是 7.80.1 的 additive 键;sdk 9.6.0 的
229
+ * `ConflictError` **还没把它带上来**(只带 activeTaskId 三件)⇒ 经 sdk 到端今天恒缺席,sdk 出键之日本包读口自动填满
230
+ * (读口按结构读 `errorCode` + `staleAfterSec` + `runId`,见 `resumeRefusalCopy.resumeContextUnavailableFromError`)。
231
+ */
232
+ export declare const RESUME_CONTEXT_UNAVAILABLE = "conflict.resume_context_unavailable";
221
233
  /**
222
234
  * 时间性拒绝族的**闭集**。
223
235
  *
@@ -309,6 +309,18 @@ export const RESUME_PREFLIGHT_REJECTED = 'resume.preflight_rejected';
309
309
  * (「有人话可补」的拒绝),两个闭集刻意分家 —— 一个回答「能不能等」,一个回答「该对人说什么」。
310
310
  */
311
311
  export const RESUME_PLACEMENT_MISMATCH = 'resume.placement_mismatch';
312
+ /**
313
+ * 409 `conflict.resume_context_unavailable`(server ≥7.80.1 S-376 起体带结构位;码本身更早就有):**这个批准无处投递** ——
314
+ * 发起这条 run 的会话当前没有可用的上下文来继续它。常见原因是部署按 `REAP_RUN_STALE_SEC` 回收了无活动会话,但 server 在
315
+ * **上下文读取失败**(如存储故障)时也发同一个码,wire 上没有判别位 ⇒ 本包只报事实不推断原因。什么都没被决定,卡仍 pending。
316
+ * 🔴 它不在 `resume.*` 族(前缀是 `conflict.`),也不进 {@link RESUME_RETRY_LATER_CODES} / `RESUME_REFUSAL_CODES`:
317
+ * 能不能等 wire 上没有判别位(回收了就等不回来,读取失败则可能恢复)⇒ 不进「可等」集;出路是「用体上的 `runId` 自己恢复这条 run」,
318
+ * 调大保留时长只能避免以后再发生。
319
+ * 🔴 体上的 `staleAfterSec`(整数秒 = 该部署当下的 `REAP_RUN_STALE_SEC` 真值)是 7.80.1 的 additive 键;sdk 9.6.0 的
320
+ * `ConflictError` **还没把它带上来**(只带 activeTaskId 三件)⇒ 经 sdk 到端今天恒缺席,sdk 出键之日本包读口自动填满
321
+ * (读口按结构读 `errorCode` + `staleAfterSec` + `runId`,见 `resumeRefusalCopy.resumeContextUnavailableFromError`)。
322
+ */
323
+ export const RESUME_CONTEXT_UNAVAILABLE = 'conflict.resume_context_unavailable';
312
324
  /**
313
325
  * 时间性拒绝族的**闭集**。
314
326
  *
@@ -240,6 +240,13 @@ export declare function isOwnWorkflowRun(runId: string): boolean;
240
240
  /** 本壳亲手启动过的 workflow run 列表(Set 插入序 = 启动序;/workflows 命令的目标 run 选择用,
241
241
  * cmd-workflows.tsx——fleet source 无行可选时的兜底 id 源)。 */
242
242
  export declare function listOwnWorkflowRuns(): string[];
243
+ /**
244
+ * CC-37(0.72.2,cli [7468] ②):只登 own 台账、不动 outstanding —— 给 adapter 的 workflow lane 门用:带 `workflowRunId`
245
+ * 的 `task_progress` 帧**且**其父指向本会话见过的 Workflow 工具卡(own-run 正向证明)时,在为其铸行的那一拍就登记,
246
+ * 不再等 run_workflow 回执;此前 fleet 行已渲 13 s 而 `listOwnWorkflowRuns()` 仍空。幂等;别的会话的 workflow 帧
247
+ * (无本会话卡为父)**不登**。
248
+ */
249
+ export declare function noteOwnWorkflowRun(runId: string): void;
243
250
  /** bridge 在 run_workflow 回执(structured type:'workflow-run')经过时登记。幂等;已通知的不再登记。 */
244
251
  export declare function registerOutstandingWorkflowRun(runId: string): void;
245
252
  export interface EngineWorkflowCompletion {
@@ -572,6 +572,17 @@ export function isOwnWorkflowRun(runId) {
572
572
  export function listOwnWorkflowRuns() {
573
573
  return [...ownWorkflowRuns];
574
574
  }
575
+ /**
576
+ * CC-37(0.72.2,cli [7468] ②):只登 own 台账、不动 outstanding —— 给 adapter 的 workflow lane 门用:带 `workflowRunId`
577
+ * 的 `task_progress` 帧**且**其父指向本会话见过的 Workflow 工具卡(own-run 正向证明)时,在为其铸行的那一拍就登记,
578
+ * 不再等 run_workflow 回执;此前 fleet 行已渲 13 s 而 `listOwnWorkflowRuns()` 仍空。幂等;别的会话的 workflow 帧
579
+ * (无本会话卡为父)**不登**。
580
+ */
581
+ export function noteOwnWorkflowRun(runId) {
582
+ if (!runId)
583
+ return;
584
+ ownWorkflowRuns.add(runId);
585
+ }
575
586
  /** bridge 在 run_workflow 回执(structured type:'workflow-run')经过时登记。幂等;已通知的不再登记。 */
576
587
  export function registerOutstandingWorkflowRun(runId) {
577
588
  if (!runId)
@@ -1,3 +1,44 @@
1
+ /**
2
+ * src/resumeRefusalCopy.ts — resume 族**拒绝文案的三端单一铸点**(L-102 下半场,0.58.0)。
3
+ *
4
+ * ── 这一件上收的是什么 ──────────────────────────────────────────────────────────────────────
5
+ * 0.57.0 已经把 L-102 的**事实读数**上收了({@link resumeRetryLaterFromError}:命中哪个码、
6
+ * server 给没给窗、等一会儿有没有用)。留在壳里的另一半是**人话** —— cli 1.0.x 的
7
+ * `src/sema/resumeRefusalCopy.ts` 自铸了一份判型 + 三句 `·` 分段文案,而 web-client / desktop
8
+ * 各自要么没有、要么将来会再抄一份。三端各抄一份文案 = 同一次拒绝在三个端上说三句不一样的话,
9
+ * 而这三句话回答的是**同一个安全问题**:「这次拒绝有没有消费掉我的决定 / 这张卡还能不能再决」。
10
+ * ⇒ 文案与判型同属**判定归包、呈现归端**里的「判定」那一半,本模块是它的单一铸点。
11
+ *
12
+ * ── 与 0.57.0 §21 那一口的分工(两个闭集刻意分家)──────────────────────────────────────────
13
+ * · {@link RESUME_RETRY_LATER_CODES}(engineErrorCodes.ts,0.57.0)闭的是「**server 在哪些码上铸
14
+ * `retryAfterSec`**」——它回答**能不能等**;
15
+ * · {@link RESUME_REFUSAL_CODES}(本文件)闭的是「**哪些 resume 拒绝有人话可补**」——它回答
16
+ * **该对人说什么**。
17
+ * 两集**交于** `resume.preflight_rejected` 一码、**各有**一个独占成员
18
+ * (`resume.usage_window_exhausted` 只在前者 / `resume.placement_mismatch` 只在后者),所以它们
19
+ * 不是同一张表的两个名字。🔴 **本模块不复制判定**:`preflight_rejected` 的窗与可等性一律**转调**
20
+ * `resumeRetryLaterFromError`,本文件里没有第二个 `retryAfterSec` 窄读器
21
+ * ([paired-mechanisms-must-share-premise]:两处各自判必然在某一格上分叉)。
22
+ *
23
+ * ── `retryAfterSec` 的窄读域比 cli 1.0.x 现行的更窄(端提货时要知道的差分)──────────────────
24
+ * cli 那份自铸读器收的是「有限数 ∧ ≥0」;本口沿用 §21 的域 =「**整数 ∧ ≥1**」,坏值一律降缺席:
25
+ * · server 的铸键逐字是「ms → 秒**向上取整**、**下限 1**」⇒ 真供给里不存在 0 / 负数 / 小数;
26
+ * · 放行 `0` 就是对端说「立刻重试」,而 resume 是 AT-MOST-ONCE 的**有副作用**动作(叫醒 = 真跑
27
+ * 一轮)—— 一个 0 会把「等一会儿」变成热循环;
28
+ * · 放行小数会让端渲出「等 0.4 秒」这种上游从未说过的量。
29
+ * ⇒ 壳提货后在这三形上的**行为会变**(从「渲一个 0 秒等待」变成「不渲等待行」),这是**修好**
30
+ * 不是回归([verdict-must-accept-stronger-form])。
31
+ *
32
+ * ── 开集纪律(与 cli 那份逐字同律)────────────────────────────────────────────────────────
33
+ * 🔴 判型是**闭集**的(只认下面两个码),消费面是**开集**的:不认识的码一律 `null` ⇒ 端一个字
34
+ * 都不补 ⇒ 机器可读那一行(`API Error: <status> <errorCode> · <msg>`)原样上屏。
35
+ * **绝不按前缀/子串猜一族码的语义** —— `resume.` 前缀下同时住着「等就好」「换参数」「没救了」
36
+ * 三种处置。
37
+ * 🔴 文案**不复述** server 的 message(那一行已经在屏上了),只补 message 里没有的那件事。
38
+ * 🔴 文案里**不铸等待的秒数**:那一行由端用 {@link ResumeRefusalDetail.retryAfterSec} 单独渲
39
+ * (cli 的 `retryAfterHint` 是那一位的唯一取值口),在这里再说一遍就是同一个数字上屏两遍。
40
+ */
41
+ import { RESUME_CONTEXT_UNAVAILABLE } from './engineErrorCodes.js';
1
42
  /**
2
43
  * 本模块认识的 resume 拒绝码(**闭集**)—— 「有人话可补」的那两个。
3
44
  *
@@ -83,3 +124,36 @@ export declare function resumeReopenFromError(err: unknown): ResumeReopenDetail
83
124
  * 🔴 零内部车道词(DS-04):只说用户能做的事;不复述 server 的 message(那一行已在屏上)。
84
125
  */
85
126
  export declare function resumeReopenContent(detail: ResumeReopenDetail): string;
127
+ /** {@link resumeContextUnavailableFromError} 的结构化读数。 */
128
+ export interface ResumeContextUnavailableDetail {
129
+ /** 恒为 {@link RESUME_CONTEXT_UNAVAILABLE}(留字段是为了与本文件其它读数同形,消费端可按 `code` 分派)。 */
130
+ code: typeof RESUME_CONTEXT_UNAVAILABLE;
131
+ /**
132
+ * 该部署当下的会话保留时长(整数秒;server 逐字 = `REAP_RUN_STALE_SEC` 真值,与回收器用的是同一个值)。
133
+ * 🔴 窄读域 = 整数 ∧ ≥1(与 `retryAfterSec` 同律);坏值**降缺席**不降 0。
134
+ * 🔴 缺席 = **没读到**:老 server(<7.80.1)不铸这一位,**sdk 9.6.0 也还没把它带到错误对象上**
135
+ * (`ConflictError` 只带 activeTaskId 三件)⇒ 经 sdk 的端今天恒缺席;这不是「保留时长为零」,
136
+ * 端渲「部署保留时长」那一行时缺席就**不渲**([honest-absence-not-fabricated-zero])。
137
+ */
138
+ staleAfterSec?: number;
139
+ /** 这条 run 的 id(体上既有键;非空串才在场)—— 出路①「自己恢复这条 run」用的句柄。缺席同上(sdk 未带)。 */
140
+ runId?: string;
141
+ }
142
+ /**
143
+ * 被 catch 的错误 → 「批准无处投递:上下文当前不可用」读数;不是本码 ⇒ `null`(绝不误吃别的 `conflict.*`)。
144
+ *
145
+ * 🔴 duck-typed 不 `instanceof`、键位只认 `errorCode`(与 {@link resumeRefusalFromError} 同律;退役 `code` 槽不做兼容)。
146
+ * 🔴 **本码不进两个 resume 闭集**:server 在上下文被回收 **或读取失败** 时都发它,能不能等 wire 上没有判别位 ⇒ 不进「可等」集;
147
+ * 也不是「换参数重来」⇒ 不进 refusal 集;出路见文案第三句(按 `runId` 在场与否)。
148
+ * 🔴 `staleAfterSec` / `runId` 都按结构读:server 铸在体上、sdk 今天没搬上来 ⇒ 缺席;sdk 出键当天自动填满,本包零改动。
149
+ */
150
+ export declare function resumeContextUnavailableFromError(err: unknown): ResumeContextUnavailableDetail | null;
151
+ /**
152
+ * 读数 → 人话三句(`·` 分段,与 {@link resumeRefusalContent} 同形):①发生了什么 · ②你的决定没被消费 · ③出路。
153
+ * 🔴 **只凭码不推断原因**(异源对抗复审实抓):server 在「上下文被回收」与「上下文读取失败(如存储故障)」两种情况下
154
+ * 都返回本码,wire 上没有判别位 ⇒ 第一句只说「当前没有可用的上下文来继续它」,不说「等得太久 / 已被回收」。
155
+ * 🔴 **调大保留时长救不回这一次**(上下文已删就是删了),它只能避免以后再发生 ⇒ 第三句按 `runId` 在场与否给恢复指引,
156
+ * 保留时长只作预防句。零内部车道词;不铸秒数(保留时长由端按 {@link ResumeContextUnavailableDetail.staleAfterSec}
157
+ * 单独渲,缺席就不渲)。
158
+ */
159
+ export declare function resumeContextUnavailableContent(d: ResumeContextUnavailableDetail): string;
@@ -38,7 +38,7 @@
38
38
  * 🔴 文案里**不铸等待的秒数**:那一行由端用 {@link ResumeRefusalDetail.retryAfterSec} 单独渲
39
39
  * (cli 的 `retryAfterHint` 是那一位的唯一取值口),在这里再说一遍就是同一个数字上屏两遍。
40
40
  */
41
- import { RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_ENV_FAILED, RESUME_TOOL_UNAVAILABLE, } from './engineErrorCodes.js';
41
+ import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_ENV_FAILED, RESUME_TOOL_UNAVAILABLE, } from './engineErrorCodes.js';
42
42
  import { resumeRetryLaterFromError } from './wireErrorTriage.js';
43
43
  /**
44
44
  * 本模块认识的 resume 拒绝码(**闭集**)—— 「有人话可补」的那两个。
@@ -157,3 +157,44 @@ export function resumeReopenContent(detail) {
157
157
  'Re-fetch the pending approvals and decide again on an engine where the same tool is available',
158
158
  ].join(' · ');
159
159
  }
160
+ /**
161
+ * 被 catch 的错误 → 「批准无处投递:上下文当前不可用」读数;不是本码 ⇒ `null`(绝不误吃别的 `conflict.*`)。
162
+ *
163
+ * 🔴 duck-typed 不 `instanceof`、键位只认 `errorCode`(与 {@link resumeRefusalFromError} 同律;退役 `code` 槽不做兼容)。
164
+ * 🔴 **本码不进两个 resume 闭集**:server 在上下文被回收 **或读取失败** 时都发它,能不能等 wire 上没有判别位 ⇒ 不进「可等」集;
165
+ * 也不是「换参数重来」⇒ 不进 refusal 集;出路见文案第三句(按 `runId` 在场与否)。
166
+ * 🔴 `staleAfterSec` / `runId` 都按结构读:server 铸在体上、sdk 今天没搬上来 ⇒ 缺席;sdk 出键当天自动填满,本包零改动。
167
+ */
168
+ export function resumeContextUnavailableFromError(err) {
169
+ if (typeof err !== 'object' || err === null)
170
+ return null;
171
+ const e = err;
172
+ if (e.errorCode !== RESUME_CONTEXT_UNAVAILABLE)
173
+ return null;
174
+ const sec = e.staleAfterSec;
175
+ const staleSec = typeof sec === 'number' && Number.isInteger(sec) && sec >= 1 ? sec : undefined;
176
+ const runId = typeof e.runId === 'string' && e.runId.length > 0 ? e.runId : undefined;
177
+ return {
178
+ code: RESUME_CONTEXT_UNAVAILABLE,
179
+ ...(staleSec !== undefined ? { staleAfterSec: staleSec } : {}),
180
+ ...(runId !== undefined ? { runId } : {}),
181
+ };
182
+ }
183
+ /**
184
+ * 读数 → 人话三句(`·` 分段,与 {@link resumeRefusalContent} 同形):①发生了什么 · ②你的决定没被消费 · ③出路。
185
+ * 🔴 **只凭码不推断原因**(异源对抗复审实抓):server 在「上下文被回收」与「上下文读取失败(如存储故障)」两种情况下
186
+ * 都返回本码,wire 上没有判别位 ⇒ 第一句只说「当前没有可用的上下文来继续它」,不说「等得太久 / 已被回收」。
187
+ * 🔴 **调大保留时长救不回这一次**(上下文已删就是删了),它只能避免以后再发生 ⇒ 第三句按 `runId` 在场与否给恢复指引,
188
+ * 保留时长只作预防句。零内部车道词;不铸秒数(保留时长由端按 {@link ResumeContextUnavailableDetail.staleAfterSec}
189
+ * 单独渲,缺席就不渲)。
190
+ */
191
+ export function resumeContextUnavailableContent(d) {
192
+ const third = d.runId !== undefined
193
+ ? '错误里带了这条运行的 id,请用它自己恢复这条运行再决;调大会话保留时长只能避免以后再发生,救不回这一次'
194
+ : '错误里没有带运行 id,请回到运行列表找到这条运行自己恢复它再决;调大会话保留时长只能避免以后再发生,救不回这一次';
195
+ return [
196
+ '这个批准无处投递:发起这次运行的会话当前没有可用的上下文来继续它',
197
+ '什么都没有被决定,你的决定没有被消费,这张卡仍在等待',
198
+ third,
199
+ ].join(' · ');
200
+ }
@@ -77,4 +77,34 @@ export declare function toCappedSpec(name: string, description: string, whenToUs
77
77
  * unit-testable. Only MODEL-INVOCABLE prompt skills are sent — UI-only / `disableModelInvocation` commands
78
78
  * are excluded (engine injection feeds the model's Skill tool, not the slash menu).
79
79
  */
80
- export declare function skillCommandsToSpecs(cmds: SkillCmdLike[], resolveBody: (cmd: SkillCmdLike) => string | null): SkillSpec[];
80
+ /** `SkillSpec` 上 wire 的形:0.72.1 起可带 `baseDir`(server ≥7.80.1 / core 7.20.0 #799;sdk 9.6.0 的 `SkillSpec` 还没声明它,
81
+ * 所以本包用交叉型出口 —— 赋给 `TaskRequestBody.skills: SkillSpec[]` 零摩擦)。 */
82
+ export type SkillSpecOnWire = SkillSpec & {
83
+ baseDir?: string;
84
+ };
85
+ /** {@link skillCommandsToSpecs} 的开关。 */
86
+ export interface SkillSpecsOptions {
87
+ /**
88
+ * 工具是否跑在**加载这些技能的这台机器**上(单用户 host 车道 = true)。
89
+ * 🔴 只有 true 才带 `baseDir`:它是「工具执行环境那台机器上的坐标」,沙箱 / 远端车道(k8s / e2b / ssh / device)上
90
+ * 本机路径在那边不存在,带过去只是假线索 ⇒ 缺席(fail-closed,与 server 出厂自扫技能在那些车道上不带同律)。
91
+ * 缺席 = 引擎不加首行、不做 `${SKILL_ROOT}` 替换,结果与 0.72.0 之前逐字节相同。
92
+ */
93
+ toolsRunHere?: boolean;
94
+ /**
95
+ * server 判 `baseDir` 用的是它自己那台机器上的 `node:path.isAbsolute`(平台相关):Linux / macOS 上 `C:\\x` **不是**绝对路径
96
+ * (整条提交 400),Windows 上 UNC `\\\\host\\share\\x` 才算。本包不知道 server 跑在哪个平台 ⇒ 由调用方声明;缺席 = `'posix'`
97
+ * (server 出厂镜像与三端 host 车道的常态)。声明错 = server 400 整拒,不是静默降级。
98
+ */
99
+ platform?: 'posix' | 'win32';
100
+ }
101
+ /**
102
+ * `SkillSpec.baseDir` 的窄读:与 server 顶层门**同一只**结构判据(绝对路径、无 `..` 段、无 NUL、≤ 4096 字符;**不做存在性检查**)。
103
+ * 🔴 「绝对路径」按 **server 所在平台**的 `node:path.isAbsolute` 判(异源对抗复审实抓:此前把盘符路径在 posix 上也放行 = 送出去必 400):
104
+ * · `'posix'`(默认):只有 `/…` 算;`C:\\x` / `\\\\host\\share` 都不算;
105
+ * · `..` 段检查两个平台都按 `/` **与** `\\` 拆(server `isValidCwd` 在所有平台都这么拆);
106
+ * · `'win32'`:`X:\\…` / `X:/…` 与 UNC `\\\\host\\share\\…` 算;段按 `\\` 与 `/` 切。
107
+ * 不合判据 ⇒ `undefined`(不发假坐标;在本包拦下比让 server 400 整拒更诚实)。
108
+ */
109
+ export declare function skillBaseDirOf(skillRoot: string | undefined, platform?: 'posix' | 'win32'): string | undefined;
110
+ export declare function skillCommandsToSpecs(cmds: SkillCmdLike[], resolveBody: (cmd: SkillCmdLike) => string | null, opts?: SkillSpecsOptions): SkillSpecOnWire[];
@@ -39,13 +39,33 @@ export function toCappedSpec(name, description, whenToUse, body) {
39
39
  return { name: n, description: desc, content: c };
40
40
  }
41
41
  /**
42
- * PURE projection: loaded skill commands → `SkillSpec[]` (content-capped, deduped by name; 0.70.0: NO item cap —
43
- * every eligible skill goes on the wire, the engine budgets the listing). `resolveBody`
44
- * supplies each command's raw SKILL.md body (null ⇒ skip); injecting it keeps this function IO-free and
45
- * unit-testable. Only MODEL-INVOCABLE prompt skills are sent — UI-only / `disableModelInvocation` commands
46
- * are excluded (engine injection feeds the model's Skill tool, not the slash menu).
42
+ * `SkillSpec.baseDir` 的窄读:与 server 顶层门**同一只**结构判据(绝对路径、无 `..` 段、无 NUL、≤ 4096 字符;**不做存在性检查**)。
43
+ * 🔴 「绝对路径」按 **server 所在平台**的 `node:path.isAbsolute` 判(异源对抗复审实抓:此前把盘符路径在 posix 上也放行 = 送出去必 400):
44
+ * · `'posix'`(默认):只有 `/…` 算;`C:\\x` / `\\\\host\\share` 都不算;
45
+ * · `..` 段检查两个平台都按 `/` **与** `\\` 拆(server `isValidCwd` 在所有平台都这么拆);
46
+ * · `'win32'`:`X:\\…` / `X:/…` 与 UNC `\\\\host\\share\\…` 算;段按 `\\` 与 `/` 切。
47
+ * 不合判据 ⇒ `undefined`(不发假坐标;在本包拦下比让 server 400 整拒更诚实)。
47
48
  */
48
- export function skillCommandsToSpecs(cmds, resolveBody) {
49
+ export function skillBaseDirOf(skillRoot, platform = 'posix') {
50
+ if (skillRoot === undefined || skillRoot.length === 0 || skillRoot.length > 4096)
51
+ return undefined;
52
+ if (skillRoot.includes('\u0000'))
53
+ return undefined;
54
+ if (platform === 'win32') {
55
+ if (!(/^[A-Za-z]:[\\/]/.test(skillRoot) || /^\\\\[^\\/]+[\\/][^\\/]+/.test(skillRoot)))
56
+ return undefined;
57
+ if (skillRoot.split(/[\\/]/).includes('..'))
58
+ return undefined;
59
+ return skillRoot;
60
+ }
61
+ if (!skillRoot.startsWith('/'))
62
+ return undefined;
63
+ // `..` 段两种分隔符都拆(server isValidCwd 在所有平台都按 /[/\\]/ 拆段;POSIX 文件名可含反斜杠 —— 复审第 2 轮实抓)
64
+ if (skillRoot.split(/[\\/]/).includes('..'))
65
+ return undefined;
66
+ return skillRoot;
67
+ }
68
+ export function skillCommandsToSpecs(cmds, resolveBody, opts) {
49
69
  const specs = [];
50
70
  const seen = new Set();
51
71
  for (const cmd of cmds) {
@@ -58,7 +78,8 @@ export function skillCommandsToSpecs(cmds, resolveBody) {
58
78
  if (!spec || seen.has(spec.name))
59
79
  continue;
60
80
  seen.add(spec.name);
61
- specs.push(spec);
81
+ const baseDir = opts?.toolsRunHere === true ? skillBaseDirOf(cmd.skillRoot, opts.platform ?? 'posix') : undefined;
82
+ specs.push(baseDir !== undefined ? { ...spec, baseDir } : spec);
62
83
  }
63
84
  return specs;
64
85
  }
@@ -37,7 +37,41 @@ export interface LiveWorkflowController {
37
37
  subscribe(onChange: () => void): () => void;
38
38
  /** abort the underlying SSE stream + stop the background loop (host unmount). */
39
39
  dispose(): void;
40
+ /**
41
+ * CC-38(0.72.2):把 `snapshot()` 的 `null` 三义**拆开**的读口 —— 宿主此前只能按「问了 N 秒还是 null」猜
42
+ * (cli 曾以 3 s 宽限窗权宜),现在按 `kind` 分派:
43
+ * · `pending`:循环在跑、首发 `get()` 还没答上来(含纯连接错误退避中 —— `lastError` 带原因);**不是**引擎说不可用;
44
+ * · `degraded`:引擎**明说** —— 501 端点不可用 / 404 run 不存在或非 owner;`code` 就是那个数字;
45
+ * · `empty`:没配 `workflowId` 且 owner 名下零 run(list 空)—— 不是错误,下一轮会再问;
46
+ * · `unavailable`:client 根本造不出来(baseUrl / 凭证非法)—— 永远不会答上来,别等;
47
+ * · `live`:有快照,`state` 与 `snapshot()` 同一份;
48
+ * · `stale`:曾经 live、之后引擎又说 501/404(run 被清)—— `state` 是最后一份快照,`code` 说明为什么不再新鲜。
49
+ * 纯读、不改内部状态;`snapshot()` 契约不变(live / stale 时非 null,其余 null)。
50
+ */
51
+ resolution(): WorkflowResolution;
40
52
  }
53
+ /** {@link LiveWorkflowController.resolution} 的六态。 */
54
+ export type WorkflowResolution = {
55
+ kind: 'pending';
56
+ lastError: string | null;
57
+ } | {
58
+ kind: 'degraded';
59
+ code: 501 | 404;
60
+ lastError: string | null;
61
+ } | {
62
+ kind: 'empty';
63
+ } | {
64
+ kind: 'unavailable';
65
+ lastError: string | null;
66
+ } | {
67
+ kind: 'live';
68
+ state: WorkflowRunState;
69
+ } | {
70
+ kind: 'stale';
71
+ state: WorkflowRunState;
72
+ code: 501 | 404;
73
+ lastError: string | null;
74
+ };
41
75
  export interface LiveWorkflowConfig {
42
76
  baseUrl: string;
43
77
  /** Bearer 串,或 `{ mode: 'same-origin-relay' }`([C175],0.29.0)—— 浏览器同源宿主形:凭证由
@@ -992,6 +992,8 @@ export function createLiveWorkflowSource(config) {
992
992
  let lastGetAt = 0;
993
993
  /** 入场打点用:只有第一发 get 是「入场」,后续都是 ticker 触发的 re-GET。 */
994
994
  let first = true;
995
+ /** CC-38:list 空(owner 零 run)与 client 造不出来 在 status() 上同形(degraded=true, code=null),用相位分开。 */
996
+ let phase = 'loop';
995
997
  /** 台账槽位被别的连线身份顶掉过 ⇒ 本源放弃 activity 腿(防两个 scope 互相换账)。 */
996
998
  let activityDisabled = false;
997
999
  const listeners = new Set();
@@ -1028,6 +1030,10 @@ export function createLiveWorkflowSource(config) {
1028
1030
  * error would misreport an unrelated failure as "still a 404 (run gone)".
1029
1031
  */
1030
1032
  function noteDegrade(err) {
1033
+ // CC-38(复审实抓):empty 相位只对「刚刚那次 list 为空」成立,之后任何失败都要退回 loop —— 否则一次空表之后的连接故障
1034
+ // 会被 resolution() 一直报成「零 run」,而 status() 早已换成新的 lastError。
1035
+ if (phase === 'empty')
1036
+ phase = 'loop';
1031
1037
  connected = false;
1032
1038
  if (err instanceof APIError) {
1033
1039
  code = err.status;
@@ -1076,6 +1082,7 @@ export function createLiveWorkflowSource(config) {
1076
1082
  const run = await client.workflows.get(id, { signal, ...engineSessionParamSpread() });
1077
1083
  lastGetAt = Date.now();
1078
1084
  current = projectWorkflowRun(run);
1085
+ phase = 'loop';
1079
1086
  runId = run.id;
1080
1087
  connected = true;
1081
1088
  degraded = false;
@@ -1100,10 +1107,13 @@ export function createLiveWorkflowSource(config) {
1100
1107
  while (!disposed && !abort.signal.aborted) {
1101
1108
  try {
1102
1109
  const id = runId ?? (await resolveRunId(abort.signal));
1110
+ if (id !== null && phase === 'empty')
1111
+ phase = 'loop'; // 名单从空变非空:还没 get 成功之前先回 pending,不再报 empty
1103
1112
  if (!id) {
1104
1113
  // owner has no runs → empty/degraded (not an error). Back off and re-poll (a run may appear).
1105
1114
  degraded = true;
1106
1115
  code = null;
1116
+ phase = 'empty';
1107
1117
  connected = false;
1108
1118
  await abortableSleep(NO_RUN_BACKOFF_MS, abort.signal);
1109
1119
  continue;
@@ -1202,6 +1212,7 @@ export function createLiveWorkflowSource(config) {
1202
1212
  // `snapshot()` 恒 null ⇒ 宿主走它既有的 mock/空态回落。**绝不抛进宿主**(与 501/404/空列表同路)。
1203
1213
  if (client === null) {
1204
1214
  degraded = true;
1215
+ phase = 'unavailable';
1205
1216
  lastError = 'client construction failed (invalid baseUrl/credentials)';
1206
1217
  }
1207
1218
  else {
@@ -1236,5 +1247,17 @@ export function createLiveWorkflowSource(config) {
1236
1247
  abort.abort();
1237
1248
  listeners.clear();
1238
1249
  },
1250
+ resolution() {
1251
+ if (phase === 'unavailable')
1252
+ return { kind: 'unavailable', lastError };
1253
+ const hardCode = degraded && (code === 501 || code === 404) ? code : null;
1254
+ if (current !== null)
1255
+ return hardCode !== null ? { kind: 'stale', state: current, code: hardCode, lastError } : { kind: 'live', state: current };
1256
+ if (hardCode !== null)
1257
+ return { kind: 'degraded', code: hardCode, lastError };
1258
+ if (phase === 'empty')
1259
+ return { kind: 'empty' };
1260
+ return { kind: 'pending', lastError };
1261
+ },
1239
1262
  };
1240
1263
  }
@@ -19,11 +19,11 @@
19
19
 
20
20
  | 项 | 值 | 真源 |
21
21
  |---|---|---|
22
- | 本包 | `@sema-agent/client-core` **0.72.0**(本批发布版 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
22
+ | 本包 | `@sema-agent/client-core` **0.72.2**(本批发布版 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
23
23
  | peer:wire 契约 | `@sema-agent/sdk` **>=9.6.0**(value-level,非 type-only;**0.71.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
- | 公开导出面 | **956** 个运行期符号(+ 44 个测试钩;= 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` 两张闭词表再导出 + `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` —— **别手抄进别处,以该文件为准** |
26
+ | 公开导出面 | **961** 个运行期符号(+ 44 个测试钩;= 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` 两张闭词表再导出 + `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` —— **别手抄进别处,以该文件为准** |
27
27
  | 常驻门 | 以 `scripts/gates-manifest.json` 的 `suites` 长度为准(**本档不抄这个数**) | `scripts/gates-manifest.json`;`npm test` 的名单等值门与它逐名对账 |
28
28
  | 沿革档 | 0.29.0 起建 `CHANGELOG.md`;更早批次记账在 `src/index.ts` 文件头 + `docs/REFACTOR-LEDGER.md` | — |
29
29
 
@@ -121,7 +121,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
121
121
 
122
122
  ## §2 公共导出面地图(按域)
123
123
 
124
- > 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**956** 项)。
124
+ > 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**961** 项)。
125
125
  > 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
126
126
  > **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
127
127
  > 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
@@ -145,7 +145,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
145
145
  `WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
146
146
  **4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
147
147
 
148
- 956 项的内部构成(帮助端估读表大小;0.72.0 −23 常量 −16 函数(CC-32 退役批);0.71.3 +4 常量 +5 函数(CC-06);0.71.0 −2 常量 `MAX_AGENT_SKILLS` / `DECIDE_WORKFLOW_HOST_NOT_PARKED` +2 函数 `projectToolRosterDelta` / `mcpEngineLegPresence`;0.70.0 起 +1 函数;0.69.2 起 +3:常量 1 / 函数 2):**278** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
148
+ 961 项的内部构成(帮助端估读表大小;0.72.2 +1 函数(CC-37);0.72.1 +1 常量 +3 函数(CC-33);0.72.0 −23 常量 −16 函数(CC-32 退役批);0.71.3 +4 常量 +5 函数(CC-06);0.71.0 −2 常量 `MAX_AGENT_SKILLS` / `DECIDE_WORKFLOW_HOST_NOT_PARKED` +2 函数 `projectToolRosterDelta` / `mcpEngineLegPresence`;0.70.0 起 +1 函数;0.69.2 起 +3:常量 1 / 函数 2):**279** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
149
149
  (矩阵、键集、env 名、锚串)而非可调用物;**6** 项是 PascalCase 运行期值
150
150
  (`ControlRouter` / `ControlSafetyError` / `HitlBridge` / `HitlSafetyError` / `DecideTransportRetryExhaustedError`);
151
151
  **37** 项是 `*For(sessionKey, …)` 的 per-session 变体(0.72.0 −4:`clearArmedGateFor` / `onGateArmedFor` / `registerArmedGateFromQuestionIdFor` / `notePlanReviewAnsweredIfDecisiveFor` 退出公面)(§6;其中 `engineNamespaceKeyFor` 是命名巧合 —— 参数是 baseUrl 不是 sessionKey,见域 14)。
@@ -160,16 +160,16 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
160
160
  | 4 | **子代 wire + 面板侧信道台账** | 86 | `tailEngineSubagent` · `installSubagentActivitySink` · `installSubagentTailMetaSink`(#280 件2:tail meta 帧发布口,`contentFrames` 判别位载体)· `stopEngineTask` + `classifyTaskStopConflict` · `fetchEngineSubagentReport` · `steerEngineSubagent`(0.32.0 未发布 #280 件A:additive 第三参 `childTaskId` —— 端有行上下文时**应当**传,传了就走「台账优先 / 缺席即诚实缺席 + `noteBgOwnerAbsence` 留痕」的 Q3 口径,与 tail·taskOutput·subagentOutput 三腿同姿势、与孪生 resume 腿共用同一个 `resolveOwnerRunId` 判据;**不传**则逐字维持旧行为=回落在飞 run)· `resumeSettledSubagent` + `resolveSubagentResumeContext` + `resolveOwnerRunId` + `classifySubagentResumeFailure` + `subagentResumeAvailable`(#242 批 2 A-028.7:resume 判定半场上收,与 steer 孪生同居;取址三态 = 台账有行用行值 / 指名了行但台账缺席则**诚实缺席绝不回落在飞 run** / 没指名行才回落。出路文案归端)· `recordSubagentOwnerFromProgress` + `getBgParentRunOwner`(A-028.6:「子代 → 宿主 run」**单表**,宿主 run 必须由持 stream-local 值的调用方显式传入,包内绝不从 `activeEngineRunId()` 推断)· `noteBgOwnerAbsence`(#242 批 3 [4000] Q3=B:tail/taskOutput·taskStop/subagentOutput 三腿台账缺席即诚实缺席**绝不回落在飞 run**,缺席 warn 留痕每 (腿,taskId) 一条)· `clearBgTerminalFacts`(#242 批 3 扫码修:复活=新周期,旧周期终态事实作废——fleetLedger 复活两腿按尾段清账,factsAccepted 方向核不再拿上周期终态当先例)· `auditRetainWithoutWake`([4000] Q5:引擎宣示 `subagentResume` + 本端在付 `retainSubagentSessions` + 端未实现 `wakeSubagent` ⇒ 响亮一条;`CLIENT_VERBS.wakeSubagent` 维持 fail-soft)· `subscribeSubagentContent` · `subscribeEngineAgentPanel` · `publishQuestionFrame` / `respondToQuestion` · `configureSubagentContentStore` / `subagentContentStoreConfig` / `SUBAGENT_CONTENT_STORE_DEFAULTS`(0.62.0:子代内容账本的**字节预算** —— 此前只有条数帽而单条无上限,一条 base64 工具结果就能让一个子代槽吃到十几 MB;越限从最早的内容开始丢并留一条可渲染的 `truncated` 记录,总帽淘汰整条最久未用的账本。配置面 fail-loud,详见 §26②)| 驱动与观测委派子代;经 module 级台账喂活体 agent/task 面板。全部**能力位 gate**(§5b) | `src/subagent/*.ts`、`src/subagentContentStore.ts`、`src/engineAgentPanelStore.ts`、`src/engineInlineTaskStats.ts`、`src/engineToolLabelStore.ts`、`src/liveQuestionStore.ts` |
161
161
  | 5 | **fleet 投影** | 38 | `createFleetLedger` · `projectTasks` · `projectWorkflows` · `projectFleetAgentRows` · `readEngineActiveBgTasks` · `FLEET_TASK_VIEW_KEYS` · `escapeDisplayControlChars`(不可见字符可见化,行标签/描述消毒的共享底座)· `capForDisplay`(0.62.0:呈前**消毒 + 封长**的共用铸点 —— 先转义、后按转义结果封长,截点避开半截转义 token 与合法代理对;本包该族四处此前各写一份、其中三份顺序是反的,详见 §26⑦)· `wireCycleSeq`(0.38.0 提货补投的 #261 §2 两位之一,另一位 `wireRetiredBy` 🔧 0.72.0 退出公面:代际号 = SendMessage 复活即 +1,**缺席 ≠ 第一代**;`retiredBy` 在场 = 这条终态是对账腿从 durable run 行投影出来的、**不是**发布方亲报 —— 幽灵行与正常收尾唯一的 wire 判据。两位都只在场才落键) | 老 `fleetClient` 那一刀的成品:**帧体归库、连接归端** —— 端持 SSE 连接,库做行投影 + 保留台账 | `src/fleet/fleetProjection.ts`、`src/fleet/fleetLedger.ts`、`src/fleetAgentPanelProjection.ts`、`src/fleetTaskDesc.ts` |
162
162
  | 6 | **请求装配(上行唯一构造口)** | 10 | `buildTaskRequest` · `REQUEST_FIELD_MATRIX` · `unregisteredRequestKeys` · `applyLiveRequestDefaults` · `taskNotificationToPrintFrame` | 两条车道(`interactive`/`print`)出站请求的**唯一**构造器;`unregisteredRequestKeys` 是可执行门 —— 端偷带一个未登记键上 wire 就红 | `src/request/taskRequest.ts`、`src/request/printNotification.ts` |
163
- | 7 | **通知与 outstanding 台账** | 51 | `installNotificationQueuePort` · `normalizeTaskNotification` · `taskNotificationDedupKeyFromWire` · `registerOutstandingBgTask` / `registerOutstandingWorkflowRun` · `notificationQueuePortMisses` · `subscribeOutstandingWorkflows` · `outstandingDeliverableWorkflowCount` | `task_notification` 归一 + 去重 + 投递进宿主命令队列的**一把闸**;`outstandingDeliverableWorkflowCount()` 是 headless `-p` 的**退出门** · `classifyPeerNotification` / `renderPeerFrameTranscriptText` / `parsePeerFrameText` / `peerFrameDisplayName` + 三张闭集表(design/385,0.54.0:同一条 `task_notification` 车道上三条**引擎注入帧**的类型化投影 —— 判别位=载体在场而非 summary 文本,详见 §17) | `src/notifications.ts`(11 个 module 台账) |
163
+ | 7 | **通知与 outstanding 台账** | 52 | `noteOwnWorkflowRun`(0.72.2 CC-37:own 台账显式登记口,adapter workflow lane 门在 own-run 正向证明下同拍调;§49)· `installNotificationQueuePort` · `normalizeTaskNotification` · `taskNotificationDedupKeyFromWire` · `registerOutstandingBgTask` / `registerOutstandingWorkflowRun` · `notificationQueuePortMisses` · `subscribeOutstandingWorkflows` · `outstandingDeliverableWorkflowCount` | `task_notification` 归一 + 去重 + 投递进宿主命令队列的**一把闸**;`outstandingDeliverableWorkflowCount()` 是 headless `-p` 的**退出门** · `classifyPeerNotification` / `renderPeerFrameTranscriptText` / `parsePeerFrameText` / `peerFrameDisplayName` + 三张闭集表(design/385,0.54.0:同一条 `task_notification` 车道上三条**引擎注入帧**的类型化投影 —— 判别位=载体在场而非 summary 文本,详见 §17) | `src/notifications.ts`(11 个 module 台账) |
164
164
  | 8 | **工具结果卡** | 24 | `structuredToToolUseResult` · `readAsyncLaunchedAgentReceipt` · `wireOutputToBody` · `parseModelFacingBash` · `getPatchFromContents` · `toolEndResultToUserFrame` · `flattenToolOutput` | 铸端要渲的 `tool_result` 卡体,含客户端 diff hunk(唯一 runtime dep 的用处) | `src/toolResult.ts`、`src/printToolResultFrame.ts`、`src/diff/patch.ts` |
165
- | 9 | **能力/旋钮 wire 门族** | 95 | `projectAgentsForWire` / `awaitTaskAgentsWire` · `hooksForWire` · `mcpConfigsToSpecs` · `ultracodeForRequest` · `resolveWebSearch` + `buildWebSearchEnv` · `attachmentsForRequest` · `projectEffectiveBody` · `classifySelfOrchestrationRefusal` / `stripSelfOrchestrationIntent` / `projectWorkflowsGate` / `SELF_ORCHESTRATION_RETRY_WITHOUT`(S-81,server 7.57.0:上面两条 stamp 腿的**背面** —— 半配置多租户形态下 server 把带 `selfOrchestration` / `settings.ultracode` 的提交 501 拒掉,判型/去键/caps 闸三处都是判定不是文案,详见 §13) · `engineCapsGeneration`(0.60.0,异源对抗复审 [medium] 逼出:caps 探测的**当代号**读口 —— 代际闸在 probe **返回之后**才跑,而宿主的读面 tee 是在 probe **内部**落地的 ⇒ 一次慢的旧探测能把上一台引擎的读数写回来。宿主在**起探测那一刻**抓号、tee 时交回 `{generation}`,陈旧那一发整只丢掉;不传 = 逐字节同行为,详见 §24e)| 逐功能的「引擎有没有这个能力 + 这个字段怎么上 wire」投影器,由 `buildTaskRequest` 组装。🔴 `hooksForWire()` 是 **fail-closed**:无 `SettingsPort` ⇒ 返回 `undefined`(信任门,不是取值) | 17 个 `src/*WireCaps.ts` + `src/scratchpadWireCaps.ts`、`src/hooksWireCaps.ts`、`src/goalStopHook.ts`、`src/websearch/searchProviderPresets.ts`、`src/selfOrchestrationDenial.ts`(S-81 拒绝判定层) |
165
+ | 9 | **能力/旋钮 wire 门族** | 96 | `skillBaseDirOf`(0.72.1 CC-33:`SkillSpec.baseDir` 窄读 = server 顶层门同一只结构判据;`skillCommandsToSpecs` 第三参 `{ toolsRunHere }` 只在本机车道带;§48)· `projectAgentsForWire` / `awaitTaskAgentsWire` · `hooksForWire` · `mcpConfigsToSpecs` · `ultracodeForRequest` · `resolveWebSearch` + `buildWebSearchEnv` · `attachmentsForRequest` · `projectEffectiveBody` · `classifySelfOrchestrationRefusal` / `stripSelfOrchestrationIntent` / `projectWorkflowsGate` / `SELF_ORCHESTRATION_RETRY_WITHOUT`(S-81,server 7.57.0:上面两条 stamp 腿的**背面** —— 半配置多租户形态下 server 把带 `selfOrchestration` / `settings.ultracode` 的提交 501 拒掉,判型/去键/caps 闸三处都是判定不是文案,详见 §13) · `engineCapsGeneration`(0.60.0,异源对抗复审 [medium] 逼出:caps 探测的**当代号**读口 —— 代际闸在 probe **返回之后**才跑,而宿主的读面 tee 是在 probe **内部**落地的 ⇒ 一次慢的旧探测能把上一台引擎的读数写回来。宿主在**起探测那一刻**抓号、tee 时交回 `{generation}`,陈旧那一发整只丢掉;不传 = 逐字节同行为,详见 §24e)| 逐功能的「引擎有没有这个能力 + 这个字段怎么上 wire」投影器,由 `buildTaskRequest` 组装。🔴 `hooksForWire()` 是 **fail-closed**:无 `SettingsPort` ⇒ 返回 `undefined`(信任门,不是取值) | 17 个 `src/*WireCaps.ts` + `src/scratchpadWireCaps.ts`、`src/hooksWireCaps.ts`、`src/goalStopHook.ts`、`src/websearch/searchProviderPresets.ts`、`src/selfOrchestrationDenial.ts`(S-81 拒绝判定层) |
166
166
  | 10 | **headless / 部署旋钮 wire** | 58 | `parseSandboxArgv` / `sandboxRequestFields` · `parseLimitsArgv` / `limitsForPrint` · `resolveHeadlessFinalVerify` · `resolveHeadlessPermissionMode` · `resolveHeadlessInteractiveTools` · `armDetachCancel` + `detachCancelArm` + `isDetachArmed` · `withHeadlessR1Reconnect` | `-p`/headless 车道的 env+argv 旋钮。🔴 `detachWire` 是**拆**的补偿:判定与 cancel-arm 台账在库,信号路径的裸 fetch 留宿主(`detachCancelArm()` 是取件口) | `src/sandboxWire.ts`、`scenarioWire.ts`、`finalVerifyWire.ts`、`limitsWire.ts`、`interactiveToolsWire.ts`、`headlessPermissionModeWire.ts`、`headlessReconnectWire.ts`、`detachWire.ts` |
167
167
  | 11 | **模型目录与预算** | 67 | `routePairingVerdict`(0.71.3 CC-06:`ModelInfo.routePairing` ok / broken / unknown 三态读口,§45)· `resolveModelCatalog` · `loadCatalogWithSources` · `PROVIDER_PRESETS` / `MODEL_FAMILIES` · `defaultMaxTokensFor` · `getLiveModelCatalog` / `setLiveModelCatalogRefresher` · `providerAuthMethods` / `beginDeviceCodeAuth` · `providerCatalogRows` / `providerCatalogRowDetail` / `providerPresetById`(#244 F4 族D A-028.17:46 家表的规范折表层 —— 全表不重排、诚实缺席「model id typed in」,cli 目录/web 向导同一份折表)· `TIER_ORDER` / `CC_TIER_ALIASES` / `isTier` / `resolveTierBinding`(A-028.18:档位词表+校验+fail-open 降档派生单源;settings 存储归宿主)· `resolveEntryVision` / `computeDeleteBlockers` / `computeDeleteWarnings`(0.38.0 #318 件③ 上收:Model Hub 供给面的三端公共判定 —— vision 生效值+来源三态、删除断链核(拒删+指路)、删除降级后果(照删但必说)。**零 IO**,读盘那半场留各端;`doc === null` 的两义在调用方分流) | 三层 provider 目录解析(线上 URL → 包内预设 → 用户覆盖)+ per-model `maxTokens` 封顶。线上腿需注入 `CatalogFetchJson`,缺席 ⇒ 整条不启用(`online.reason='no-fetch-port'`);缓存落盘经 `CatalogCachePort` | `src/model/{catalog,catalogLoader,providerAuth,providerPresets,providerCatalog,tierVocabulary}.ts`、`src/liveModelCatalog.ts`、`src/modelBudgetRule.ts`、`src/sessionModelLatch.ts`、`src/effortWire.ts` |
168
168
  | 12 | **workflow 与后台工作视图** | 21 | `projectWorkflowRun` · `readWorkflowResumeAdmissionIncomplete`(0.68.3 CC-05:core 7.18.0 `resumeAdmissionIncomplete` 在场 = 不是 resume 基,与 `readWorkflowParks` 同一条投影义务)· `createLiveWorkflowSource` · `ensureWorkflowActivityLedger` · `readWorkflowActivityLedger` · `stopWorkflowActivityLedger` · `resetWorkflowActivityLedgers` · `createBackgroundView` · `projectBackgroundView` · `recordWorkflowAgentTaskId` · `agentDisplayStatus` | 活过一个 turn 的长任务读面:workflow run + 跨 session 后台任务归一表(`assistant.tasks` 与 fleet SSE **两源独立降级**) | `src/workflow.ts`、`src/workflowClient.ts`、`src/workflowMonitor.ts`、`src/agentSession/backgroundView.ts`(+ 纯类型 `src/agentSession/contract.ts`) |
169
169
  | 13 | **座位 IPC 契约** | 34 | `LOCAL_SESSIONS_SPEC` · `SEAT_METHOD_NAMES` · `SEAT_EVENT_TYPES` · `isLocalSessionEvent` · `isToolPermissionRequest` · `toolPermissionRequestId` · `SEAT_VALIDATOR_KEY_COVERAGE` · `SEAT_SEND_MESSAGE_KEY_ORIGINS`(0.62.0:座位载荷**逐键出身**登记 —— 每个位要么写明转投哪个引擎请求位、要么写明为什么不上 wire;常驻门对**装在盘上的** sdk 型面逐名核,详见 §26③)| desktop↔web 座位 IPC 契约的**单一真源**(此前两边各一份、名字零重合 ⇒ 编译器永远不会告诉你它们漂了)。🔴 加 verb 忘了加 `LOCAL_SESSIONS_SPEC` **不报错**:preload 不注册 channel、渲染端读到 `undefined` | `src/seatContract.ts`(**零 import**,纯类型 + 常量 + 纯谓词)。🔴 **证据等级标注(0.42.0,test [5087] 的「语料**种类**缺口」/ cli [5088] 认领件)**:该文件里所有以「CC 如何如何」为形的断言(`212 methods` / `854-channel census` / 方法名逐字保留 / `fQe` 逐字段对照 / 一切 `.vite/build/index.chunk-*.js` 坐标)**证据等级 = 桌面 unpack,本地语料库不可复验** —— 本仓手边可复验的参照语料**只覆盖终端 CLI 形态**的静态产物,拿它去 grep 桌面壳里的符号只会零命中,而零命中在这里**既不证真也不证伪**。复核这些断言**不得**拿本仓语料当反证 |
170
170
  | 14 | **宿主端口与会话槽** | 41 | `installHost` · `installHostFor` · `installCoreValuePorts` + 十读口 + 三存在性口(0.69.0 CC-07:core 值级面端口注入,Node 宿主装配根装、浏览器 lane 恒缺席)· `hostPortMisses(For)` · `DEFAULT_SESSION_KEY` · `hostEnv` · `unrefTimer` · `parseLocaleTag` / `pickUiLanguage`(#244 F4 族D A-028.20:locale tag 手术单源 + UI 语言判定;与 `resolveRegionHint` 双出口成文 —— 语言偏好域 en/zh ≠ 地址可达域 cn/intl/unknown,`zh-Hant` 前者 zh 后者 intl 是设计)· `engineNamespaceKeyFor` / `mergeSessionMapRecord` / `mergeEngineEntry`(A-028.12:会话 id 映射单一键形 + merge 判定;存储经 `SessionMapStorePort` 归端 —— cli 文件锁/原子写,web localStorage)| 进程/端级装配层(settings/fs/queue/timers/session/log/probe),与 per-turn 的 `AdapterContext` **分层**。头注的判定规则:**这个能力每 turn 都会变吗?** 会 ⇒ `ctx`;不会 ⇒ `installHost` | `src/host.ts`、`src/hostEnv.ts`、`src/sessionSlot.ts`、`src/unrefTimer.ts`、`src/env/{localeGeo,localeTag,uiLanguage}.ts`、`src/sessionMap.ts` |
171
- | 15 | **控制面与传输** | 122 | `mcpEngineLegPresence`(0.71.0 CC-19:引擎侧 MCP 在场三值,只从面板视图求;§42)· `ControlRouter`(+ `ControlSafetyError`)· `fetchMcpPanel`(0.69.0:经 sdk `sessions.mcp` 取体 + 投视图,不裸 fetch)· `projectMcpPanel` + `mcpPanelLastLegDetail`(0.68.2 CC-03:`GET /v1/sessions/:id/mcp` 面板体防御读视图 + `lastLegMcp` 一行措辞铸点;缺席 = 键不铸、读不懂 = `lastLegMcpUnreadable`、禁与 `servers[]` 对账)· `makeEngineWireClient` + `resolveWireAuth` · `installEngineWireTarget` · `diagnoseSseIdleTear` / `isSseIdleError` · `attemptActiveRunSelfHeal` + `activeRunBusySignal` + `activeRunSelfHealRow` / `activeRunBusyHeadlessRow` · `kickEngineCapsProbe` / `engineCapTrue` / `invalidateEngineCaps(baseUrl, probe?)`(#307 S25:引擎温切后的 caps 生产失效口 —— kick 自带幂等闸,同 baseUrl 重启后不显式失效就永远读到旧引擎那一版能力位;调用方 = 壳的 respawn/restartEngine。🔴 **推荐两参形**:第二参给替代探测则「推进代际 + 注册新探测」在同一同步块内完成,失效与下一次 kick 之间那个「等待者读到未判」的窗按构造不存在;单参形保留给「只丢缓存、这一刻没有替代探测」的调用方,那种情形下读到未判是诚实结局) · `engineCapValue`(S-131,0.59.0:能力位的**四态**通用读口 `unobserved`/`not_reported`/`null`/`value` —— 既有三口把四种「读不出」全折成 fail-closed 一档,对**放行**问题是对的、对**读面/诊断**问题是错的:`null`(引擎明确说没有,正面事实)会与「老引擎不报」「还没探到」在屏上同形。`value` 位刻意不做形校验,形归各能力位自己的窄读器,详见 §23b)· `projectSqlEngineCapability` / `observedSqlEngine` / `noteEngineCapsForSqlEngine` / `forgetSqlEngineReading` / `sqlEngineDoctorDetail`(S-131,0.59.0:`Capabilities.sql`(server ≥7.60.0)的四态读面**从壳侧上收** —— 归层债,0.58.0 时它长在壳里正是因为包侧没有嵌套对象读口。🔴 **导出名与壳侧那份逐字同名 = drift-lock**;`txnMode: null` 是铸点域内的合法值不是畸形;换代失效口清成未观测而不是留旧值,详见 §23b)· `mapBrainStatusToRetry` · `waitForClaimRelease` + `CLAIM_RELEASED_STATES` / `CLAIM_HELD_STATES` · `atMostOnceFailureClass` / `readSteerDelivery` · `clearRunningChoiceOffer`(Inkglow-1085 P0b①:「Do nothing」登记的清口 —— 端的「重新打开操作菜单」入口;登记在场时 attemptActiveRunSelfHeal 不整卡重弹,not-parked 结局带 `alreadyOffered: true` 判别位,端据此降级渲一行)· `INTERACTIVE_WAY_OUT`(默认出路串单源)· `engineSessionParamFor`(design/285 批 0:`?session=` 派生的 **per-key** 形 —— `hostSessionFor(sessionKey)?.currentSessionId()` + [1501] 空串归一;零参 `engineSessionParam()` = 默认槽兼容层,取值链逐字等价)· `normalizeWirePrincipal`(A-028.10:principal 在场性 trim 原语 —— 全空白=缺席不发头,engineWireTarget 两臂/makeEngineWireClient/壳 livePrincipal 同尺)· `readSessionMemoryStatus` / `classifyMemoryStatusFailure` / `readCaptureOptOut` / `readLastCapture`(S-53 会话记忆姿态读面,0.48.0:失败分诊**码优先**——两个 404 分道 `not_found.session` / `not_found.route`,无码 404 不猜落 failed;五键逐键缺席语义两个合读器,`lastCapture` 三态的判别材料是 `committedCount` 不是本键;IO 归宿主注入 `MemoryStatusClientLike`,详见 §11) · `classifyTurnWireError` / `isWireTransportError` / `isPreStreamDrainingReject` / `isResumeAtRejection` / `drainingRetryDelayMs` / `scenarioDenyFromError` + `WIRE_NETWORK_ERROR_PATTERN`(A-028.11/.13:turn 错误分型判定半场,人话文案与渲染归端)· `resumeRetryLaterFromError`(L-102,0.57.0:resume 族**时间性拒绝**二码的判型半场 —— 这一族里唯一**带得出「等多久」**(`retryAfterSec`)的两个码。🔴 闭集**不是**「哪些码可以等」的名单:同族 `resume.row_recycling` 同样可等(窗口自清)只是没有秒数 ⇒ 本读口返回 `null` 只意味着没命中这两码,详见 §21) · `projectWriteProtectionCapability` / `observedWriteProtection` / `noteEngineCapsForWriteProtection` / `forgetWriteProtectionReading` / `writeProtectionDoctorDetail` / `projectWriteProtectionPosture` / `writeProtectionPostureDetail`(S-138,0.60.0:`Capabilities.writeProtection` (engine ≥7.63.0)的**四态**读面 + operator 面行表 —— 与上面 S-131 那一格**同构同纪律**。🔴 三位刻意不合成一个布尔;`not_reported` **不是**「这台部署没有写保护表」(座位缺席恰是缺省表在岗);逐行 name/kind 走**最小披露**只上 operator 面,详见 §24e)· `projectReadFacePosture` / `readFacePostureDetail` / `readFaceDisagreement`(S-167,0.61.0:operator 面 `diagnostics.wiring.readFace`(engine ≥7.65.0)的窄读器 —— 与上面S-138 那一格**同构同纪律**。🔴 三句「答不出来」逐字互异且没有一句等于「没有 READ 档」;`source` 按开集读;与租户面 `capabilities.readFace` 刻意不合流,只带一个纯比较函数,详见 §25)| 上行通道的**监管**半场(submit / steer / kill / 队列命令定序)+ 传输构造、caps 探测、SSE 断流分诊、**409 active-run 自愈** | `src/controlRouter.ts`、`steering.ts`、`sseIdleTriage.ts`、`retryStatus.ts`、`diagnostics.ts`、`engineWireSdk.ts`、`engineWireTarget.ts`、`src/principalWire.ts`、`src/wireErrorTriage.ts`、`engineSessionParam.ts`、`engineCapsCache.ts`、`liveInitToolFace.ts`、`adapter/activeRunSelfHeal.ts`、`src/sessionMemoryStatus.ts`、`src/writeProtectionCapability.ts`、`src/readFacePosture.ts` |
172
- | 16 | **引擎词汇表与包自检** | 90 | `RESUME_REOPEN_CODES` / `RESUME_ENV_FAILED` / `RESUME_TOOL_UNAVAILABLE` / `RESUME_TOOL_CONTRACT_MISMATCH` · `resumeReopenFromError` / `resumeReopenContent`(0.71.3 CC-06:resume reopen 族三码闭集 + 读口 + 三句,§45)· `readSkillsListingTruncated`(0.70.0 CC-04:`skills.listing_truncated` 事实读器,§39)· `CONFIG_REFUSAL_CODES` / `isConfigRefusalCode` · `DECIDE_WORKFLOW_LANE_CODES`(+ 三个具名码;`/decide` workflow 车道,三条出路刻意不合并,详见 §30h)· `STOP_CONFLICT_CODES` · `isInterruptedToolEndCode` · `isRewindFamilyCode` · `CLIENT_VERBS` · `compensationSplitViolations` · `DELEGATION_CAP_CODES` / `isDelegationCapCode` / `DELEGATION_CONCURRENCY_CAP` / `DELEGATION_SESSION_CAP`(0.38.0 #318 件④:core 5.48.0 design/323 委派席位到限**两码,处置不对称禁合并** —— 并发帽=**可等**(兄弟结束即有位)/ 会话累计帽=**等也没用**(这条会话的配额用尽))· `CONFIG_DELEGATION_ENTRY_CAPS`(同批入 `CONFIG_REFUSAL_CODES` 识别表)· `delegationCapDispositionOf` / `MCP_SERVER_REVOKED`(0.39.0 载体到货消费件:core 5.50.0 补 `{ error: code, code }` 孪生拼法后两码真上 `tool_end.errorCode`,0.38.0「先立词不落消费分支」的已知局限自此解除;处置轴 `wait-for-slot` / `reuse-existing-or-await-reap` 机器可读(累计帽=retained-window 帐,行回收配额即回,处置=SendMessage 复用,**非**「换会话/永久耗尽」——0.38.0 段该句系勘误),未知 `delegation.*` 码 ⇒ `undefined`;`mcp.server_revoked` = 操作员 mid-session 吊销 server 后的工具面本地闸(被吊销的 server **名**今天不过 wire 境:detail.server 是进程内位,抬升腿只 lift code——归因渲染候 core 补 typed detail,已点名);载体门 = engine-vocab G3 腿锚 core dist 铸点)· `CAPABILITY_SELF_ORCHESTRATION_REQUIRED`(S-81,server 7.57.0:提交面的 selfOrchestration 准入拒绝码。🔴 **复用码** —— 与其它 `capability.*` 501 同体形而处置不同,消费点必须按**恰等**判、绝不放宽成前缀判;判型与「去键重发一次」归 `src/selfOrchestrationDenial.ts`,详见 §13) · `GATE_PARKED_ERROR_CODE`(0.60.0:「门把这次调用 park 了」的机读码单源 —— `frameRouter` 的连坐/中断判据与 `gateOutcome.isGateParkedToolEnd` 读同一个常量;真机黑盒直证 park 短路帧上**没有 `gate`**,这个码是那一形唯一的信号,详见 §24c)| 三端分臂共用的**去字面化** `errorCode` 词表(病根正是三端各抄一份字面);编译期 verb 闭合门;搬迁补偿登记表 | `src/engineErrorCodes.ts`(计数以 `scripts/public-export-baseline.json` 为准,别手抄;A-028.11/.13 补 `DRAINING_ERROR_CODE`/`SCENARIO_NOT_ALLOWED_ERROR_CODE`/`RESUME_AT_ERROR_CODE_PREFIX`;#318 件④ 补 `delegation.*` 族四位 + `config.delegation_entry_caps`;0.39.0 补三新码消费件三位);S-81 补 `capability.self_orchestration_required` 一位;L-102 补 `resume.*` 时间性拒绝二码 + 闭集 `RESUME_RETRY_LATER_CODES` 三位)、`src/classifierVerdictWire.ts`、`src/compensations.ts`、`src/clientSlice.ts`;**0.67.0 补锚**(这三件的导出一直计在本域,而本表此前没有它们的锚行 —— 如实补上,不是搬家):`src/gateVocabulary.ts`(`GATE_DENIED_BY_WORDS`/`gateDeniedByDetail`/`ASK_ORIGIN_WORDS`/`askOriginDetail` + 🆕 `RULE_STORE_UNREADABLE_KINDS`/`isRuleStoreUnreadableKind`/`ruleStoreUnreadableDetail`,详见 §32d)、`src/autoModeUnavailable.ts`(`AUTO_MODE_UNAVAILABLE_CAUSES` + 🆕 `CLASSIFIER_DENY_CAUSES`/`isClassifierDenyCause`/`classifierDenyCauseOf`/`classifierDenyCauseDetail`;🔴 同批**删**`classifierUnavailableOf`/`classifierUnavailableDetail`,详见 §32b)、`src/classifierStatus.ts`(`CLASSIFIER_STATUS_STATES`/`classifierStatusOf`/`classifierStatusDetail`)|
171
+ | 15 | **控制面与传输** | 124 | `resumeContextUnavailableFromError` / `resumeContextUnavailableContent`(0.72.1 CC-33:409 `conflict.resume_context_unavailable` 读数 `{ code, staleAfterSec?, runId? }` + 三句人话;§48)· `mcpEngineLegPresence`(0.71.0 CC-19:引擎侧 MCP 在场三值,只从面板视图求;§42)· `ControlRouter`(+ `ControlSafetyError`)· `fetchMcpPanel`(0.69.0:经 sdk `sessions.mcp` 取体 + 投视图,不裸 fetch)· `projectMcpPanel` + `mcpPanelLastLegDetail`(0.68.2 CC-03:`GET /v1/sessions/:id/mcp` 面板体防御读视图 + `lastLegMcp` 一行措辞铸点;缺席 = 键不铸、读不懂 = `lastLegMcpUnreadable`、禁与 `servers[]` 对账)· `makeEngineWireClient` + `resolveWireAuth` · `installEngineWireTarget` · `diagnoseSseIdleTear` / `isSseIdleError` · `attemptActiveRunSelfHeal` + `activeRunBusySignal` + `activeRunSelfHealRow` / `activeRunBusyHeadlessRow` · `kickEngineCapsProbe` / `engineCapTrue` / `invalidateEngineCaps(baseUrl, probe?)`(#307 S25:引擎温切后的 caps 生产失效口 —— kick 自带幂等闸,同 baseUrl 重启后不显式失效就永远读到旧引擎那一版能力位;调用方 = 壳的 respawn/restartEngine。🔴 **推荐两参形**:第二参给替代探测则「推进代际 + 注册新探测」在同一同步块内完成,失效与下一次 kick 之间那个「等待者读到未判」的窗按构造不存在;单参形保留给「只丢缓存、这一刻没有替代探测」的调用方,那种情形下读到未判是诚实结局) · `engineCapValue`(S-131,0.59.0:能力位的**四态**通用读口 `unobserved`/`not_reported`/`null`/`value` —— 既有三口把四种「读不出」全折成 fail-closed 一档,对**放行**问题是对的、对**读面/诊断**问题是错的:`null`(引擎明确说没有,正面事实)会与「老引擎不报」「还没探到」在屏上同形。`value` 位刻意不做形校验,形归各能力位自己的窄读器,详见 §23b)· `projectSqlEngineCapability` / `observedSqlEngine` / `noteEngineCapsForSqlEngine` / `forgetSqlEngineReading` / `sqlEngineDoctorDetail`(S-131,0.59.0:`Capabilities.sql`(server ≥7.60.0)的四态读面**从壳侧上收** —— 归层债,0.58.0 时它长在壳里正是因为包侧没有嵌套对象读口。🔴 **导出名与壳侧那份逐字同名 = drift-lock**;`txnMode: null` 是铸点域内的合法值不是畸形;换代失效口清成未观测而不是留旧值,详见 §23b)· `mapBrainStatusToRetry` · `waitForClaimRelease` + `CLAIM_RELEASED_STATES` / `CLAIM_HELD_STATES` · `atMostOnceFailureClass` / `readSteerDelivery` · `clearRunningChoiceOffer`(Inkglow-1085 P0b①:「Do nothing」登记的清口 —— 端的「重新打开操作菜单」入口;登记在场时 attemptActiveRunSelfHeal 不整卡重弹,not-parked 结局带 `alreadyOffered: true` 判别位,端据此降级渲一行)· `INTERACTIVE_WAY_OUT`(默认出路串单源)· `engineSessionParamFor`(design/285 批 0:`?session=` 派生的 **per-key** 形 —— `hostSessionFor(sessionKey)?.currentSessionId()` + [1501] 空串归一;零参 `engineSessionParam()` = 默认槽兼容层,取值链逐字等价)· `normalizeWirePrincipal`(A-028.10:principal 在场性 trim 原语 —— 全空白=缺席不发头,engineWireTarget 两臂/makeEngineWireClient/壳 livePrincipal 同尺)· `readSessionMemoryStatus` / `classifyMemoryStatusFailure` / `readCaptureOptOut` / `readLastCapture`(S-53 会话记忆姿态读面,0.48.0:失败分诊**码优先**——两个 404 分道 `not_found.session` / `not_found.route`,无码 404 不猜落 failed;五键逐键缺席语义两个合读器,`lastCapture` 三态的判别材料是 `committedCount` 不是本键;IO 归宿主注入 `MemoryStatusClientLike`,详见 §11) · `classifyTurnWireError` / `isWireTransportError` / `isPreStreamDrainingReject` / `isResumeAtRejection` / `drainingRetryDelayMs` / `scenarioDenyFromError` + `WIRE_NETWORK_ERROR_PATTERN`(A-028.11/.13:turn 错误分型判定半场,人话文案与渲染归端)· `resumeRetryLaterFromError`(L-102,0.57.0:resume 族**时间性拒绝**二码的判型半场 —— 这一族里唯一**带得出「等多久」**(`retryAfterSec`)的两个码。🔴 闭集**不是**「哪些码可以等」的名单:同族 `resume.row_recycling` 同样可等(窗口自清)只是没有秒数 ⇒ 本读口返回 `null` 只意味着没命中这两码,详见 §21) · `projectWriteProtectionCapability` / `observedWriteProtection` / `noteEngineCapsForWriteProtection` / `forgetWriteProtectionReading` / `writeProtectionDoctorDetail` / `projectWriteProtectionPosture` / `writeProtectionPostureDetail`(S-138,0.60.0:`Capabilities.writeProtection` (engine ≥7.63.0)的**四态**读面 + operator 面行表 —— 与上面 S-131 那一格**同构同纪律**。🔴 三位刻意不合成一个布尔;`not_reported` **不是**「这台部署没有写保护表」(座位缺席恰是缺省表在岗);逐行 name/kind 走**最小披露**只上 operator 面,详见 §24e)· `projectReadFacePosture` / `readFacePostureDetail` / `readFaceDisagreement`(S-167,0.61.0:operator 面 `diagnostics.wiring.readFace`(engine ≥7.65.0)的窄读器 —— 与上面S-138 那一格**同构同纪律**。🔴 三句「答不出来」逐字互异且没有一句等于「没有 READ 档」;`source` 按开集读;与租户面 `capabilities.readFace` 刻意不合流,只带一个纯比较函数,详见 §25)| 上行通道的**监管**半场(submit / steer / kill / 队列命令定序)+ 传输构造、caps 探测、SSE 断流分诊、**409 active-run 自愈** | `src/controlRouter.ts`、`steering.ts`、`sseIdleTriage.ts`、`retryStatus.ts`、`diagnostics.ts`、`engineWireSdk.ts`、`engineWireTarget.ts`、`src/principalWire.ts`、`src/wireErrorTriage.ts`、`engineSessionParam.ts`、`engineCapsCache.ts`、`liveInitToolFace.ts`、`adapter/activeRunSelfHeal.ts`、`src/sessionMemoryStatus.ts`、`src/writeProtectionCapability.ts`、`src/readFacePosture.ts` |
172
+ | 16 | **引擎词汇表与包自检** | 91 | `RESUME_CONTEXT_UNAVAILABLE`(0.72.1 CC-33;不进两个 resume 闭集:不可等、也不是换参数)· `RESUME_REOPEN_CODES` / `RESUME_ENV_FAILED` / `RESUME_TOOL_UNAVAILABLE` / `RESUME_TOOL_CONTRACT_MISMATCH` · `resumeReopenFromError` / `resumeReopenContent`(0.71.3 CC-06:resume reopen 族三码闭集 + 读口 + 三句,§45)· `readSkillsListingTruncated`(0.70.0 CC-04:`skills.listing_truncated` 事实读器,§39)· `CONFIG_REFUSAL_CODES` / `isConfigRefusalCode` · `DECIDE_WORKFLOW_LANE_CODES`(+ 三个具名码;`/decide` workflow 车道,三条出路刻意不合并,详见 §30h)· `STOP_CONFLICT_CODES` · `isInterruptedToolEndCode` · `isRewindFamilyCode` · `CLIENT_VERBS` · `compensationSplitViolations` · `DELEGATION_CAP_CODES` / `isDelegationCapCode` / `DELEGATION_CONCURRENCY_CAP` / `DELEGATION_SESSION_CAP`(0.38.0 #318 件④:core 5.48.0 design/323 委派席位到限**两码,处置不对称禁合并** —— 并发帽=**可等**(兄弟结束即有位)/ 会话累计帽=**等也没用**(这条会话的配额用尽))· `CONFIG_DELEGATION_ENTRY_CAPS`(同批入 `CONFIG_REFUSAL_CODES` 识别表)· `delegationCapDispositionOf` / `MCP_SERVER_REVOKED`(0.39.0 载体到货消费件:core 5.50.0 补 `{ error: code, code }` 孪生拼法后两码真上 `tool_end.errorCode`,0.38.0「先立词不落消费分支」的已知局限自此解除;处置轴 `wait-for-slot` / `reuse-existing-or-await-reap` 机器可读(累计帽=retained-window 帐,行回收配额即回,处置=SendMessage 复用,**非**「换会话/永久耗尽」——0.38.0 段该句系勘误),未知 `delegation.*` 码 ⇒ `undefined`;`mcp.server_revoked` = 操作员 mid-session 吊销 server 后的工具面本地闸(被吊销的 server **名**今天不过 wire 境:detail.server 是进程内位,抬升腿只 lift code——归因渲染候 core 补 typed detail,已点名);载体门 = engine-vocab G3 腿锚 core dist 铸点)· `CAPABILITY_SELF_ORCHESTRATION_REQUIRED`(S-81,server 7.57.0:提交面的 selfOrchestration 准入拒绝码。🔴 **复用码** —— 与其它 `capability.*` 501 同体形而处置不同,消费点必须按**恰等**判、绝不放宽成前缀判;判型与「去键重发一次」归 `src/selfOrchestrationDenial.ts`,详见 §13) · `GATE_PARKED_ERROR_CODE`(0.60.0:「门把这次调用 park 了」的机读码单源 —— `frameRouter` 的连坐/中断判据与 `gateOutcome.isGateParkedToolEnd` 读同一个常量;真机黑盒直证 park 短路帧上**没有 `gate`**,这个码是那一形唯一的信号,详见 §24c)| 三端分臂共用的**去字面化** `errorCode` 词表(病根正是三端各抄一份字面);编译期 verb 闭合门;搬迁补偿登记表 | `src/engineErrorCodes.ts`(计数以 `scripts/public-export-baseline.json` 为准,别手抄;A-028.11/.13 补 `DRAINING_ERROR_CODE`/`SCENARIO_NOT_ALLOWED_ERROR_CODE`/`RESUME_AT_ERROR_CODE_PREFIX`;#318 件④ 补 `delegation.*` 族四位 + `config.delegation_entry_caps`;0.39.0 补三新码消费件三位);S-81 补 `capability.self_orchestration_required` 一位;L-102 补 `resume.*` 时间性拒绝二码 + 闭集 `RESUME_RETRY_LATER_CODES` 三位)、`src/classifierVerdictWire.ts`、`src/compensations.ts`、`src/clientSlice.ts`;**0.67.0 补锚**(这三件的导出一直计在本域,而本表此前没有它们的锚行 —— 如实补上,不是搬家):`src/gateVocabulary.ts`(`GATE_DENIED_BY_WORDS`/`gateDeniedByDetail`/`ASK_ORIGIN_WORDS`/`askOriginDetail` + 🆕 `RULE_STORE_UNREADABLE_KINDS`/`isRuleStoreUnreadableKind`/`ruleStoreUnreadableDetail`,详见 §32d)、`src/autoModeUnavailable.ts`(`AUTO_MODE_UNAVAILABLE_CAUSES` + 🆕 `CLASSIFIER_DENY_CAUSES`/`isClassifierDenyCause`/`classifierDenyCauseOf`/`classifierDenyCauseDetail`;🔴 同批**删**`classifierUnavailableOf`/`classifierUnavailableDetail`,详见 §32b)、`src/classifierStatus.ts`(`CLASSIFIER_STATUS_STATES`/`classifierStatusOf`/`classifierStatusDetail`)|
173
173
 
174
174
  🔴 **`engineErrorCodes` 的开集纪律**(该文件头注逐字):这些 `ReadonlySet` / 前缀谓词一律是**识别表**,
175
175
  回答的是「我认不认得这个码」,**绝不是**「合法码只有这些」。消费点 `switch` **必须留 `default`**,
@@ -8293,3 +8293,60 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
8293
8293
  3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动。
8294
8294
 
8295
8295
  **包侧缺口:** ① CC-30 MCP 会话内重连消费口(候 core re-dial → server S-381);② CC-31 WebSearch 后端名读口(候 server S-382 `capabilities.webSearch.backend`);③ `agents.listing_truncated` detail 读器候消费场景(by-design);④ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑤ §NNz「declined 键真零命中」机读第二刀(候形式化);⑥ internal 34 放大件收回候模块拆分(by-design)。
8296
+
8297
+ ## §48 🆕 0.72.1 server 7.80.1 提货(CC-33:`conflict.resume_context_unavailable` 结构读数 + `SkillSpec.baseDir`;patch)
8298
+
8299
+ > **patch**:型面纯 additive(公面 960:+1 常量 +3 函数;零 `_sema_` 键;peer 不动;devDep 不动 —— server 不是本包依赖)。发车帖 [7430] @client-core 三条:① 409 体新键 `staleAfterSec` ② `TaskRequestBody.skills` 声明加宽(`baseDir` 可提交)③ `wiring_manifest.writeProtection` 段(0.71.4 §46 已镜像,consumed)。**sdk 9.6.0 还没把 ① 带到错误对象上**(`ConflictError` 只带 activeTaskId 三件),本包读口按结构读、今天经 sdk 恒缺席,sdk 出键之日自动填满([7430] ③ 已点名 @sdk)。
8300
+
8301
+ ### 48a. 处置表
8302
+
8303
+ | # | 面 | 本包做了什么 | 端要做什么 |
8304
+ |---|---|---|---|
8305
+ | S-1 | 409 `conflict.resume_context_unavailable` 体键 `staleAfterSec`(整数秒 = 部署 `REAP_RUN_STALE_SEC` 真值)+ 既有 `runId` | **consumed**:`resumeContextUnavailableFromError(err) → { code, staleAfterSec?, runId? } \| null`(duck-typed,只认 `errorCode`;`staleAfterSec` 窄读域整数 ≥1,坏值降缺席;`runId` 非空串才在场)+ `resumeContextUnavailableContent(d)` 三句人话(零内部车道词、不铸秒数;**只凭码不推断原因** —— server 在上下文被回收 **或读取失败** 时都发本码,第一句只说「当前没有可用的上下文」;第三句按 `runId` 在场与否给恢复指引,调大保留时长只作预防)+ 码常量 `RESUME_CONTEXT_UNAVAILABLE`(**不进** `RESUME_RETRY_LATER_CODES` / `RESUME_REFUSAL_CODES`:不可等、也不是换参数) | 决断失败路径上 `resumeContextUnavailableFromError(e)` 非 null ⇒ 渲三句 + 若 `staleAfterSec` 在场再渲一行「部署保留时长 N 秒」(缺席不渲、不折 120)+ 若 `runId` 在场给「恢复这条运行」入口;别再从 message 散文里抠数字或车道词 |
8306
+ | S-2 | `TaskRequestBody.skills[]` 声明加宽为 `SkillSpec` 本体,`baseDir` 可提交(server 顶层门按形判:绝对 / 无 `..` / 无 NUL / ≤4096) | **consumed**:`skillCommandsToSpecs(cmds, resolveBody, { toolsRunHere })` —— 只在 `toolsRunHere === true` 时从 `command.skillRoot` 带 `baseDir`;`skillBaseDirOf(root, platform = 'posix')` 窄读 = server 同一只结构判据,「绝对」按 **server 所在平台**的 `node:path.isAbsolute` 判(posix 只认 `/…`;`win32` 才收盘符与 UNC —— 且 win32 分支比 server **严**:`/a`、`\\a`、`//host/share` 这类 Windows `path.isAbsolute` 会收的形本包不发;声明错 = server 400 整拒)—— 第三参 `{ toolsRunHere, platform? }`;出口型 `SkillSpecOnWire = SkillSpec & { baseDir?: string }`(sdk 9.6.0 的 `SkillSpec` 未声明该键,交叉型零摩擦) | 本机车道(单用户 host,工具与技能同一台机)传 `{ toolsRunHere: true }`;沙箱 / 远端车道(k8s / e2b / ssh / device)**不传**(缺席 = fail-closed,引擎不加首行不做替换,与 0.72.0 之前逐字节相同);要让模型真读得到目录还得把它放进 `additionalReadDirectories` |
8307
+ | S-3 | `wiring_manifest.writeProtection` 段 | 0.71.4 §46 已镜像(`_sema_writeProtection` / chrome `writeProtection?`) | 零动作 |
8308
+
8309
+ ### 48z. 逐键处置表
8310
+
8311
+ | # | 键 / 面 | 处置 | 坐标 / 理由 |
8312
+ |---|---|---|---|
8313
+ | 1 | 409 体 `staleAfterSec` | **consumed** | `src/resumeRefusalCopy.ts` 的 `#resumeContextUnavailableFromError`;门 `run-resume-refusal-copy-test.mjs` ⑧ 段(非本码 null / 窄读域 / 缺席不在场 / 三句 / 零车道词 / 不铸数字 / 纯函数) |
8314
+ | 2 | 409 体 `runId`(既有键) | **consumed** | 同上;非空串才在场 |
8315
+ | 3 | 码 `conflict.resume_context_unavailable` | **consumed** | `src/engineErrorCodes.ts` 的 `#RESUME_CONTEXT_UNAVAILABLE`;不进两个 resume 闭集(门 ⑧ 与 ③ 段共同钉) |
8316
+ | 4 | `SkillSpec.baseDir` | **consumed** | `src/skillsWireCaps.ts` 的 `#skillBaseDirOf` / `#skillCommandsToSpecs` 第三参;门 `run-client-core-pure-test.mjs` skills 段 +8 格(默认不带 / 本机带 / 相对·`..`·NUL·超长不带 / posix 默认拒盘符·UNC / win32 收盘符·UNC / platform 透传 / posix 的 `..` 段两种分隔符都拆 / 其余三键不变) |
8317
+ | 5 | 21 条 4xx/5xx `error` 文案换句(码不变) | **declined** | 本包从不按文案分支(wire 锚契约),零动作;按旧句 grep 的端脚本自行改按码 |
8318
+
8319
+ ### 48y. 🔴 三端升级必读(固定段式,[C295])
8320
+
8321
+ 1. 换钉 `^0.72.1`:决断失败路径接 `resumeContextUnavailableFromError`,并把「120 秒」这类写死数字改读 `staleAfterSec`(缺席就不渲);文案由 `resumeContextUnavailableContent` 给,别自己写「等太久 / 已回收」(server 读取失败也发同码);**经 sdk 9.6.0 的端今天读到的恒是缺席**,这是诚实缺席不是 bug,sdk 出键后零改动填满。
8322
+ 2. 本机车道调 `skillCommandsToSpecs(cmds, resolveBody, { toolsRunHere: true, platform })`(`platform` = server 所在平台,缺席 posix);沙箱 / 远端车道保持两参调用,行为逐字节不变。
8323
+ 3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;`SkillSpecOnWire` 是 `SkillSpec` 的交叉型,赋给 sdk 的 `skills: SkillSpec[]` 无需断言。
8324
+
8325
+ **包侧缺口:** ① CC-30 MCP 会话内重连消费口(候 core #857 设计车 + server S-381);② CC-31 WebSearch 后端名读口(候 server S-382);③ CC-34 `permission_denials` 自动升级验证(候 server S-394 出 `toolCallId`);④ CC-35 core 7.21.0 三件(候 server 装载 7.21.0 发车帖);⑤ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 把体键带上 `ConflictError`,[7430] ③);⑥ `agents.listing_truncated` detail 读器候消费场景(by-design);⑦ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑧ §NNz「declined 键真零命中」机读第二刀(候形式化)。
8326
+
8327
+ ## §49 🆕 0.72.2 workflow 视图两票(CC-38 `snapshot()` 的 `null` 三义拆开 + CC-37 own 台账同拍登记;patch)
8328
+
8329
+ > **patch**:型面纯 additive(公面 961:+1 函数;`LiveWorkflowController` +1 方法 `resolution()`;零 wire 键;peer 不动)。cli [7468] ②③ 点名、[7469] ⑧ 认领。
8330
+
8331
+ ### 49a. 处置表
8332
+
8333
+ | # | 面 | 本包做了什么 | 端要做什么 |
8334
+ |---|---|---|---|
8335
+ | S-1 | `LiveWorkflowController.snapshot()` 返 `null` 有三义(还没答上来 / 引擎说不可用 / 列表为空),壳只能按「问了 N 秒还是 null」猜(cli 3 s 宽限窗) | **consumed**:新方法 `resolution(): WorkflowResolution` 六态 —— `pending{lastError}`(循环在跑、首发 get 未答,含纯连接错误退避)/ `degraded{code: 501\|404, lastError}`(引擎明说)/ `empty`(未配 workflowId 且**刚刚那次** list 为空;之后任何失败退回 `pending`)/ `unavailable{lastError}`(client 造不出来,永不会答)/ `live{state}`(= `snapshot()`)/ `stale{state, code, lastError}`(曾 live 后引擎又说 501/404,`state` 是最后一份)。纯读;`snapshot()` / `status()` 契约不变 | `/workflows` 详情按 `resolution().kind` 分派:`pending` 渲加载(可附 lastError)、`degraded` / `unavailable` 渲不可用(带 code)、`empty` 渲「本会话无 run」、`live` / `stale` 渲快照(`stale` 加一句已过期);**撤掉 3 s 宽限窗** |
8336
+ | S-2 | `ownWorkflowRuns` 只在 run_workflow 回执登记 ⇒ fleet 行已渲 13 s 而 `listOwnWorkflowRuns()` 仍空 | **consumed**:adapter workflow lane 门在「`task_progress` 帧带 `workflowRunId` ∧ 父 `parentToolCallId` 是本会话见过的 Workflow 工具卡」(own-run 正向证明)时,为其铸行那一拍同拍 `noteOwnWorkflowRun(runId)`;只有 `workflowRunId` 无父卡 / 父是别的卡 ⇒ 不登(老引擎广播别的会话的 run 也带 `workflowRunId`);回执登记点保留(两个数据源对齐,不是替换) | 零动作(`isOwnWorkflowRun` / `listOwnWorkflowRuns` 读口不变,只是更早为真);壳若曾按拍重取 target 兜底可保留 |
8337
+
8338
+ ### 49z. 逐键处置表
8339
+
8340
+ | # | 键 / 面 | 处置 | 坐标 / 理由 |
8341
+ |---|---|---|---|
8342
+ | 1 | `LiveWorkflowController.resolution()` | **consumed(新方法)** | `src/workflowClient.ts` 的 `#createLiveWorkflowSource`(内部相位 `loop / empty / unavailable` + `current` / `degraded` / `code` 合成六态);门 `run-client-core-pure-test.mjs` CC-38 段 13 格(pending / 连接错误仍 pending / 404 / 501 / empty / live / unavailable / 纯读 / empty→连接失败退回 pending / empty→名单非空且 get 挂住即回 pending→get 失败仍 pending 且 lastError 与 status() 同源),变异「empty 折成 pending」红 |
8343
+ | 2 | `noteOwnWorkflowRun(runId)` | **consumed(新导出)** | `src/notifications.ts` 的 `#noteOwnWorkflowRun`(只登 own 台账、不动 outstanding);调用点 `src/adapt/arms.ts` workflow lane 门;门 pure CC-37 段 5 格(正向登 / 无父不登 / Task 卡父不登 / belt 不变 / 幂等拒空串),变异「去掉同拍登记」红 |
8344
+ | 3 | `task_progress.workflowRunId` / `parentToolCallId` | **consumed(既有键,新用途)** | 同上;两键都在 sdk `events.d.ts` 已声明 |
8345
+
8346
+ ### 49y. 🔴 三端升级必读(固定段式,[C295])
8347
+
8348
+ 1. 换钉 `^0.72.2`:workflow 详情按 `resolution().kind` 六态分派,撤掉按时间猜的宽限窗;`snapshot()` 老读法仍可用但分不出三义。
8349
+ 2. `isOwnWorkflowRun` / `listOwnWorkflowRuns` 语义不变,只是 own-run 正向证明成立时更早为真;别在壳侧再自铸一份「fleet 帧带 workflowRunId 即亲启」的判据(那会把别的会话的 run 记成亲启)。
8350
+ 3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;零 wire 键。
8351
+
8352
+ **包侧缺口:** ① CC-30 MCP 会话内重连消费口(候 core #857 设计车 + server S-381);② CC-31 WebSearch 后端名读口(候 server S-382);③ CC-34 `permission_denials` 自动升级验证(候 server S-394);④ CC-35 core 7.21.x 三件(候 server 装载发车帖);⑤ CC-36 托管 MCP 活性三态读口(候 core #874 + server 转发半场;到货前缺席 = indeterminate 不折 off);⑥ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑦ `agents.listing_truncated` detail 读器候消费场景(by-design);⑧ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑨ §NNz「declined 键真零命中」机读第二刀(候形式化)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/client-core",
3
- "version": "0.72.0",
3
+ "version": "0.72.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",