@sema-agent/client-core 0.72.9 → 0.72.11

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,27 @@
49
49
  > 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
50
50
  > commit 漏转在发布前就红,不再靠人记。
51
51
 
52
+ ## 0.72.11(2026-09-18)
53
+
54
+ > 主题:**core 7.23.0 提货**(发车帖 [7537] / 提货单 [7538] @client-core 段:镜像一件 + 加法三件 + 零动作两件;CC-49)。**patch**:型面零变化(通告闭集 +1,零新导出;公面 989 不变;peer 不动;devDep core `~7.23.0`)。接入面 §58。
55
+
56
+ ### Added
57
+
58
+ - **`ENGINE_NOTICE_CODES` +1 = 六十七码**(顺序同源):`config.write_protection_unresolved`(core #869 / C-R61 ②;operator;governance-codes 元组紧跟兄弟码 `config.write_protection_target_view_absent`)—— 这条腿的写保护判官**有** target 视图、但解析不出这一次写的目标(`detail: { reason, cause, sessionId, runId }`,`reason` 两词 `unresolved-symlink` / `unresolvable-target`),于是那次写按拼法半场判并把这件事说出来;去重单位 = **每 leg 每 reason**(引擎侧;本包只镜像码与受众),**不带任何调用身份**。🔴 与 7.20.1 的兄弟码是**两件事**:`target_view_absent` = 没有视图(判官只判拼写),`unresolved` = 有视图但这一次解析不出;三种沉默(全解得出 / 没有视图 / 有界等待放弃)别折在一起。码册门 G8b 六十七 + G11 三格(红先绿后);A1 上游对账 67 / 67。
59
+
60
+ ### Changed
61
+
62
+ - **`permission_denials` 自动升级腿通电(CC-34 引擎半场)**:core 7.23.0 把六份内联 gate 行收成具名 `HumanReviewGateRow` 并加 `toolCallId?`(行身份;缺席 = 不可 join,**不是**「没有调用」,永不占位)⇒ 本包 `_sema_permission_denials[].tool_use_id` **自动带值**(0.66.0 起的开集宽读腿,mint 点一行没改);`tool_input` 仍无 ⇒ CC 数组仍只收三键齐全的记录。permission-denial 门 E 段改锚具名接口真字节(E5 翻正:账本带 `toolCallId?` 且仍无 `toolInput`;E5b 缺席语义逐字;E7 改锚「`toolArg` rides every mint」);源头注同步(此前写的「今天 wire 上没有」已不真)。到端还要 server 承载版透传(候 7.87.0)。
63
+ - devDep `@sema-agent/core` `~7.22.0` → `~7.23.0`(码册对账真源;peer 不动)。core 7.23.0 其余两件对本包零动作:`ReadEntry.transmittedByToolCallId?`(本包不读持久 read-state)、新导出 `WriteProtectionViewAbsence`(库直调面,非 wire 键)、`ReadRootGrantCandidate.covers` 型面零变化只是终于有值(0.71.0 起读在场不读缺席)。
64
+
65
+ ## 0.72.10(2026-09-18)
66
+
67
+ > 主题:**CC-41 leader run 终局 `needs_human` + `result.conflict` 读面**(server ≥7.83.0 C-R63 ④,发车帖 [7495] ④ @client-core「请新开渲染面」;cli [7499] 先包后壳;契约 §15)。**patch**:型面纯 additive(+2 常量 +2 函数,公面 985 → 989;零 wire 新键 —— 形由 server 7.83.0 铸,本包只读;sdk `LeaderRecord.result` 声明为 `unknown`,本读器是它在客户端的唯一形;peer 不动)。接入面 §57。
68
+
69
+ ### Added
70
+
71
+ - **`src/leaderConflict.ts`(CC-41)**:`projectLeaderConflict(record)` 把 `GET /v1/leader/:id` 的记录投成三形 `LeaderConflictView` —— 🔴 **`none`**(`result` 无 `conflict` 键 = 这一趟没有冲突 **或** 老 server <7.83.0,wire 上不可分 ⇒ 措辞把两种可能都摆出来,不替 server 断言其中一种)/ 🔴 **`unreadable`**(`conflict` 在场但必填座缺 / 形坏 —— 与 `none` 是**两个词**:server 明明报了冲突,壳若因读不懂而渲成「没冲突」,用户会把一棵带冲突标记的树当干净树用)/ **`conflict`**(`baseSha` / `files[]` / `filesTruncated?` / `workers[]{workerId, branch, applied}` / `rejHead?`)。三形都带 `status`(**开集**透传,契约闭集四词 `LEADER_RUN_STATUSES` 只作词表)与 `salvaged[]`(非冲突终局也可含未完成 worker 的补丁;缺席 = 空数组;坏行**逐行丢弃**不整只畸形)+ 🔴 `salvagedIncomplete?: true`(`salvaged` **在场但读不全** —— 非数组 / 非空全坏 / 好坏混合 —— 在场恒 true,好行照常保留;读不出的一张表 ≠ 「没有补丁」:契约 §15 明说沙箱销毁、分支不承诺可 fetch,`salvaged[]` 是冲突终局的唯一补偿)。🔴 `filesTruncated` **只认 `true`**(缺席 = 这就是全部;`false` / `1` / `"true"` ⇒ unreadable,不编「全部」也不编「截断」);`workers[].applied` 是布尔事实原样带出(`false` = 这只的补丁没进树);`salvaged[].patch` 是**工件**给落盘口 —— 原样透传、不消毒、不截断;`rejHead` 是**屏上诊断片段**(server 已脱敏 ≤2 KiB)—— 呈前转义控制符 + 封长 ≤ `LEADER_REJ_HEAD_DISPLAY_MAX`(2048)。记录本身不成形(非对象 / `status` 缺席或非串 / 敌意 getter)⇒ `undefined` **永不抛**;多余成员不过境、数组是新拷贝。`leaderConflictDetail(view)` 一句措辞**单源**(三端零自拼):`conflict` = 等人 + 基点短 sha + 冲突文件数(截断则明说「at least N … list truncated」)+ 至多五条路径(逐条消毒)+ 进树 / 未进树分支 + 可打捞补丁数(零则如实说「No salvaged patches」,不说 `0 salvaged` 像个答案);`none` 只说「没有报告冲突详情」并**明说这不证明已经合并**(`running` 与未进合并的 `failed` 也走这句 —— 缺席只证明没有冲突报告,不证明执行过合并);`unreadable` 说读不出、去 server 侧看;三句共用同一条打捞补丁句(有数带数 / 零则如实说没有 / 读不全则说材料存在但读不出,绝不说「没有」);🔴 句子里**不出现重试**(契约:`needs_human` 在等人,不许据它自动重试一条 leader run);`rejHead` / `patch` 一个字节不进句子。门 `run-leader-conflict-test.mjs` 27 格(红先绿后;发车前异源对抗复审一轮两条 [medium] 真修:`none` 句曾把「没报告冲突」说成「已无冲突合并」/ 打捞表全坏曾被渲成「没有补丁」);singleton +1;typeshape `unknownExport` 354 → 355(负控锚同批);portability index 闭包 168。
72
+
52
73
  ## 0.72.9(2026-09-18)
53
74
 
54
75
  > 主题:**server 7.85.0 提货批**(发车帖 [7522] @client-core;CC-30 会话内 MCP re-dial 消费口 / CC-39② memory-status `autoConsolidationArmed` 读数)+ **CC-45 resume 补充句渲保留秒数**(cli L-383 / test [7516] N-G10)+ **CC-47 / CC-48**(test 0.72.8 验收 sema-internal#56 / #57)。**patch**:型面纯 additive(+2 常量 +6 函数,公面 977 → 985;`MemoryStatusFacts` 加一可选键;零 wire 新键 —— 端点 / 能力位 / 新键由 server 7.85.0 铸,本包只读;peer 不动)。接入面 §56。
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.9
38
+ **Version:** 0.72.11
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
@@ -311,6 +311,7 @@ public-surface guard checks that last one).
311
311
  | `scripts/run-export-liveness-test.mjs` | Every runtime export in the public baseline must be **alive**: referenced by some gate, or explicitly registered in `scripts/export-liveness.json` as `contract` (consumed by a client with no gate yet), `internal` (an internal helper amplified onto the public surface by `export *`), `candidate` (with ticket + retire-by) or `retire` (dead; retire-by version). Registration is accounting, not exemption: a row for a name a gate already references is stale and must go, a row for a name no longer exported is red, `retire`/`candidate` rows go red the moment `package.json` reaches their retire-by version, and the row count only ratchets down. When the sibling client trees are on disk the consumption evidence is checked by name — a `contract` row's claimed consumers must equal the real set, and a `retire` name must not be imported by any client. Names that have already left the surface are kept in a per-version `removed` ledger: they must never reappear in the baseline or the registry, and the ledger's versions must not run ahead of the changelog. |
312
312
  | `scripts/run-tool-disclosure-progress-projection-test.mjs` | The two wire arms sdk 9.6.0 adds — `tool_disclosure` (name-only tool census: open-set `policy`, `thresholdPercent` absent ≠ default, `deferred`/`activated` full snapshots) and `tool_progress` (one frame, two beats: Bash ticks carry an output tail with `totalLines`/`totalBytes` that come and go together; other tools carry only `elapsedSeconds`) — project to neutral internal arms plus chrome arms. Required keys missing ⇒ `malformed`; bad optional keys drop only themselves; the sub-flow three-key gate keeps child frames off the leader lane; both arms are `required: false` in the arm table with duties stated (the output tail is untrusted raw and must never be fed back to the model). |
313
313
  | `scripts/run-mcp-panel-projection-test.mjs` | The `GET /v1/sessions/:id/mcp` panel reader (`projectMcpPanel`; server >=7.77.0 adds the optional `lastLegMcp` key) and the single wording mint for its "last leg" line. Absence of `lastLegMcp` is one literal sentence that never blames the engine version (a new session, a leg outside the retention window, a leg without a manifest and an older engine all look the same on the wire); a key that is present but unreadable is a different sentence plus a `lastLegMcpUnreadable: true` mark, never folded into absence. The `mcp[]` roster goes through the same reader as the live `wiring_manifest` third section, so a replayed roster and a live one have one shape. The two faces of the panel (`servers[]` and the last-leg roster) may legitimately differ, so the view carries no agreement flag and none of the five sentences mentions `servers`. Required keys are pinned to the SDK `openapi.yaml` component bytes **0.69.0:** `fetchMcpPanel` fetches the panel through the SDK client's own `sessions.mcp` call (same transport and auth as every other read) and projects it; transport failure, an unreadable body and an empty session id all come back as `undefined`, never as a fabricated empty panel 0.71.0 adds section K: `mcpEngineLegPresence(view)` — the engine-side MCP presence tri-state read only off the panel view (`unknown` when the view could not be read, never rendered as "no MCP configured") |
314
+ | `scripts/run-leader-conflict-test.mjs` | The leader-run terminal `needs_human` + `result.conflict` (engine ≥7.83.0), read once for all three shells. A `result` without a `conflict` key is reported as `none` and worded as "no conflict details" rather than "no conflict": on the wire it is indistinguishable from an older engine that never reports one, and the reader does not pick a side. A `conflict` that is present but unreadable is a third word, never folded into `none`, because a tree that carries conflict markers must not be rendered as clean. `filesTruncated` is honoured only as `true` (absent means the list is complete; any other value makes the section unreadable), `workers[].applied` is passed through as the boolean fact it is, `salvaged[].patch` is handed to the save path byte-for-byte (an artifact, not screen text; a malformed row is dropped alone, and a salvage list that is present but cannot be fully read is flagged rather than rendered as "no patches"), and `rejHead` — the one on-screen diagnostic — is escaped and bounded before display. The record never throws on hostile input, extra members do not cross, arrays are fresh copies, and the single sentence minted here names the base, the files, which branches landed and which did not, and how many patches can be saved, without ever suggesting a retry: `needs_human` is a run waiting for a person, and the no-details sentence says plainly that it is not proof of a merge |
314
315
  | `scripts/run-mcp-reconnect-test.mjs` | The in-session MCP re-dial verb (`POST /v1/sessions/:id/mcp/reconnect`, engine ≥7.85.0), consumed. The single discriminant is `outcome` and all three answers are HTTP 200, so the reader branches on the word and never on the status; the `unsupported` answer carries exactly five keys and the reader refuses to invent a zero or an empty list for the four fields the engine did not produce, while `accepted` / `refused` treat those four as required and go malformed when one is missing. The tool roster follows the **presence** of `toolNames` (absent = untouched, empty = withdrawn), the connection record passes `errorCode` through as an open set, and every remote-authored string is sanitised and bounded before display. Failures are classified by `errorCode` alone, a missing code is reported as unknown rather than guessed, the verb never throws, and the request-side guard (non-empty name, ≤190 chars) stops a call that the contract would reject anyway. The capability bit reads absent as "cannot tell" rather than "unavailable", and the one sentence the contract insists every UI carries — that re-dialing is a transaction, not a refresh — is minted here once |
315
316
  | `scripts/run-core-value-ports-test.mjs` | The port-injection seam for ten **engine value-level** facilities (autonomous-loop prompt assembly, permission-rule loosening, tool-policy composition, protocol/retired-name/grammar lookups, rule compilation, the discussion workflow name). This package cannot re-export them (the engine barrel drags Node built-ins into the browser bundle), so it declares the ports and honest-absence readers; a Node host installs the engine's own functions verbatim. The guard pins: every reader returns `undefined` when nothing is installed (never a fabricated empty array or default policy), arguments and results pass through by reference, engine errors propagate unchanged, partial installs read partially, restore functions unwind to the previous bag, and the module source has zero engine imports |
316
317
  | `scripts/run-read-face-posture-projection-test.mjs` | The operator-face `readFace: ReadFacePosture` reader (server >=7.65.0). Three ways of "can't say" are pinned to three different, literal sentences, and none of them may read as "nothing is pinned" — that statement belongs to exactly one case, `face: null`, which is a positive fact reported by the engine, not an absence: not having read an operator response yet, having read one from an engine too old to report the key, and the engine actually saying nothing is pinned are three different next steps for an operator and must not collapse into each other. `source` is read as an open set (the server's closed four words plus an escape hatch) rather than narrowed to an enum, so a new word added upstream is not silently turned into a bad reading. The free-text `note` is sanitized and length-capped before it is ever rendered. A companion pure function flags disagreement between this face and the tenant-facing `capabilities.readFace` — silent only when the two actually agree, honest-absent when either side cannot be read at all, never asserting agreement as a fact. The gate's last leg reads the installed SDK's own `openapi.yaml` directly rather than restating the schema in prose, so the package's leniency cannot quietly drift from the real contract |
@@ -128,16 +128,17 @@ export interface SemaFlatUsage {
128
128
  * tool_input: Record<string, unknown>}` **三键必填**)的三键 + 一位 sema 超集,**每一键都按
129
129
  * wire 能不能兑现决定在不在**。
130
130
  *
131
- * 🔴 **今天三键里只兑现得出一键**:这本账在 wire 上是 `TaskStats.humanReview.gates[]`,而 core
132
- * 的 gate 记录只有五格(`kind` / `waitMs` / `decision?` / `toolName?` / `toolArg?`,
133
- * `task-result.d.ts` 真字节)—— **没有** `toolCallId`,**没有**被拒时的入参对象(core 逐字:
134
- * 「a durable-resume gate carries `toolName` only (its input is not threaded onto the persisted
135
- * gate — a documented follow-on)」;sdk `types.d.ts` 的同一格也逐字记着「`tool_input`/
136
- * `toolInput` **不在** gate ledger 上」)。⇒ 那两键**缺席**,绝不铸 `""` / `{}`:一个空对象在
137
- * CC 形上读起来是「这次调用的入参是空的」,那是编的。
138
- * 🔴 **两键仍然声明在这里**(不是假 affordance):mint 点对它们是**开集宽读** —— 上游哪天把
139
- * 两格串上 gate 账本,这一形与 CC 那条清单**自动**开始带值(见 {@link permissionDenialParts}
140
- * 的自动升级腿),门里同时钉着今天的缺席证据与那一天的正控。消费端读它们**必须按可选位读**。
131
+ * 🔴 **三键里兑现得出两键**(引擎 ≥7.23.0):这本账在 wire 上是 `TaskStats.humanReview.gates[]`,core
132
+ * 的 gate 行是具名 `HumanReviewGateRow` 六格(`kind` / `waitMs` / `decision?` / `toolName?` /
133
+ * `toolArg?` / `toolCallId?`,`task-result.d.ts` 真字节)。`toolCallId` 是**行身份**(core 逐字:
134
+ * 「absent = not joinable … Never a placeholder」—— 缺席 = 铸点没有调用 id 可给:探针行 / 非
135
+ * tool_approval 的耐久门 / 老引擎;**不是**「没有调用」)。被拒时的**入参对象**仍然**没有**
136
+ * (sdk `types.d.ts` 同一格逐字记着「`tool_input`/`toolInput` **不在** gate ledger 上」)。⇒ 那一键
137
+ * **缺席**,绝不铸 `{}`:一个空对象在 CC 形上读起来是「这次调用的入参是空的」,那是编的。
138
+ * 🔴 **两键都声明在这里**(不是假 affordance):mint 点对它们是**开集宽读** —— `toolCallId` 在
139
+ * 7.23.0 串上账本那天 `tool_use_id` 就**自动**开始带值(见 {@link permissionDenialParts} 的自动
140
+ * 升级腿,门里钉着 7.23.0 的真字节正控);`toolInput` 仍等上游。消费端读它们**必须按可选位读**
141
+ * (老引擎 / 不可 join 的行两键缺席)。
141
142
  * 🔴 `_sema_tool_arg` = core 已经**脱敏并截短**的一行入参摘要(`primaryActivityArg` 同一道口),
142
143
  * 它是 CC「denied: Bash(rm …)」那行显示唯一拿得到的材料。UNTRUSTED-for-display:只渲染,
143
144
  * 绝不回喂模型、绝不当鉴权判据。
@@ -145,7 +146,7 @@ export interface SemaFlatUsage {
145
146
  export interface SemaPermissionDenial {
146
147
  /** 被拒的工具名(⇐ `gates[].toolName`);wire 没报 ⇒ 键缺席,绝不编一个名字。 */
147
148
  readonly tool_name?: string;
148
- /** 被拒的**那一次调用**(⇐ `gates[].toolCallId`,今天 wire 上没有 ⇒ 恒缺席,见下方 mint 点头注)。 */
149
+ /** 被拒的**那一次调用**(⇐ `gates[].toolCallId`,引擎 ≥7.23.0 带;缺席 = 不可 join,不是没有调用)。 */
149
150
  readonly tool_use_id?: string;
150
151
  /** 被拒调用的**完整入参**(⇐ `gates[].toolInput`,今天 wire 上没有 ⇒ 恒缺席;非对象一律不铸)。 */
151
152
  readonly tool_input?: Record<string, unknown>;
@@ -89,11 +89,11 @@ const GATE_NON_DENIAL_DECISIONS = new Set(['allow', 'approve', 'edit', 'reject']
89
89
  * 🔴 **为什么是两条清单而不是把 wire 的记录塞进 CC 数组**(异源复审 [medium] 逼出的口径订正):
90
90
  * CC 的 `SDKPermissionDenial` 三键 `tool_name` / `tool_use_id` / `tool_input` **全是必填**
91
91
  * (agent-types `permissions.d.ts` 与壳侧 zod `SDKPermissionDenialSchema` 皆然),而 wire 的 gate
92
- * 账本只有五格、给不出后两键。两条路都不能走:**补零补空 = 编造**;**塞半条记录 = 破坏元素契约**
92
+ * 账本(7.23.0 起六格)给不出 `tool_input`。两条路都不能走:**补零补空 = 编造**;**塞半条记录 = 破坏元素契约**
93
93
  * ——严格消费方 `safeParse` 会把**整条 result 帧**判非法(丢一格 vs 丢整帧,后者严重得多)。
94
- * ⇒ CC 数组只收**三键齐全**的记录(今天恒空),wire 上真有的每一条走 sema 载体
95
- * `_sema_permission_denials`,键按能兑现的铸。**自动升级腿**:上游哪天把 `toolCallId` /
96
- * `toolInput` 串上 gate 账本,CC 数组自己就开始填,本函数一行不用改(门里有那一条的正控)。
94
+ * ⇒ CC 数组只收**三键齐全**的记录(`toolInput` 上账本前恒空),wire 上真有的每一条走 sema 载体
95
+ * `_sema_permission_denials`,键按能兑现的铸。**自动升级腿**:`toolCallId` 已于引擎 7.23.0 串上
96
+ * 账本 ⇒ `tool_use_id` 自动带值(本函数一行没改;门里有真字节正控);`toolInput` 哪天串上,CC 数组自己就开始填。
97
97
  *
98
98
  * 🔴 判别位 `_sema_permission_denials_absent` = **「CC 那条清单不可声称完整」**,四条路径:
99
99
  * ① 账本整个读不出(`humanReview` 缺席 / 坏形 / `gates` 不是数组 / 无 stats);
@@ -134,9 +134,9 @@ function permissionDenialParts(stats) {
134
134
  }
135
135
  const toolName = nonEmptyStr(row.toolName);
136
136
  const toolArg = nonEmptyStr(row.toolArg);
137
- // 🔴 开集宽读两键:今天 core 的 gate 账本上没有它们(门里锚着这条缺席证据),按 core 自己的
138
- // 命名习惯(`toolName` / `toolArg` 同族)预读 `toolCallId` / `toolInput`;上游若用别的名字
139
- // 补上,缺席证据当天红 ⇒ 那一批改读真名。绝不自铸值。
137
+ // 🔴 开集宽读两键:`toolCallId` 自引擎 7.23.0 起真在账本上(门里锚着真字节;老引擎 / 不可 join 的行
138
+ // 缺席);`toolInput` 今天仍没有,按 core 自己的命名习惯(`toolName` / `toolArg` 同族)预读,
139
+ // 上游若用别的名字补上,门里的缺席证据当天红 ⇒ 那一批改读真名。绝不自铸值。
140
140
  const toolUseId = nonEmptyStr(row.toolCallId);
141
141
  const rawInput = row.toolInput;
142
142
  const toolInput = rawInput !== null && typeof rawInput === 'object' && !Array.isArray(rawInput)
@@ -54,7 +54,7 @@
54
54
  /** 一条通告是**说给谁听**的。两值,刻意不设第三值(见模块顶注)。 */
55
55
  export type NoticeAudience = 'user' | 'operator';
56
56
  /**
57
- * 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.22.0 = 六十六码**(7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
57
+ * 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.23.0 = 六十七码**(7.22.0 六十六 + 7.23.0 一枚 `config.write_protection_unresolved`(#869 / C-R61 ②,operator;governance-codes.js 元组紧跟兄弟码 `config.write_protection_target_view_absent`:那一枚是「没有 target 视图」,这一枚是「有视图但解析不出这次写的目标」,`detail {reason, cause, sessionId, runId}`,`reason` 两词 `unresolved-symlink` / `unresolvable-target`,去重每 leg 每 reason 是引擎侧);7.22.0 六十六 = 7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
58
58
  * 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
59
59
  * ⚠️ `EngineNotice.code` 的型面在上游**故意留 `string`**(宿主把自己的通告转发进同一个水槽是
60
60
  * 被支持的形),所以本表是**判据**不是型 —— 别拿它去窄化那个字段。
@@ -52,7 +52,7 @@
52
52
  * 出现在本包源码或产物里 => 当场红。
53
53
  */
54
54
  /**
55
- * 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.22.0 = 六十六码**(7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
55
+ * 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.23.0 = 六十七码**(7.22.0 六十六 + 7.23.0 一枚 `config.write_protection_unresolved`(#869 / C-R61 ②,operator;governance-codes.js 元组紧跟兄弟码 `config.write_protection_target_view_absent`:那一枚是「没有 target 视图」,这一枚是「有视图但解析不出这次写的目标」,`detail {reason, cause, sessionId, runId}`,`reason` 两词 `unresolved-symlink` / `unresolvable-target`,去重每 leg 每 reason 是引擎侧);7.22.0 六十六 = 7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
56
56
  * 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
57
57
  * ⚠️ `EngineNotice.code` 的型面在上游**故意留 `string`**(宿主把自己的通告转发进同一个水槽是
58
58
  * 被支持的形),所以本表是**判据**不是型 —— 别拿它去窄化那个字段。
@@ -80,6 +80,7 @@ export const ENGINE_NOTICE_CODES = Object.freeze([
80
80
  'config.task_root_not_canonical',
81
81
  // core 7.20.1(0.71.4 提货,#853 C-R55):写保护判官只判拼写(spelling-only)又挂了受保护写工具 ⇒ 每 run 一条;顺序同源(紧跟 task_root_not_canonical)。
82
82
  'config.write_protection_target_view_absent',
83
+ 'config.write_protection_unresolved',
83
84
  'config.execution_env_capability_invalid',
84
85
  'config.tool_card_undeclared',
85
86
  'config.tool_face_undeclared',
@@ -172,6 +173,7 @@ export const ENGINE_NOTICE_AUDIENCE = Object.freeze({
172
173
  'config.artifact_host_invalid': 'operator',
173
174
  'config.task_root_not_canonical': 'operator',
174
175
  'config.write_protection_target_view_absent': 'operator',
176
+ 'config.write_protection_unresolved': 'operator',
175
177
  'config.execution_env_capability_invalid': 'operator',
176
178
  'config.tool_card_undeclared': 'operator',
177
179
  'config.tool_face_undeclared': 'operator',
package/dist/index.d.ts CHANGED
@@ -156,6 +156,7 @@ export * from './sqlEngineCapability.js';
156
156
  export * from './writeProtectionCapability.js';
157
157
  export * from './webSearchBackendCapability.js';
158
158
  export * from './mcpReconnect.js';
159
+ export * from './leaderConflict.js';
159
160
  export * from './runTerminal.js';
160
161
  export * from './readFacePosture.js';
161
162
  export * from './mcpPanel.js';
package/dist/index.js CHANGED
@@ -190,6 +190,9 @@ export * from './webSearchBackendCapability.js';
190
190
  // S-381 / core 7.22.0 #857(0.72.9 CC-30;server ≥7.85.0,sdk 尚未声明):会话内 MCP re-dial 的消费口 —— 200 三态按 outcome 分形读、
191
191
  // unsupported 恒五键、名册按 toolNames 在场性、失败按 errorCode 分诊、「重连 = 一次交易」措辞单源;能力位 mcpReconnect 三态读。
192
192
  export * from './mcpReconnect.js';
193
+ // 0.72.10:leader run 终局 needs_human + result.conflict 读面(契约 §15)—— 缺席不可分(none)/ 在场读不懂(unreadable)/ 读出(conflict)三形;
194
+ // filesTruncated 只认 true、salvaged[].patch 原样给落盘口、rejHead 呈前消毒封长;一句措辞单源不提重试。
195
+ export * from './leaderConflict.js';
193
196
  // 0.60.0(engine ≥7.64.0 / sdk 8.4.0):终局因由与门记录两只**判定归包**的读器。
194
197
  export * from './runTerminal.js';
195
198
  // 0.61.0(engine ≥7.65.0 / sdk 8.5.0 / S-167):READ 容纳面档位 + 来源的 operator 面窄读器
@@ -0,0 +1,97 @@
1
+ /**
2
+ * leaderConflict — leader run 终局 `needs_human` + `result.conflict` 的**三端共用读面**(0.72.10;server ≥7.83.0 C-R63 ④;
3
+ * 契约 §15;sdk `LeaderRecord.result` 声明为 `unknown`,本读器是它在客户端的唯一形)。
4
+ *
5
+ * ── 这一口答的是哪件事 ────────────────────────────────────────────────────────────────────
6
+ * 7.83.0 起 worker 分支合不上时,leader run **不再**起任何模型去解冲突,而是把冲突**列给用户**:`status:"needs_human"` +
7
+ * `result.conflict { baseSha, files[], filesTruncated?, workers[], rejHead? }` + `result.salvaged[]`(全部 worker 各一份补丁,尽力而为)。
8
+ * 壳只有「列出来 + 把补丁落盘」两件事;缺席语义 / 坏形判别 / 措辞三端各写一遍必各错一遍 ⇒ 归包。
9
+ *
10
+ * ── 🔴 五条契约读法(§15 逐字)──────────────────────────────────────────────────────────────
11
+ * ① **缺席不可分**:`result` 无 `conflict` 键 = 这一趟没有冲突,**或**对面是老 server(<7.83.0,那时冲突走别的终局)。
12
+ * 两者 wire 上不可区分 ⇒ 读数 `none`,措辞把两种可能都摆出来,不替 server 断言其中一种。
13
+ * ② **在场但读不懂 ≠ 缺席**:`conflict` 在场但必填座缺 / 形坏 ⇒ `unreadable`。它和 `none` 是两个词 —— server 明明报了冲突,
14
+ * 壳若因读不懂而渲成「没冲突」,用户会把一棵带冲突标记的树当干净树用。
15
+ * ③ **`filesTruncated` 只在清单被截断时在场且恒 `true`;缺席 = 这就是全部**。在场却不是 `true` ⇒ unreadable,不编「全部」也不编「截断」。
16
+ * ④ **`workers[].applied` 是布尔事实**:`false` = 这只 worker 的补丁没进树(冲突者本人,或排在它后面没轮到的)。`salvaged[].patch`
17
+ * 是**工件**(给落盘口),原样透传、不消毒、不截断;`rejHead` 是**屏上诊断片段**(server 已脱敏 ≤2 KiB),呈前按 UNTRUSTED-for-display
18
+ * 再过一次(转义控制符 + 封长)。两者在 server 侧走同一只脱敏口,客户端只按用途分「落盘 / 上屏」,不再加第二套判据。
19
+ * ⑤ **`needs_human` 是「等人」不是「失败」**:契约明令不许据它自动重试一条 leader run。措辞单源 {@link leaderConflictDetail},
20
+ * 句子里不出现重试;壳零自拼句子。
21
+ *
22
+ * ── 防御读纪律(与 `mcpReconnect` / `sessionMemoryStatus` 同律)─────────────────────────────
23
+ * · 永不抛:载体非对象 / 敌意 getter ⇒ `undefined`(记录本身不成形);`status` 缺席或非串 ⇒ `undefined`;
24
+ * · `status` 按**开集**透传(契约闭集四词,但客户端不替 server 断言闭集 —— 新词照带,壳 switch 必带 default);
25
+ * · 多余成员不过境,数组是新拷贝(壳改视图不回写 wire 体)。
26
+ */
27
+ /** 契约 §15 `GET /v1/leader/:id` 的 `status` 四词(仅作词表;读器按开集透传)。 */
28
+ export declare const LEADER_RUN_STATUSES: readonly string[];
29
+ /** `rejHead` 上屏封长(显示字符;server 侧已 ≤2 KiB,这里是呈前的第二道,与工件字节无关)。 */
30
+ export declare const LEADER_REJ_HEAD_DISPLAY_MAX = 2048;
31
+ /** `conflict.workers[]` 一行:全部 completed worker;`applied:false` = 这只的补丁没进树。 */
32
+ export interface LeaderConflictWorkerView {
33
+ workerId: string;
34
+ branch: string;
35
+ applied: boolean;
36
+ }
37
+ /** `result.conflict` 段(契约 §15 表)。`filesTruncated` 只在为 `true` 时在场;`rejHead` 已按 UNTRUSTED-for-display 处理。 */
38
+ export interface LeaderConflictSectionView {
39
+ /** 用户侧的合并基点 = 这一趟的 durable base。 */
40
+ baseSha: string;
41
+ /** 有冲突标记 / `.rej` 的路径(只有路径,不含内容);可为空数组。 */
42
+ files: string[];
43
+ /** 在场恒 `true` = 清单被截断(缺的一条是未证明缺席);缺席 = 这就是全部。 */
44
+ filesTruncated?: true;
45
+ workers: LeaderConflictWorkerView[];
46
+ /** `.rej` 头,给人看冲突长什么样;已转义控制符并封长 ≤ {@link LEADER_REJ_HEAD_DISPLAY_MAX}。 */
47
+ rejHead?: string;
48
+ }
49
+ /** `result.salvaged[]` 一行:一只 worker 的补丁(工件,原样;给落盘口,不上屏)。 */
50
+ export interface LeaderSalvagedPatchView {
51
+ workerId: string;
52
+ sessionId: string;
53
+ patch: string;
54
+ }
55
+ /**
56
+ * 三形:
57
+ * · `none` —— `result` 无 `conflict` 键(未冲突 或 老 server,不可分);
58
+ * · `unreadable` —— `conflict` 在场但读不出(必填座缺 / 形坏);
59
+ * · `conflict` —— 读出来了。
60
+ * 三形都带 `status`(开集原样)与 `salvaged`(非冲突终局也可含未完成 worker 的补丁;缺席 = 空数组)+ `salvagedIncomplete?`。
61
+ *
62
+ * 🔴 `salvagedIncomplete`(异源对抗复审采纳):`salvaged` **在场但读不全**(不是数组 / 非空却全是坏行 / 好坏混合)⇒ 在场恒 `true`,
63
+ * 好行照常保留。它和「没有补丁」是两件事 —— 契约 §15 明说集成沙箱在 run 结束时销毁、分支不承诺可 fetch,`salvaged[]` 是冲突终局下
64
+ * 的**唯一补偿**;把一张读不出的表渲成「没有补丁」会让用户放弃去找原始结果。缺席 / `[]` / 全好 ⇒ 键不在场。
65
+ */
66
+ export type LeaderConflictView = {
67
+ kind: 'none';
68
+ status: string;
69
+ salvaged: LeaderSalvagedPatchView[];
70
+ salvagedIncomplete?: true;
71
+ } | {
72
+ kind: 'unreadable';
73
+ status: string;
74
+ salvaged: LeaderSalvagedPatchView[];
75
+ salvagedIncomplete?: true;
76
+ } | {
77
+ kind: 'conflict';
78
+ status: string;
79
+ conflict: LeaderConflictSectionView;
80
+ salvaged: LeaderSalvagedPatchView[];
81
+ salvagedIncomplete?: true;
82
+ };
83
+ /**
84
+ * 把 `GET /v1/leader/:id` 的记录(sdk `LeaderRecord`,`result` 为 `unknown`)投成 {@link LeaderConflictView}。
85
+ * 永不抛;记录本身不成形(非对象 / `status` 缺席或非串 / 敌意 getter)⇒ `undefined`。
86
+ */
87
+ export declare function projectLeaderConflict(record: unknown): LeaderConflictView | undefined;
88
+ /**
89
+ * 一句措辞的**唯一铸点**(三端共用;壳零自拼)。
90
+ * · `conflict`:等人 + 基点短 sha + 冲突文件数(截断则明说)+ 哪几支进了树 / 没进 + 打捞补丁句;
91
+ * · `none`:只说「没有报告冲突详情」,🔴 **明说这不证明已经合并**(异源对抗复审采纳:`running` 与未进合并的 `failed` 也走这句,
92
+ * 缺席只证明没有冲突报告,不证明执行过合并 —— 说成「已无冲突合并」会让用户以为工作已合入而不去恢复);
93
+ * · `unreadable`:server 报了冲突但读不出,让用户去 server 侧看。
94
+ * 三句都带同一条打捞补丁句(有数带数 / 零则如实说没有 / 读不全则说材料存在但读不出,绝不说「没有」)。
95
+ * 🔴 句子里不出现重试(契约:`needs_human` 在等人)。`rejHead` / `patch` 一个字节都不进句子。
96
+ */
97
+ export declare function leaderConflictDetail(view: LeaderConflictView): string;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * leaderConflict — leader run 终局 `needs_human` + `result.conflict` 的**三端共用读面**(0.72.10;server ≥7.83.0 C-R63 ④;
3
+ * 契约 §15;sdk `LeaderRecord.result` 声明为 `unknown`,本读器是它在客户端的唯一形)。
4
+ *
5
+ * ── 这一口答的是哪件事 ────────────────────────────────────────────────────────────────────
6
+ * 7.83.0 起 worker 分支合不上时,leader run **不再**起任何模型去解冲突,而是把冲突**列给用户**:`status:"needs_human"` +
7
+ * `result.conflict { baseSha, files[], filesTruncated?, workers[], rejHead? }` + `result.salvaged[]`(全部 worker 各一份补丁,尽力而为)。
8
+ * 壳只有「列出来 + 把补丁落盘」两件事;缺席语义 / 坏形判别 / 措辞三端各写一遍必各错一遍 ⇒ 归包。
9
+ *
10
+ * ── 🔴 五条契约读法(§15 逐字)──────────────────────────────────────────────────────────────
11
+ * ① **缺席不可分**:`result` 无 `conflict` 键 = 这一趟没有冲突,**或**对面是老 server(<7.83.0,那时冲突走别的终局)。
12
+ * 两者 wire 上不可区分 ⇒ 读数 `none`,措辞把两种可能都摆出来,不替 server 断言其中一种。
13
+ * ② **在场但读不懂 ≠ 缺席**:`conflict` 在场但必填座缺 / 形坏 ⇒ `unreadable`。它和 `none` 是两个词 —— server 明明报了冲突,
14
+ * 壳若因读不懂而渲成「没冲突」,用户会把一棵带冲突标记的树当干净树用。
15
+ * ③ **`filesTruncated` 只在清单被截断时在场且恒 `true`;缺席 = 这就是全部**。在场却不是 `true` ⇒ unreadable,不编「全部」也不编「截断」。
16
+ * ④ **`workers[].applied` 是布尔事实**:`false` = 这只 worker 的补丁没进树(冲突者本人,或排在它后面没轮到的)。`salvaged[].patch`
17
+ * 是**工件**(给落盘口),原样透传、不消毒、不截断;`rejHead` 是**屏上诊断片段**(server 已脱敏 ≤2 KiB),呈前按 UNTRUSTED-for-display
18
+ * 再过一次(转义控制符 + 封长)。两者在 server 侧走同一只脱敏口,客户端只按用途分「落盘 / 上屏」,不再加第二套判据。
19
+ * ⑤ **`needs_human` 是「等人」不是「失败」**:契约明令不许据它自动重试一条 leader run。措辞单源 {@link leaderConflictDetail},
20
+ * 句子里不出现重试;壳零自拼句子。
21
+ *
22
+ * ── 防御读纪律(与 `mcpReconnect` / `sessionMemoryStatus` 同律)─────────────────────────────
23
+ * · 永不抛:载体非对象 / 敌意 getter ⇒ `undefined`(记录本身不成形);`status` 缺席或非串 ⇒ `undefined`;
24
+ * · `status` 按**开集**透传(契约闭集四词,但客户端不替 server 断言闭集 —— 新词照带,壳 switch 必带 default);
25
+ * · 多余成员不过境,数组是新拷贝(壳改视图不回写 wire 体)。
26
+ */
27
+ import { capForDisplay } from './fleetTaskDesc.js';
28
+ /** 契约 §15 `GET /v1/leader/:id` 的 `status` 四词(仅作词表;读器按开集透传)。 */
29
+ export const LEADER_RUN_STATUSES = Object.freeze(['running', 'completed', 'failed', 'needs_human']);
30
+ /** `rejHead` 上屏封长(显示字符;server 侧已 ≤2 KiB,这里是呈前的第二道,与工件字节无关)。 */
31
+ export const LEADER_REJ_HEAD_DISPLAY_MAX = 2048;
32
+ /** 冲突句里最多点名几条冲突路径(其余以「and N more」收口;路径是 UNTRUSTED-for-display,逐条消毒)。 */
33
+ const DETAIL_FILES_MAX = 5;
34
+ const DETAIL_PATH_MAX = 120;
35
+ const DETAIL_BRANCH_MAX = 80;
36
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
37
+ const nonEmptyString = (v) => typeof v === 'string' && v.length > 0;
38
+ /** JSON 永远带不来 `undefined`;本地拼出来的 `{ key: undefined }` 按缺席读,与 wire 上整键缺席同义。 */
39
+ const present = (o, key) => Object.hasOwn(o, key) && o[key] !== undefined;
40
+ function readWorkers(v) {
41
+ if (!Array.isArray(v))
42
+ return undefined;
43
+ const out = [];
44
+ for (const row of v) {
45
+ if (!isRecord(row) || !nonEmptyString(row.workerId) || !nonEmptyString(row.branch) || typeof row.applied !== 'boolean')
46
+ return undefined;
47
+ out.push({ workerId: row.workerId, branch: row.branch, applied: row.applied });
48
+ }
49
+ return out;
50
+ }
51
+ function readConflict(v) {
52
+ if (!isRecord(v))
53
+ return undefined;
54
+ if (!nonEmptyString(v.baseSha))
55
+ return undefined;
56
+ if (!Array.isArray(v.files) || !v.files.every(nonEmptyString))
57
+ return undefined;
58
+ const workers = readWorkers(v.workers);
59
+ if (!workers)
60
+ return undefined;
61
+ const out = { baseSha: v.baseSha, files: [...v.files], workers };
62
+ if (present(v, 'filesTruncated')) {
63
+ if (v.filesTruncated !== true)
64
+ return undefined;
65
+ out.filesTruncated = true;
66
+ }
67
+ if (present(v, 'rejHead')) {
68
+ if (typeof v.rejHead !== 'string')
69
+ return undefined;
70
+ out.rejHead = capForDisplay(v.rejHead, LEADER_REJ_HEAD_DISPLAY_MAX);
71
+ }
72
+ return out;
73
+ }
74
+ /**
75
+ * 尽力而为的表:坏行逐行丢弃(一行坏不该让用户拿不到别的 worker 的补丁);`patch` 原样。
76
+ * 返回 `{ rows, incomplete }`:`incomplete` = 在场但读不全(非数组 / 非空全坏 / 混合);缺席、`[]`、全好 ⇒ false。
77
+ */
78
+ function readSalvaged(result) {
79
+ if (!isRecord(result) || !present(result, 'salvaged'))
80
+ return { rows: [], incomplete: false };
81
+ if (!Array.isArray(result.salvaged))
82
+ return { rows: [], incomplete: true };
83
+ const rows = [];
84
+ let dropped = 0;
85
+ for (const row of result.salvaged) {
86
+ if (!isRecord(row) || !nonEmptyString(row.workerId) || typeof row.sessionId !== 'string' || !nonEmptyString(row.patch)) {
87
+ dropped += 1;
88
+ continue;
89
+ }
90
+ rows.push({ workerId: row.workerId, sessionId: row.sessionId, patch: row.patch });
91
+ }
92
+ return { rows, incomplete: dropped > 0 };
93
+ }
94
+ /**
95
+ * 把 `GET /v1/leader/:id` 的记录(sdk `LeaderRecord`,`result` 为 `unknown`)投成 {@link LeaderConflictView}。
96
+ * 永不抛;记录本身不成形(非对象 / `status` 缺席或非串 / 敌意 getter)⇒ `undefined`。
97
+ */
98
+ export function projectLeaderConflict(record) {
99
+ try {
100
+ if (!isRecord(record) || !nonEmptyString(record.status))
101
+ return undefined;
102
+ const status = record.status;
103
+ const result = record.result;
104
+ const { rows: salvaged, incomplete } = readSalvaged(result);
105
+ const tail = incomplete ? { salvaged, salvagedIncomplete: true } : { salvaged };
106
+ if (!isRecord(result) || !present(result, 'conflict'))
107
+ return { kind: 'none', status, ...tail };
108
+ const conflict = readConflict(result.conflict);
109
+ if (!conflict)
110
+ return { kind: 'unreadable', status, ...tail };
111
+ return { kind: 'conflict', status, conflict, ...tail };
112
+ }
113
+ catch {
114
+ return undefined;
115
+ }
116
+ }
117
+ const plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
118
+ /** 打捞补丁句(三形共用):有数带数;读不全 ⇒ 说材料存在但读不出、去看原始结果,绝不落到「没有补丁」;零且读全 ⇒ 如实说没有。 */
119
+ function salvageSentence(view) {
120
+ const n = view.salvaged.length;
121
+ if (view.salvagedIncomplete) {
122
+ return n === 0
123
+ ? 'Salvage material was returned but could not be read; check the raw run result before concluding that no patches exist.'
124
+ : `${plural(n, 'salvaged patch', 'salvaged patches')} available to save, but part of the salvage material could not be read; check the raw run result for the rest.`;
125
+ }
126
+ return n === 0 ? 'No salvaged patches were returned.' : `${plural(n, 'salvaged patch', 'salvaged patches')} available to save.`;
127
+ }
128
+ /**
129
+ * 一句措辞的**唯一铸点**(三端共用;壳零自拼)。
130
+ * · `conflict`:等人 + 基点短 sha + 冲突文件数(截断则明说)+ 哪几支进了树 / 没进 + 打捞补丁句;
131
+ * · `none`:只说「没有报告冲突详情」,🔴 **明说这不证明已经合并**(异源对抗复审采纳:`running` 与未进合并的 `failed` 也走这句,
132
+ * 缺席只证明没有冲突报告,不证明执行过合并 —— 说成「已无冲突合并」会让用户以为工作已合入而不去恢复);
133
+ * · `unreadable`:server 报了冲突但读不出,让用户去 server 侧看。
134
+ * 三句都带同一条打捞补丁句(有数带数 / 零则如实说没有 / 读不全则说材料存在但读不出,绝不说「没有」)。
135
+ * 🔴 句子里不出现重试(契约:`needs_human` 在等人)。`rejHead` / `patch` 一个字节都不进句子。
136
+ */
137
+ export function leaderConflictDetail(view) {
138
+ const salvage = salvageSentence(view);
139
+ if (view.kind === 'none') {
140
+ return `No merge-conflict details were reported for this leader run. This does not show that the worker branches were merged: the run may not have reached a merge, it may have merged cleanly, or the server may not report conflicts. ${salvage}`;
141
+ }
142
+ if (view.kind === 'unreadable') {
143
+ return `The server reported a merge conflict for this leader run, but its details were unreadable; inspect the run on the server before using the tree. ${salvage}`;
144
+ }
145
+ const c = view.conflict;
146
+ const shortSha = capForDisplay(c.baseSha, 12);
147
+ const shown = c.files.slice(0, DETAIL_FILES_MAX).map(f => capForDisplay(f, DETAIL_PATH_MAX));
148
+ const rest = c.files.length - shown.length;
149
+ const fileCount = c.filesTruncated ? `at least ${plural(c.files.length, 'file', 'files')} (list truncated)` : plural(c.files.length, 'file', 'files');
150
+ const fileList = shown.length === 0 ? 'no paths were listed' : `${shown.join(', ')}${rest > 0 ? `, and ${rest} more` : ''}`;
151
+ const applied = c.workers.filter(w => w.applied).map(w => capForDisplay(w.branch, DETAIL_BRANCH_MAX));
152
+ const notApplied = c.workers.filter(w => !w.applied).map(w => capForDisplay(w.branch, DETAIL_BRANCH_MAX));
153
+ const branches = c.workers.length === 0
154
+ ? 'No worker branches were listed.'
155
+ : `Applied: ${applied.length ? applied.join(', ') : 'none'}. Not applied: ${notApplied.length ? notApplied.join(', ') : 'none'}.`;
156
+ return `This leader run is waiting for a human: worker branches could not be merged onto base ${shortSha}; ${fileCount} in conflict (${fileList}). ${branches} ${salvage}`;
157
+ }
@@ -19,11 +19,11 @@
19
19
 
20
20
  | 项 | 值 | 真源 |
21
21
  |---|---|---|
22
- | 本包 | `@sema-agent/client-core` **0.72.9**(本批发布版 = **patch**:server 7.85.0 提货 —— CC-30 会话内 MCP re-dial 消费口(`reconnectMcpServer` 三态 / unsupported 恒五键 / 交易文案单源)+ CC-39② memory-status `autoConsolidationArmed` 三态 + CC-45 resume 补充句渲保留秒数;型面纯 additive、公面 985、peer 不动;§56。上一版 0.72.8 = **patch**:清账三票 —— `memory:"off"` 请求键(CC-39③,server 7.84.0 S-405)+ `runStream` 第二条中性臂 `Model output error:`(CC-43)+ 注入件撞活 run 自动 steer 零卡(CC-44);型面纯 additive、公面 977、peer 不动;§55。上一版 0.72.7 = **patch**:core 7.22.0 提货 —— 通告码 66 `mcp.server_redialed` + 读器 `readMcpServerRedialed` + `wiring_manifest.readDeny` 第九段 `_sema_readDeny`(缺席 = 没有内置行判这条腿);型面纯 additive、公面 971、peer 不动、devDep core ~7.22.0;§54。上一版 0.72.6 = **patch**:cli L-379 包侧半场 —— `steerFollowIntent` steer 后续听意图三态(tail / after-decision / after-wake)+ `activeRunSelfHealRow` 续听声明第五参;型面纯 additive、公面 969、peer 不动;§53。上一版 0.72.5 = **patch**:server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面(键缺席 = 老引擎判不了 ≠ `none`);型面纯 additive、公面 968、peer 不动;§52。上一版 0.72.4 = **patch**:core 7.21.x 三件经 server 7.82.0 提货 —— `wiring_manifest.autoConsolidation` 第八段 `_sema_autoConsolidation`(缺席 = indeterminate 不折 false);型面纯 additive、公面 962、peer 不动;§51。上一版 0.72.3 = **patch**:core #863 记忆单系统半场 ① —— `projectAgentsForWire` 投影 `agents[].memory`(user|project|local 三词同映射引擎平面 agent:<type>);型面纯 additive、公面 962、零 wire 新键、peer 不动;§50。上一版 0.72.2 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
22
+ | 本包 | `@sema-agent/client-core` **0.72.11**(本批发布版 = **patch**:core 7.23.0 提货 —— CC-49 通告码 66 → 67 `config.write_protection_unresolved`(operator;兄弟码 `target_view_absent` = 没有视图,这枚 = 有视图解析不出)+ `permission_denials` 自动升级腿通电(`gates[].toolCallId` ⇒ `tool_use_id`;CC-34 引擎半场);型面零变化、公面 989、peer 不动、devDep core ~7.23.0;§58。上一版 0.72.10 = **patch**:CC-41 leader run 终局 `needs_human` + `result.conflict` 三形读面(none 缺席不可分 / unreadable 在场读不懂 / conflict;`salvaged[]` 原样给落盘口;措辞单源不提重试);型面纯 additive、公面 989、peer 不动;§57。上一版 0.72.9 = **patch**:server 7.85.0 提货 —— CC-30 会话内 MCP re-dial 消费口(`reconnectMcpServer` 三态 / unsupported 恒五键 / 交易文案单源)+ CC-39② memory-status `autoConsolidationArmed` 三态 + CC-45 resume 补充句渲保留秒数;型面纯 additive、公面 985、peer 不动;§56。上一版 0.72.8 = **patch**:清账三票 —— `memory:"off"` 请求键(CC-39③,server 7.84.0 S-405)+ `runStream` 第二条中性臂 `Model output error:`(CC-43)+ 注入件撞活 run 自动 steer 零卡(CC-44);型面纯 additive、公面 977、peer 不动;§55。上一版 0.72.7 = **patch**:core 7.22.0 提货 —— 通告码 66 `mcp.server_redialed` + 读器 `readMcpServerRedialed` + `wiring_manifest.readDeny` 第九段 `_sema_readDeny`(缺席 = 没有内置行判这条腿);型面纯 additive、公面 971、peer 不动、devDep core ~7.22.0;§54。上一版 0.72.6 = **patch**:cli L-379 包侧半场 —— `steerFollowIntent` steer 后续听意图三态(tail / after-decision / after-wake)+ `activeRunSelfHealRow` 续听声明第五参;型面纯 additive、公面 969、peer 不动;§53。上一版 0.72.5 = **patch**:server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面(键缺席 = 老引擎判不了 ≠ `none`);型面纯 additive、公面 968、peer 不动;§52。上一版 0.72.4 = **patch**:core 7.21.x 三件经 server 7.82.0 提货 —— `wiring_manifest.autoConsolidation` 第八段 `_sema_autoConsolidation`(缺席 = indeterminate 不折 false);型面纯 additive、公面 962、peer 不动;§51。上一版 0.72.3 = **patch**:core #863 记忆单系统半场 ① —— `projectAgentsForWire` 投影 `agents[].memory`(user|project|local 三词同映射引擎平面 agent:<type>);型面纯 additive、公面 962、零 wire 新键、peer 不动;§50。上一版 0.72.2 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
23
23
  | peer:wire 契约 | `@sema-agent/sdk` **>=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
- | 公开导出面 | **985** 个运行期符号(+ 45 个测试钩;= 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` 两张闭词表再导出 + `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
+ | 公开导出面 | **989** 个运行期符号(+ 45 个测试钩;= 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` 两张闭词表再导出 + `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`(**985** 项)。
124
+ > 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**989** 项)。
125
125
  > 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
126
126
  > **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
127
127
  > 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
@@ -145,12 +145,12 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
145
145
  `WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
146
146
  **4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
147
147
 
148
- 985 项的内部构成(帮助端估读表大小;0.72.9 +2 常量 +6 函数(CC-30 / CC-39②);0.72.8 +2 常量 +4 函数(CC-39③ / CC-43);0.72.7 +1 常量 +1 函数(CC-42);0.72.6 +1 函数(CC-40);0.72.5 +1 常量 +5 函数(CC-31);0.72.3 +1 常量(CC-39①);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):**286** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
148
+ 989 项的内部构成(帮助端估读表大小;0.72.10 +2 常量 +2 函数(CC-41);0.72.9 +2 常量 +6 函数(CC-30 / CC-39②);0.72.8 +2 常量 +4 函数(CC-39③ / CC-43);0.72.7 +1 常量 +1 函数(CC-42);0.72.6 +1 函数(CC-40);0.72.5 +1 常量 +5 函数(CC-31);0.72.3 +1 常量(CC-39①);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):**288** 项是 `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)。
152
152
 
153
- ### 2b. 域图(16 域,逐域计数之和 = 985)
153
+ ### 2b. 域图(16 域,逐域计数之和 = 989)
154
154
 
155
155
  | # | 域 | 名数 | 承重导出 | 用途 | 实现锚 |
156
156
  |---|---|---|---|---|---|
@@ -165,11 +165,11 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
165
165
  | 9 | **能力/旋钮 wire 门族** | 97 | `AGENT_MEMORY_WORDS`(0.72.3 CC-39①:`memory: user|project|local` 三词;`projectAgentsForWire` 把它们同映射为 `agents[].memory = { scopes:[agent:<type>], writeScope }`;§50)· `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
- | 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`) |
168
+ | 12 | **workflow 与后台工作视图** | 25 | `projectLeaderConflict` / `leaderConflictDetail` + `LEADER_RUN_STATUSES` / `LEADER_REJ_HEAD_DISPLAY_MAX`(0.72.10 CC-41:leader run 终局 `needs_human` + `result.conflict` 三形读面 none / unreadable / conflict,缺席不可分、filesTruncated 只认 true、salvaged 原样给落盘口;§57)· `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
171
  | 15 | **控制面与传输** | 139 | `reconnectMcpServer` / `projectMcpReconnectResult` / `classifyMcpReconnectFailure` / `projectMcpReconnectCapability` / `mcpReconnectOutcomeDetail` + `MCP_RECONNECT_OUTCOMES` / `MCP_RECONNECT_TRANSACTION_NOTICE`(0.72.9 CC-30:会话内 MCP re-dial 消费口,outcome 三态 / unsupported 恒五键 / 名册按 toolNames 在场性;§56)· `readAutoConsolidationArmed`(0.72.9 CC-39②:memory-status `autoConsolidationArmed` 三态,缺席 = 老 server 判不了;§56)· `steerFollowIntent`(0.72.6 CC-40:steer 后续听意图三态 tail / after-decision / after-wake,按 `SteerReceipt.delivery` 判;§53)· `projectWebSearchBackendCapability` / `observedWebSearchBackend` / `noteEngineCapsForWebSearchBackend` / `forgetWebSearchBackendReading` / `webSearchBackendDoctorDetail` + `WEB_SEARCH_BACKEND_NONE`(0.72.5 CC-31:`capabilities.webSearch.backend` 四态读面 —— 键缺席 = 老引擎判不了 ≠ `none` = 引擎明说没有默认后端;与 `sqlEngineCapability` / `writeProtectionCapability` 同构;§52)· `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/webSearchBackendCapability.ts`、`src/mcpReconnect.ts`、`src/readFacePosture.ts` |
172
- | 16 | **引擎词汇表与包自检** | 93 | `MCP_REDIAL_OUTCOMES` / `readMcpServerRedialed`(0.72.7 CC-42:通告 `mcp.server_redialed` 事实读器,outcome 三词闭集、added/removed 计数;§54)· `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`)|
172
+ | 16 | **引擎词汇表与包自检** | 93 | `ENGINE_NOTICE_CODES` 67(0.72.11 CC-49:core 7.23.0 +1 `config.write_protection_unresolved`,operator,兄弟码 `target_view_absent` 之后;§58)· `MCP_REDIAL_OUTCOMES` / `readMcpServerRedialed`(0.72.7 CC-42:通告 `mcp.server_redialed` 事实读器,outcome 三词闭集、added/removed 计数;§54)· `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`**,
@@ -4631,7 +4631,7 @@ an argument」。audience 答另一问:这条事实**说给谁听**。
4631
4631
  **签名**
4632
4632
 
4633
4633
  ```ts
4634
- ENGINE_NOTICE_CODES: readonly string[] // 66 码,顺序同源(core 7.22.0 +1 mcp.server_redialed;0.72.7)
4634
+ ENGINE_NOTICE_CODES: readonly string[] // 67 码,顺序同源(core 7.23.0 +1 config.write_protection_unresolved;0.72.11)
4635
4635
  ENGINE_NOTICE_AUDIENCE: Readonly<Record<string, 'user' | 'operator'>>
4636
4636
  noticeAudienceOf(code: unknown): 'user' | 'operator'
4637
4637
  engineNoticeInCatalog(code: unknown): boolean
@@ -8558,3 +8558,65 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
8558
8558
  3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;server <7.85.0 上端点 404 `not_found.route` ⇒ `unsupported/route`、能力位 `not_reported`、新键缺席 ⇒ `indeterminate`。
8559
8559
 
8560
8560
  **包侧缺口:** ① CC-41 leader `needs_human` + `result.conflict` 渲染面(0.72.10);② CC-46 `plan_review` 体 `permissionModeAfter` 发口(候 server 7.86.0 S-433 + sdk 型面);③ CC-34 `permission_denials` 自动升级验证(候 core #897 + server 透传);④ CC-36 托管 MCP 活性三态读口(候 core #874);⑤ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑥ `Capabilities.webSearch` / `mcpReconnect` / `TaskRequestBody.memory` / `WiringManifest.readDeny` / `SessionMemoryStatus.autoConsolidationArmed` / reconnect 端点与体 经 sdk 声明(候 sdk 出键);⑦ `agents.listing_truncated` detail 读器候消费场景(by-design);⑧ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑨ §NNz「declined 键真零命中」机读第二刀(候形式化)。
8561
+
8562
+ ## §57 🆕 0.72.10 CC-41 leader run 终局 `needs_human` + `result.conflict` 读面;patch
8563
+
8564
+ > **patch**:型面纯 additive(+2 常量 +2 函数,公面 985 → 989;零 wire 新键 —— 形由 server 7.83.0 C-R63 ④ 铸,本包只读;sdk 9.6.0 `LeaderRecord.result` 声明为 `unknown`,本读器是它在客户端的唯一形;peer 不动)。票来源:server [7495] ④ @client-core「请新开渲染面」/ cli [7499] 先包后壳(CC-41)。
8565
+
8566
+ ### 57a. 处置表
8567
+
8568
+ | # | 面 | 本包做了什么 | 端要做什么 |
8569
+ |---|---|---|---|
8570
+ | S-1 | **`GET /v1/leader/:id` 终局 `status:"needs_human"` + `result.conflict { baseSha, files[], filesTruncated?, workers[], rejHead? }` + `result.salvaged[]`**(server ≥7.83.0;契约 §15) | **consumed**:`projectLeaderConflict(record)` ⇒ `LeaderConflictView` 三形 `none` / `unreadable` / `conflict`(永不抛;记录不成形 ⇒ undefined);`leaderConflictDetail(view)` 一句单源;`salvagedIncomplete?: true`(`salvaged` 在场但读不全 ≠ 空表);`LEADER_RUN_STATUSES` 四词词表;`LEADER_REJ_HEAD_DISPLAY_MAX` = 2048 | leader run 终局面:`kind:'conflict'` ⇒ 渲 `leaderConflictDetail` + 列 `conflict.files[]`(`filesTruncated` 在场加「清单被截断」标)+ `workers[]` 按 `applied` 两栏 + `rejHead` 作诊断片段(已消毒,直接渲);🔴 `salvaged[]` 交**落盘口**(每只 `{workerId, sessionId, patch}` 一个文件,`patch` 原样字节不进屏);`salvagedIncomplete` 在场 ⇒ 落盘口旁必渲包句里那半句「材料存在但读不出」并把原 `result` 留给 `--debug`,**不渲「没有补丁」**;🔴 `needs_human` 是「等人」—— 端**不许**据它自动重试、也不许渲成「失败」;`kind:'none'` 渲包句(不自拼「没冲突」);`kind:'unreadable'` 渲包句并把原 `result` 留给 `--debug` |
8571
+ | S-2 | `status` 四词 `running` / `completed` / `failed` / `needs_human` | **consumed(开集透传)** | 壳 switch 必带 default;`LEADER_RUN_STATUSES` 只作分档词表,新词照渲原串 |
8572
+
8573
+ ### 57z. 逐键处置表
8574
+
8575
+ | # | 键 / 面 | 处置 | 坐标 / 理由 |
8576
+ |---|---|---|---|
8577
+ | 1 | `result.conflict` 整键缺席 | **consumed(`none`;未冲突 ∨ 老 server 不可分,措辞两可能都摆)** | `src/leaderConflict.ts` `#projectLeaderConflict`;门 `run-leader-conflict-test.mjs` S1b / S1c / S2e |
8578
+ | 2 | `conflict` 在场但 `baseSha` 空 / `files` 非串数组 / `workers` 缺或成员缺 `applied` / 非对象 / null | **consumed(`unreadable` ≠ `none`)** | `#readConflict` / `#readWorkers`;S1d / S1e 判别力自证 |
8579
+ | 3 | `conflict.filesTruncated` | **consumed(只认 `true`;缺席 = 全部;别的值 ⇒ unreadable)** | S1g |
8580
+ | 4 | `conflict.rejHead` | **consumed(呈前转义 + 封长 ≤2048;非串 ⇒ unreadable)** | `capForDisplay`;S1h |
8581
+ | 5 | `result.salvaged[]` | **consumed(`patch` 原样;坏行逐行丢 + `salvagedIncomplete:true`;非数组 / 非空全坏 ⇒ `[]` + incomplete;缺席 / `[]` / 全好 ⇒ 键不在场;三形都带)** | `#readSalvaged`;S1i / S1m / S1n;措辞 S2c2 |
8582
+ | 8 | `conflict.workers[]` 重复 `workerId` | **pending(契约未定处置;原样带出,句子按 `applied` 分栏可能两栏同现)** | 契约 §15 未言重复身份;server 单趟每 worker 一行,出现即 server 侧病;候契约明文后加反钉 |
8583
+ | 6 | `result.suspended[]` / `result.candidatePatch` / `result.replan` / `result.repairLoop` | **declined** | 不在契约 §15 本面(C4 / repair loop 面另票);本读器不碰,端要读走 `record.result` 原体 |
8584
+ | 7 | `record.error` | **declined** | 契约 §15 未把它列进本面;`needs_human` 不是失败,不拿 `error` 当冲突文案 |
8585
+
8586
+ ### 57y. 🔴 三端升级必读(固定段式,[C295])
8587
+
8588
+ 1. 换钉 `^0.72.10`:leader run 终局面接 `projectLeaderConflict` + `leaderConflictDetail`;`salvaged[]` 接落盘口(`salvagedIncomplete` 在场不渲「没有补丁」);`needs_human` 不重试不渲失败;`none` 句不是「已合并」的证明。
8589
+ 2. 不接线的端零变化:纯新读面,零既有导出改动。
8590
+ 3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;server <7.83.0 上 `conflict` 恒缺席 ⇒ `none`(措辞已含「或 server 不报」)。
8591
+
8592
+ **包侧缺口:** ⓪ CC-49 通告码 67 `config.write_protection_unresolved` 镜像(0.72.11;候 core 7.23.0 上 npm);① CC-46 `plan_review` 体 `permissionModeAfter` 发口(候 server 7.86.0 S-433 + sdk 型面);② CC-34 `permission_denials` 自动升级验证(候 core 7.23.0 #897 + server 透传);③ CC-36 托管 MCP 活性三态读口(候 core 7.23.x #874);④ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑤ `Capabilities.webSearch` / `mcpReconnect` / `TaskRequestBody.memory` / `WiringManifest.readDeny` / `SessionMemoryStatus.autoConsolidationArmed` / reconnect 端点与体 / `LeaderRecord.result` 冲突形 经 sdk 声明(候 sdk 出键);⑥ `agents.listing_truncated` detail 读器候消费场景(by-design);⑦ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑧ §NNz「declined 键真零命中」机读第二刀(候形式化)。
8593
+
8594
+ ## §58 🆕 0.72.11 core 7.23.0 提货(CC-49:通告码 67 `config.write_protection_unresolved`;patch)
8595
+
8596
+ > **patch**:型面零变化(通告闭集 +1、零新导出、公面 989 不变;peer 不动;devDep core `~7.23.0`)。提货单 [7538] @client-core 段:镜像一件 + 加法三件 + 零动作两件 + 一处解阻(CC-34 的 core 半场);本包只镜像码与受众,通告本身由 server 承载版透传到端(老 server 上这枚码不出现)。
8597
+
8598
+ ### 58a. 处置表
8599
+
8600
+ | # | 面 | 本包做了什么 | 端要做什么 |
8601
+ |---|---|---|---|
8602
+ | S-1 | **`config.write_protection_unresolved`**(operator;`detail: { reason, cause, sessionId, runId }`;`reason` ∈ `unresolved-symlink` / `unresolvable-target`;去重 = 每 leg 每 reason;不带调用身份) | `ENGINE_NOTICE_CODES` 镜像 +1(紧跟兄弟码 `config.write_protection_target_view_absent`)+ audience operator;`engineNoticeInCatalog` / `noticeAudienceOf` 即认 | 运维通知面按 operator 渲,措辞用引擎 `message`(单铸律);🔴 与兄弟码**两句不同**(没有视图 ≠ 有视图解析不出);一条 leg 至多两条(两个 reason),第二条 leg 再来一次是引擎的去重单位不是端的重复;`detail.reason` 只渲不分支 |
8603
+ | S-2 | `TaskStats.humanReview.gates[]` 行型 `HumanReviewGateRow` 加 `toolCallId?`(#897;六份内联收一;缺席 = 不可 join **不是**「没有调用」,永不占位)| **consumed(自动升级腿通电)**:`_sema_permission_denials[].tool_use_id` 在行带 `toolCallId` 时自动有值(mint 点零改;门 E5 / E5b 真字节);`tool_input` 仍缺 ⇒ CC `permission_denials` 数组仍只收三键齐全的记录(今天恒空) | 渲被拒清单时 `tool_use_id` 按**可选位**读(老引擎 / 探针行 / 非 tool_approval 耐久门缺席);有值可与转录里的 `tool_use` 块 join,**缺席别渲「无调用」**;到端还要 server 承载版透传(候 7.87.0 [7539]) |
8604
+ | S-2b | 持久 checkpoint 行 / `ReadEntry.transmittedByToolCallId?` | **零动作**(本包不读持久 checkpoint 行与 read-state) | 零动作 |
8605
+ | S-3 | 新导出 `WriteProtectionViewAbsence`(interface)/ `ReadRootGrantCandidate.covers` 有值 | **零动作**(非 wire 键 / 型面 0.71.0 已在场,读在场不读缺席) | 零动作;`covers:"exact"` 那格接受时回传**那一串本身**(0.71.0 §42 读法不变,现在会通电) |
8606
+
8607
+ ### 58z. 逐键处置表
8608
+
8609
+ | # | 键 / 面 | 处置 | 坐标 / 理由 |
8610
+ |---|---|---|---|
8611
+ | 1 | `config.write_protection_unresolved` + `detail` 四键 | **consumed(镜像 +1;detail 不另立读器,`reason` 只渲)** | `src/engineNoticeCodes.ts` `#ENGINE_NOTICE_CODES` / `#NOTICE_AUDIENCE`;码册门 G8b 67 + G11 三格 |
8612
+ | 2 | `gates[].toolCallId`(wire `TaskStats.humanReview.gates[]`) | **consumed(⇒ `tool_use_id`;缺席 = 键不在场)** | `src/adapter/downstream/terminalToSdkResult.ts` `#permissionDenialParts`;permission-denial 门 A 自动升级腿 + E5 / E5b / E7 真字节 |
8613
+ | 2b | 持久 checkpoint 行三工具字段 / `ReadEntry.transmittedByToolCallId` | **declined** | 本包不读持久行 / read-state |
8614
+ | 3 | `WriteProtectionViewAbsence` / `WriteProtectionCompileOptions.onViewAbsent` | **n/a** | 库直调面,零 core 值级 import |
8615
+
8616
+ ### 58y. 🔴 三端升级必读(固定段式,[C295])
8617
+
8618
+ 1. 换钉 `^0.72.11`:operator 通知面多一码 `config.write_protection_unresolved`(与兄弟码两句不同);被拒清单 `_sema_permission_denials[].tool_use_id` 开始有值(按可选位读;server 承载版到货才到端);其余零接线。
8619
+ 2. `ENGINE_NOTICE_CODES` 67,码册镜像随包;型面零变化,公面 989 不变。
8620
+ 3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;server 承载版到货前这枚码不出现。
8621
+
8622
+ **包侧缺口:** ① CC-46 `plan_review` 体 `permissionModeAfter` 发口(候 server 7.86.0 S-433 [7532] 裁定 + sdk 型面);② CC-34 `permission_denials` 自动升级验证(core #897 已到 7.23.0;候 server 7.87.0 透传半场);③ CC-36 托管 MCP 活性三态读口(候 core 7.23.x #874);④ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑤ `Capabilities.webSearch` / `mcpReconnect` / `TaskRequestBody.memory` / `WiringManifest.readDeny` / `SessionMemoryStatus.autoConsolidationArmed` / reconnect 端点与体 / `LeaderRecord.result` 冲突形 经 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.9",
3
+ "version": "0.72.11",
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",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@sema-agent/agent-types": "^0.3.0",
38
- "@sema-agent/core": "~7.22.0",
38
+ "@sema-agent/core": "~7.23.0",
39
39
  "@sema-agent/sdk": "^9.6.0",
40
40
  "@sema-agent/settings-schema": "^2.0.0",
41
41
  "esbuild": "^0.27.4",