@sema-agent/client-core 0.22.0 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/dist/adapt/arms.d.ts +4 -4
  3. package/dist/adapt/arms.js +6 -6
  4. package/dist/adapt/toolCards.d.ts +2 -2
  5. package/dist/adapt/turnFlags.d.ts +2 -2
  6. package/dist/adapt.js +2 -2
  7. package/dist/adapter/downstream/eventToSdkMessage.d.ts +13 -1
  8. package/dist/adapter/downstream/eventToSdkMessage.js +39 -5
  9. package/dist/adapter/downstream/terminalToSdkResult.js +1 -1
  10. package/dist/adapter/runStream.js +1 -1
  11. package/dist/adapter/types.d.ts +1 -1
  12. package/dist/agentSession/backgroundView.d.ts +2 -2
  13. package/dist/agentSession/backgroundView.js +5 -4
  14. package/dist/agentSession/contract.d.ts +1 -1
  15. package/dist/attachmentsWireCaps.d.ts +2 -2
  16. package/dist/attachmentsWireCaps.js +3 -3
  17. package/dist/classifierVerdictWire.d.ts +1 -1
  18. package/dist/classifierVerdictWire.js +1 -1
  19. package/dist/goalStopHook.d.ts +1 -1
  20. package/dist/goalStopHook.js +1 -1
  21. package/dist/headlessPermissionModeWire.d.ts +1 -1
  22. package/dist/headlessPermissionModeWire.js +1 -1
  23. package/dist/headlessReconnectWire.d.ts +1 -1
  24. package/dist/headlessReconnectWire.js +1 -1
  25. package/dist/hitl/approvalsFeed.d.ts +1 -1
  26. package/dist/hitl/frameRouter.js +1 -1
  27. package/dist/hitl/gateLedger.d.ts +1 -1
  28. package/dist/hitl/hitlHostSurface.d.ts +1 -1
  29. package/dist/hitl/hitlHostSurface.js +1 -1
  30. package/dist/hitl/toolApprovalWire.d.ts +1 -1
  31. package/dist/hitl/toolApprovalWire.js +4 -4
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/interactiveToolsWire.d.ts +1 -1
  35. package/dist/interactiveToolsWire.js +1 -1
  36. package/dist/limitsWire.d.ts +1 -1
  37. package/dist/limitsWire.js +1 -1
  38. package/dist/notifications.d.ts +2 -2
  39. package/dist/notifications.js +2 -2
  40. package/dist/permissionWireCaps.d.ts +1 -1
  41. package/dist/permissionWireCaps.js +1 -1
  42. package/dist/retryStatus.d.ts +2 -2
  43. package/dist/seam.d.ts +2 -2
  44. package/dist/skillsWireCaps.d.ts +1 -1
  45. package/dist/subagent/engineRowStopGate.d.ts +1 -1
  46. package/dist/subagent/engineRowStopGate.js +1 -1
  47. package/dist/subagent/engineTaskHandleWire.js +1 -1
  48. package/dist/toolResult.d.ts +3 -3
  49. package/dist/toolResult.js +8 -1
  50. package/dist/workflow.d.ts +2 -2
  51. package/dist/workflow.js +2 -2
  52. package/package.json +2 -2
package/README.md CHANGED
@@ -23,7 +23,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
23
23
 
24
24
  ## Scope
25
25
 
26
- **Version:** 0.22.0
26
+ **Version:** 0.23.1
27
27
 
28
28
  - **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
29
29
  B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
@@ -5,15 +5,15 @@
5
5
  * · 每条臂是一个具名 generator,`break` 变 `return`(语义逐条对位,`default:` 空臂 = 表里查不到);
6
6
  * · 臂拿不到驱动壳的局部变量 —— 它要什么状态,必须写在自己的 deps 类型里。
7
7
  *
8
- * 🔴 表用 `Map` 而不是普通对象(codex verdict 3):对象表被 `{type:'__proto__'}` /
8
+ * 🔴 表用 `Map` 而不是普通对象(复审结论 3):对象表被 `{type:'__proto__'}` /
9
9
  * `{type:'toString'}` 这种帧一命中就是原型污染(wire 帧是 UNTRUSTED 的开集)。
10
10
  *
11
11
  * 🔴 **两级 deps 是判别力本身,不是洁癖**(矩阵 §3.5):
12
12
  * `ProjectionArmFn` 只吃 `{ctx, idOf}` —— 于是「这几条臂碰不到任何适配器状态」这件事从
13
13
  * 注释里的断言变成**编译期事实**。全量注入(一个大 deps 喂所有臂)会让封闭性声明失去判别力,
14
- * 那正是 A 族 codex 复审里 5/11 那次翻车的根因。
14
+ * 那正是 A 族 对抗复审里 5/11 那次翻车的根因。
15
15
  *
16
- * 🔴 **7 组由输入帧顺序耦合的臂对**(codex verdict 3 的清单;源码级无顺序耦合 —— 每帧单键分发 +
16
+ * 🔴 **7 组由输入帧顺序耦合的臂对**(复审结论 3 的清单;源码级无顺序耦合 —— 每帧单键分发 +
17
17
  * return,但**帧到达顺序**会改判别结果)。逐条点名在下面各臂的注释里,标记 `⟨帧序耦合 N/7⟩`:
18
18
  * 1. assistant(开卡)→ task_progress(FIFO 猜父只认**已开**的卡)
19
19
  * 2. assistant(Workflow 卡)→ task_progress(判据③ 认 seenWorkflowToolCallIds)
@@ -62,6 +62,6 @@ export type ProjectionArmFn = (m: Frame, deps: ProjectionArmDeps) => Generator<A
62
62
  export type ArmFn = (m: Frame, deps: ArmDeps) => Generator<AdapterOutput>;
63
63
  /**
64
64
  * 帧类型 → 臂。**Map 而不是对象字面量**:`{type:'__proto__'}` 这种 UNTRUSTED 帧命中对象表
65
- * 就是原型污染(codex verdict 3)。表里查不到 = 拆分前 `switch` 的 `default:` 空臂,行为同。
65
+ * 就是原型污染(复审结论 3)。表里查不到 = 拆分前 `switch` 的 `default:` 空臂,行为同。
66
66
  */
67
67
  export declare const ARMS: ReadonlyMap<string, ArmFn>;
@@ -16,7 +16,7 @@ const assistantArm = function* (m, { ctx, idOf, text, cards, inst }) {
16
16
  const toolUseIdx = blocks.findIndex(b => b?.type === 'tool_use');
17
17
  // 拆分同批消掉一处 `!` 非空断言(规范禁用):`findIndex >= 0` 与「取到的不是 undefined」
18
18
  // 本来就是同一件事(判别式 `b?.type === 'tool_use'` 对 undefined 恒假),写成显式取值即可。
19
- // 收货裁定(codex 复审 #4):旧版此处直接取值使用,畸形帧(accessor/稀疏形,非 JSON 数据帧)
19
+ // 收货裁定(对抗复审 #4):旧版此处直接取值使用,畸形帧(accessor/稀疏形,非 JSON 数据帧)
20
20
  // 会抛 TypeError;guard 保留=有意的健壮性变化 —— 正常 wire 帧(JSON.parse 产物)下
21
21
  // `findIndex >= 0 ⇒ 恒非 undefined`,零行为差。
22
22
  //
@@ -213,7 +213,7 @@ const workspaceChangedArm = function* (m, { idOf }) {
213
213
  });
214
214
  };
215
215
  /**
216
- * FIX⑦(2026-08-07,黑板 [3017]/[3020])—— `human_input` 生命周期账本帧。
216
+ * FIX⑦(2026-08-07,[3017]/[3020])—— `human_input` 生命周期账本帧。
217
217
  *
218
218
  * 姿势抄同族的 `steering_injected` / `workspace_changed`(都是「引擎侧发生了一件事,壳记一笔」的
219
219
  * 非持久帧,归 chrome),但**不走 `attachment` 臂**:那三条 attachment 是要在转录流里渲出一行给
@@ -249,7 +249,7 @@ const humanInputArm = function* (m) {
249
249
  ...(str(m.issuer) !== undefined ? { issuer: str(m.issuer) } : {}),
250
250
  ...(actor !== undefined && Object.keys(actor).length > 0 ? { actor } : {}),
251
251
  ...(str(m.entryId) !== undefined ? { entryId: str(m.entryId) } : {}),
252
- // 宿主幂等落账的键(codex 复审二轮):重放同一条账本帧必须得到同一个 eventId。
252
+ // 宿主幂等落账的键(对抗复审二轮):重放同一条账本帧必须得到同一个 eventId。
253
253
  ...(str(m.eventId) !== undefined ? { eventId: str(m.eventId) } : {}),
254
254
  });
255
255
  };
@@ -343,7 +343,7 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
343
343
  // 都在 footer 铸一条幽灵 local_agent 行,还能骑错 run_workflow 卡的 inline stats)。
344
344
  // 判据三级:① 帧带 workflowRunId(一手证据)② wa+16hex 形 id(core BCE 合成 id)
345
345
  // ③ 显式父指向本会话见过的 Workflow 工具卡(实例台账,覆盖 uuid 形子代 id + 跨 turn 迟到 tick)。
346
- // 🔴 codex 独立发现的拆分风险:**本门必须先于任何 panel 写**,否则重造 workflow 幽灵前台行 ——
346
+ // 🔴 复审独立发现的拆分风险:**本门必须先于任何 panel 写**,否则重造 workflow 幽灵前台行 ——
347
347
  // 这也是它在本臂第一段、`bind()` 之前的原因,别按「先绑定再分类」重排。
348
348
  const workflowRunId = typeof m.workflowRunId === 'string' ? m.workflowRunId : undefined;
349
349
  if (workflowRunId !== undefined ||
@@ -659,7 +659,7 @@ const retryStatusArm = function* (m, { ctx, flags }) {
659
659
  // (TurnFlags 的「主 lane 内容帧到达即清」)可能已经清过了:已安装 core 在内容流跑完的 finally
660
660
  // 里发 `recovered`,所以 `retrying → 内容 → recovered` 才是常态顺序。故用 `takeRetryOverlay()`
661
661
  // 的**原子读落**决定要不要发:旗还在 ⇒ 发这一发并落旗;旗已落 ⇒ 沉默(没有覆盖层可摘)。
662
- // 首版写成「无条件发 + clearRetryOverlay」,在常态顺序上双清(codex 复审命中)。
662
+ // 首版写成「无条件发 + clearRetryOverlay」,在常态顺序上双清(对抗复审命中)。
663
663
  if (status === null) {
664
664
  if (flags.takeRetryOverlay())
665
665
  yield chrome({ kind: 'retry_status', laneProof: MAIN, status: null });
@@ -671,7 +671,7 @@ const retryStatusArm = function* (m, { ctx, flags }) {
671
671
  };
672
672
  /**
673
673
  * 帧类型 → 臂。**Map 而不是对象字面量**:`{type:'__proto__'}` 这种 UNTRUSTED 帧命中对象表
674
- * 就是原型污染(codex verdict 3)。表里查不到 = 拆分前 `switch` 的 `default:` 空臂,行为同。
674
+ * 就是原型污染(复审结论 3)。表里查不到 = 拆分前 `switch` 的 `default:` 空臂,行为同。
675
675
  */
676
676
  export const ARMS = new Map([
677
677
  ['assistant', assistantArm],
@@ -5,7 +5,7 @@
5
5
  * (TodoWrite 划删线 diff 的 oldTodos)三行状态 + C4 mintResponseId / C10 buildToolResult /
6
6
  * C11 sweepOpenCards 三个闭包 + `PendingToolUse` 形本身。
7
7
  *
8
- * 🔴 拆分硬约束(SPLIT-03,codex verdict 2 采纳形):**S1 复位在 `close()` 内部、第一个 `yield`
8
+ * 🔴 拆分硬约束(SPLIT-03,复审结论 2 采纳形):**S1 复位在 `close()` 内部、第一个 `yield`
9
9
  * 之前**。理由是生成器语义 —— yield 之后的语句只有消费者再要下一个值时才跑,消费者早退
10
10
  * (`it.return()` / break)时永不执行。把复位留在调用方,调用方就还能写出「yield 后复位」的形;
11
11
  * 收进被调方之后,这条时序由**一处**保证。原 `tool_end_result` 臂 :1054-1056(delete → 复位 →
@@ -16,7 +16,7 @@
16
16
  * turn 级,两行之后紧跟 `break`,早退时生成器已死、再无读者 ⇒ 零可观测后果),所以前移是
17
17
  * **纯一致性改动、零行为差**。反钉见矩阵 §2.2:前移不影响 mint —— 影响窗口只有
18
18
  * 「复位语句与原复位点(yield 之后)」之间那几行,窗口内无 mint 点;三条支随即退出本臂,
19
- * 后续帧的 mint 走各自臂的常规路径,与拆分前同(codex 复审校准:break 退出的是臂不是 turn)。
19
+ * 后续帧的 mint 走各自臂的常规路径,与拆分前同(对抗复审校准:break 退出的是臂不是 turn)。
20
20
  *
21
21
  * 🔴 `pending` 是唯一跨 M2→M3 的数据面(矩阵 §1.2 注):面板族只读两个字段(`name` 判
22
22
  * SUBAGENT_TOOL_NAMES / `rawInput` T50 双形读)。所以对外给的是 `OpenCardView` **只读视图**,
@@ -29,7 +29,7 @@ export interface TurnFlags {
29
29
  emitTurnUsageEnd(outputTokens: number): Generator<AdapterOutput>;
30
30
  /** A7 `result`:只有还没发过 end 且这帧真带了 outputTokens 时才补发(`!endEmitted` 门)。 */
31
31
  /** `readOutputTokens` 惰性:只在真的要发 end 度量时才读 usage(与拆分前「`!endEmitted`
32
- * 门内才读 `m.usage`」逐字同语义 —— codex 复审 #3 收货修)。 */
32
+ * 门内才读 `m.usage`」逐字同语义 —— 对抗复审 #3 收货修)。 */
33
33
  emitResultEndIfNeeded(readOutputTokens: () => number | undefined): Generator<AdapterOutput>;
34
34
  /** A15 `retry_status`:挂旗(下一帧主 lane 内容到达即清)。 */
35
35
  noteRetryOverlay(): void;
@@ -37,7 +37,7 @@ export interface TurnFlags {
37
37
  * A15 `retry_status` 的反向动作(#3004 跟修批 2026-08-08):**引擎直报恢复**(`recovered` 相)那一拍
38
38
  * 调它 —— 返回「本次是否**仍需**发清除」并同时落旗(**原子**:读+落一步完成)。
39
39
  *
40
- * 🔴 为什么必须是「take」而不是「clear」(codex 复审命中的双清):两条清除腿共用同一个布尔位,
40
+ * 🔴 为什么必须是「take」而不是「clear」(对抗复审命中的双清):两条清除腿共用同一个布尔位,
41
41
  * 而它们的触发顺序两个方向都真实存在 ——
42
42
  * · `retrying → recovered`:直报腿先到,旗还在 ⇒ 本次要发清除,发完落旗;间接腿之后看不到旗。
43
43
  * · `retrying → 主lane内容 → recovered`:**间接腿先到**(已发过一次 null 并落了旗),直报腿这一拍
package/dist/adapt.js CHANGED
@@ -160,7 +160,7 @@ class WireToCcAdapterImpl {
160
160
  }
161
161
  };
162
162
  const s = state;
163
- // 单次快照(codex 复审 #2 收货修):拆分前这里对 `renderedNotifications` 恰一次属性读。
163
+ // 单次快照(对抗复审 #2 收货修):拆分前这里对 `renderedNotifications` 恰一次属性读。
164
164
  const rendered = s.renderedNotifications;
165
165
  if (Array.isArray(rendered))
166
166
  n += this.ledger.takeRenderedNotifications(rendered);
@@ -278,7 +278,7 @@ class WireToCcAdapterImpl {
278
278
  if (m.type !== 'stream_event')
279
279
  yield* text.drainLive();
280
280
  // ── 分派(拆分前是一个 600 行的 switch;`default:` 空臂 = 表里查不到,行为同)────────────
281
- // 单读快照(codex 复审 #1 收货修):旧 switch 对 `m.type` 恰一次属性读,`typeof m.type
281
+ // 单读快照(对抗复审 #1 收货修):旧 switch 对 `m.type` 恰一次属性读,`typeof m.type
282
282
  // ? m.type` 是两读 —— 对 accessor 形帧可观测,降回一读。
283
283
  const rawType = m.type;
284
284
  const armKey = typeof rawType === 'string' ? rawType : undefined;
@@ -35,6 +35,18 @@
35
35
  */
36
36
  import type { AgentEvent, CheckpointGate } from '@sema-agent/sdk';
37
37
  import { type SDKMessage, type EmitContext, type ModelUsage } from '../types.js';
38
+ /**
39
+ * 本适配器铸出的**内部臂** `type` 全集(A-004.4 上游半场,2026-08-08)——「内部臂」= 桥面
40
+ * (bridge-facing)消息,**不是** CC SDK stdout 联合体里的帧形(那些是 assistant/stream_event/
41
+ * system 等真帧)。消费方(壳 REPL 桥、`-p` print 出口、web/desktop 座位层)对内部臂只有两种
42
+ * 合法处置:**吞**(不外泄)或**转成真 CC 帧**;顺着兜底裸透传到 stdout/wire = 病族⑥投影缺口
43
+ * (cli A-004.11/12 实翻:human_input/diagnostics/workspace_changed 曾漏进 `-p` stream-json)。
44
+ *
45
+ * 这张表是**唯一权威源**:消费方的吞/转名单必须对账本表(全覆盖,禁手抄子集——A-004.4 的病形
46
+ * 就是壳手抄了 4 词的子集);本包 pure 门有源码对账腿(armBody 铸点抽取 ≡ 本表),加臂不登记
47
+ * 即红。`turn_usage` 的铸点在 runStream.ts(usage 聚合腿),不在本文件的 switch 里,同属本表。
48
+ */
49
+ export declare const INTERNAL_SDK_ARM_TYPES: ReadonlySet<string>;
38
50
  /** 「本切片不投影这条臂」的**如实分类**(REF-CC-058 / xlate-04)。 */
39
51
  export type EventProjectionNoneReason =
40
52
  /** `turn_end`:usage 折叠是 run driver 的活(`turnEndUsage`),本层无独立可渲染臂。 */
@@ -61,7 +73,7 @@ export type EventProjectionDropReason =
61
73
  | 'unknown_arm'
62
74
  /**
63
75
  * 类型面**认得**这条臂、它也带着用户可见的决策内容,但本包**今天没有任何消费口**
64
- * (2026-08-08 codex 复审第 4/5 轮命中,首例 = `approval_request`)。
76
+ * (2026-08-08 对抗复审第 4/5 轮命中,首例 = `approval_request`)。
65
77
  *
66
78
  * 为什么不能并进 `not_in_slice`:那一档的语义是「本切片不投影,**因为别处接了/本来就没有可渲染物**」,
67
79
  * 它走 `kind:'none'` —— 而 `none` 是**静默**的,只有 `dropped` 会经 `reportDroppedFrame` 走宿主
@@ -19,6 +19,30 @@ function armBody(body) {
19
19
  const SUGGESTION_BATCH_CAP = 8;
20
20
  /** 单条建议的字符上界;超出截断并留可见痕迹(尾部 `…`)。 */
21
21
  const SUGGESTION_CHARS_CAP = 200;
22
+ /**
23
+ * 本适配器铸出的**内部臂** `type` 全集(A-004.4 上游半场,2026-08-08)——「内部臂」= 桥面
24
+ * (bridge-facing)消息,**不是** CC SDK stdout 联合体里的帧形(那些是 assistant/stream_event/
25
+ * system 等真帧)。消费方(壳 REPL 桥、`-p` print 出口、web/desktop 座位层)对内部臂只有两种
26
+ * 合法处置:**吞**(不外泄)或**转成真 CC 帧**;顺着兜底裸透传到 stdout/wire = 病族⑥投影缺口
27
+ * (cli A-004.11/12 实翻:human_input/diagnostics/workspace_changed 曾漏进 `-p` stream-json)。
28
+ *
29
+ * 这张表是**唯一权威源**:消费方的吞/转名单必须对账本表(全覆盖,禁手抄子集——A-004.4 的病形
30
+ * 就是壳手抄了 4 词的子集);本包 pure 门有源码对账腿(armBody 铸点抽取 ≡ 本表),加臂不登记
31
+ * 即红。`turn_usage` 的铸点在 runStream.ts(usage 聚合腿),不在本文件的 switch 里,同属本表。
32
+ */
33
+ export const INTERNAL_SDK_ARM_TYPES = new Set([
34
+ 'workflow_complete',
35
+ 'tool_end_result',
36
+ 'retry_status',
37
+ 'task_progress',
38
+ 'task_notification',
39
+ 'diagnostics',
40
+ 'steering_injected',
41
+ 'workspace_changed',
42
+ 'prompt_suggestions',
43
+ 'human_input',
44
+ 'turn_usage',
45
+ ]);
22
46
  /** Wrap neutral content blocks in the CC `assistant` message envelope. */
23
47
  function assistantArm(ctx, content) {
24
48
  return stamp(ctx, armBody({
@@ -64,7 +88,7 @@ function assertNeverArm(_ev) {
64
88
  */
65
89
  export function eventToSdkMessage(ev, ctx) {
66
90
  switch (ev.type) {
67
- // ── `human_input`(core 5.14.0 design/171 / server 7.4.0 SSE,黑板 [3017]/[3020])────────────
91
+ // ── `human_input`(core 5.14.0 design/171 / server 7.4.0 SSE,[3017]/[3020])────────────
68
92
  // 🔴 **到期复核已兑现(sdk 6.9.0 提货,2026-08-08)**:本臂此前是 switch **之前**的一条 raw
69
93
  // 预分派(理由 = 它还没进 SDK 6.3.0 的 `AgentEvent` union,`case 'human_input'` 在 `ev.type`
70
94
  // 上是编译错),头注写着「在 union 里的那天就把它搬进 switch」。sdk 6.9.0 的 events.d.ts
@@ -91,9 +115,19 @@ export function eventToSdkMessage(ev, ctx) {
91
115
  if (typeof ev.runId !== 'string' || ev.runId.length === 0) {
92
116
  return dropped('malformed', 'workflow_complete');
93
117
  }
118
+ // A-004.9(病族⑤ default-arm-lie,2026-08-08):status 的**合同**是闭集 'completed'|'failed'
119
+ // (server workflow-completion-inbox.d.ts `status: "completed" | "failed"` 直证;sdk events.d.ts
120
+ // 宽成 string 只是类型面松),但 wire 是 JSON 开集——此前 `=== 'failed' ? failed : completed`
121
+ // 把任何第三词(上游未来加终态/坏帧垃圾值)**谎成 completed**。诚实形=与本臂 runId 缺失同款
122
+ // malformed 处置(dropped 留痕):第三词到达=上游换了合同,提货跟车该在这里翻红显形,而
123
+ // server 的 WorkflowStatus poll floor 对被丢的完成推送有结构性兜底(inbox 头注明写)。
124
+ if (ev.status !== 'completed' && ev.status !== 'failed') {
125
+ return dropped('malformed', 'workflow_complete');
126
+ }
94
127
  return projected(stamp(ctx, armBody({
95
128
  type: 'workflow_complete',
96
129
  runId: ev.runId,
130
+ // 卫后二值闭集,三元只在 known 词间选路(TS 不从 string 否定收窄字面量,故保留三元形)。
97
131
  status: ev.status === 'failed' ? 'failed' : 'completed',
98
132
  summary: typeof ev.summary === 'string' ? ev.summary : '',
99
133
  })));
@@ -220,7 +254,7 @@ export function eventToSdkMessage(ev, ctx) {
220
254
  ...(retryInMs !== undefined ? { retryInMs } : {}),
221
255
  ...(attempt !== undefined ? { attempt } : {}),
222
256
  ...(maxRetries !== undefined ? { maxRetries } : {}),
223
- // 🔴 §E2 lane 身份必须透传(2026-08-08 codex 二轮复审命中的**跨 lane 状态破坏**)。
257
+ // 🔴 §E2 lane 身份必须透传(2026-08-08 对抗复审二轮复审命中的**跨 lane 状态破坏**)。
224
258
  // `status` 臂本来就是 `& EventIdentity`(SDK events.d.ts),server 两腿共用的
225
259
  // `brainStatusEventData` 也经 `identityFields` 发 eventId/parentToolCallId —— 而本层此前
226
260
  // 把两键都剥掉了。后果:`arms.ts` 的 `retryStatusArm` 首行那条子代断闸
@@ -253,7 +287,7 @@ export function eventToSdkMessage(ev, ctx) {
253
287
  // `workflowRunId`/`workflowAgentLabel`(lane 归属自描述位)。此前这层 spread 白名单把两键剥掉,
254
288
  // bridge 想判 lane 也判不了(「送到了但没人读」的精确坐标其实是「没转」)。additive 透传,
255
289
  // 防御读(旧 core/server 缺席 ⇒ 形状不变)。注意 server 侧 project.ts 投影白名单在 1.272.0
256
- // 仍剥这两键(server a76bd77 才修,黑板 [1619])——真 wire 于 1.273+ 才带,此处先备好通路。
290
+ // 仍剥这两键(server a76bd77 才修,[1619])——真 wire 于 1.273+ 才带,此处先备好通路。
257
291
  const workflowRunId = ev.workflowRunId;
258
292
  const workflowAgentLabel = ev.workflowAgentLabel;
259
293
  return projected(stamp(ctx, armBody({
@@ -451,7 +485,7 @@ export function eventToSdkMessage(ev, ctx) {
451
485
  /**
452
486
  * `approval_request`(design/172 流内审批协议,server ≥7.3.0、7.5.0 起默认开)。
453
487
  *
454
- * 🔴 与上面两条**不同源**,所以单列(2026-08-08 codex 复审第 4 轮命中:首版把三条并成一句
488
+ * 🔴 与上面两条**不同源**,所以单列(2026-08-08 对抗复审第 4 轮命中:首版把三条并成一句
455
489
  * 「都由 frameRouter 消费」—— 而 `isToolApprovalFrame` 只认 tool_approval/tool_approval_complete,
456
490
  * 这条帧在**包内今天零消费口**,那句话是假的;pure 门 058⑬ 段把这个事实钉住了)。
457
491
  *
@@ -522,7 +556,7 @@ function humanInputProjection(ev, ctx) {
522
556
  ...(str(ev.issuer) !== undefined ? { issuer: str(ev.issuer) } : {}),
523
557
  ...(actor !== undefined && Object.keys(actor).length > 0 ? { actor } : {}),
524
558
  ...(str(ev.entryId) !== undefined ? { entryId: str(ev.entryId) } : {}),
525
- // 🔴 `eventId` 必须带到底(codex 复审二轮):durable 腿按 `Last-Event-ID` 续读会**重放**同一条
559
+ // 🔴 `eventId` 必须带到底(对抗复审二轮):durable 腿按 `Last-Event-ID` 续读会**重放**同一条
526
560
  // 账本帧,而本地行 id 是现铸的 —— 审计/时间线消费者若没有引擎铸的稳定键,一次人工注入会被
527
561
  // 记成多次。`inputId`/`entryId` 在公开形上都是可选的,`eventId` 是那个恒在的身份位。
528
562
  ...(str(ev.eventId) !== undefined ? { eventId: str(ev.eventId) } : {}),
@@ -261,7 +261,7 @@ export function doneToSdkResult(ev, ctx) {
261
261
  ctx.sessionId = echoedSid;
262
262
  // P1-5 — modelUsage/usage 的构造已收敛到 `flattenUsage` / `modelUsageFor`(REF-CC-055/062),
263
263
  // 四个 error 臂经 `errorResult` 信封拿到同一份,success 臂在下方直接调 —— 同一输入同一输出。
264
- // clay P0 壳半场(黑板 [450],2026-07-05):上游 4xx(如无 vision 模型收到 image)时
264
+ // clay P0 壳半场([450],2026-07-05):上游 4xx(如无 vision 模型收到 image)时
265
265
  // 引擎的 done 帧本体带 result.status='failed' + errorMessage —— 传播链没吞,断点在这:
266
266
  // 此前无条件投影 subtype:'success'/is_error:false,把失败洗成"成功空回复"= 用户看到的
267
267
  // 静默卡死。status failed → 走 SDKResultError 形态(errors[] 渲染线现成)。
@@ -118,7 +118,7 @@ function sanitizeFrameType(type) {
118
118
  * 🔴 已知限制(诚实披露):Ink 挂载后宿主会吞 console,所以 TUI 里这行未必上屏 —— 那正是
119
119
  * `EventProjection.dropped` 存在的意义:想在自己那一端把它渲出来的宿主,读返回值即可。
120
120
  *
121
- * ── [C77]① 宿主出口 `ctx.onDroppedFrame`(2026-08-02,小黑板 web-client 请托)────────────────
121
+ * ── [C77]① 宿主出口 `ctx.onDroppedFrame`(2026-08-02,协作板 web-client 请托)────────────────
122
122
  * 上一段那条「读返回值即可」只对**自己驱动投影器**的宿主成立;经 `runStream` 消费的宿主
123
123
  * (web/desktop 都是)看不到 `EventProjection`,于是丢帧对它只剩一行 stderr。装了 sink 的宿主
124
124
  * 从此收到结构化的 `{type, why}`,自己那一端想渲成告警条还是计数器随它。
@@ -75,7 +75,7 @@ export interface EmitContext {
75
75
  */
76
76
  emitChrome?(event: ChromeEvent): void | Promise<void>;
77
77
  /**
78
- * [C77]① 新增(小黑板 web-client 请托)—— **丢帧留痕的宿主出口**。runStream 的 `dropped` 臂
78
+ * [C77]① 新增(协作板 web-client 请托)—— **丢帧留痕的宿主出口**。runStream 的 `dropped` 臂
79
79
  * (引擎发了一帧、这个 build 渲不出来)此前只有包侧一行 `console.error`,宿主拿不到结构化的
80
80
  * `{type, why}`:web 想把它并进自己的 frame-warnings 面只能去 scrape stderr,而 Ink 宿主
81
81
  * 干脆把 console 吞了。形制与上面的 `emitChrome` 同款 —— **可选注入,缺席 = 该宿主不消费**
@@ -26,7 +26,7 @@
26
26
  * 能探则探:`GET /v1/capabilities` 的 **`approvals`** 位为 false ⇒ 'not-configured';
27
27
  * caps 面自己不可达 ⇒ 判别缺席,**如实回 'ok'**(绝不编造判别)。
28
28
  *
29
- * 🔴 件 3 考据(读错键的定谳,小黑板 [C33]③.3 → server [C34],server 3.13.0 已把辖域写进
29
+ * 🔴 件 3 考据(读错键的定谳,协作板 [C33]③.3 → server [C34],server 3.13.0 已把辖域写进
30
30
  * 代码注与 ARCHITECTURE):本实现此前读 `scheduler`,那是**错的键**。
31
31
  * · `/v1/assistant/*` 的挂载条件是 `checkpointStore`(server `routes/approvals-assistant.ts:67`
32
32
  * 的分支头:`if (deps.checkpointStore && (url.startsWith("/v1/approvals") ||
@@ -53,7 +53,7 @@
53
53
  * 两处逐位说明。fleet 行的 `sessionId`/`scope` 被 server `stripT` 剥掉不上 wire,别在投影里等。
54
54
  *
55
55
  * ── 📋 下一批工单(件 4 调研,不在本批实现):BackgroundRow 的 canonical stop 能力判别 ────────
56
- * 起因(小黑板 [C33]③.4):web 报「`runs.cancel` 的 id 空间是 taskId,而 fleet 顶层行 id 是 runId、
56
+ * 起因(协作板 [C33]③.4):web 报「`runs.cancel` 的 id 空间是 taskId,而 fleet 顶层行 id 是 runId、
57
57
  * 子行是复合 id」⇒ 他们对 fleet 行**不渲 Stop**(没有已挣得的取消路径就不摆按钮 —— 这个处置本身
58
58
  * 是对的,server [C34] 也同意)。主会话裁定:**不是「fleet 行没有停止路径」,而是要按行类型分**。
59
59
  * 下一批要落的形状(本批只调研落档,不新建 API):
@@ -16,8 +16,9 @@ export function backgroundStatusFromAssistant(s) {
16
16
  default: {
17
17
  const exhaustive = s; // 上游加词 ⇒ 这里编译红(闭集穷举卫兵)
18
18
  void exhaustive;
19
- // wire 开集回落:assistant.tasks 只列活跃调度行,未知新词按「活着」渲(同 workflowClient coerce 族)。
20
- return 'running';
19
+ // A-004.10:wire 开集回落改诚实形——此前未知新词按「活着」渲 'running',上游若加的是
20
+ // 终态词就是幽灵活跃行(#182 同病)。'unknown' = 不编造任何一头。
21
+ return 'unknown';
21
22
  }
22
23
  }
23
24
  }
@@ -45,9 +46,9 @@ export function backgroundStatusFromFleet(s) {
45
46
  case 'killed':
46
47
  return 'stopped';
47
48
  default: {
48
- const exhaustive = s; // 上游加词 ⇒ 编译红;wire 未知词(读侧开集)⇒ 按活跃行回落
49
+ const exhaustive = s; // 上游加词 ⇒ 编译红;wire 未知词(读侧开集)⇒ 'unknown' 诚实回落(A-004.10)
49
50
  void exhaustive;
50
- return 'running';
51
+ return 'unknown';
51
52
  }
52
53
  }
53
54
  }
@@ -117,7 +117,7 @@ export type BackgroundSource = 'assistant' | 'fleet';
117
117
  /** not-configured = assistant 无 TiDB 时的 `{tasks:[]}` 形 —— 与「真没有任务」必须可区分。 */
118
118
  export type BackgroundSourceHealth = 'ok' | 'unavailable' | 'not-configured';
119
119
  /** 第三套中性词表(不用任一方词表:3 值压不住 9 值,9 值会造 assistant 侧不存在的态)。 */
120
- export type BackgroundStatus = 'running' | 'waiting-on-human' | 'queued' | 'stopping' | 'done' | 'failed' | 'stopped';
120
+ export type BackgroundStatus = 'running' | 'waiting-on-human' | 'queued' | 'stopping' | 'done' | 'failed' | 'stopped' | 'unknown';
121
121
  export interface BackgroundRow {
122
122
  /** 带来源判别;fleet 复合 id("<runId> <taskId>")不拆 —— 裸 id union 会重复计数。 */
123
123
  readonly key: {
@@ -47,11 +47,11 @@
47
47
  * 语法(逗号分隔,大小写不敏感,允许空白):
48
48
  * · `off|0|false|no|none`(整值) ⇒ **真·全关**:literal-true 族一个不发(那一族的 off 就是
49
49
  * 删键)+ DEFAULT-ON 两键发 `false`。
50
- * 🔴 codex 复审 [medium](2026-08-07)判的真病:这一支此前直接 `return undefined`(不发字段),
50
+ * 🔴 对抗复审 [medium](2026-08-07)判的真病:这一支此前直接 `return undefined`(不发字段),
51
51
  * 而「不发字段」对 DEFAULT-ON 两键的含义**恰恰是保持开着** —— 一个叫 off 的总开关关不掉十件里
52
52
  * 的两件,且用户没有任何办法察觉。旧行为在 <1.254 的 server 上与新行为**逐字节等价**(那些
53
53
  * server 静默丢 false),在 ≥1.254 上新行为才第一次兑现这个旋钮的字面承诺。
54
- * ⚠️ **能力边界说清楚**(codex 复审二轮):本模块是**纯 env→spec 投影**,手里没有 server
54
+ * ⚠️ **能力边界说清楚**(对抗复审二轮):本模块是**纯 env→spec 投影**,手里没有 server
55
55
  * 版本/capability 这个量,所以对 <1.254 的部署它兑现不了「全关」—— 那两键仍会默认开着,而
56
56
  * 壳侧无从察觉。补这个洞的正位在**请求装配层**(按已探到的 capability 判,与 limitsWire 的
57
57
  * 两道地板同族),已记进 docs/refactor/README.md 的宿主/上游工单表。本层只保证两件:
@@ -47,11 +47,11 @@
47
47
  * 语法(逗号分隔,大小写不敏感,允许空白):
48
48
  * · `off|0|false|no|none`(整值) ⇒ **真·全关**:literal-true 族一个不发(那一族的 off 就是
49
49
  * 删键)+ DEFAULT-ON 两键发 `false`。
50
- * 🔴 codex 复审 [medium](2026-08-07)判的真病:这一支此前直接 `return undefined`(不发字段),
50
+ * 🔴 对抗复审 [medium](2026-08-07)判的真病:这一支此前直接 `return undefined`(不发字段),
51
51
  * 而「不发字段」对 DEFAULT-ON 两键的含义**恰恰是保持开着** —— 一个叫 off 的总开关关不掉十件里
52
52
  * 的两件,且用户没有任何办法察觉。旧行为在 <1.254 的 server 上与新行为**逐字节等价**(那些
53
53
  * server 静默丢 false),在 ≥1.254 上新行为才第一次兑现这个旋钮的字面承诺。
54
- * ⚠️ **能力边界说清楚**(codex 复审二轮):本模块是**纯 env→spec 投影**,手里没有 server
54
+ * ⚠️ **能力边界说清楚**(对抗复审二轮):本模块是**纯 env→spec 投影**,手里没有 server
55
55
  * 版本/capability 这个量,所以对 <1.254 的部署它兑现不了「全关」—— 那两键仍会默认开着,而
56
56
  * 壳侧无从察觉。补这个洞的正位在**请求装配层**(按已探到的 capability 判,与 limitsWire 的
57
57
  * 两道地板同族),已记进 docs/refactor/README.md 的宿主/上游工单表。本层只保证两件:
@@ -123,7 +123,7 @@ function refuse(token, why) {
123
123
  */
124
124
  export function attachmentsForRequest(env = hostEnv()) {
125
125
  const raw = (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
126
- // 总开关 off = 真·全关(见文件头注 §env 的 codex [medium] 登记),不是「不发字段」。
126
+ // 总开关 off = 真·全关(见文件头注 §env 的 复审 [medium] 登记),不是「不发字段」。
127
127
  if (envFlagOff(raw))
128
128
  return allDefaultOnOff();
129
129
  const tokens = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
@@ -8,7 +8,7 @@
8
8
  * 逐字纪律:CLASSIFIER_DENY_SIGNATURE / NOTICE_REASON_MAX(80)/ 通知行三段格式一字节不改。
9
9
  */
10
10
  /**
11
- * src/sema/classifierVerdictWire.ts — auto-mode 分类器裁决帧的壳侧消费(分类器批3 壳半场,黑板 [907])。
11
+ * src/sema/classifierVerdictWire.ts — auto-mode 分类器裁决帧的壳侧消费(分类器批3 壳半场,[907])。
12
12
  *
13
13
  * WIRE 形状(gap-check 2026-07-16 实勘,core 1.279 dist 亲核):
14
14
  * 引擎侧分类器 block(core hooks.js runToolGate)→ decision = deny + decisionReason:"classifier",
@@ -8,7 +8,7 @@
8
8
  * 逐字纪律:CLASSIFIER_DENY_SIGNATURE / NOTICE_REASON_MAX(80)/ 通知行三段格式一字节不改。
9
9
  */
10
10
  /**
11
- * src/sema/classifierVerdictWire.ts — auto-mode 分类器裁决帧的壳侧消费(分类器批3 壳半场,黑板 [907])。
11
+ * src/sema/classifierVerdictWire.ts — auto-mode 分类器裁决帧的壳侧消费(分类器批3 壳半场,[907])。
12
12
  *
13
13
  * WIRE 形状(gap-check 2026-07-16 实勘,core 1.279 dist 亲核):
14
14
  * 引擎侧分类器 block(core hooks.js runToolGate)→ decision = deny + decisionReason:"classifier",
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * 🟢 **本 overlay 默认开**(2026-07-26 翻默认;逃生口 `SEMA_GOAL_STOP_HOOK_WIRE=0/false/no/off`)。
23
23
  *
24
- * 修前默认关,理由是两条**前提**——两条都已被 server 侧行为取证**证伪**(黑板 [1721],6 条行为
24
+ * 修前默认关,理由是两条**前提**——两条都已被 server 侧行为取证**证伪**([1721],6 条行为
25
25
  * 用例已进 server 仓;cli 仓另有 scripts/run-goal-stop-hook-live-test.mjs 的真引擎+真模型复验):
26
26
  * ① 旧论断「SDK 类型 DEFERRED ⇒ 服务端会 400」**是把类型面当成了运行时校验面**,对 server
27
27
  * 不成立:`parseHooksConfig({Stop:[{hooks:[{type:"prompt",prompt}]}]})` 无 error、真解析;
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * 🟢 **本 overlay 默认开**(2026-07-26 翻默认;逃生口 `SEMA_GOAL_STOP_HOOK_WIRE=0/false/no/off`)。
23
23
  *
24
- * 修前默认关,理由是两条**前提**——两条都已被 server 侧行为取证**证伪**(黑板 [1721],6 条行为
24
+ * 修前默认关,理由是两条**前提**——两条都已被 server 侧行为取证**证伪**([1721],6 条行为
25
25
  * 用例已进 server 仓;cli 仓另有 scripts/run-goal-stop-hook-live-test.mjs 的真引擎+真模型复验):
26
26
  * ① 旧论断「SDK 类型 DEFERRED ⇒ 服务端会 400」**是把类型面当成了运行时校验面**,对 server
27
27
  * 不成立:`parseHooksConfig({Stop:[{hooks:[{type:"prompt",prompt}]}]})` 无 error、真解析;
@@ -21,7 +21,7 @@
21
21
  * · flag 来源:显式表态一律显式 stamp——wire 五词直 stamp,`default` 走 stampDefault 显式垫
22
22
  * (旧形 default 不 stamp ⇒ server 侧 `settings.permissions.defaultMode` 恒缺席 ⇒
23
23
  * `deriveSettingsPolicy` 早退返回 `{}` ⇒ **按模式派生的那套门一个不铸**,print 车道 ask 门
24
- * 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。黑板 [2713] 写的
24
+ * 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。[2713] 写的
25
25
  * 「applyTaskSettings 整跳」是那条链的简写,它成不成立还要看 body.settings 里有没有别的
26
26
  * parsed 字段 —— 那是 server 的控制流,会随 server 改版漂,别在本注释里复述第二遍,要查就去
27
27
  * 读 server task-settings.ts);壳内部词(`manual`=CC default 别名、`dontAsk`=壳侧最严
@@ -21,7 +21,7 @@
21
21
  * · flag 来源:显式表态一律显式 stamp——wire 五词直 stamp,`default` 走 stampDefault 显式垫
22
22
  * (旧形 default 不 stamp ⇒ server 侧 `settings.permissions.defaultMode` 恒缺席 ⇒
23
23
  * `deriveSettingsPolicy` 早退返回 `{}` ⇒ **按模式派生的那套门一个不铸**,print 车道 ask 门
24
- * 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。黑板 [2713] 写的
24
+ * 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。[2713] 写的
25
25
  * 「applyTaskSettings 整跳」是那条链的简写,它成不成立还要看 body.settings 里有没有别的
26
26
  * parsed 字段 —— 那是 server 的控制流,会随 server 改版漂,别在本注释里复述第二遍,要查就去
27
27
  * 读 server task-settings.ts);壳内部词(`manual`=CC default 别名、`dontAsk`=壳侧最严
@@ -42,7 +42,7 @@
42
42
  * 落账,守卫 = ①终帧唯一(本 wrapper 首终帧即 return + adapter runStream 首终帧 return + 批 B
43
43
  * 双帧守卫「恰一条 result」)②seq 锚(首帧起锁存,attempt 间绝不回放)③gap-check 记账:换道前
44
44
  * 已消费的 delta 与账本聚合 text 事件无逐字节对齐关系,真正的精确锚需要 server 给 tasks/stream
45
- * 帧发 id(引擎侧诉求,走黑板,非壳侧可解)。
45
+ * 帧发 id(引擎侧诉求,走协作板,非壳侧可解)。
46
46
  *
47
47
  * ── 账本空(现役 server sync 腿)时的续收降级(R1b)────────────────────────────────────────
48
48
  * 同一实证的另一面:detach 后 run 后台跑完,账本无事件行,runs.events 只会心跳保活直到 run row
@@ -80,7 +80,7 @@ export async function* withHeadlessR1Reconnect(live, deps) {
80
80
  const probe = deps.probeAlive ?? probeEngineAlive;
81
81
  // REF-CC-148(域词表-19):originalTearErr 在环内从不被重写(它是进入本重试环前唯一捕获的
82
82
  // 错误对象),所以这个判型是**环不变式**——算一次即可,不必逐轮重算。
83
- // wave1 回炉复审(codex blocker):求值时机必须排在铁律 3(用户中止恒先行)**之后**才对 main
83
+ // wave1 回炉复审(复审 blocker):求值时机必须排在铁律 3(用户中止恒先行)**之后**才对 main
84
84
  // 逐字——main 是「每轮入口先查 aborted,再判型」,若把判型提到循环顶(环外、抢在第一轮的
85
85
  // aborted 检查之前),当 originalTearErr 是一个 `.name` getter 会抛的畸形错误对象、且入环时
86
86
  // signal 已经 aborted 时,新顺序会先让 isSseIdleError 抛出**那个畸形对象的二次异常**,盖过
@@ -89,7 +89,7 @@ export interface ApprovalsFeedOptions {
89
89
  /** 降级后多久再试一次 stream;缺省 60_000ms。0 = 不再试(永久轮询)。 */
90
90
  streamRetryMs?: number;
91
91
  /**
92
- * [C77]② 轮询条件旋钮(小黑板 desktop 请托:那一端的现行纪律是**仅活跃 run 时轮询**)。
92
+ * [C77]② 轮询条件旋钮(协作板 desktop 请托:那一端的现行纪律是**仅活跃 run 时轮询**)。
93
93
  * 每一拍**触发时**查询一次:`false` ⇒ 跳过本拍取件,但照常排下一拍。缺省(不传)= 恒 true,
94
94
  * 行为与加旋钮之前一字不差。
95
95
  *
@@ -270,7 +270,7 @@ async function routeToolApprovalFrame(ev, ctx) {
270
270
  hostLog('debug', `liveHitlAskWire: tool_approval frame ${ev.approvalId} but no respond wire — engine self-settles (TTL deny)`);
271
271
  return { kind: 'skip' };
272
272
  }
273
- // 补验批 askq 案定谳(2026-07-23,黑板 [1534],引擎 dist 逐坐标读定):core 的 durable
273
+ // 补验批 askq 案定谳(2026-07-23,[1534],引擎 dist 逐坐标读定):core 的 durable
274
274
  // question policy 对 AskUserQuestion 出 action:"ask",本意让 durable gate park(suspended
275
275
  // → 下方 bridge 弹卡收答);但 core suspendAsk 的退位条件(safety 缺席 + onAsk 在场)
276
276
  // 把问题门也抢进了同步审批帧腿(壳为 fs 写权限三选卡开的 TOOL_APPROVAL_ENABLED)——同步帧
@@ -46,7 +46,7 @@ export interface GateLedger {
46
46
  /** 首见 ⇒ true(并记账);durable 重放的已渲 call ⇒ false。 */
47
47
  markStarted(callId: string): boolean;
48
48
  /** 🔴 存 **tool_start 当拍的 `args` 快照**而非帧引用(与拆分前 `askArgsByCall` 逐字同语义;
49
- * codex 复审确证差异 #1 的收货修)——存帧引用意味着「上游在 yield 后改写 `ev.args`」会漂进
49
+ * 对抗复审确证差异 #1 的收货修)——存帧引用意味着「上游在 yield 后改写 `ev.args`」会漂进
50
50
  * 审批 payload,且台账持帧延长了整帧生命周期。载荷仍是 UNTRUSTED unknown,台账只搬运不解释。 */
51
51
  noteGatedStart(callId: string, ev: AgentEvent): void;
52
52
  gatedStartArgs(): ReadonlyMap<string, unknown>;
@@ -56,7 +56,7 @@ export declare function surfaceRememberNotApplied(): void;
56
56
  * 「编辑并批准」带了 `updatedInput`,而 ack 回报 `updatedInputForwarded:false`(server 1.241 起
57
57
  * 诚实回显)—— 引擎拿到的是**原始**入参。
58
58
  *
59
- * 🔴 这一条比 remember 那条严重一个量级,它是本批 codex 复审判的 [high]:用户在卡上把
59
+ * 🔴 这一条比 remember 那条严重一个量级,它是本批 对抗复审判的 [high]:用户在卡上把
60
60
  * `rm -rf /tmp/x` 改成 `rm -rf /tmp/x/build` 然后按了批准,而真正执行的是他改之前那条。
61
61
  * **事后没有 fail-closed 的余地**(allow 已经送达,工具已经在跑),所以唯一诚实的处置就是立刻
62
62
  * 响亮地说出来 —— 静默(此前只写 debug 日志)等于让用户以为自己的编辑生效了。
@@ -130,7 +130,7 @@ export function surfaceRememberNotApplied() {
130
130
  * 「编辑并批准」带了 `updatedInput`,而 ack 回报 `updatedInputForwarded:false`(server 1.241 起
131
131
  * 诚实回显)—— 引擎拿到的是**原始**入参。
132
132
  *
133
- * 🔴 这一条比 remember 那条严重一个量级,它是本批 codex 复审判的 [high]:用户在卡上把
133
+ * 🔴 这一条比 remember 那条严重一个量级,它是本批 对抗复审判的 [high]:用户在卡上把
134
134
  * `rm -rf /tmp/x` 改成 `rm -rf /tmp/x/build` 然后按了批准,而真正执行的是他改之前那条。
135
135
  * **事后没有 fail-closed 的余地**(allow 已经送达,工具已经在跑),所以唯一诚实的处置就是立刻
136
136
  * 响亮地说出来 —— 静默(此前只写 debug 日志)等于让用户以为自己的编辑生效了。
@@ -264,7 +264,7 @@ export type RespondToolApprovalFn = (approvalId: string, decision: ToolApprovalR
264
264
  * 「拿到一个不好用的值」不如「诚实地什么都没有」。两个可选布尔位非布尔时**单独**降缺席
265
265
  * (它们直接决定要不要渲「本会话全放行」,透传一个 `'yes'` 字符串会让 `!== false` 这类读法说反话)。
266
266
  *
267
- * 🔴 `decision` 判到 **wire 三词闭集**而不是「是不是串」(codex 复审二轮):ack 上那两个布尔位会
267
+ * 🔴 `decision` 判到 **wire 三词闭集**而不是「是不是串」(对抗复审二轮):ack 上那两个布尔位会
268
268
  * 触发**高危安全声明**(「工具正在用原始入参跑」),所以一个 `decision:'garbage'` 的回执绝不许被
269
269
  * 当成合规 ack 放行。**相关性**(「这个 ack 是不是**这一次**审批的回执」)不在本函数判 —— 本函数
270
270
  * 只认形,对不对得上由 {@link surfaceToolApprovalFrameAndRespond} 拿着 frame 与刚发出的 decision 核。
@@ -329,7 +329,7 @@ function isToolApprovalDelegation(v) {
329
329
  if (typeof d.parentToolCallId !== 'string' || d.parentToolCallId.trim().length === 0)
330
330
  return false;
331
331
  // 深度:上游语义是「宿主直接子代 = 1」⇒ **正安全整数**。0 / 负数 / 小数都不是可渲染的层数,
332
- // 而 `Number.isFinite` 会把它们全放过(codex 复审命中:`depth: 0` / `-1` / `1.5` 曾一律判真)。
332
+ // 而 `Number.isFinite` 会把它们全放过(对抗复审命中:`depth: 0` / `-1` / `1.5` 曾一律判真)。
333
333
  if (typeof d.depth !== 'number' || !Number.isSafeInteger(d.depth) || d.depth < 1)
334
334
  return false;
335
335
  return d.agentName === undefined || typeof d.agentName === 'string';
@@ -354,7 +354,7 @@ function isRespondDecision(v) {
354
354
  * 「拿到一个不好用的值」不如「诚实地什么都没有」。两个可选布尔位非布尔时**单独**降缺席
355
355
  * (它们直接决定要不要渲「本会话全放行」,透传一个 `'yes'` 字符串会让 `!== false` 这类读法说反话)。
356
356
  *
357
- * 🔴 `decision` 判到 **wire 三词闭集**而不是「是不是串」(codex 复审二轮):ack 上那两个布尔位会
357
+ * 🔴 `decision` 判到 **wire 三词闭集**而不是「是不是串」(对抗复审二轮):ack 上那两个布尔位会
358
358
  * 触发**高危安全声明**(「工具正在用原始入参跑」),所以一个 `decision:'garbage'` 的回执绝不许被
359
359
  * 当成合规 ack 放行。**相关性**(「这个 ack 是不是**这一次**审批的回执」)不在本函数判 —— 本函数
360
360
  * 只认形,对不对得上由 {@link surfaceToolApprovalFrameAndRespond} 拿着 frame 与刚发出的 decision 核。
@@ -469,7 +469,7 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
469
469
  ...(isFromSubagent(frame) ? { workerBadge: subagentBadgeFor(frame) } : {}),
470
470
  ...(wireNote !== undefined ? { wireNote } : {}),
471
471
  ...(frame.governanceForced === true ? { governanceForced: true } : {}),
472
- // 🔴 跨字段不变量(codex 复审命中):`delegation` 只在**子代 ask** 的门上在场(SDK 头注:
472
+ // 🔴 跨字段不变量(对抗复审命中):`delegation` 只在**子代 ask** 的门上在场(SDK 头注:
473
473
  // "Present on the same door as fromSubagent (child asks only)")。只校对象形不校这一条 ⇒
474
474
  // 一个**宿主自己**的破坏性工具审批也能带着 delegation 到卡口,被呈成「某层子代发起的」——
475
475
  // 把归属这件安全展示位渲错,正是本键存在的反面。`isToolApprovalFrame` 只验 type/approvalId,
@@ -488,7 +488,7 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
488
488
  ...(signal && !signal.aborted ? { signal } : {}),
489
489
  ...(card.kind === 'allow' && card.updatedInput !== undefined ? { updatedInput: card.updatedInput } : {}),
490
490
  });
491
- // 🔴 相关性门(codex 复审二轮):ack 必须是**这一次**审批的回执 —— id 与决断词都要对上。
491
+ // 🔴 相关性门(对抗复审二轮):ack 必须是**这一次**审批的回执 —— id 与决断词都要对上。
492
492
  // 对不上的 ack(注入面串了别人的响应 / 坏 mock / raw-fetch 包装器复用了连接)如果照样被
493
493
  // 消费,一次普通审批就能弹出「你的编辑没生效、工具正在用原始入参跑」这种强安全声明。
494
494
  // 不匹配 ⇒ 整个 ack 丢弃(降成「未知」)+ 响亮留痕,绝不据此触发任何用户告警。
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @sema-agent/client-core — 客户端会话运行时(sema wire → CC 会话词汇表 + 端无关会话逻辑)。
3
- * 定位公理:黑板 [1832](CC 皮肤形状全收本包、wire 保持中性;TUI/web/桌面共用同一个包)。
3
+ * 定位公理:[1832](CC 皮肤形状全收本包、wire 保持中性;TUI/web/桌面共用同一个包)。
4
4
  * seam 设计对签:[1651]/[1652]/[1653];依赖方向:sdk(wire)+agent-types(词汇表)→ 本包,永不反向。
5
5
  * 沿革:@sema-agent/wire-cc-adapter 0.1.0 = seam 类型 + id 确定性派生 + 首批踩坑纯函数;
6
6
  * 0.1.2(#52a)= adapt() 管线首批(纯投影臂全落 + 壳态耦合臂投影成 ChromeEvent + 差分守卫);
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @sema-agent/client-core — 客户端会话运行时(sema wire → CC 会话词汇表 + 端无关会话逻辑)。
3
- * 定位公理:黑板 [1832](CC 皮肤形状全收本包、wire 保持中性;TUI/web/桌面共用同一个包)。
3
+ * 定位公理:[1832](CC 皮肤形状全收本包、wire 保持中性;TUI/web/桌面共用同一个包)。
4
4
  * seam 设计对签:[1651]/[1652]/[1653];依赖方向:sdk(wire)+agent-types(词汇表)→ 本包,永不反向。
5
5
  * 沿革:@sema-agent/wire-cc-adapter 0.1.0 = seam 类型 + id 确定性派生 + 首批踩坑纯函数;
6
6
  * 0.1.2(#52a)= adapt() 管线首批(纯投影臂全落 + 壳态耦合臂投影成 ChromeEvent + 差分守卫);
@@ -38,7 +38,7 @@
38
38
  * · 旧 server 白名单 fail-soft:server resolveSpec 逐字段白名单拼 TaskSpec,未知 body 字段静默
39
39
  * 忽略(limits wire 同款勘察结论)——本字段发了白发不炸。gap-check 实拆 server 1.210.0 dist:
40
40
  * resolveSpec(main.js:1233-)【不】读 body.interactiveTools ⇒ 需 server 半场补一行白名单,
41
- * 壳先备(黑板记账)。
41
+ * 壳先备(协作板记账)。
42
42
  */
43
43
  import { type EnvLike } from './hostEnv.js';
44
44
  /** 部署旋钮 env 键名(settings.json env 块 → 1a-envseed → process.env 同车道)。 */
@@ -38,7 +38,7 @@
38
38
  * · 旧 server 白名单 fail-soft:server resolveSpec 逐字段白名单拼 TaskSpec,未知 body 字段静默
39
39
  * 忽略(limits wire 同款勘察结论)——本字段发了白发不炸。gap-check 实拆 server 1.210.0 dist:
40
40
  * resolveSpec(main.js:1233-)【不】读 body.interactiveTools ⇒ 需 server 半场补一行白名单,
41
- * 壳先备(黑板记账)。
41
+ * 壳先备(协作板记账)。
42
42
  */
43
43
  import { hostEnv } from './hostEnv.js';
44
44
  import { envFlagOff, envFlagOn } from './envFlag.js';
@@ -2,7 +2,7 @@
2
2
  * src/limitsWire.ts — headless `-p` run-limits wire: expose the engine's TASK-LEVEL budget face on
3
3
  * the headless `-p` path via `TaskRequest.limits`.
4
4
  *
5
- * ── core 5.8.0 词表迁移(黑板 [2489],2026-08-04)────────────────────────────────────────────
5
+ * ── core 5.8.0 词表迁移([2489],2026-08-04)────────────────────────────────────────────
6
6
  * `limits` 是**唯一预算面,默认全空 = 无限制**。本模块拼的三个键都骑 5.8.0 的新词表:
7
7
  * · `maxWalltimeMs`(**毫秒**;5.7 的 `limits.timeoutSec` 已删,单位一并变)
8
8
  * · `maxTurns`
@@ -2,7 +2,7 @@
2
2
  * src/limitsWire.ts — headless `-p` run-limits wire: expose the engine's TASK-LEVEL budget face on
3
3
  * the headless `-p` path via `TaskRequest.limits`.
4
4
  *
5
- * ── core 5.8.0 词表迁移(黑板 [2489],2026-08-04)────────────────────────────────────────────
5
+ * ── core 5.8.0 词表迁移([2489],2026-08-04)────────────────────────────────────────────
6
6
  * `limits` 是**唯一预算面,默认全空 = 无限制**。本模块拼的三个键都骑 5.8.0 的新词表:
7
7
  * · `maxWalltimeMs`(**毫秒**;5.7 的 `limits.timeoutSec` 已删,单位一并变)
8
8
  * · `maxTurns`
@@ -40,7 +40,7 @@ export declare function deriveNotificationResidualLines(n: Record<string, unknow
40
40
  * 字段名映射按 wire 真形:task_id/output_file/task_type/source 是 snake/wire 名,其余同名。
41
41
  */
42
42
  export declare function normalizeTaskNotification(n: Record<string, unknown>): TaskNotificationFields | null;
43
- /** 通知去重键——cli engineTaskNotificationDedupKey **逐字等价**(codex 对抗复审抓的
43
+ /** 通知去重键——cli engineTaskNotificationDedupKey **逐字等价**(对抗复审抓的
44
44
  * 等价性破坏,0.1.1 修):无 seq 不追加段(与 seq:1 是不同键);仅 external 用
45
45
  * `external:` 前缀;seq 收 number|string。格式:`[external:]taskId:status[:seq]`。 */
46
46
  export declare function taskNotificationDedupKey(n: {
@@ -54,7 +54,7 @@ export declare function taskNotificationDedupKey(n: {
54
54
  * 的等价物(入参是引擎 `task_notification` 帧的原始 payload:snake_case `task_id` / `task_type`)。
55
55
  *
56
56
  * 🔴 **不是第二份算法**:字段归一之后直接委托给上面那一个 `taskNotificationDedupKey`。
57
- * 两份手写算法正是这条键在 0.1.1 被 codex 对抗复审抓到过的形(无 seq 追不追段的差异会让
57
+ * 两份手写算法正是这条键在 0.1.1 被 对抗复审抓到过的形(无 seq 追不追段的差异会让
58
58
  * 「重放去重」整条失效而两边代码看着都对);pure 门 B7 段对两个入口做**同键对拍**。
59
59
  *
60
60
  * 键形:`[external:]taskId:status[:seq]`。缺 `task_id` ⇒ 空 taskId 段(与 cli 逐字一致 ——
@@ -92,7 +92,7 @@ export function normalizeTaskNotification(n) {
92
92
  ...(typeof n.source === 'string' && n.source.length > 0 ? { externalSource: n.source } : {}),
93
93
  };
94
94
  }
95
- /** 通知去重键——cli engineTaskNotificationDedupKey **逐字等价**(codex 对抗复审抓的
95
+ /** 通知去重键——cli engineTaskNotificationDedupKey **逐字等价**(对抗复审抓的
96
96
  * 等价性破坏,0.1.1 修):无 seq 不追加段(与 seq:1 是不同键);仅 external 用
97
97
  * `external:` 前缀;seq 收 number|string。格式:`[external:]taskId:status[:seq]`。 */
98
98
  export function taskNotificationDedupKey(n) {
@@ -105,7 +105,7 @@ export function taskNotificationDedupKey(n) {
105
105
  * 的等价物(入参是引擎 `task_notification` 帧的原始 payload:snake_case `task_id` / `task_type`)。
106
106
  *
107
107
  * 🔴 **不是第二份算法**:字段归一之后直接委托给上面那一个 `taskNotificationDedupKey`。
108
- * 两份手写算法正是这条键在 0.1.1 被 codex 对抗复审抓到过的形(无 seq 追不追段的差异会让
108
+ * 两份手写算法正是这条键在 0.1.1 被 对抗复审抓到过的形(无 seq 追不追段的差异会让
109
109
  * 「重放去重」整条失效而两边代码看着都对);pure 门 B7 段对两个入口做**同键对拍**。
110
110
  *
111
111
  * 键形:`[external:]taskId:status[:seq]`。缺 `task_id` ⇒ 空 taskId 段(与 cli 逐字一致 ——
@@ -12,7 +12,7 @@
12
12
  * acceptEdits/bypassPermissions ⇒ loosening, coerced to default engine-side, enforced client-side). This keeps the
13
13
  * shell a thin per-turn intent projector that's identical across TOC-local / TOB-cloud / centralized-session axes.
14
14
  *
15
- * `auto`(分类器批3,黑板 [907] server 五模式表):server ≥1.209 coercePermissionMode 认 "auto"
15
+ * `auto`(分类器批3,[907] server 五模式表):server ≥1.209 coercePermissionMode 认 "auto"
16
16
  * (解释 = default 同款 fs 写 ask 门;存活 ask 由引擎侧 auto-mode 分类器先行裁决——武装 AND 门
17
17
  * RuntimeCaps.autoMode ∧ RunnerDeps.autoMode,缺一静默回 ask,fail-closed)。壳只透传意图,分类器
18
18
  * 规则/权益都在装配面,非 TaskSpec 字段。版本安全:老 server coerce 未知非空词 → "default"
@@ -12,7 +12,7 @@
12
12
  * acceptEdits/bypassPermissions ⇒ loosening, coerced to default engine-side, enforced client-side). This keeps the
13
13
  * shell a thin per-turn intent projector that's identical across TOC-local / TOB-cloud / centralized-session axes.
14
14
  *
15
- * `auto`(分类器批3,黑板 [907] server 五模式表):server ≥1.209 coercePermissionMode 认 "auto"
15
+ * `auto`(分类器批3,[907] server 五模式表):server ≥1.209 coercePermissionMode 认 "auto"
16
16
  * (解释 = default 同款 fs 写 ask 门;存活 ask 由引擎侧 auto-mode 分类器先行裁决——武装 AND 门
17
17
  * RuntimeCaps.autoMode ∧ RunnerDeps.autoMode,缺一静默回 ask,fail-closed)。壳只透传意图,分类器
18
18
  * 规则/权益都在装配面,非 TaskSpec 字段。版本安全:老 server coerce 未知非空词 → "default"
@@ -24,7 +24,7 @@
24
24
  export type RetryStatus =
25
25
  /** 等 API 响应(`reconnecting`)。**计数两位在场**:实装 core 的 reconnecting 帧与 retrying/
26
26
  * rate_limited 同形,六字段全发(`stream-engine.js` 三处 `sleepAnnouncingRetry` 逐处实测)——
27
- * 丢掉它们正好是在「用户最需要看重连进度」的那一刻把进度藏起来(2026-08-08 codex 复审命中)。 */
27
+ * 丢掉它们正好是在「用户最需要看重连进度」的那一刻把进度藏起来(2026-08-08 对抗复审命中)。 */
28
28
  {
29
29
  kind: 'stalled';
30
30
  deadline: number;
@@ -36,7 +36,7 @@ export type RetryStatus =
36
36
  attempt?: number;
37
37
  maxRetries?: number;
38
38
  /**
39
- * 🔴 **终态位**(2026-08-08 codex 复审命中):`true` ⇔ 引擎**不会再重试了**(`gave_up` 相)。
39
+ * 🔴 **终态位**(2026-08-08 对抗复审命中):`true` ⇔ 引擎**不会再重试了**(`gave_up` 相)。
40
40
  * 缺席 = 仍在重试循环里(retrying / rate_limited / circuit_open)。
41
41
  *
42
42
  * 为什么必须有这一位:`deadline` 的语义是「距下次重试」,而 gave_up 根本没有下次 —— 实装 core
package/dist/seam.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * client-core seam types — 黑板 [1651] 设计稿 v1.1 已对签形([1652] core 签/[1653] 钉版)。
2
+ * client-core seam types — [1651] 设计稿 v1.1 已对签形([1652] core 签/[1653] 钉版)。
3
3
  *
4
4
  * 平面判据(成文,[1652]):「重启后还该看得见的进 transcript,纯瞬态进 chrome。」
5
5
  * transcript id 纪律([1653] v1 定案,后改=BREAKING):优先从 wire 稳定键确定性派生
@@ -377,7 +377,7 @@ export type ChromeEvent = {
377
377
  result: unknown;
378
378
  }
379
379
  /**
380
- * FIX⑦(2026-08-07,黑板 [3017]/[3020];core 5.14.0 design/171 新 `TaskEvent` 臂,server 7.4.0
380
+ * FIX⑦(2026-08-07,[3017]/[3020];core 5.14.0 design/171 新 `TaskEvent` 臂,server 7.4.0
381
381
  * 起真上 SSE)——「**谁把什么喂进了这条 run**」的生命周期账本帧:objective / 实时 steer /
382
382
  * nextTurn / parked-steer 续跑 / wake 五个载体共用一个投影点。
383
383
  *
@@ -12,7 +12,7 @@
12
12
  * content ≤1MB — a violation is a 400, so we truncate/limit HERE to make each FIELD well-formed
13
13
  * by construction.
14
14
  *
15
- * 🔴 措辞收窄(2026-08-08 codex 复审命中):原文写「make the live request well-formed by construction」——
15
+ * 🔴 措辞收窄(2026-08-08 对抗复审命中):原文写「make the live request well-formed by construction」——
16
16
  * 那是**过头的承诺**,本模块只管每个字段的**逐字段**帽,管不到整请求。server 那边 10 项 × 1MB 与
17
17
  * 它自己 8MB 的 `MAX_BODY` 是两个互不知情的帽,所以极端技能集仍可能整请求 400/413。本层不加
18
18
  * 「按剩余预算偷偷多截一点」的聚合补偿:那恰好把一个响亮的 400 换回一次静默截断(= 本次修掉的病)。
@@ -11,7 +11,7 @@ export declare function engineTaskHandlesCapable(): boolean;
11
11
  *
12
12
  * true ⇒ 行的执行者是引擎,端写 `killed` 是一句它没证实过的断言 —— 必须 `POST …/stop` 拿到 200
13
13
  * 才翻;409 `stop.not_landed` / `stop.not_local` / `stop.parked` 一律保持原状(引擎里
14
- * 可能还在跑),下一拍由行帧/`stopped-by` 归因 settle(黑板 [1754]③)。
14
+ * 可能还在跑),下一拍由行帧/`stopped-by` 归因 settle([1754]③)。
15
15
  * false ⇒ 行跑在本进程(CC 逐字形态),`abortController.abort()` 就是执行本身,端写 `killed`
16
16
  * 按构造恒真 ⇒ 同步翻,与 CC 2.1.220 `UPd`(pretty220.js:507299)一字不差。
17
17
  */
@@ -45,7 +45,7 @@ export function engineTaskHandlesCapable() {
45
45
  *
46
46
  * true ⇒ 行的执行者是引擎,端写 `killed` 是一句它没证实过的断言 —— 必须 `POST …/stop` 拿到 200
47
47
  * 才翻;409 `stop.not_landed` / `stop.not_local` / `stop.parked` 一律保持原状(引擎里
48
- * 可能还在跑),下一拍由行帧/`stopped-by` 归因 settle(黑板 [1754]③)。
48
+ * 可能还在跑),下一拍由行帧/`stopped-by` 归因 settle([1754]③)。
49
49
  * false ⇒ 行跑在本进程(CC 逐字形态),`abortController.abort()` 就是执行本身,端写 `killed`
50
50
  * 按构造恒真 ⇒ 同步翻,与 CC 2.1.220 `UPd`(pretty220.js:507299)一字不差。
51
51
  */
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * 读面游标语义([1501]§一 + [1505] must-fix 修正,UI 必须按此做):是否「读即消费」取决于句柄
23
23
  * 形态——spooled 腿全量可重读、GET 幂等;cursor-only 腿每次 GET 只出新字节、读走就没了。
24
- * 两形判别用 **wire 契约自带标记**(server [1505] 钉版承诺稳定,变更走 CHANGELOG+黑板;core
24
+ * 两形判别用 **wire 契约自带标记**(server [1505] 钉版承诺稳定,变更走 CHANGELOG+协作板;core
25
25
  * CC-verbatim 固定形):content 含 `--- stdout (full, re-readable) ---` = spool 全量形 → 整体
26
26
  * 替换;含 `--- new stdout ---` = cursor 增量形 → append。初版的「前缀延展」启发式被 [1505]
27
27
  * 否决——spool content 首行 `status: <displayStatus>` 在任务完成时刻从 running 翻 exited,
@@ -44,7 +44,7 @@ export declare const PROTOCOL_MARKERS: {
44
44
  * [1505] spool 标记判别(REF-CC-域词表-06 提单源):判「读游标该整体替换还是追加」这一件事,
45
45
  * 唯一真源在此——`engineTaskHandleWire.ts` 的 `mergeTaskOutput` 消费它,此前是各写一份
46
46
  * `.includes()` 的独立判读,现在改成两处调用同一个函数,不再靠两份手抄字面量碰巧对齐。
47
- * ⚠️ 措辞收窄(opus/codex 复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
47
+ * ⚠️ 措辞收窄(opus/对抗复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
48
48
  * 单源"——`parseModelFacingTaskOutput` 里的 `taskOutputStdoutLine` 是解**另一件事**(T13
49
49
  * TaskOutput 模型面正文里 stdout 段的边界在哪),两者字面量近似但语义不同、输入来源也不同
50
50
  * (读游标累积 vs 单次模型面文本反解),存在能让两者给出不同答案的输入(如带前导垃圾字节的
@@ -69,12 +69,12 @@ export declare function stripUntrustedFence(text: string): {
69
69
  /**
70
70
  * T13 回落解析结果(REF-CC-TYPESHAPE-14:命名 discriminated union —— 此前是 4 成员内联匿名形,
71
71
  * 三个构造点各自手写、`'unknown'` 分支「没有 output」原来只是注释里的一句话,现在类型强制)。
72
- * 🔴 抽 DU **不改运行时形**(二次回炉,codex #4):`taskId`/`status` 缺值时**键照样在、值是
72
+ * 🔴 抽 DU **不改运行时形**(二次回炉,复审 #4):`taskId`/`status` 缺值时**键照样在、值是
73
73
  * `undefined`**(与 main 逐字节一致)——本函数是 npm 公面导出,`Object.keys()` / `'taskId' in r` /
74
74
  * JSON 序列化都是下游看得见的契约,类型重构无权改它。eopt 收官(E-seat 卡裁定):「公面键恒在」
75
75
  * 形不许被本批翻回条件展开——三键改 `| undefined` 显式并集,继续如实描述「键恒在、值可能 undefined」
76
76
  * 这个已裁定的公面契约(不是收窄成条件展开,那会静默改变 `Object.keys()` 的下游可见形)。
77
- * 常驻钉见 `run-client-core-pure-test.mjs` ⑪ 段「公面形(codex #4 回卷钉)」三条。
77
+ * 常驻钉见 `run-client-core-pure-test.mjs` ⑪ 段「公面形(复审 #4 回卷钉)」三条。
78
78
  */
79
79
  export type ModelFacingTaskOutput = {
80
80
  kind: 'bash';
@@ -95,6 +95,13 @@ export const STRUCTURED_DETAIL_TYPES = new Set([
95
95
  'agent-transcript',
96
96
  'a2a',
97
97
  'document',
98
+ // ── core 5.20.0 跟车两词(A-004.5,2026-08-08;engine-vocab 等值门对 5.20.0 实装物直证)──────
99
+ // 本条的病根不在词表本身,在**对账物**:门锚的是本仓 devDep core,而 devDep 停在 5.10.0 ⇒
100
+ // 生态已 5.17.0+(ask-question 已实发)门仍恒绿。修 = devDep 升 5.20.0(门自然翻红显出全部
101
+ // 漂移)+ 补词。`ask-question` = AskUserQuestion 卡;`bash_invalid_timeout` 与
102
+ // `path_not_in_root`/`readonly_out_of_root` 同族(参数拒绝的结构化错误卡)。
103
+ 'ask-question',
104
+ 'bash_invalid_timeout',
98
105
  ]);
99
106
  // 🔴 同批**删三词**(core 5.10.0 BREAKING「幽灵卡」清仓):`multiedit` / `memory-saved` /
100
107
  // `memory-recall` —— 全树零铸点(MultiEdit/批量重放铸的是 `type:"edit"` 带 `edits[]`;core
@@ -163,7 +170,7 @@ export const PROTOCOL_MARKERS = {
163
170
  * [1505] spool 标记判别(REF-CC-域词表-06 提单源):判「读游标该整体替换还是追加」这一件事,
164
171
  * 唯一真源在此——`engineTaskHandleWire.ts` 的 `mergeTaskOutput` 消费它,此前是各写一份
165
172
  * `.includes()` 的独立判读,现在改成两处调用同一个函数,不再靠两份手抄字面量碰巧对齐。
166
- * ⚠️ 措辞收窄(opus/codex 复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
173
+ * ⚠️ 措辞收窄(opus/对抗复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
167
174
  * 单源"——`parseModelFacingTaskOutput` 里的 `taskOutputStdoutLine` 是解**另一件事**(T13
168
175
  * TaskOutput 模型面正文里 stdout 段的边界在哪),两者字面量近似但语义不同、输入来源也不同
169
176
  * (读游标累积 vs 单次模型面文本反解),存在能让两者给出不同答案的输入(如带前导垃圾字节的
@@ -24,9 +24,9 @@
24
24
  export declare function rowIdTail(id: string): string;
25
25
  /** core 1.356 BCE 合成 workflow-agent id 形:wa+16hex(判据①)。
26
26
  * 真实 fleet 子行 id 是 `${runId} ${engineTaskId}` 复合形——必须取空白分隔尾段再匹配
27
- * (cli footerRowBelt 原版语义;codex 对抗复审抓的等价性破坏,0.1.1 修)。
27
+ * (cli footerRowBelt 原版语义;对抗复审抓的等价性破坏,0.1.1 修)。
28
28
  * upstreamBridge 的 task_progress 前台 lane 门在 wire 无 workflowRunId 时(server <a76bd77,
29
- * 黑板 [1619]:1.272.0 投影白名单仍剥该键)以此为次级判别——与 belt 双判据同模板。 */
29
+ * [1619]:1.272.0 投影白名单仍剥该键)以此为次级判别——与 belt 双判据同模板。 */
30
30
  export declare function isWorkflowAgentTaskId(taskId: string): boolean;
31
31
  export declare function recordWorkflowAgentTaskId(taskId: string): void;
32
32
  export declare function isKnownWorkflowAgentTaskId(taskId: string): boolean;
package/dist/workflow.js CHANGED
@@ -26,9 +26,9 @@ export function rowIdTail(id) {
26
26
  }
27
27
  /** core 1.356 BCE 合成 workflow-agent id 形:wa+16hex(判据①)。
28
28
  * 真实 fleet 子行 id 是 `${runId} ${engineTaskId}` 复合形——必须取空白分隔尾段再匹配
29
- * (cli footerRowBelt 原版语义;codex 对抗复审抓的等价性破坏,0.1.1 修)。
29
+ * (cli footerRowBelt 原版语义;对抗复审抓的等价性破坏,0.1.1 修)。
30
30
  * upstreamBridge 的 task_progress 前台 lane 门在 wire 无 workflowRunId 时(server <a76bd77,
31
- * 黑板 [1619]:1.272.0 投影白名单仍剥该键)以此为次级判别——与 belt 双判据同模板。 */
31
+ * [1619]:1.272.0 投影白名单仍剥该键)以此为次级判别——与 belt 双判据同模板。 */
32
32
  export function isWorkflowAgentTaskId(taskId) {
33
33
  return /^wa[0-9a-f]{16}$/.test(rowIdTail(taskId));
34
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/client-core",
3
- "version": "0.22.0",
3
+ "version": "0.23.1",
4
4
  "description": "Client-side session runtime shared by every sema human client (TUI / web / desktop): sema wire frames (AgentEvent) -> CC session vocabulary (SDKMessage) with dual-plane output (transcript/chrome), deterministic transcript ids, lane discipline as a type, and the notification/dedup ledgers. Every CC-skin shape is collected here so the wire itself stays neutral. Blackboard [1832] design axioms; [1651]/[1652]/[1653] signed seam design. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "devDependencies": {
34
34
  "@sema-agent/agent-types": "^0.2.0",
35
- "@sema-agent/core": "^5.10.0",
35
+ "@sema-agent/core": "^5.20.0",
36
36
  "@sema-agent/sdk": "^6.9.0",
37
37
  "esbuild": "^0.27.4",
38
38
  "typescript": "^6.0.2"