@sema-agent/client-core 0.64.2 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +11 -3
  3. package/dist/adapt/arms.js +125 -7
  4. package/dist/adapt/ids.d.ts +22 -0
  5. package/dist/adapt/ids.js +29 -0
  6. package/dist/adapt/panelTasks.d.ts +22 -0
  7. package/dist/adapt/panelTasks.js +45 -0
  8. package/dist/adapt/textStream.js +6 -3
  9. package/dist/adapt.d.ts +1 -1
  10. package/dist/adapt.js +3 -0
  11. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -10
  12. package/dist/adapter/downstream/eventToSdkMessage.js +207 -65
  13. package/dist/adapter/downstream/terminalToSdkResult.d.ts +4 -4
  14. package/dist/adapter/downstream/terminalToSdkResult.js +43 -12
  15. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +23 -2
  16. package/dist/adapter/downstream/turnUsageToModelUsage.js +7 -1
  17. package/dist/adapter/runStream.js +39 -2
  18. package/dist/adapter/types.d.ts +12 -0
  19. package/dist/autoModeUnavailable.d.ts +39 -83
  20. package/dist/autoModeUnavailable.js +58 -111
  21. package/dist/classifierStatus.d.ts +25 -71
  22. package/dist/classifierStatus.js +110 -105
  23. package/dist/decideReceipt.d.ts +117 -0
  24. package/dist/decideReceipt.js +142 -0
  25. package/dist/engineErrorCodes.d.ts +32 -0
  26. package/dist/engineErrorCodes.js +42 -0
  27. package/dist/fleet/fleetProjection.d.ts +24 -1
  28. package/dist/fleet/fleetProjection.js +26 -1
  29. package/dist/fleetAgentPanelProjection.js +6 -1
  30. package/dist/gateVocabulary.d.ts +9 -1
  31. package/dist/gateVocabulary.js +46 -4
  32. package/dist/hitl/askGateWire.js +22 -1
  33. package/dist/hitl/gateLedger.d.ts +24 -0
  34. package/dist/hitl/gateLedger.js +8 -0
  35. package/dist/hitl/hitlBridge.js +14 -2
  36. package/dist/hitl/parkResolver.d.ts +23 -2
  37. package/dist/hitl/parkResolver.js +34 -6
  38. package/dist/hitl/toolApprovalWire.d.ts +12 -1
  39. package/dist/hitl/toolApprovalWire.js +15 -6
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.js +16 -6
  42. package/dist/notifications.js +11 -2
  43. package/dist/runTerminal.d.ts +48 -0
  44. package/dist/runTerminal.js +59 -0
  45. package/dist/seam.d.ts +131 -1
  46. package/dist/seam.js +22 -0
  47. package/docs/INTEGRATION-CLIENTS.md +673 -63
  48. package/package.json +2 -2
@@ -19,11 +19,11 @@
19
19
 
20
20
  | 项 | 值 | 真源 |
21
21
  |---|---|---|
22
- | 本包 | `@sema-agent/client-core` **0.64.1**(= npm 最新;`package.json` `version` 未动)。**工作树另有一批未发内容** = **0.64.2**(server 7.69.0 提货批的包侧**六件**:四件 additive —— `ApprovalCardRequest.classifierUnavailable` 两腿投影 / `mcpConfigToSpec` 透明键 `toolFaces` 透传 / `readDenialLimitFallback` 上公面 / durable park 行两位对偶;外加**一条行为面订正**(`classifierUnavailableOf` 不再吞未知成因词)与**一处同形存量族扫**(`cloudMcpToSpecs` 同样透传),详见 §29),进 `CHANGELOG.md` `## 0.64.2(未发布)` 段;bump 与冻结账两阶段由发包批做,本内容批**不 bump** | `package.json` `version` |
22
+ | 本包 | `@sema-agent/client-core` **0.65.0**(本批发布版;内容批 = 两车合并 commit 79610d7:① 投影臂族归层修 B-071 / B-072 / B-073 / B-074 / L-215③ ② 接入审计 B 战役包侧四件 B-070 / B-078 / L-215①② / B-080;🔴 本版有 BREAKING = 熔断族公面 clean-cut(`AUTO_MODE_BREAKER_CAUSES` / `classifierBreakerOf` / `ClassifierBreakerView` / `autoMode.breaker` / `breaker_open`),其余 additive;逐件见 §30a–§30n,`CHANGELOG.md` `## 0.65.0(2026-09-11)`;bump 与冻结账两阶段由发包批做) | `package.json` `version` |
23
23
  | peer:wire 契约 | `@sema-agent/sdk` **>=8.4.0**(value-level,非 type-only;**0.60.0 抬版**,四条硬理由见 §24a 与 `scripts/run-sdk-floor-test.mjs` 的 `FLOOR` 注;上一次是 0.59.0 的 `>=8.3.0`)。🔴 支持窗同批收到 **engine ≥7.64.0**:sdk 8.4.0 与 7.63.0 及以前的 wire **不同窗** | `package.json` `peerDependencies` |
24
24
  | peer:会话词汇表 | `@sema-agent/agent-types` **>=0.2.0**(type-only,零运行时) | 同上 |
25
25
  | runtime dep | `diff` ^9.0.0(**唯一**一条;portability 门按**等值**钉死) | `package.json` `dependencies` |
26
- | 公开导出面 | **919** 个运行期符号(+ 44 个测试钩;= 工作树当下的值 = **0.64.2 一件 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`/`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.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
+ | 公开导出面 | **928** 个运行期符号(+ 44 个测试钩;= 工作树当下的值 = **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`/`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.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
 
@@ -111,7 +111,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
111
111
 
112
112
  ## §2 公共导出面地图(按域)
113
113
 
114
- > 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**919** 项)。
114
+ > 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**928** 项)。
115
115
  > 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
116
116
  > **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
117
117
  > 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
@@ -135,18 +135,18 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
135
135
  `WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
136
136
  **4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
137
137
 
138
- 919 项的内部构成(帮助端估读表大小):**278** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
138
+ 928 项的内部构成(帮助端估读表大小):**283** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
139
139
  (矩阵、键集、env 名、锚串)而非可调用物;**5** 项是 PascalCase 运行期值
140
140
  (`ControlRouter` / `ControlSafetyError` / `HitlBridge` / `HitlSafetyError` / `DecideTransportRetryExhaustedError`);
141
141
  **41** 项是 `*For(sessionKey, …)` 的 per-session 变体(§6;其中 `engineNamespaceKeyFor` 是命名巧合 —— 参数是 baseUrl 不是 sessionKey,见域 14)。
142
142
 
143
- ### 2b. 域图(16 域,逐域计数之和 = 919)
143
+ ### 2b. 域图(16 域,逐域计数之和 = 928)
144
144
 
145
145
  | # | 域 | 名数 | 承重导出 | 用途 | 实现锚 |
146
146
  |---|---|---|---|---|---|
147
- | 1 | **适配内核(下行主链)** | 39 | `adapt` · `createWireToCcAdapter` · `runStream` · `eventToSdkMessage` · `terminalToSdkResult` · `turnUsageToModelUsage` · `isRunStreamActive` · `ADAPTER_DIVERGENCES` · `readRunTerminal` / `runTerminalCode` / `runTerminalGateKind` / `runTerminalGateToolName` / `isReviewPark` / `REVIEW_PARK_GATE_KINDS`(0.60.0 / engine ≥7.64.0:一次 run **怎么结束的**唯一读器 —— 终局从八个平面键换成一条带标因由 `terminal`,四臂 + `unknown` 防御臂 + `plane` 两代字节标;🔴 不认识的终态词绝不折成成功、本包不提供「因由→五词 status」的兼容投影,详见 §24b)| 引擎 SSE `AgentEvent` → 端要渲的**双面输出**:transcript(`SDKMessage`)+ chrome(瞬态 `ChromeEvent`)。**本包存在的理由** | `src/adapt.ts`、`src/adapt/{arms,wireShapes,panelTasks}.ts`(经 `adapt.ts` 再导出)、`src/adapter/runStream.ts`、`src/adapter/downstream/*`、`src/adapter/types.ts`、`src/runTerminal.ts` |
147
+ | 1 | **适配内核(下行主链)** | 43 | `adapt` · `createWireToCcAdapter` · `runStream` · `eventToSdkMessage` · `terminalToSdkResult` · `TERMINAL_NOT_SUCCESS_STATUSES`/`isTerminalNotSuccess`/`TERMINAL_STATUSES`/`isTerminalStatus`(L-215② 终局词汇的**单铸谓词** —— `blocked` 是 agent 自报终态,`suspended`/`needs_review` 刻意不在表里,详见 §30j) · `turnUsageToModelUsage` · `isRunStreamActive` · `ADAPTER_DIVERGENCES` · `readRunTerminal` / `runTerminalCode` / `runTerminalGateKind` / `runTerminalGateToolName` / `isReviewPark` / `REVIEW_PARK_GATE_KINDS`(0.60.0 / engine ≥7.64.0:一次 run **怎么结束的**唯一读器 —— 终局从八个平面键换成一条带标因由 `terminal`,四臂 + `unknown` 防御臂 + `plane` 两代字节标;🔴 不认识的终态词绝不折成成功、本包不提供「因由→五词 status」的兼容投影,详见 §24b)| 引擎 SSE `AgentEvent` → 端要渲的**双面输出**:transcript(`SDKMessage`)+ chrome(瞬态 `ChromeEvent`)。**本包存在的理由** | `src/adapt.ts`、`src/adapt/{arms,wireShapes,panelTasks}.ts`(经 `adapt.ts` 再导出)、`src/adapter/runStream.ts`、`src/adapter/downstream/*`、`src/adapter/types.ts`、`src/runTerminal.ts` |
148
148
  | 2 | **seam 公共契约** | 2(其余为 type-only) | `CHROME_ARMS` · `deriveTranscriptId` | 公共词汇 + **id 确定性不变量**(同一条流重放 ⇒ 同一串 id)。`CHROME_ARMS` = 端「我要消费哪些 chrome 臂」的对照清单 | `src/seam.ts` |
149
- | 3 | **HITL 决断卡链**(§4/§5 主战场) | 166 | `makeHitlCanUseTool` · `HitlBridge` · `findPendingForTask` · `HitlSafetyError` · `bridgeAskUserQuestionGates` · `surfaceToolApprovalFrameAndRespond` / `surfaceFsApprovalAndDecide` · `readToolApprovalRespondAck` · `installApprovalCardPort(For)` · `installHitlHostSurface(For)` · `armPlanReviewApproval` · `reopenPlanReviewCard` · `decidePlanReview` · `startApprovalsFeed` · `pendingRowIsOwnedByThisSession` · `approvalCallKey`/`liveFrameCallKey`/`planReviewQuestionId` · `registerArmedGateFor`/`wasGateArmedFor`/`clearArmedGateFor` · `waitForGateArmed(For)`/`onGateArmed(For)`/`gateArmedWaitMs`(#244 F1 呈现回执事件源) · `planReviewArmedKey(For)`/`notePlanReviewAnswered(For)`/`notePlanReviewAnsweredIfDecisive(For)`(A-024.4 plan 呈现分代) · `toolEndOutputText` · `isAskTool` · `waitForParkRowBirth` · `classifyAskParkRows` / `askParkRowArm` / `classifyAskParkChainFailure` · `readDecisionNoteAudit` / `decisionNoteAuditLine` · `resumeRunningOptions` / `resumeChoiceFromLabels` · `persistedRulesLaneAvailable`/`persistedRulesGovernanceAvailable` · `classifyRulesFailure` · `listAllPersistedRules` · `classifySkippedReason` · `readRulePersistOutcome`(#244 F2:persist-ack 读口与 `readToolApprovalRespondAck` 合成一处) · `parseLocalAllowRule`(durable 腿本地落规则窄化骨架,谓词经 `LocalAllowRuleDeps` 注入) · `readToolApprovalRespondRefusal`(#225 件5,0.42.0:respond 抛错的结构化原文读口 —— 三位各自防御读、各自缺席不铸、**三位皆缺席时整只返 `undefined`**;原样交还零加工,UNTRUSTED-for-display)· `installEditedRuleTextPrechecker` / `hasEditedRuleTextPrechecker` / `precheckEditedRuleText`([5076] 转出口,0.42.0:core 5.57.0 `precheckEditedRuleText` 的**端口注入形** —— 类型面 + 注入口 + 诚实缺席读口。🔴 **不是** value 级 re-export,理由见 §7 缺口 **P-34**;未装 ⇒ 返 `undefined`,绝不编一个 `{ok:true}`)· `surfaceRuleArmNotSent` / `RULE_NOT_SENT_WARN_TEXT` + `surfaceRuleArmRejected` / `RULE_NOT_SENT_REJECTED_WARN_TEXT`(#334,0.43.0:人在卡上按下的「不再询问」被整条丢弃时的诚实告知——**两条刻意分开**:前者=**引擎能力位未确认**(换台引擎/等探测就好),后者=**这次选择没过包内表核/互斥核**(表外文本/坏下标/两臂同场,换引擎也不会变) —— 编辑臂 `respondFreeFormRules` 与批臂 `respondBatchRuleOffers` 两条同形存量共用一条,与 `surfaceRememberNotApplied` 同族纪律:决断照送、只是规则没存,静默丢掉用户明确意图 = 让人以为功能坏了)· `projectCrashConverged`(L-38,0.49.0:`/v1/approvals` additive 键 `crashConverged` 的分桶投影 —— 崩溃收敛的孤儿审批读面,**缺席 ≠ 空数组**、分桶恰一个合取、坏行丢弃并计数,详见 §12;同批把 `ApprovalsResourceLike.list()` 的返回位 additive 放宽成 `ApprovalsListEnvelope`,老形 `{pending}` 仍可赋值)· `readRuleOffers` / `readRuleOfferSupply`(L-103/[C228],0.57.0 additive 导出:「不再询问」候选两代 wire 键的窄读器**公面化** —— 此前只经卡端口出包,不走卡端口架构的宿主只能自己重铸一把,而它承载的是兑付安全判据(原始下标不前移/逐条丢坏/闭集 kind/两代取舍序),详见 §20)· `RULE_OFFERS_ABSENCE_REASONS` / `DENIAL_LIMIT_KINDS`(0.59.0 / sdk 8.3.0 提货:`ruleOffersAbsence` 三词与 `denialLimitFallback.limit` 二词的**运行期**闭词表再导出 —— 与 0.58.0 那三张同一条纪律:端拿它做判定别再手抄字面量。⚠️ **本包自己不拿这两张表做窄读判定**(两处都按开集透传,词表属主是 core、server 已按闭集拒过),再导出只是给端的 `switch` 一份可数的表,端仍必须带 `default` 臂,详见 §23a)· `DecideTransportRetryExhaustedError`(Inkglow-1085 P0a:decide 出站瞬断重试耗尽的 typed 判别 —— HitlBridge 内建单次退避重试,耗尽走重呈臂不判死 turn;端一般只消费行为,不需要 instanceof) · `gateOutcomeOf` / `isDeniedGate` / `gateDeniedBy` / `gateApprover` / `isApprovalWindowExpiredGate` / `isDenialLimitAutoDeniedGate` / `isParkSlaExpiredGate` / `isHumanSettledGate`(0.60.0 / engine ≥7.64.0:`tool_end.gate` 整条门记录的窄读器 + 判定谓词 —— 取代退役的四个正交词 `settledBy`/`resolution`/`autoDenied`/`approver`。🔴 **判定归包**:「是不是审批窗自己走完的拒绝」旧形上是端各自拼的两键合取,而三条窗词现在分得开、合并读回去等于把刚修好的判别力扔掉;⚠️ 公面型一律带 `View` 后缀 —— 本文件的 `GateOutcome`(决断腿结局)与 sdk 的 `GateOutcome`(引擎门记录)**同名不同义**,详见 §24c)· `isGateParkedToolEnd`(「这次调用没在这里结算」的**第二形**谓词:gate 缺席 + `errorCode:"gate.parked"`;端判这件事必须与 `isApprovalWindowExpiredGate` **两形合读**) · `readWireErrorCode`(B-037 候包件②:decide/取件失败上引擎 wire 机器码的单源读口,结构视图读不 `instanceof`;与本包铸的 `code` 是两个命名空间,详见 §24g)| suspended→decide→resume 环。🔴 **D-1 两元组 verbatim 回显**是字节级断言的安全不变量,端**不许重实现它的任何一段**。🔴 键空间边界(web [C1] d3 拦截):`gateIdentity` 四常量两函数只覆盖 HITL questionId/callKey 空间;seat 的 `TOOL_PERMISSION_REQUEST_ID_DOMAINS`(`plan:` 等)是另一键空间,**两者绝不合并**(合并=座位校验器静默拒全部 plan-review 卡) | `src/hitl/hitlBridge.ts`、`toolApprovalWire.ts`、`askGateWire.ts`、`planReviewWire.ts`、`hitlHostSurface.ts`、`gateIdentity.ts`、`armedGateRegistry.ts`、`parkOwnership.ts`、`parkResolver.ts`、`approvalsFeed.ts`、`frameRouter.ts`(**只挑名导出** `toolEndOutputText`/`ENGINE_ABORT_TOOL_RESULT`/`isAskTool`/`HITL_REJECT_MESSAGE`/`HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE`)、`parkRowBirthWait.ts`、`approvalDecisionNoteAudit.ts`、`askParkRowRouting.ts`、`resumeRunningCard.ts`(#265 上收的判定层)、`persistedRulesWire.ts`、`localAllowRule.ts`(#244 F2 规则侧)、`crashConverged.ts`(L-38 崩溃收敛读面)、`src/gateOutcome.ts` |
149
+ | 3 | **HITL 决断卡链**(§4/§5 主战场) | 167 | `makeHitlCanUseTool` · `HitlBridge` · `findPendingForTask` · `readDecideReceipt`/`decideAcceptedNotResolved`/`decideRefusalFromError`(B-070:`/decide` 200 = **投递受理**不是「门已解决」;`executionOutcome` 缺席 = 未知,详见 §30h) · `HitlSafetyError` · `bridgeAskUserQuestionGates` · `surfaceToolApprovalFrameAndRespond` / `surfaceFsApprovalAndDecide` · `readToolApprovalRespondAck` · `installApprovalCardPort(For)` · `installHitlHostSurface(For)` · `armPlanReviewApproval` · `reopenPlanReviewCard` · `decidePlanReview` · `startApprovalsFeed` · `pendingRowIsOwnedByThisSession` · `approvalCallKey`/`liveFrameCallKey`/`planReviewQuestionId` · `registerArmedGateFor`/`wasGateArmedFor`/`clearArmedGateFor` · `waitForGateArmed(For)`/`onGateArmed(For)`/`gateArmedWaitMs`(#244 F1 呈现回执事件源) · `planReviewArmedKey(For)`/`notePlanReviewAnswered(For)`/`notePlanReviewAnsweredIfDecisive(For)`(A-024.4 plan 呈现分代) · `toolEndOutputText` · `isAskTool` · `waitForParkRowBirth` · `classifyAskParkRows` / `askParkRowArm` / `classifyAskParkChainFailure` · `readDecisionNoteAudit` / `decisionNoteAuditLine` · `resumeRunningOptions` / `resumeChoiceFromLabels` · `persistedRulesLaneAvailable`/`persistedRulesGovernanceAvailable` · `classifyRulesFailure` · `listAllPersistedRules` · `classifySkippedReason` · `readRulePersistOutcome`(#244 F2:persist-ack 读口与 `readToolApprovalRespondAck` 合成一处) · `parseLocalAllowRule`(durable 腿本地落规则窄化骨架,谓词经 `LocalAllowRuleDeps` 注入) · `readToolApprovalRespondRefusal`(#225 件5,0.42.0:respond 抛错的结构化原文读口 —— 三位各自防御读、各自缺席不铸、**三位皆缺席时整只返 `undefined`**;原样交还零加工,UNTRUSTED-for-display)· `installEditedRuleTextPrechecker` / `hasEditedRuleTextPrechecker` / `precheckEditedRuleText`([5076] 转出口,0.42.0:core 5.57.0 `precheckEditedRuleText` 的**端口注入形** —— 类型面 + 注入口 + 诚实缺席读口。🔴 **不是** value 级 re-export,理由见 §7 缺口 **P-34**;未装 ⇒ 返 `undefined`,绝不编一个 `{ok:true}`)· `surfaceRuleArmNotSent` / `RULE_NOT_SENT_WARN_TEXT` + `surfaceRuleArmRejected` / `RULE_NOT_SENT_REJECTED_WARN_TEXT`(#334,0.43.0:人在卡上按下的「不再询问」被整条丢弃时的诚实告知——**两条刻意分开**:前者=**引擎能力位未确认**(换台引擎/等探测就好),后者=**这次选择没过包内表核/互斥核**(表外文本/坏下标/两臂同场,换引擎也不会变) —— 编辑臂 `respondFreeFormRules` 与批臂 `respondBatchRuleOffers` 两条同形存量共用一条,与 `surfaceRememberNotApplied` 同族纪律:决断照送、只是规则没存,静默丢掉用户明确意图 = 让人以为功能坏了)· `projectCrashConverged`(L-38,0.49.0:`/v1/approvals` additive 键 `crashConverged` 的分桶投影 —— 崩溃收敛的孤儿审批读面,**缺席 ≠ 空数组**、分桶恰一个合取、坏行丢弃并计数,详见 §12;同批把 `ApprovalsResourceLike.list()` 的返回位 additive 放宽成 `ApprovalsListEnvelope`,老形 `{pending}` 仍可赋值)· `readRuleOffers` / `readRuleOfferSupply`(L-103/[C228],0.57.0 additive 导出:「不再询问」候选两代 wire 键的窄读器**公面化** —— 此前只经卡端口出包,不走卡端口架构的宿主只能自己重铸一把,而它承载的是兑付安全判据(原始下标不前移/逐条丢坏/闭集 kind/两代取舍序),详见 §20)· `RULE_OFFERS_ABSENCE_REASONS` / `DENIAL_LIMIT_KINDS`(0.59.0 / sdk 8.3.0 提货:`ruleOffersAbsence` 三词与 `denialLimitFallback.limit` 二词的**运行期**闭词表再导出 —— 与 0.58.0 那三张同一条纪律:端拿它做判定别再手抄字面量。⚠️ **本包自己不拿这两张表做窄读判定**(两处都按开集透传,词表属主是 core、server 已按闭集拒过),再导出只是给端的 `switch` 一份可数的表,端仍必须带 `default` 臂,详见 §23a)· `DecideTransportRetryExhaustedError`(Inkglow-1085 P0a:decide 出站瞬断重试耗尽的 typed 判别 —— HitlBridge 内建单次退避重试,耗尽走重呈臂不判死 turn;端一般只消费行为,不需要 instanceof) · `gateOutcomeOf` / `isDeniedGate` / `gateDeniedBy` / `gateApprover` / `isApprovalWindowExpiredGate` / `isDenialLimitAutoDeniedGate` / `isParkSlaExpiredGate` / `isHumanSettledGate`(0.60.0 / engine ≥7.64.0:`tool_end.gate` 整条门记录的窄读器 + 判定谓词 —— 取代退役的四个正交词 `settledBy`/`resolution`/`autoDenied`/`approver`。🔴 **判定归包**:「是不是审批窗自己走完的拒绝」旧形上是端各自拼的两键合取,而三条窗词现在分得开、合并读回去等于把刚修好的判别力扔掉;⚠️ 公面型一律带 `View` 后缀 —— 本文件的 `GateOutcome`(决断腿结局)与 sdk 的 `GateOutcome`(引擎门记录)**同名不同义**,详见 §24c)· `isGateParkedToolEnd`(「这次调用没在这里结算」的**第二形**谓词:gate 缺席 + `errorCode:"gate.parked"`;端判这件事必须与 `isApprovalWindowExpiredGate` **两形合读**) · `readWireErrorCode`(B-037 候包件②:decide/取件失败上引擎 wire 机器码的单源读口,结构视图读不 `instanceof`;与本包铸的 `code` 是两个命名空间,详见 §24g)| suspended→decide→resume 环。🔴 **D-1 两元组 verbatim 回显**是字节级断言的安全不变量,端**不许重实现它的任何一段**。🔴 键空间边界(web [C1] d3 拦截):`gateIdentity` 四常量两函数只覆盖 HITL questionId/callKey 空间;seat 的 `TOOL_PERMISSION_REQUEST_ID_DOMAINS`(`plan:` 等)是另一键空间,**两者绝不合并**(合并=座位校验器静默拒全部 plan-review 卡) | `src/hitl/hitlBridge.ts`、`toolApprovalWire.ts`、`askGateWire.ts`、`planReviewWire.ts`、`hitlHostSurface.ts`、`gateIdentity.ts`、`armedGateRegistry.ts`、`parkOwnership.ts`、`parkResolver.ts`、`approvalsFeed.ts`、`frameRouter.ts`(**只挑名导出** `toolEndOutputText`/`ENGINE_ABORT_TOOL_RESULT`/`isAskTool`/`HITL_REJECT_MESSAGE`/`HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE`)、`parkRowBirthWait.ts`、`approvalDecisionNoteAudit.ts`、`askParkRowRouting.ts`、`resumeRunningCard.ts`(#265 上收的判定层)、`persistedRulesWire.ts`、`localAllowRule.ts`(#244 F2 规则侧)、`crashConverged.ts`(L-38 崩溃收敛读面)、`src/gateOutcome.ts` |
150
150
  | 4 | **子代 wire + 面板侧信道台账** | 87 | `tailEngineSubagent` · `installSubagentActivitySink` · `installSubagentTailMetaSink`(#280 件2:tail meta 帧发布口,`contentFrames` 判别位载体)· `stopEngineTask` + `classifyTaskStopConflict` · `fetchEngineSubagentReport` · `steerEngineSubagent`(0.32.0 未发布 #280 件A:additive 第三参 `childTaskId` —— 端有行上下文时**应当**传,传了就走「台账优先 / 缺席即诚实缺席 + `noteBgOwnerAbsence` 留痕」的 Q3 口径,与 tail·taskOutput·subagentOutput 三腿同姿势、与孪生 resume 腿共用同一个 `resolveOwnerRunId` 判据;**不传**则逐字维持旧行为=回落在飞 run)· `resumeSettledSubagent` + `resolveSubagentResumeContext` + `resolveOwnerRunId` + `classifySubagentResumeFailure` + `subagentResumeAvailable`(#242 批 2 A-028.7:resume 判定半场上收,与 steer 孪生同居;取址三态 = 台账有行用行值 / 指名了行但台账缺席则**诚实缺席绝不回落在飞 run** / 没指名行才回落。出路文案归端)· `recordSubagentOwnerFromProgress` + `getBgParentRunOwner`(A-028.6:「子代 → 宿主 run」**单表**,宿主 run 必须由持 stream-local 值的调用方显式传入,包内绝不从 `activeEngineRunId()` 推断)· `noteBgOwnerAbsence`(#242 批 3 [4000] Q3=B:tail/taskOutput·taskStop/subagentOutput 三腿台账缺席即诚实缺席**绝不回落在飞 run**,缺席 warn 留痕每 (腿,taskId) 一条)· `clearBgTerminalFacts`(#242 批 3 扫码修:复活=新周期,旧周期终态事实作废——fleetLedger 复活两腿按尾段清账,factsAccepted 方向核不再拿上周期终态当先例)· `auditRetainWithoutWake`([4000] Q5:引擎宣示 `subagentResume` + 本端在付 `retainSubagentSessions` + 端未实现 `wakeSubagent` ⇒ 响亮一条;`CLIENT_VERBS.wakeSubagent` 维持 fail-soft)· `subscribeSubagentContent` · `subscribeEngineAgentPanel` · `publishQuestionFrame` / `respondToQuestion` · `configureSubagentContentStore` / `subagentContentStoreConfig` / `SUBAGENT_CONTENT_STORE_DEFAULTS`(0.62.0:子代内容账本的**字节预算** —— 此前只有条数帽而单条无上限,一条 base64 工具结果就能让一个子代槽吃到十几 MB;越限从最早的内容开始丢并留一条可渲染的 `truncated` 记录,总帽淘汰整条最久未用的账本。配置面 fail-loud,详见 §26②)| 驱动与观测委派子代;经 module 级台账喂活体 agent/task 面板。全部**能力位 gate**(§5b) | `src/subagent/*.ts`、`src/subagentContentStore.ts`、`src/engineAgentPanelStore.ts`、`src/engineInlineTaskStats.ts`、`src/engineToolLabelStore.ts`、`src/liveQuestionStore.ts` |
151
151
  | 5 | **fleet 投影** | 47 | `createFleetLedger` · `projectTasks` · `projectWorkflows` · `projectFleetAgentRows` · `readEngineActiveBgTasks` · `FLEET_TASK_VIEW_KEYS` · `escapeDisplayControlChars`(不可见字符可见化,行标签/描述消毒的共享底座)· `capForDisplay`(0.62.0:呈前**消毒 + 封长**的共用铸点 —— 先转义、后按转义结果封长,截点避开半截转义 token 与合法代理对;本包该族四处此前各写一份、其中三份顺序是反的,详见 §26⑦)· `wireCycleSeq` / `wireRetiredBy`(0.38.0 提货补投的 #261 §2 两位:代际号 = SendMessage 复活即 +1,**缺席 ≠ 第一代**;`retiredBy` 在场 = 这条终态是对账腿从 durable run 行投影出来的、**不是**发布方亲报 —— 幽灵行与正常收尾唯一的 wire 判据。两位都只在场才落键) | 老 `fleetClient` 那一刀的成品:**帧体归库、连接归端** —— 端持 SSE 连接,库做行投影 + 保留台账 | `src/fleet/fleetProjection.ts`、`src/fleet/fleetLedger.ts`、`src/fleetAgentPanelProjection.ts`、`src/fleetTaskDesc.ts` |
152
152
  | 6 | **请求装配(上行唯一构造口)** | 8 | `buildTaskRequest` · `REQUEST_FIELD_MATRIX` · `unregisteredRequestKeys` · `applyLiveRequestDefaults` · `taskNotificationToPrintFrame` | 两条车道(`interactive`/`print`)出站请求的**唯一**构造器;`unregisteredRequestKeys` 是可执行门 —— 端偷带一个未登记键上 wire 就红 | `src/request/taskRequest.ts`、`src/request/printNotification.ts` |
@@ -159,7 +159,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
159
159
  | 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 桌面壳里的符号只会零命中,而零命中在这里**既不证真也不证伪**。复核这些断言**不得**拿本仓语料当反证 |
160
160
  | 14 | **宿主端口与会话槽** | 26 | `installHost` · `installHostFor` · `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` |
161
161
  | 15 | **控制面与传输** | 113 | `ControlRouter`(+ `ControlSafetyError`)· `makeEngineWireClient` + `resolveWireAuth` · `installEngineWireTarget` · `diagnoseSseIdleTear` / `isSseIdleError` · `attemptActiveRunSelfHeal` + `activeRunBusySignal` + `activeRunSelfHealRow` / `activeRunBusyHeadlessRow` · `kickEngineCapsProbe` / `engineCapTrue` / `invalidateEngineCaps(baseUrl, probe?)`(#307 S25:引擎温切后的 caps 生产失效口 —— kick 自带幂等闸,同 baseUrl 重启后不显式失效就永远读到旧引擎那一版能力位;调用方 = 壳的 respawn/restartEngine。🔴 **推荐两参形**:第二参给替代探测则「推进代际 + 注册新探测」在同一同步块内完成,失效与下一次 kick 之间那个「等待者读到未判」的窗按构造不存在;单参形保留给「只丢缓存、这一刻没有替代探测」的调用方,那种情形下读到未判是诚实结局) · `engineCapValue`(S-131,0.59.0:能力位的**四态**通用读口 `unobserved`/`not_reported`/`null`/`value` —— 既有三口把四种「读不出」全折成 fail-closed 一档,对**放行**问题是对的、对**读面/诊断**问题是错的:`null`(引擎明确说没有,正面事实)会与「老引擎不报」「还没探到」在屏上同形。`value` 位刻意不做形校验,形归各能力位自己的窄读器,详见 §23b)· `projectSqlEngineCapability` / `observedSqlEngine` / `noteEngineCapsForSqlEngine` / `forgetSqlEngineReading` / `sqlEngineDoctorDetail`(S-131,0.59.0:`Capabilities.sql`(server ≥7.60.0)的四态读面**从壳侧上收** —— 归层债,0.58.0 时它长在壳里正是因为包侧没有嵌套对象读口。🔴 **导出名与壳侧那份逐字同名 = drift-lock**;`txnMode: null` 是铸点域内的合法值不是畸形;换代失效口清成未观测而不是留旧值,详见 §23b)· `mapBrainStatusToRetry` · `waitForClaimRelease` + `CLAIM_RELEASED_STATES` / `CLAIM_HELD_STATES` · `atMostOnceFailureClass` / `readSteerDelivery` · `clearRunningChoiceOffer`(Inkglow-1085 P0b①:「Do nothing」登记的清口 —— 端的「重新打开操作菜单」入口;登记在场时 attemptActiveRunSelfHeal 不整卡重弹,not-parked 结局带 `alreadyOffered: true` 判别位,端据此降级渲一行)· `INTERACTIVE_WAY_OUT`(默认出路串单源)· `engineSessionParamFor`(design/285 批 0:`?session=` 派生的 **per-key** 形 —— `hostSessionFor(sessionKey)?.currentSessionId()` + [1501] 空串归一;零参 `engineSessionParam()` = 默认槽兼容层,取值链逐字等价)· `normalizeWirePrincipal`(A-028.10:principal 在场性 trim 原语 —— 全空白=缺席不发头,engineWireTarget 两臂/makeEngineWireClient/壳 livePrincipal 同尺)· `readSessionMemoryStatus` / `classifyMemoryStatusFailure` / `readCaptureOptOut` / `readLastCapture`(S-53 会话记忆姿态读面,0.48.0:失败分诊**码优先**——两个 404 分道 `not_found.session` / `not_found.route`,无码 404 不猜落 failed;五键逐键缺席语义两个合读器,`lastCapture` 三态的判别材料是 `committedCount` 不是本键;IO 归宿主注入 `MemoryStatusClientLike`,详见 §11) · `classifyTurnWireError` / `isWireTransportError` / `isPreStreamDrainingReject` / `isResumeAtRejection` / `drainingRetryDelayMs` / `scenarioDenyFromError` + `WIRE_NETWORK_ERROR_PATTERN`(A-028.11/.13:turn 错误分型判定半场,人话文案与渲染归端)· `resumeRetryLaterFromError`(L-102,0.57.0:resume 族**时间性拒绝**二码的判型半场 —— 这一族里唯一**带得出「等多久」**(`retryAfterSec`)的两个码。🔴 闭集**不是**「哪些码可以等」的名单:同族 `resume.row_recycling` 同样可等(窗口自清)只是没有秒数 ⇒ 本读口返回 `null` 只意味着没命中这两码,详见 §21) · `projectWriteProtectionCapability` / `observedWriteProtection` / `noteEngineCapsForWriteProtection` / `forgetWriteProtectionReading` / `writeProtectionDoctorDetail` / `projectWriteProtectionPosture` / `writeProtectionPostureDetail`(S-138,0.60.0:`Capabilities.writeProtection` (engine ≥7.63.0)的**四态**读面 + operator 面行表 —— 与上面 S-131 那一格**同构同纪律**。🔴 三位刻意不合成一个布尔;`not_reported` **不是**「这台部署没有写保护表」(座位缺席恰是缺省表在岗);逐行 name/kind 走**最小披露**只上 operator 面,详见 §24e)· `projectReadFacePosture` / `readFacePostureDetail` / `readFaceDisagreement`(S-167,0.61.0:operator 面 `diagnostics.wiring.readFace`(engine ≥7.65.0)的窄读器 —— 与上面S-138 那一格**同构同纪律**。🔴 三句「答不出来」逐字互异且没有一句等于「没有 READ 档」;`source` 按开集读;与租户面 `capabilities.readFace` 刻意不合流,只带一个纯比较函数,详见 §25)| 上行通道的**监管**半场(submit / steer / kill / 队列命令定序)+ 传输构造、caps 探测、SSE 断流分诊、**409 active-run 自愈** | `src/controlRouter.ts`、`steering.ts`、`sseIdleTriage.ts`、`retryStatus.ts`、`diagnostics.ts`、`engineWireSdk.ts`、`engineWireTarget.ts`、`src/principalWire.ts`、`src/wireErrorTriage.ts`、`engineSessionParam.ts`、`engineCapsCache.ts`、`liveInitToolFace.ts`、`adapter/activeRunSelfHeal.ts`、`src/sessionMemoryStatus.ts`、`src/writeProtectionCapability.ts`、`src/readFacePosture.ts` |
162
- | 16 | **引擎词汇表与包自检** | 69 | `CONFIG_REFUSAL_CODES` / `isConfigRefusalCode` · `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` |
162
+ | 16 | **引擎词汇表与包自检** | 73 | `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` |
163
163
 
164
164
  🔴 **`engineErrorCodes` 的开集纪律**(该文件头注逐字):这些 `ReadonlySet` / 前缀谓词一律是**识别表**,
165
165
  回答的是「我认不认得这个码」,**绝不是**「合法码只有这些」。消费点 `switch` **必须留 `default`**,
@@ -232,7 +232,7 @@ type EventProjection =
232
232
  🔴 栏内只写**成员**;反例/对照臂(终态那两条之类)一律写到栏外去,否则会被读成成员。 -->
233
233
 
234
234
  `meta`(流首帧身份信号,SDK/传输层自消费)· `file_link` / `prompt_assembled` / `model_usage` /
235
- `context_usage` / `config_assembled` / `message_committed`(引擎可观测/审计面,CC transcript 无对位物)·
235
+ `context_usage` / `config_assembled`(引擎可观测/审计面,CC transcript 无对位物)·
236
236
  `needs_review`(壳消费的是 `done{status:'needs_review'}` 终帧,事件形重复且更早)·
237
237
  `compaction_outcome`(压缩**非 compacted 结局**报告;CC transcript 无对位物,见 §7 缺口 **P-6**)·
238
238
  `tool_approval` / `tool_approval_complete`(**不是丢帧**:它们走
@@ -241,6 +241,12 @@ type EventProjection =
241
241
 
242
242
  <!-- /ARM-SET:not_in_slice -->
243
243
 
244
+ 📌 **`message_committed` 自 0.65.0 起离开本表**(B-072 ④,§30b):它此前列在这里的理由写的是
245
+ 「CC transcript 无对位物」—— 那句话对**转录行**成立、对**定位**不成立。core 亲口说消费方用本帧
246
+ 自建 `entryId → message` 映射来解析 `compacted.preserved_segment`(压缩分割线画在哪条消息之前),
247
+ 所以只投那个锚而把本帧丢掉,等于交给端一个解析不出东西的锚。现在它投**中性内部臂 + 可选 chrome
248
+ 记账**,仍然**绝不铸 transcript 行**(本帧不带正文)。
249
+
244
250
  📌 **`wiring_manifest` 自 0.56.0 起离开本表,但它只被接了两段**(L-70 / L-108②③)——
245
251
  `modelGate` 与 `autoMode` 投成内部臂 + chrome 臂(§19),整份 manifest 的**其余十一段**
246
252
  (leg / ask / question / interaction / elicit / parkLane / session / fleet / permissionRules /
@@ -260,12 +266,19 @@ governance / configFingerprint)仍然一件没接。两段都不成形的那些
260
266
 
261
267
  ### 3d. 键级剥离(帧投影了,但键被投影边界剥掉)
262
268
 
263
- `case 'task_progress'` 的白名单**逐字**只 stamp 八键(0.47.0 起,#363 补 `model`):
269
+ `case 'task_progress'` 的白名单**逐字**只 stamp 九键(0.47.0 起 #363 补 `model`;0.65.0 / B-074 补 `status`):
264
270
 
265
271
  ```
266
- taskId · name · usage · model · currentAction · workflowRunId · workflowAgentLabel · parentToolCallId
272
+ taskId · name · usage · status · model · currentAction · workflowRunId · workflowAgentLabel · parentToolCallId
267
273
  ```
268
274
 
275
+ 🆕 **`status`(0.65.0 / B-074;core ≥7.0 / server ≥7.69.0)** = 这条 tick 的**终态面**。core 的臂注把
276
+ 它存在的理由写死了:「ONE final tick fires at the sub-run's settle with the terminal face
277
+ (`"completed"` | `"failed"`) …… **so a uuid-lane consumer sees the row finish** instead of a bare
278
+ removal after the last running beat」。**按开集透传**(空串 / 非串 / 缺席整键不铸);「哪些词**是**终态」
279
+ 由 `src/adapt/arms.ts` 的 `TERMINAL_TICK_STATUSES` 闭二词回答 —— 透传与裁决分两层,上游加词那天
280
+ 不会把一条还在跑的行提前结掉。准入条件(谁读它、读来干什么)见 §30d。
281
+
269
282
  🆕 **`model`(0.47.0;server ≥7.52.1)** = 这条 tick 所属**子 run 的模型 id**(core 铸点
270
283
  `prepared.model.id`;server `trace/project.js` 的 `taskProgressEventData` 里条件 spread:
271
284
  `string` 且非空才发)。本层同条件透传 —— **空串/缺席一律整键不铸**(空串既不是模型 id 也不是
@@ -276,8 +289,8 @@ taskId · name · usage · model · currentAction · workflowRunId · workflowAg
276
289
  🔴 **退役的是 cast,不是运行期判**:`typeof` 门保留(旧 server 缺席 ⇒ 键不 stamp;wire 是 JSON,
277
290
  类型声明是上游承诺、不是本层前提)。端侧**行为逐字节不变**。
278
291
 
279
- **仍然被本层剥掉的五键**(`seq` / `taskType` / `parentTaskId` / `status` / `eventId`):
280
- - `taskType` / `status` / `parentTaskId` —— 在册的 §7 缺口 **P-1**;lane 归属今天改用 id 形状 /
292
+ **仍然被本层剥掉的四键**(`seq` / `taskType` / `parentTaskId` / `eventId`;0.65.0 `status` 已离开本表):
293
+ - `taskType` / `parentTaskId` —— 在册的 §7 缺口 **P-1**;lane 归属今天改用 id 形状 /
281
294
  `workflowRunId` 启发式判(`src/adapt/arms.ts`)。
282
295
  - `seq` —— core #258 的 stop-cycle 代际号(复活即 +1)。fleet 面已有同轴的 `wireCycleSeq`(0.38.0),
283
296
  **tick 这条腿今天没有消费方** ⇒ 照旧剥。
@@ -4664,10 +4677,10 @@ auto 模式下门会就一只 ask 去咨询分类器;**没跑成**时引擎在
4664
4677
  **签名**
4665
4678
 
4666
4679
  ```ts
4667
- AUTO_MODE_UNAVAILABLE_CAUSES: readonly string[] // ['error','timeout','breaker_open']
4668
- AUTO_MODE_BREAKER_CAUSES: readonly string[] // ['error','timeout','parse_error']
4680
+ AUTO_MODE_UNAVAILABLE_CAUSES: readonly string[] // 2 词:['error','timeout'](core 7.12.0 收窄;0.65.x 跟)
4669
4681
  classifierUnavailableOf(ask: unknown): { cause: string } | undefined
4670
4682
  classifierUnavailableDetail(cause: unknown): string
4683
+ // 🔴 `AUTO_MODE_BREAKER_CAUSES` **已退役**(core 7.12.0 Removed(BREAKING));详见 §30k②
4671
4684
  ```
4672
4685
 
4673
4686
  **输入形**:一只 `AskRequest`,**或**一条 durable park 行的 `PendingAction.tool_approval` 载荷 ——
@@ -4679,20 +4692,24 @@ classifierUnavailableDetail(cause: unknown): string
4679
4692
  消费端只拿它渲一句话,**绝不**据它翻转任何裁决。
4680
4693
  - 🔴 **缺席 ≠「分类器跑成了」**:绝大多数 ask 根本没咨询过分类器(部署没武装 auto、或这只 ask 走的
4681
4694
  是别的门)。缺席只意味着「这只 ask 上没有这条事实」。
4682
- - 🔴 **两条 cause 轴,不是一张表**:`AUTO_MODE_UNAVAILABLE_CAUSES` 答「这一轮分类**为什么没跑成**」
4683
- (这是 `classifierUnavailable.cause` 的值域);`AUTO_MODE_BREAKER_CAUSES` 答「**熔断闩为什么合上**」。
4684
- 两集交于 `error`/`timeout`,各有一个独占成员 —— 合成一张表就把两条轴的差别扔了。
4685
- - 🔴 **`parse_error` 只在熔断轴上**:上游顶注逐字「`parse_error` stamps nothing」—— 分类器
4686
- **跑了并且答了**,只是答在契约之外,那是**另一句话**。读器把**熔断轴独占**的词判**缺席**;
4687
- 把它读成一个「没跑成」的成因,就是替引擎编一件它明说没发生的事。
4688
- 措辞表仍为它备了一句(给**渲熔断面**的消费端用同一个铸点),那一句逐字说的是「答在契约之外」。
4689
- - 🔴 **未知(表外)成因词照收**(**0.64.2 订正**,详见 §29e;修前判缺席):词表属主在 core,抄一份
4690
- 闭集只会在 core 加词那天把一个合法值判没 —— 读器只排除**熔断轴独占**的词
4691
- (`AUTO_MODE_BREAKER_CAUSES` `AUTO_MODE_UNAVAILABLE_CAUSES`,派生而非手抄)。
4692
- - 未知词 / 坏值 一句**兜底**:仍告诉用户这只 ask 是分类器那条腿引出来的,但不冒充四句里的任何
4695
+ - ⚠️ **0.65.x 订正**(原文写的是「两条 cause 轴」):熔断那条轴随 core 7.12.0 的
4696
+ Removed(BREAKING) **整只退役**(详见 §30k②)。今天只剩**一条**:`AUTO_MODE_UNAVAILABLE_CAUSES`
4697
+ 答「这一轮分类**为什么没跑成**」(= `classifierUnavailable.cause` 的值域,两词)。
4698
+ - 🔴 **`parse_error` 判缺席,行为一字未变**:它是 core `AutoModeVerdict` 的**判据轴**成员 ——
4699
+ 分类器**跑了并且答了**,只是答在契约之外(`tool-policy.d.ts:297` 逐字「a `block` and a
4700
+ `parse_error` deny carry nothing here」),所以它一个字节都不 stamp 到这一格。读器把它判**缺席**;
4701
+ 把它读成一个「没跑成」的成因,就是替引擎编一件它明说没发生的事。措辞表仍为它备了一句(
4702
+ **渲判据面**的消费端用同一个铸点),那一句逐字说的是「答在契约之外」。
4703
+ ⚠️ 这条排除的**出处**在 0.65.x 换了(行为没变):修前是两张表的差集,而右操作数随熔断表一起没了
4704
+ 现按理由直写一张具名单员表 `NEVER_STAMPED_CAUSES`。
4705
+ - 🔴 **未知(表外)成因词照收**(**0.64.2 订正**,详见 §29e / **射程收窄见 §30l**;修前判缺席):
4706
+ 词表属主在 core,抄一份闭集只会在 core 加词那天把一个合法值判没。
4707
+ ⚠️ 0.65.x 起 `breaker_open` 也走这一条(core 已删该词)—— **旧引擎的合法帧照旧过境**,只是本端
4708
+ 不再为它自铸一句解释。
4709
+ - 未知词 / 坏值 ⇒ 一句**兜底**:仍告诉用户这只 ask 是分类器那条腿引出来的,但不冒充三句里的任何
4693
4710
  一句,并原样带上那个词供运维追问上游。
4694
4711
 
4695
- **为什么是镜像**:这两张表与那一格在 sdk 8.8.0 与 agent-types 上**都还没有**(亲验两棵树全树零命中),
4712
+ **为什么是镜像**:这张表与那一格在 sdk 8.8.0 与 agent-types 上**都还没有**(亲验两棵树全树零命中),
4696
4713
  唯一出处是 `@sema-agent/core`;而 core **不是本包消费者的依赖** ⇒ 与 ⑦ 同一条处置(镜像 + 门对实装
4697
4714
  core 双向对账)。**候上游导出即整只退役改成从 sdk 取**。
4698
4715
 
@@ -4961,18 +4978,19 @@ VOCABULARY … are the consuming side's single point」)。真源是 core 的
4961
4978
  **签名**
4962
4979
 
4963
4980
  ```ts
4964
- CLASSIFIER_STATUS_STATES: readonly string[] // 3 词:available / breaker_open / unavailable_this_round
4981
+ CLASSIFIER_STATUS_STATES: readonly string[] // 3 词:armed / available / unavailable_this_round(0.65.0 两处同批:B-071 加 `armed` 见 §30f、熔断族退役删 `breaker_open` §30k②)
4965
4982
 
4966
- classifierBreakerOf(autoMode: unknown): ClassifierBreakerView | undefined
4967
4983
  classifierStatusOf(autoMode: unknown, ask?: unknown): ClassifierStatusView | undefined
4968
4984
  classifierStatusDetail(view: ClassifierStatusView): string
4969
4985
 
4970
- interface ClassifierBreakerView { openedAtMs: number; lastCause: string; failures: number; runId?: string }
4971
- interface ClassifierStatusView { state: string; breaker?: ClassifierBreakerView; cause?: string }
4986
+ interface ClassifierStatusView { state: string; cause?: string }
4987
+ // 🔴 `classifierBreakerOf` / `ClassifierBreakerView` / `breaker_open` 这一态与
4988
+ // `ClassifierStatusView.breaker` 一位 **0.65.x 全部退役**(core 7.12.0 Removed(BREAKING));详见 §30k②
4972
4989
  ```
4973
4990
 
4974
- **wire 加员**:`WiringManifestAutoMode` 上 additive 一键 `breaker`(core 7.10.0 `AutoModeBreakerTrip`
4975
- 的四键;**server 7.69.0 才投**),随 `_sema_autoMode` 段过帧。
4991
+ **wire 加员**:~~`WiringManifestAutoMode` 上 additive 一键 `breaker`~~ —— ⚠️ **0.65.x 已退役**
4992
+ (core 7.12.0 删 `WiringManifest.autoMode.breaker`);那一段今天只剩 `armed` / `reason` 两位,老引擎
4993
+ 若仍带这一键,它落在投影白名单之外被丢弃。详见 §30k②。
4976
4994
 
4977
4995
  **输入形**:`autoMode` 吃 `wiring_manifest` 的 `autoMode` 段(投影后的或原始的都吃,本函数自己窄读);
4978
4996
  `ask` 吃一只 ask 或 durable park 行的 `tool_approval` 载荷(与 `classifierUnavailableOf` 同一只读器)。
@@ -4981,32 +4999,24 @@ interface ClassifierStatusView { state: string; breaker?: ClassifierBreakerView;
4981
4999
 
4982
5000
  | 形 | 语义 | 🔴 不许渲成 |
4983
5001
  |---|---|---|
4984
- | `breaker` 键**不在场** | **没有可用的熔断记录** —— 四种成因不可分辨:①这个会话从没熔断过 ②账本(有界 FIFO)把它淘汰了 ③这一次是 standalone prepare(账本压根没接上)④server <7.69.0 不投这一段 | 「没熔断过」;也**别**读成「一定是老引擎」 |
4985
- | `classifierStatusOf(...) === undefined` | 这一端说不出分类器的健康状况(段缺席;或没武装、且既无本轮事实也无历史记录) | `available` |
4986
- | `runId` 缺席 | 引擎没报是哪条腿合的闩 | 编一个 |
4987
- | 熔断记录三键(`openedAtMs`/`lastCause`/`failures`)缺任一 | **整段**判缺席(半句没有出口的话不如不渲) | 半句 |
4988
-
4989
- **四条承重(照抄进端的复审清单)**
4990
-
4991
- - 🔴 **熔断记录与 `armed`/`reason` 之间零互证**:闩合上之后被闩住的那条腿**不再把 auto 意图传给后续
4992
- 腿**,于是后续腿读作 `no_intent` 而**不是** `latch_open` —— `{armed:false, reason:"no_intent",
4993
- breaker:{…}}` 是**最常见**的合法形。补一条「有 breaker 就该 latch_open」的互证会把真读数整段判没。
4994
- - 🔴 **优先序:本轮事实 > 这条腿的 `armed` > 历史熔断记录**。判据锚在**真正决定「分类器现在跑不跑」
4995
- 的量**上,而那个量是**这条腿的 `armed`**,不是账本里有没有一条旧记录 —— core 顶注逐字:
4996
- 「A decider is minted per run (its latch is a RUN fact) … the ledger below carries the most recent one
4997
- forward per session」⇒ 同一会话的**后一条腿完全可以重新武装**(新 decider 的闩由构造关着),而账本
4998
- 仍把那次旧 trip 带着。`armed === true` 时判 `breaker_open`,就是把一个**正在放行**的分类器显示成
4999
- 已经关掉了。
5000
- - 🔴 **历史记录不因为被压下去就丢掉**:任何一态上 `view.breaker` 都照带。`available` 因此有**两句**
5001
- 措辞 —— 「在跑」与「在跑、但这个会话上**曾经**熔断过」是两条不同的下一步(后者要去看那次失败为什么
5002
- 发生,它随时可能再来一次)。
5003
- - 🔴 **别渲「不新开会话就恢复不了」**:闩是**一条腿**的事实,后一条腿会铸一只新的、闩关着的
5004
- decider ⇒ 那句话是编的。本包的两句熔断措辞都只说真的发生过的事(什么时候、因为什么、连着几次)。
5005
- - 🔴 **`lastCause` 开集读**:词的属主在 core;端按具名词写的 `switch` **必须带 `default`**,
5006
- 或者直接用 `classifierStatusDetail()`(它自带兜底句,原样带上那个词供运维追问上游)。
5007
- - 🔴 **时刻是 UTC ISO**:时区是宿主的事。端要本地化就拿 `view.breaker.openedAtMs` **自己**格式化,
5008
- 别去改那句话 —— 而 `openedAtMs` 已由窄读收进 `Date` 的真实值域(一个 wire 上的 `1e20` 会让
5009
- `toISOString()` 当场 `RangeError`,那是整屏崩不是一行渲不出)。
5002
+ | `classifierStatusOf(...) === undefined` | 这一端**说不出**分类器的健康状况:`autoMode` 段缺席( mint / 外部 derive),或段在但没武装、且卡上也没有任何本轮事实 | `available`(把「没报」渲成「一切正常」) |
5003
+ | `state === 'armed'`,没有 `cause` | **这条腿铸出了分类器 decider**(装配期事实),本轮跑没跑这一端没有证据 | 「在跑 / 可用」——那是 `available` 那一句 |
5004
+ | `cause` 缺席而 `state === 'unavailable_this_round'` | 引擎报了「本轮没跑成」但没给成因词 | 编一个成因 |
5005
+ | 一份仍带 `breaker` 的老引擎 manifest | 那一位**落在投影白名单之外**,一个字节都到不了端(0.65.0 退役);`armed`/`reason` 两位照旧过帧 | 任何一句熔断解释(那个机制在这一代引擎上不存在) |
5006
+
5007
+ **三条承重(照抄进端的复审清单)**
5008
+
5009
+ - 🔴 **优先序:本轮事实(否定 + 肯定)> 这条腿的 `armed`**。判据锚在**真正决定「分类器现在跑不跑」的
5010
+ 量**上 —— core 顶注逐字「A decider is minted per run (its latch is a RUN fact)」,而可用性逐字是
5011
+ 「a per-CALL fact」。⇒ 卡上带 `classifierUnavailable` 判 `unavailable_this_round`;卡上
5012
+ `origin === "denial_limit_fallback"` `available`(那只 ask 的存在本身证明分类器跑过);
5013
+ 都没有而 `armed === true` 判 `armed`。详见 §30f。
5014
+ - 🔴 **`armed` `available`(0.65.0 / B-071)**:前者是装配期读数、后者是每次调用的事实。端自己
5015
+ `switch` `state` 的要补 `armed` 一臂;直接渲 `classifierStatusDetail()` 那句话的端**零改**。
5016
+ - 🔴 **表外态不抛也不冒充**:一份从旧持久态恢复回来的视图可能带着已退役的 `breaker_open`
5017
+ —— 措辞铸点为它走兜底句、原样带上那个词,端**不要**在自己那侧补一张闭集表(那等于把这次退役的
5018
+ 承诺又复制一份出去)。
5019
+
5010
5020
 
5011
5021
  ---
5012
5022
 
@@ -5256,10 +5266,13 @@ per-tool 面(写围栏与敏感路径策略读的 `pathTarget` 那一格)在**
5256
5266
  `classifierStatusOf({armed:true}, card)` 还会答 **`available`** —— 一条真实的故障事实被渲成「一切正常」。
5257
5267
  - **自证**:`classifierUnavailableDetail` 早就为这一形备了兜底句(「a word newer than this client」),
5258
5268
  而在修前那句话**永远不可达** —— 一个永远走不到的兜底分支,本身就是判据写错了的证据。
5259
- - **修后判据**:`cause` **非空串即收**,只排除**熔断轴独占**的词
5260
- (`AUTO_MODE_BREAKER_CAUSES``AUTO_MODE_UNAVAILABLE_CAUSES`,今天 = `{parse_error}`)。
5261
- 🔴 排除集是**派生**的,不是手抄一个词:排除的理由是 core 逐字说过「`parse_error` stamps nothing」,
5262
- 这条理由天然属于「只在熔断轴上的那些词」,core 再加一个独占词时这里自动跟上。
5269
+ - **修后判据**:`cause` **非空串即收**,只排除 core 明说「不 stamp 到这一格」的词(今天 = `{parse_error}`)。
5270
+ ⚠️ **0.65.x 订正**:这条排除修前由「熔断轴 不可用轴」的差集派生,而 core 7.12.0 把熔断表删了
5271
+ 右操作数不存在。排除的**理由**从头到尾在判据轴上(`tool-policy.d.ts:297`),现按理由直写一张
5272
+ 具名单员表 `NEVER_STAMPED_CAUSES`。**行为一字未变**,变的是理由的坐标。
5273
+ - ⚠️ **射程收窄(0.65.x,见 §30l)**:本条「集外成因词逐字上 wire」只对**活卡帧 / `card_json`** 腿
5274
+ 成立;**耐久腿**(inbox 行 / durable park 行)由 core `summarizeCheckpoint` 按
5275
+ `isAutoModeUnavailableCause` **枚举**,集外词读作缺席 —— 它到不了本包。
5263
5276
  - **`parse_error` 的行为一字未变** ⇒ 0.63.0 起的黑盒判据 **G-19 照旧成立**;变的只是「表外词」那一格,
5264
5277
  而「表外」与「另一条轴上的词」本来就是两件事,修前把它们判成了同一件。
5265
5278
  - **端要做什么**:零改。未知词从此渲兜底句;端**不许**在自己那一侧再补一张闭集表(那等于把这次修的病
@@ -5368,3 +5381,600 @@ mcp 域 → 请求面 `McpServerSpec[]`)也是逐键白名单重建,同样把 `t
5368
5381
  | `scripts/run-package-hygiene-test.mjs` | (既有门,本批真红过一次)出包面中性词表 —— 本批新写的 JSDoc 里对协作面的称呼被它当场判红,改成中性技术词后绿 |
5369
5382
 
5370
5383
  ---
5384
+
5385
+ ## §30 🆕 0.65.0 内容批(两半场:投影臂族归层修 B-071 / B-072 / B-073 / B-074 / L-215③ + 接入审计 B 战役的包侧归层四件 B-070 / B-078 / L-215①② / B-080)
5386
+
5387
+ ### 30a. 本节速览
5388
+
5389
+ | 件 | 一句话 | 端要做什么 |
5390
+ |---|---|---|
5391
+ | ① B-072 | 压缩边界帧:`trigger` 开集透传(`forced` 不再被折成 `auto`)+ 两个超集键 + `message_committed` 从「不投影」改投中性臂/chrome | 渲压缩分割线的端接 `_sema_preserved_segment` + 新 chrome 臂;只渲「自动/手动」的端**零改** |
5392
+ | ② B-073 | 成本:**显式 0 = 声明免费** 与 **缺席 = 没定价** 两档不再互折;`costUSD` 保 CC 形 + 同行判别位 | 账单/footer 面改成**两键合读**;只读 `costUSD` 的端零改(值一字未变) |
5393
+ | ③ B-073b | `usage.cacheCreationInputTokens` 不再硬编 0;扁平 usage 四格改有限数守卫 | 端**零改**;缓存写入从此算得对 |
5394
+ | ④ B-074 | 子代 `task_progress.status` 透传 + 终态那一拍**直接落面板行** | 端**零改**(chrome 事件形不变);子代行不再等 sweep/通知帧收尸 |
5395
+ | ⑤ L-215③ | assistant 行补 `id`/`model`;`usage`/`stop_reason` 按帧序**不铸在臂上**,真值走 `turn_usage` 两超集键 | 壳侧估算腿可退役;要 usage/stopReason 的端改吃 `turn_usage` 的两个新键;宿主需**钉 `EmitContext.model`** |
5396
+ | ⑥ B-071 | 分类器状态面 `armed` 与 `available` 拆成两个词 | 措辞面**零改**(单铸点);自己 `switch` 状态词的端加一臂 |
5397
+ | ⑦ B-070 | `/decide` 的 200 = **投递受理**,不是「门已解决」;`ParkResolution.handoffTaskId` 换挂 + 新模块 `decideReceipt.ts` | 据 200 清卡的端**必须改**(否则幽灵卡);换挂腿按 §30h 接 |
5398
+ | ⑧ B-078 | `approval_request` / `approval_revoke` 两条 **chrome 臂**(修前 `dropped('unsupported_arm')`) | **新义务**:不接 = 流内审批卡整面哑掉(§30i) |
5399
+ | ⑨ L-215①② | fleet `parked` ⇒ `awaiting approval`;「非成功终局」单铸谓词 `isTerminalNotSuccess` | 端零改;自己内联三词判据的端改读谓词(§30j) |
5400
+ | ⑩ B-080 | devDep core `~7.12.0`;🔴 **熔断族 clean-cut 退役**(公面删两件 + 型/词/位);AskOrigin 三句订正 | 读过熔断两件的端**编译红** ⇒ 删读点(§30k) |
5401
+
5402
+ 🔴 **本节两半场**:①–⑥(小节 **§30a–§30g**)是投影臂族归层修;⑦–⑩(小节 **§30h–§30n**)是接入审计
5403
+ B 战役的包侧归层四件 —— 两批同版发出,**合成一节**登记,小节编号连续不重号。
5404
+
5405
+ **共同形**:①③④⑤ 是「上游已经把事实摆在 wire 上,而**包边界这一格空转**」的第 N 例(`toolFaces` /
5406
+ `model` / `workflowRunId` 的同族);②⑥ 是另一条形 —— **包在边界用一个更粗的读法回答了一个更细的问题**
5407
+ (②把两档折成一档;⑥拿装配期事实答每次调用的问题)。
5408
+
5409
+ **出处**:①–⑥ = cli 台账 B-071 / B-072 / B-073 / B-074 与 DEBTS-cli L-215③;⑦–⑩ = 接入审计 B 战役的
5410
+ B-070 / B-078 / B-080 与 DEBTS-cli L-200 / L-208 / L-210 / L-215①②。合同真源 = core 7.12.0 的
5411
+ `task-event.d.ts` / `task-result.d.ts` / `wiring-manifest.d.ts` / `ask-origin.d.ts` / `auto-mode.d.ts` 与
5412
+ sdk 的 `events.d.ts` / `types.d.ts` / README §9.0.0(逐条坐标写在各小节)。
5413
+
5414
+ ---
5415
+
5416
+ ### 30b. ① B-072 压缩边界帧三件(core ≥5.16 起真发 `forced`;server ≥7.69.0 白名单)
5417
+
5418
+ **键名与载体**
5419
+
5420
+ | 键 | 载体 | 来源 | 缺席语义 |
5421
+ |---|---|---|---|
5422
+ | `compact_metadata.trigger` | CC `system{subtype:'compact_boundary'}` | `compacted.trigger` | **读不出**才回落 `'auto'`(空串/非串/缺席);读得出的词一律原样 |
5423
+ | `compact_metadata._sema_preserved_segment` | 同上(超集键) | `compacted.preserved_segment` | 键不铸 = 这次压缩**没有报保留段底**(或旧引擎)。**绝不**折成 `null`/空对象 |
5424
+ | `compact_metadata._sema_clamped_ratio` | 同上(超集键) | `compacted.clampedRatio` | 键不铸 = 这次压缩**没有钳**(或旧引擎)。🔴 **真 0 是事实不是缺席** |
5425
+ | chrome 臂 `message_committed` | `ChromeEvent`(新臂,`required:false`) | `message_committed` 帧 | 臂不发 = 这条消息没落账 / 这是 durable 腿(见下) |
5426
+
5427
+ **🔴 `trigger` 为什么必须开集**:core 的 `compacted` 臂注逐字 ——「the wire now carries the **SAME
5428
+ value the hooks saw** instead of flattening it to `"auto"`」。上游刚刚停止折叠,包在下游又折一次,
5429
+ 等于把上游的修复抹掉。core 同一段也写明这是 **additive value space**:「a consumer switching on
5430
+ auto/manual keeps its exact old behavior」⇒ **不是破坏性变更**。今天的第三个词是 `forced`
5431
+ (prompt-too-long 恢复腿 / trim-pressure 腿:压缩**不是可选的**)。
5432
+
5433
+ **🔴 `_sema_preserved_segment` 与 `message_committed` 是一对,拆开就没用**:
5434
+ core 说 `firstKeptEntryId` 是**会话树条目 id**,消费方「builds its own `entryId → message` map from
5435
+ these [`message_committed`] to resolve `preserved_segment`」。所以本批把 `message_committed` 从
5436
+ `not_in_slice` 搬出来,投**中性内部臂 + 可选 chrome 记账**。它**仍然绝不铸 transcript 行** —— 本帧
5437
+ 不带正文,铸一行就是替引擎编一句它没说过的话(同 `human_input` 那条硬约束)。
5438
+
5439
+ **⚠️ 两条诚实边界**
5440
+
5441
+ 1. **投递腿只有 live**(亲读 engine 7.69.0:`http/routes/tasks.js:491/506` 的 live 白名单真发;
5442
+ `runs.js:358` 与 `http/server.js:1696` 的 durable / resume 腿把本帧喂给 rewind 锚而**不入账本**)
5443
+ ⇒ replay / resume 上端的映射表是**空的**。那时正解是**不画分割线**,不是回退成「画在最后一条」。
5444
+ 2. **`clampedRatio` 的型面座位还没到**:server `trace/project.js:467` 真发,而 sdk 8.8.0 的 `compacted`
5445
+ 臂上没有这一位 ⇒ 包侧是**防御 raw 读**。记账带退出条件:
5446
+ `run-compaction-boundary-projection-test.mjs` 的 F10 行断言那一位**现在不在**,sdk 补上当天红。
5447
+
5448
+ **端怎么接**
5449
+
5450
+ ```ts
5451
+ // 压缩分割线(只有 live 腿解析得出)
5452
+ const anchor = msg.compact_metadata?._sema_preserved_segment?.firstKeptEntryId
5453
+ // 端自建的映射表(从 chrome 臂 message_committed 落):entryId -> 已渲消息
5454
+ const target = anchor !== undefined ? entryIdToMessage.get(anchor) : undefined
5455
+ if (target !== undefined) renderDividerBefore(target) // 查不到就不画,别回落
5456
+ ```
5457
+
5458
+ **黑盒判据(test 视角可执行)**
5459
+
5460
+ - **G30-1**:一条走 prompt-too-long 恢复腿的 run,其 `compact_boundary` 消息的
5461
+ `compact_metadata.trigger` **逐字为 `"forced"`**(修前恒为 `"auto"`)。
5462
+ - **G30-2**:同一条 run,若引擎报了保留段,`compact_metadata._sema_preserved_segment.firstKeptEntryId`
5463
+ 与该 run **某一条** `message_committed` chrome 事件的 `entryId` **逐字相等**;引擎没报时该键**不出现**
5464
+ (不是 `null`)。
5465
+ - **G30-3**:一次触发了摘要钳制的压缩,`_sema_clamped_ratio` 是一个有限数;没钳的那次该键不出现。
5466
+ - **G30-4**:live 腿上一条已落账的 assistant 消息**恰好**产生一条 `message_committed` chrome 事件
5467
+ (`role:"assistant"`,带 `entryId`);同一条 run 的转录里**没有**因此多出任何一行。
5468
+ - **G30-5**(负控):durable/resume 腿回放同一条 run 时 `message_committed` chrome 事件为 **0 条**
5469
+ —— 这是上游投递事实,端据此必须把「解析不出锚」当成正常态。
5470
+
5471
+ ---
5472
+
5473
+ ### 30c. ②③ B-073 成本可分性 + 缓存写入读真值
5474
+
5475
+ **病**:core 把「没定价」与「声明免费」**在 wire 上分开**了(`TaskStats.costMicroUsd` 缺席 = 有花销
5476
+ 没定价;`=== 0` = 这台模型显式声明免费),而包边界把它们折成同一个输出,而且**两个方向各错一半**:
5477
+
5478
+ | 面 | 修前 | 修后 |
5479
+ |---|---|---|
5480
+ | `SDKResult.total_cost_usd` | `usd > 0 ? usd : null` ⇒ 真免费也渲 `null` | 照实报:显式 `0` ⇒ `0`;缺席/非有限 ⇒ `null`;负数原样 |
5481
+ | `ModelUsage.costUSD` | `finiteOrZero(...)/1e6` ⇒ 缺席渲 `0`(假免费) | 值仍 `0`(CC 形不破)+ **同行** `_sema_cost_absent: true` |
5482
+ | `usage.cacheCreationInputTokens` | 字面量 `0` | ⇐ `TaskStats.cacheWriteTokens`(合成 modelUsage 行同形第二处一并扫) |
5483
+ | 扁平 usage 四格 | `?? 0` | 有限数守卫(`"12"` / `NaN` / `Infinity` 折 0 而不是原样落进 `number` 槽) |
5484
+
5485
+ **🔴 为什么判别位必须长在 CC 镜像上**(与 [2295]「CC 形状不承载非 CC 语义」**不矛盾**,差别有出处):
5486
+ `totalInputTokens` 有**另一条逐字通道**(`EngineTurnUsage` / `last_turn_usage.engineUsage`),所以镜像
5487
+ 不必长第二个座位;而**成本缺席没有任何别的载体** —— CC 的 `costUSD` 型面上是**必填 number**,
5488
+ 「这笔花销没定价」在 CC 形里根本不可表达。不加这一位,唯一写法就是 `costUSD: 0`,那正是 core 逐字
5489
+ 禁止的 `a fabricated 0`。
5490
+
5491
+ **读法:两键合读**
5492
+
5493
+ | `costUSD` | `_sema_cost_absent` | 含义 | 下一步 |
5494
+ |---|---|---|---|
5495
+ | `0` | 缺席 | **声明免费** | 渲 `$0.00`,进总计 |
5496
+ | `0` | `true` | **没定价** | 渲「未定价」,**别进总计** |
5497
+ | `> 0` | 缺席 | 有账 | 照渲 |
5498
+
5499
+ 🔴 判别位**只在缺席时铸,从不铸 `false`**(「键在值假」会被读成三态)。新导出类型 `SemaModelUsage`
5500
+ (= `ModelUsage` 的超集);只读 `costUSD` 的旧消费者**行为逐字不变**。
5501
+
5502
+ **端要做什么**:账单/footer 面改两键合读(cli / desktop / web 各一处);只渲 `total_cost_usd` 的端
5503
+ 零改,但要知道 `0` 从此是**真的免费**而不再是「不知道」。
5504
+
5505
+ **黑盒判据**
5506
+
5507
+ - **G30-6**:一台**声明免费**的模型跑完一条 run,`-p --output-format json` 的 `total_cost_usd` 为 **`0`**
5508
+ (修前为 `null`);`modelUsage[<model>]` 上 `costUSD === 0` 且**没有** `_sema_cost_absent` 键。
5509
+ - **G30-7**:一台**没有价表**的 worker 上同一条 run,`total_cost_usd` 为 **`null`**,且
5510
+ `modelUsage[<model>]._sema_cost_absent === true`(`costUSD` 仍是 `0`)。
5511
+ - **G30-8**:一条真的写过 prompt cache 的 run,`usage.cacheCreationInputTokens > 0`(修前恒 `0`)。
5512
+
5513
+ ---
5514
+
5515
+ ### 30d. ④ B-074 子代终态那一拍(core ≥7.0 `task_progress.status`;server ≥7.69.0 白名单)
5516
+
5517
+ **病**:core 的臂注逐字「**ONE final tick fires** at the sub-run's settle with the terminal face
5518
+ (`"completed"` | `"failed"`)」,并且把理由也写死了 ——「so a uuid-lane consumer **sees the row finish**
5519
+ instead of a bare removal after the last running beat」。而包边界:投影白名单里**没有 `status` 这一格**,
5520
+ adapt 层的注释还写着「子代从不发终态 tick」(那句话在 core 7.x 上已经是假的)⇒ 终态那一拍与一次普通
5521
+ running 拍**逐字节同形**,面板行只能等一次**防御 sweep**(而它只结「本 turn 活绑」的行)或一条
5522
+ `task_notification` 来收尸。
5523
+
5524
+ **修**
5525
+
5526
+ - 投影层:`task_progress.status` **开集**透传(词表属主在 core;缺席 / 空串 / 非串不铸)。
5527
+ - adapt 层:`completed` / `failed` ⇒ 走新的 `PanelTaskLedger.settleFromTerminalTick(taskId, isError)`
5528
+ —— 按 **taskId** 收(引擎说的是「这个子代结束了」,不是「这张卡关了」)、车道证明走 `laneOf`
5529
+ (绑了卡的行属 subagent lane,拿 main lane 的证明去落终态是帧×lane 矩阵那一族的病)、
5530
+ 同拍冻结 inline 群组行孪生、清常驻账、`SubagentStop` 走 if-started 门、与另两条 settle 腿
5531
+ 共用 `endedPanelTasks` 判重。**不标 live、不发第二条 tick。**
5532
+
5533
+ **🔴 三条不改判**(缺席语义)
5534
+
5535
+ 1. `status === 'running'` —— 逐字走修前那条路;
5536
+ 2. **`status` 缺席** —— 旧引擎不发这一格,读成终态会让**每一条**子代行在首拍就消失;
5537
+ 3. **开集里的第四个词** —— 走 running 那条路。猜错成终态 = 把一条还在跑的行提前结掉;
5538
+ 多渲一拍 running 只是慢一点。词表属主在 core,包不替它裁决。
5539
+
5540
+ **端要做什么**:**零改** —— 落行走的是既有 `panel_task{kind:'end'}` / `subagent_lifecycle{phase:'stop'}` /
5541
+ `inline_task_stats{op:'settle'}` 三条既有 chrome 臂,形一个字节没变。
5542
+
5543
+ **黑盒判据**
5544
+
5545
+ - **G30-9**:一条委派子代正常跑完,**在父卡 `tool_end` 之前**面板行已落终态(`panel_task{kind:'end',
5546
+ isError:false}` 恰一条);修前该行要等到关卡 sweep 或通知帧。
5547
+ - **G30-10**:子代失败时该 end 的 `isError === true`。
5548
+ - **G30-11**:同一 taskId 收到两拍终态(重放 / 双腿投递)⇒ `panel_task{kind:'end'}` 仍**恰一条**。
5549
+ - **G30-12**(负控):一台**只发 running、不发终态 tick** 的旧引擎上,子代行的行为与修前逐字相同。
5550
+ - **G30-13**(负控):workflow 子代即使带终态 `status`,前台面板**零事件**(lane 门仍在最前)。
5551
+
5552
+ **🔴 两条承重细节(异源对抗复审逼出,别按「先判终态再干活」重排)**
5553
+
5554
+ 1. **终态那一拍先把最终数字落到行上,再落终态**。它带的是子代的**最终**累计 usage;早退会让面板行
5555
+ 与 inline 群组行**冻在倒数第二拍**(实测 3 次工具 /150 tokens 被冻成 2 次 /100)。
5556
+ 2. **只落「关卡腿不会来收」的行**(`!panel.isLiveBound`)。绑在本 turn 还开着的委派卡上的行由
5557
+ `panel.settle(cardId, isError, report)` 收 —— **只有那条腿带得动子代的最终报告**,而三条 settle
5558
+ 腿共用 `endedPanelTasks` 判重 ⇒ 终态 tick 抢先落行会让关卡腿整条让位,报告从此到不了面板。
5559
+
5560
+ **⚠️ 已知边界:代际(`seq`)不参与判重**
5561
+
5562
+ core 的 `task_progress.seq` 是同一条后台行的**复活代际**(fresh spawn = 1,每次复活 +1),而本包三条
5563
+ settle 腿共用的 `endedPanelTasks` **只按 taskId 判重** ⇒ 第一代落终态之后,**第二代的终态在面板上
5564
+ 出不来**。本批**不修**,理由是「半个代际模型比没有更坏」:要修就得三条腿一起认代际,而关卡那条腿
5565
+ (`tool_end`)手上根本没有 `seq`,通知腿的 `seq` 又在另一个载体上 —— 只给终态 tick 认代际会让同一条行
5566
+ 在两条腿上按不同的键判重,后果是**重复落终态**(比漏落更坏)。⇒ 作为**跨腿的独立件**移交;
5567
+ `run-task-progress-terminal-projection-test.mjs` 的 **B9** 段钉住了今天的行为,它变好或变坏都当场红。
5568
+ (`seq` 今天连投影白名单都没进 —— §3d 的登记理由是「无消费方」。)
5569
+
5570
+ ---
5571
+
5572
+ ### 30e. ⑤ L-215③ assistant 行的身份四键(两铸两不铸)
5573
+
5574
+ **病**:`assistantArm` 交给渲染端的 `message` 是**裸** `{role, content}` —— CC `SDKAssistantMessage.message`
5575
+ 上那四个键(`id` / `model` / `usage` / `stop_reason`)一个都没有,于是壳侧十几处消费面各自**估算**
5576
+ (cli 1.0.107 已在壳侧回落 `turn_end` 真值当补丁,本件到货后那条补丁可退役)。
5577
+
5578
+ **两铸**
5579
+
5580
+ | 键 | 来源 | 缺席语义 |
5581
+ |---|---|---|
5582
+ | `message.id` | wire 的 `eventId`(core 铸 uuidv7,§E2) | 键不铸。🔴 **绝不现铸随机 v4**:同一条消息在 live 与 durable replay 上必须**同 id**,否则宿主去重与 R8 rewind 会把重放当新消息 |
5583
+ | `message.model` | **宿主**开流时钉的 `EmitContext.model` | 键不铸,**绝不猜**(猜错的模型名会被账单/能力面拿去查价表) |
5584
+
5585
+ ⚠️ `message.id` 与信封自己的 `uuid` 是**两个**身份位:后者是本地渲染键(`stamp` 现铸),前者是引擎身份。
5586
+ ⚠️ `EmitContext.model` 是**这条流声明的模型**,不是「这一轮真正服务的模型」—— mid-run degrade / 网关
5587
+ 重路由不改写它(与 `TaskResult.model` 同一条纪律)。要「真正服务的那一个」读终帧的 `model` / `degraded`。
5588
+
5589
+ **两不铸(帧序,不是遗漏)**
5590
+
5591
+ 🔴 wire 顺序是**内容臂先、`turn_end` 后**(sdk 臂注自陈:`text`/`text_delta` 是内容腿,`turn_end` 是
5592
+ 这一轮的收尾腿,两者不同帧)⇒ assistant 臂发出的那一刻,引擎**还没说**这一轮花了多少、为什么停。
5593
+ 在那里铸一个数只能是**估算**,而估算正是本件要根治的东西。
5594
+
5595
+ **也不采**「`turn_end` 到达时补发一条 CC 形 `assistant` 更新」:CC 的消息面**没有这种形**,合成一条
5596
+ 会让宿主的转录里出现一条引擎从没发过的消息。
5597
+
5598
+ **真值出口 = `turn_usage` 臂的两个超集键**
5599
+
5600
+ | 键 | 值 | 缺席语义 |
5601
+ |---|---|---|
5602
+ | `_sema_last_assistant_usage` | 这一轮的 CC `ModelUsage` 镜像 —— 与 footer 折叠用的是**同一只** `turnEndUsage()` 产物(不铸第二份 ⇒ 两面不会各漂各的) | `turn_end.usage` 整体缺席时**本臂根本不发**(既有行为) |
5603
+ | `_sema_stop_reason` | `turn_end.stopReason` **原词**透传(core 归一化后的五词 `stop`/`length`/`toolUse`/`error`/`aborted`;sdk 型面是开放 string ⇒ **按开集读**) | 键不铸(旧引擎不发)。🔴 缺席 ≠ `"stop"` |
5604
+
5605
+ **端要做什么**
5606
+
5607
+ - **必做**:开流时把模型 id 钉进 `EmitContext.model`,否则 `message.model` 恒缺席(与修前同形,不报错)。
5608
+ - 要「这一轮花了多少 / 为什么停」的面改吃 `turn_usage` 的两个新键;**别再等 assistant 行上的 usage**,
5609
+ 它按设计不会来。
5610
+ - 壳侧自建的估算腿可以整只退役。
5611
+
5612
+ **黑盒判据**
5613
+
5614
+ - **G30-14**:一条 live run 里每一条 assistant 转录行都带 `message.id`,且**与同 run durable replay 的
5615
+ 同一条消息逐字相同**。
5616
+ - **G30-15**:宿主钉了模型后,assistant 行 `message.model` 等于它;不钉时该键**不出现**(不是空串)。
5617
+ - **G30-16**:assistant 行上**没有** `message.usage` / `message.stop_reason` 两键(任何一条 run、任何一拍)。
5618
+ - **G30-17**:一轮被 max_tokens 截断的 turn,其 `turn_usage` 帧 `_sema_stop_reason === "length"`;
5619
+ 正常结束时为 `"stop"`;旧引擎上该键**不出现**。
5620
+ - **G30-18**:`turn_usage._sema_last_assistant_usage` 的六个 token 位与同 run `last_turn_usage` chrome
5621
+ 事件的 `usage` **逐键相等**(两面同源的可观察后果)。
5622
+
5623
+ **🔴 两条诚实缺席(异源对抗复审逼出,本节的 additive 之外还有这两件)**
5624
+
5625
+ | 情形 | `turn_usage` 臂 | `last_turn_usage` chrome |
5626
+ |---|---|---|
5627
+ | `turn_end.usageMissing === true` | **不铸**镜像,改铸 `_sema_usage_missing: true` | 同行加 `usageMissing: true` |
5628
+ | 真零账(没有 `usageMissing`) | 照铸镜像(全零),判别位不铸 | 不铸判别位 |
5629
+ | `usage` 整体缺席但有 `stopReason` | 本臂**照发**(不带 `outputTokens` 键) | 不发(那条腿的 `usage` 是必填位) |
5630
+ | 两者都缺席 | 不发(既有行为一字未动) | 不发 |
5631
+
5632
+ - **`usageMissing`**:core 的臂注逐字「Consumers must treat the missing usage as UNKNOWN — **not
5633
+ zero**」,而它与 `usage` **可以同帧**。把它剥掉,这条新通道就会把「不知道」渲成一笔全零的**已知**
5634
+ 账 —— 与 B-073 的成本 0/缺席是同一条病换了个量。
5635
+ - **`stopReason` 不被 usage 的存在性吞掉**:core 会发
5636
+ `{type:'turn_end', usageMissing:true, stopReason:'error'}` 这种合法帧,旧的发臂条件让它整条静默 ⇒
5637
+ 「这一轮为什么停」在最需要它的那一刻(出错 / 中止)出不去。🔴 **这是一条有意的行为变更**:此前
5638
+ 发 0 条的那一格现在发 1 条;**旧消费者零影响** —— `outputTokens` 读不出时整键不铸,而既有消费者
5639
+ (`adapt` 的 `turnUsageArm`)以 `typeof m.outputTokens === 'number'` 开门 ⇒ 对它是 no-op。
5640
+
5641
+ **🔴 身份两位必须穿过第二层投影**(`adapt`)
5642
+
5643
+ `adapt` 的五个 assistant 构造点都是**重建** `{role, content}` 的,不接力就把上游铸好的两位原地丢掉
5644
+ (异源对抗复审 [high]② 实抓)。现在由 `adapt/ids.ts` 的 `messageIdentityOf(frame, ctx)` 单点接力,
5645
+ 规矩两条:**`model` 帧优先、ctx 兜底**(live 分段腿的 `stream_event` 锚上没有它);**`id` 只认帧**。
5646
+ 两处例外**刻意保留且有理由**:
5647
+
5648
+ - **tool_use 卡臂只接 `model`,不接 `id`** —— 那条臂铸的是 **per-RESPONSE** 分组键(CC 的
5649
+ grouped-agent 渲染按 `${message.id}:${toolName}` 分组),换成 per-EVENT id 会把一张 Agent 卡拆成 N 张。
5650
+ - **终帧补差腿只接 `model`** —— 那条消息的正文是终帧的 `result`,把终帧的 eventId 当成一条 assistant
5651
+ 消息的身份,会让宿主把「补差出来的那一段」与终帧本身当成同一条东西。
5652
+
5653
+ - **G30-23**:`turn_end{usageMissing:true}` 的那一拍,`turn_usage` 上**没有** `_sema_last_assistant_usage`
5654
+ 而有 `_sema_usage_missing === true`;换成同形的**真零账**则相反(两档逐字可分)。
5655
+ - **G30-24**:`turn_end{usageMissing:true, stopReason:"error"}` 产出恰一条 `turn_usage`,带
5656
+ `_sema_stop_reason === "error"` 且**没有** `outputTokens` 键。
5657
+ - **G30-25**:一条 durable run 的每条 assistant 转录行都带 `message.id`/`message.model`;live 分段腿
5658
+ 上 `model` 来自宿主钉的值而 `id` **不出现**。
5659
+
5660
+ ---
5661
+
5662
+ ### 30f. ⑥ B-071 `armed` 与 `available` 拆成两个词
5663
+
5664
+ **病**:`classifierStatusOf` 读到 `autoMode.armed === true` 就判 `available`。而 core 的
5665
+ `WiringManifest.autoMode` 顶注把两件事**明确分开**了:
5666
+
5667
+ - `armed` ⇔ `reason === "armed"` —— 「the **classifier decider was minted for this leg**」,一个**装配期**事实;
5668
+ - 而「The classifier's **availability is a per-CALL fact**」(core 7.12.0 逐字;下一句还写明
5669
+ 「an unavailable round is a deny that says so, and **the next round is classified afresh**」)。
5670
+
5671
+ ⇒ 拿 `armed` 回答「可用吗」= 用装配期读数回答每次调用的问题。一个武装了的分类器完全可能在某一轮
5672
+ 跑不了(那一轮是一条 deny),下一轮又好了 —— 这正是 core 说「没有会话级 breaker 面」的理由。
5673
+
5674
+ **修**
5675
+
5676
+ - `CLASSIFIER_STATUS_STATES`:新增 `armed`(插在 `available` 之前)。⚠️ **与 ⑩ 同批**:`breaker_open`
5677
+ 随熔断族退役(§30k②)⇒ 合成后的表是**三词** `armed` / `available` / `unavailable_this_round`。
5678
+ - 优先序(承重):**本轮事实**(否定 `classifierUnavailable` ⇒ `unavailable_this_round`;
5679
+ **肯定** `origin === 'denial_limit_fallback'` ⇒ `available`)> 这条腿的 `armed`(⇒ `armed`)>
5680
+ `undefined`(说不出来)。⚠️ 修前那一档「历史熔断记录 ⇒ `breaker_open`」随 ⑩ 整只退役。
5681
+ - `classifierStatusDetail` 新增 `armed` **一句**(与 ⑩ 合成后熔断那半句不复存在),与既有各句**逐字互异**,
5682
+ 且**不说**「在跑」。
5683
+
5684
+ **🔴 为什么 `denial_limit_fallback` 是唯一的正向证据**:core `ask-origin.d.ts` 逐字 ——
5685
+ 「the auto-mode classifier reached its denial bound and handed the call to a person; **the classifier
5686
+ stands BEFORE this ask**」⇒ 这只 ask 的存在本身就证明分类器在这条调用链上跑过。别的 origin 一个都不算,
5687
+ 而且不是保守起见:
5688
+
5689
+ - `org_*` / `hook` / `ask_rule` / `unresolvable` / `content_question` —— core 的 `CLASSIFIER_MAY_ANSWER`
5690
+ 表逐行 `false`,分类器**结构上**就不许碰这些 ask ⇒ 它们的存在与分类器跑没跑完全无关;
5691
+ - `policy` / `safety_tighten` / `shell_gate_tighten` —— 分类器**可以**答(表里 `true`),但一只**存活到
5692
+ 卡上的** ask 恰恰说明这一轮它**没有**把它解决掉:可能是没跑,也可能是跑了判 ask。两种情形在这一格上
5693
+ 不可分 ⇒ 拿它判 `available` 就是在猜。
5694
+
5695
+ 判不出来时正解是回落 `armed`(「武装了,本轮如何不知道」),不冒充 `available`。
5696
+
5697
+ **缺席语义**:`autoMode` 段缺席(旧 mint / 外部 derive)**且卡上没有任何本轮事实** ⇒ `undefined`
5698
+ (**绝不**折成任何一态);🔴 但**本轮两条臂都不依赖那一段** —— 段缺席而卡上带 `classifierUnavailable`
5699
+ 仍判 `unavailable_this_round`、带 `denial_limit_fallback` 仍判 `available`(可用性是这次调用的事实,
5700
+ 不是装配的事实;门 G1d 逐格钉住)。`origin` 读不出 ⇒ 不判 `available`。⚠️ 修前「历史熔断记录在任何
5701
+ 一态上照带(`view.breaker`)」随 ⑩ 退役(那一位已从 `ClassifierStatusView` 上删掉)。
5702
+
5703
+ **端要做什么**:`/doctor` 那一行的词由本包 `classifierStatusDetail` **单铸** ⇒ **端零改即接通新词**。
5704
+ 自己 `switch` 过 `state` 的端(而不是直接渲那句话)要加 `armed` 一臂;按开集写的端零改。
5705
+
5706
+ **黑盒判据**
5707
+
5708
+ - **G30-19**:一条 auto 模式武装、本轮没有任何 ask 的会话,`/doctor` 那一行说的是「**armed**」,
5709
+ 且**不含**「is running」字样(修前逐字是「the auto-mode classifier is running on this session」)。
5710
+ - **G30-20**:同一会话上出现一只 `origin === "denial_limit_fallback"` 的审批卡后,状态读数为 `available`。
5711
+ - **G30-21**:同一会话上出现一只 `origin === "policy"` 的审批卡(且卡上无 `classifierUnavailable`),
5712
+ 状态读数仍为 `armed` —— **不是** `available`。
5713
+ - **G30-22**(不改判):`autoMode` 段缺席**且本轮无任何事实**时状态读数仍是「说不出来」;卡上带
5714
+ `classifierUnavailable` 时仍是 `unavailable_this_round`。⚠️ 原第三条判据「没武装 + 有熔断记录 ⇒
5715
+ `breaker_open`」随 ⑩ 作废(那条腿在这一代引擎上不存在),对位的新判据见 G30-23。
5716
+ - **G30-23**(⑥⑩ 合成后的对位判据):一台**旧引擎**仍在 `autoMode` 上带 `breaker` 时 ——
5717
+ ① `armed:true` 的那份读数是 **`armed`**(旧账本不改判这条腿的事实,也不渲任何熔断解释);
5718
+ ② **没武装**的那份读数是「说不出来」(修前会渲 `breaker_open`);
5719
+ ③ 两种情形下 `breaker` 那一位都**一个字节到不了端**(投影白名单;§30k②)。
5720
+
5721
+ ---
5722
+
5723
+ ### 30g. 常驻门
5724
+
5725
+ | 门 | 守什么 |
5726
+ |---|---|
5727
+ | `scripts/run-compaction-boundary-projection-test.mjs` | 🆕 ① 三键 + `message_committed` 两面;`clampedRatio` 的 sdk 座位带**退出条件**(补上当天红逼复核 raw 读) |
5728
+ | `scripts/run-cost-absence-projection-test.mjs` | 🆕 ②③ 显式 0 ≠ 缺席、两键合读、判别位从不铸 `false`、`cacheCreationInputTokens` 读真值、扁平四格有限数守卫 |
5729
+ | `scripts/run-task-progress-terminal-projection-test.mjs` | 🆕 ④ `status` 开集透传 + 终态落行 + **三条不改判** + 幂等 + workflow lane 门在先 |
5730
+ | `scripts/run-assistant-arm-identity-test.mjs` | 🆕 ⑤ `id`/`model` 与缺席语义、`usage`/`stop_reason` **不在臂上**的反向钉、`turn_usage` 两超集键 |
5731
+ | `scripts/run-classifier-status-test.mjs` | 🆕 **G 段**(⑥):**三词表**(与 ⑩ 合成后)、`armed` ≠ `available`、`denial_limit_fallback` 是唯一正向证据(其余十一词逐词负控)、优先序、措辞**三句互异**;`per-CALL` 那句的 core 7.12.0 逐字锚 —— ⑩ 把 devDep 抬到 `~7.12.0` ⇒ C1 车那条「领先登记」按它自己写的退出条件**当场销账**,换成正向逐字断言 |
5732
+ | `scripts/run-integration-doc-freshness-test.mjs` | §3c 臂表(`message_committed` 离表)、`CLASSIFIER_STATUS_STATES` **成员换代**(表长仍 3:删 `breaker_open`、加 `armed`)、本节新增坐标在盘 + 入库 |
5733
+ | `scripts/run-public-surface-test.mjs` | ①–⑥ 公面**零新增运行期导出**(全是类型:`SemaModelUsage` / `MessageCommittedChromeEvent`)⇒ 基线由 ⑦–⑩ 单独抬到 **928**(十一件 additive、两件删除,见 §30k) |
5734
+
5735
+ ---
5736
+
5737
+ **⑦–⑩(小节 §30h–§30n):接入审计 B 战役的包侧归层四件**
5738
+
5739
+ 本半场修的是同一类病:**上游早就说清楚了,而本包这一层要么没读、要么读成了另一件事**。四件各自
5740
+ 独立,但都落在「判定归包、呈现归端」这条线上 —— 端不该为同一条 wire 各写一份读法。
5741
+
5742
+ ---
5743
+
5744
+ ### 30h. B-070 / L-200 `/decide` 的 **200 是投递受理,不是「门已解决」**
5745
+
5746
+ **合同(三处逐字)**:
5747
+
5748
+ | 出处 | 逐字 |
5749
+ |---|---|
5750
+ | sdk `README.md` §9.0.0「谁受伤」 | 「workflow 车道的 200 只是**投递受理** —— 子代的 checkpoint 仍 pending,`/v1/approvals` 上那张卡**可能还在**。据 200 立刻把卡从 UI 抹掉,用户会看到一张『批过了却还在』的幽灵卡」 |
5751
+ | sdk `README.md` §9.0.0「逐件」 | 成功形 = `{taskId, sessionId, status:"resuming", bindingEnforced:true}`,`taskId` 是**宿主新铸**的 run id(**poll 它,不要盯那张卡**) |
5752
+ | core `runner/contracts.d.ts:1492` | 那一步 **launches the run that re-invokes** |
5753
+ | core `checkpoint-store.d.ts:1785` / sdk `types.d.ts:3812` | `executionOutcome` 缺席 = **the execution outcome is not known, never "it was allowed"** |
5754
+
5755
+ **病与修(三格)**:
5756
+
5757
+ | # | 病(修前坐标) | 修 |
5758
+ |---|---|---|
5759
+ | ① | `hitl/hitlBridge.ts` 的 `decideRaw`:`approvals.decide` 一回 200 就 `this.active = null` —— 而**同一行上方的注释**自己写着「the gate clears on the next running arm」,注释与码互相矛盾 | 删掉那一行。`active` 由 `observe()` 在**流上的下一条 running 臂 / 终态臂**上清(那条腿修前就在,本批没有新增任何清除路径)。⚠️ 射程如实说:`active` 只在宿主真驱动 `observe()` 时 latch,两处生产调用点都不驱动 ⇒ 现实效果 = 对已驱动 observe 的宿主(desktop/web 座位层)不再谎报「门没了」,不驱动的宿主**逐字节不变** |
5760
+ | ② | `hitl/parkResolver.ts:629/677` 的重挂腿恒用**原** `taskId` 重挂 `runs.events` —— workflow 车道已经把续跑交给**宿主新铸**的 run,旧流上再也不会有推进帧 ⇒ 预算一路烧到 hop 上限,终帧是一句与真因无关的话 | 新增 `ParkResolution.handoffTaskId`(两条 reattach 臂都带)。判据是**两件合取**:回执 `status === "resuming"` ∧ 非空 `taskId`(判在 `readDecideReceipt`),**再加**「与当前 taskId 不同」(判在 `resolvePark`)—— 少了后者,任务级车道的受理形回执会被当成换挂而白白丢掉 `lastEventId`。`askGateWire` 收到它就换挂,并 **同时丢 `lastEventId` + `led.forgetSeq()`**:durable seq 是 **per-run** 的,拿旧 run 的序号去续读新 run 是跨命名空间取数 |
5761
+ | ③ | `executionOutcome` 在本包**零消费**;三条新码(`decide.workflow_host_unknown` / `_host_not_parked` / `_remember_unsupported`)**零消费** | 新模块 `src/decideReceipt.ts`:`readDecideReceipt()` 读 200 的四种形(受理 / 终局 / parked 回执 / 幂等回放),`executionOutcome` 走 **`gateOutcome.ts` 的同一只读器**(包回 `{gate: …}` 的形喂进去,不在这里另写一份门记录读法);三码入 `engineErrorCodes.ts` 的闭集 `DECIDE_WORKFLOW_LANE_CODES`,`decideRefusalFromError()` 各给**一句人话**(单铸,端零自拼)+ 一个 `resendable` 处置位 |
5762
+
5763
+ 🔴 **`executionOutcome` 的消费纪律(端必读)**:它**只在幂等回放形上**;`decision` 说的是「人批了没有」,
5764
+ 它说的是「执行时被放行还是被部署复核在 post-CAS 否掉」,**两者可以相反**。**缺席 = 未知**(判词还没落上 /
5765
+ 记录读不懂 / 命中行之间分歧)—— 🔴 **禁读成 allowed**。卡上「这次到底执行了没有」那一行:**在场才说**,
5766
+ 缺席一个字都不说。
5767
+
5768
+ 🔴 **本包刻意**不提供 `isDecideResolved()`:不存在任何一位能从 200 体上读出「门已解决」。给的是方向相反的
5769
+ `decideAcceptedNotResolved()` —— 它答的是「这个 200 **明说**了续跑还没做完吗」,`false` **也不是**「已解决」。
5770
+ 解决的证据只有一处:**流上的下一条 running 臂 / 新 run 的事件**。
5771
+
5772
+ 🔴 **三码各自的出路刻意不同**(合并判就会把「重发没用」与「等一会儿重发」说成同一件事):
5773
+ `host_unknown`(409)= **无重试价值**(`resendable:false`);`host_not_parked`(409)= 等宿主再 park 后重发;
5774
+ `remember_unsupported`(400)= **去掉 `remember` 重发**,零副作用。
5775
+ ⚠️ 三码**都不带窗**:server 只在 `RESUME_RETRY_LATER_CODES` 那两码上铸 `retryAfterSec` ⇒ 端**不许**据
5776
+ `resendable` 渲一个编出来的倒计时。
5777
+ ⚠️ `DecideRefusalDetail.runId` 与拒体的 `taskId` 是**两个句柄位**,「各自只在自己那条车道上在场,按
5778
+ `.errorCode` 分,**不要互相回落**」(sdk README §9.0.0 逐字)—— 读不出就缺席,绝不拿手上的 taskId 顶上去。
5779
+
5780
+ ---
5781
+
5782
+ ### 30i. B-078 / L-208 `approval_request` / `approval_revoke` 两条 **chrome 臂**(归层修)
5783
+
5784
+ **病**:标准管线 `adapter/downstream/eventToSdkMessage.ts` 对这两臂的处置是 `dropped('unsupported_arm')`
5785
+ —— 有痕,但**包内零消费口**。壳(cli)于是在自己的 `sema-cli/src/sema/approvalStreamWire.ts:1030/1500` 单独接了一份,
5786
+ 而 desktop / web **只走包管线** ⇒ ①开流 preamble 恢复不了 pending 卡集、②撤销后本地卡不清。
5787
+ 同一条 wire 上的同一件事,一个端有、两个端没有 —— 归层违例。
5788
+
5789
+ **修**:两臂投成 chrome 事件 `kind:'approval_request'` / `'approval_revoke'`,载荷 = **帧原样窄读**。
5790
+ 消费义务写在 `seam.ts` 的 `ApprovalRequestChromeEvent` / `ApprovalRevokeChromeEvent` 两个接口头注里
5791
+ (那是端要读的那一份),并登记进 `CHROME_ARM_TABLE`,两条都是 **`required: true`**。
5792
+
5793
+ 🔴 **载荷是信封,不是 v1 卡**(sdk `events.d.ts:961-968` 当场挡下来的那条):sdk 把这两臂声明成
5794
+ `ApprovalFrameEnvelope`(`type` + `schemaVersion: number` + 开集键)而**不是** v1 帧型 —— SSE 解析腿只做
5795
+ `JSON.parse(...) as AgentEvent`、**不跑**谓词,臂若窄化到 v1,一条 `schemaVersion: 2` 的合法帧会被类型
5796
+ 系统当成 v1 端上来,消费端于是去取 `card.risk.requiresRealApproval`,而未知版本的卡根本不保证有这些键。
5797
+ ⇒ 包只做**信封级**成形判(`schemaVersion` 是不是有限数 / `frame` 是不是对象),窄化
5798
+ (`isApprovalRequestFrameV1` / `isApprovalRevokeFrameV1`)是**端**的动作;窄不下来 ⇒ **呈通用卡 + 人工
5799
+ approve/deny,🔴 永不 auto-deny**(呈卡臂)/ **该批本地卡照清**(撤卡臂)。
5800
+
5801
+ 🔴 **包不做去重/归属过滤**:`approvalId` 去重(同一只 ask 在开关打开时出两帧,顺序钉死「先 legacy、后
5802
+ 本帧」)、按 `taskId` 归属(晚入分发集合的 run 账本可出现**无配对卡帧的孤儿撤帧行**)、开流 preamble 全量
5803
+ 对账 —— 三件都需要**端的卡集状态**,库这一层没有也不该有。
5804
+ 🔴 **账本重放的帧只用于时间线渲染,不是卡集基准**(呈卡帧带的 `expiresInMs` 是铸帧时刻的旧值;撤卡帧
5805
+ **可能整帧丢失** —— 帧是通知,行才是真源)。卡集的全量对账基准恒为**开流 preamble**。
5806
+ 🔴 **刻意没有子流断闸**(与 `engine_notice` / `text_segment_end` 三臂相反,这是有理由的差别):那几条断闸挡
5807
+ 的是「把子代腿的东西渲到 leader 面上」;而审批卡**必须**上到人面前 —— 一张属于子代调用的卡也要人来点,
5808
+ 断掉它等于把那条 run 挂死在没人看得见的地方。归属由端按帧上的 `taskId` **过滤**,不是**丢弃**。
5809
+
5810
+ ---
5811
+
5812
+ ### 30j. L-215①② fleet `parked` 与「非成功终局」的**单铸谓词**
5813
+
5814
+ **①`coerceWorkflowStatus` 认 `parked`**(`src/fleet/fleetProjection.ts`)。修前没有这个 `case` ⇒ 它落
5815
+ `default` 被折成 `running`:fleet 车道上一条**停着等人**的工作流被渲成「在跑」,用户没有任何线索去找那张卡。
5816
+ 现与 `coerceTaskStatus` 的 `parked` 臂**同一个落点** `awaiting approval`(同一件事在两条车道上必须渲同一个词)。
5817
+
5818
+ 🔴 **选形理由(直接加词,不铸 `_sema_parked` 超集键)**:判据是 sdk 那一位**在型面上开不开**,不是「它今天
5819
+ 有几个已知值」。`FleetWorkflowRow.status` 在 sdk 8.8.0 与 9.0.0 上**都**声明成裸 `string`
5820
+ (`dist/resources/fleet.d.ts`,头注逐字「the NEUTRAL workflow run status (`running`|`completed`|`failed`),
5821
+ **open on read**」)—— **它不是闭集**,新词在 wire 上、在型面上都合法,消费端要做的就是认它。此时再加一个
5822
+ `_sema_` 前缀的孪生布尔 = 替一件上游已经能说清楚的事另铸第二个真源,而两个真源迟早分叉。超集键留给
5823
+ 「上游那一位真是闭集、加词会让严格消费端判违约」的那一类,这里不是。
5824
+ ⚠️ 本函数同时收 run 席与 item 席:core 的两张词表里 `parked` 只在 item 席,但**渲染面的处置相同**(都是
5825
+ 「等人」),为「哪一席」分叉只会长出一条没有用户面差别的分支。
5826
+
5827
+ **②「非成功终局」的单铸谓词**(`src/runTerminal.ts` 新增):
5828
+
5829
+ ```ts
5830
+ export const TERMINAL_NOT_SUCCESS_STATUSES = ['failed', 'killed', 'blocked'] // 闭集
5831
+ export function isTerminalNotSuccess(status: unknown): boolean
5832
+ export const TERMINAL_STATUSES = ['completed', ...TERMINAL_NOT_SUCCESS_STATUSES]
5833
+ export function isTerminalStatus(status: unknown): boolean
5834
+ ```
5835
+
5836
+ 🔴 **`blocked` 与 `suspended`/`needs_review` 的分界是这张表存在的全部理由**(core [6908] 定谳):
5837
+ `blocked` = **agent 自报的终态**(它自己判定这条 run 走不下去了),**不是「等人」**;
5838
+ `suspended` / `needs_review` = **等一次人的决定**,run 还活着 —— 把它们读成「非成功终局」会把一条**正等着你**
5839
+ 的 run 在面板上判死,与本件要修的方向相反的同一类错。
5840
+
5841
+ **同形存量族扫(三处,一次改齐)**:
5842
+
5843
+ | 坐标 | 修前 | 后果 |
5844
+ |---|---|---|
5845
+ | `notifications.ts` 的 bg 面板 settle | `isError: n.status === 'failed' \|\| n.status === 'killed'` | 一条**自报走不下去**的后台 run 在面板上被 settle 成**成功** |
5846
+ | `fleetAgentPanelProjection.ts` 的同名位 | 同上(内联两词) | ⚠️ **射程如实说**:这一处今天是**单源化**而不是活的修复 —— 它的收口判据在外层 `TERMINAL_FLEET_TASK_STATUSES.has(status)` 之内,而喂进来的 `status` 是 `coerceTaskStatus` 出来的**渲染词汇**(闭集,没有 `blocked`)⇒ `blocked` 结构上到不了这一格。改它的价值是「下一次加词时不会再漏一处」,不是「今天修好了一条路」 |
5847
+ | `notifications.ts` 的通知 seed 扫描 / `adapt/arms.ts` 的 bgshell settle 门 | 手抄 `completed\|failed\|killed` 三词 | 一条 `blocked` 通知不进 `notifiedKeys`(重开会话再投一次);一条 `blocked` 的后台行**永远不 settle**(面板上挂着一条不会再动的「在跑」)。⚠️ 边界:`adapt/arms.ts` 那一格读的是 `normalizeTaskNotification` **归一后**的 `status`,而那只归一器对**非串**状态(缺席 / `null` / 数字)按既有的调用方契约回填成 `completed` ⇒ 那三形今天仍以「成功」收口。这是**修前就在**的一处诚实性缺口(与本件的 `blocked` 无关,谓词对 `undefined` 照旧答 `false`),**本批刻意不动它** —— 去掉那条回填是行为面改动、且与该函数写明的调用方契约冲突,另立一批;见 §30m 的消费方待办第 8 行 |
5848
+
5849
+ 🔴 **`false` 不等于「成功」**:两只谓词对表外词答 `false`,那只说「这个词不在本端认得的表里」。判「成功」
5850
+ 必须读成功那一侧的正向证据(`readRunTerminal` 的 `completed` 臂),**不能拿本谓词的取反当成功判据** ——
5851
+ 那正是「不认识的终态词折成成功」那条已定谳的事故形。
5852
+
5853
+ ---
5854
+
5855
+ ### 30k. B-080 / L-210 闭集镜像过期族(devDep 随引擎 + 熔断族退役 + AskOrigin 三句订正)
5856
+
5857
+ **①`devDep @sema-agent/core` `~7.10.0` → `~7.12.0`**。所有「镜像 vs 实装 core」的门此前都在**对旧物校**
5858
+ (7.11 / 7.12 的三张闭集变动整批漏过)。抬版后**逐条处置**见 §30n 的门表。
5859
+
5860
+ **②熔断族整只退役(clean-cut,不留别名、不留兼容读)**。合同 = core 7.12.0 CHANGELOG
5861
+ 「Removed (BREAKING)」`AUTO_MODE_BREAKER_CAUSES` / `WiringManifest.autoMode.breaker`,
5862
+ `AUTO_MODE_UNAVAILABLE_CAUSES` 同批收成 `["error","timeout"]`(`dist/core/auto-mode.d.ts:9` 真字节);
5863
+ server 7.70.0([6927])读面同批收窄。
5864
+
5865
+ | 退役物 | 修前坐标 |
5866
+ |---|---|
5867
+ | `breaker_open` 这个**成因词** | `autoModeUnavailable.ts` 的 `AUTO_MODE_UNAVAILABLE_CAUSES` 与 `CAUSE_SENTENCES` |
5868
+ | `AUTO_MODE_BREAKER_CAUSES` / `ClassifierBreakerView` / `classifierBreakerOf` | `autoModeUnavailable.ts`(公面三件) |
5869
+ | `breaker?: ClassifierBreakerView` 型位 + 它的窄读 | `adapter/downstream/eventToSdkMessage.ts` 的 `WiringManifestAutoMode` 与 `projectAutoModeSection` |
5870
+ | `breaker_open` **状态词** + `ClassifierStatusView.breaker` + `BREAKER_CAUSE_PHRASES` + 两句熔断人话 | `classifierStatus.ts`(删这一态;与 §30f 的 `armed` 同批合成后是**三态**) |
5871
+
5872
+ ⚠️ **如实登记一句被推翻的旧承诺**:0.64.0 的 `classifierStatus.ts` 顶注写过「上游若把 `breaker` 退役,
5873
+ 本模块**零改**(缺席臂当天就是正解)」。那句话对**读数**成立(读不到就是没有),对**词表与型面**不成立 ——
5874
+ `CLASSIFIER_STATUS_STATES` 里 `breaker_open` 那个成员与 `ClassifierStatusView.breaker` 仍在公面上承诺着一件上游已经不发
5875
+ 的事,`/doctor` 的 Auto classifier 行因此**永远渲不出那一态**而它还写在表里(假 affordance)。本批因此不是
5876
+ 「零改」,是**按退役条款把承诺一起收掉**。
5877
+
5878
+ ⚠️ **`parse_error` 的排除行为一字未变**(黑盒判据 G-19 照旧成立),但**派生的出处换了**:修前它是
5879
+ 「熔断轴 − 不可用轴」的**差集**,而 core 7.12.0 删掉熔断表之后那条派生的右操作数不存在了。排除的**理由**
5880
+ 从头到尾都不在熔断轴上 —— core `AutoModeVerdict` 的 `parse_error` 臂逐字是「分类器**跑了并且答了**,只是
5881
+ 答在契约之外,按 BLOCK 处置」。现按理由的真出处直写一张单员表 `NEVER_STAMPED_CAUSES`。
5882
+
5883
+ ⚠️ **旧引擎发来的 `breaker_open` 仍照旧过境**(`cause` 的开集读一个字节没动),只是走
5884
+ `classifierUnavailableDetail` 的兜底句、不再冒充一句本端自铸的熔断解释。
5885
+
5886
+ **③AskOrigin 三句订正**(`gateVocabulary.ts`;合同 = core `dist/core/ask-origin.d.ts` 真字节):
5887
+
5888
+ | 词 | 修前(漂开了上游) | 修后 | 出处 |
5889
+ |---|---|---|---|
5890
+ | `unresolvable` | 「the gate could not decide on its own, so it asks」(渲成「门拿不定主意」⇒ 用户去找一个不存在的「让门自己拿主意」的配置) | 「an ancestor marked this call (an inherited approver-unavailable float, or a durable mandate): it must reach the park with no synchronous decision-maker in between」 | `ask-origin.d.ts:36-38` |
5891
+ | `shell_gate_tighten` | 「asks about **every** shell command at this gate setting」(过度陈述 ⇒ 用户以为旋钮只有开/关两档) | 「asks about shell commands the coarse shell gate rates **above this tier**」 | `ask-origin.d.ts:58-59` |
5892
+ | `rule_store_unavailable` | 固定句「the rule store was unavailable」(而这个词盖的是**两种机制**) | 中性定义句「this call could not be checked against your standing deny/ask rules, so it asks」+ **引擎 `message` 优先** | `ask-origin.d.ts:44-51` + core CHANGELOG 7.9.1 逐字「a card that hard-codes store wording for the origin should read the message」 |
5893
+
5894
+ `askOriginDetail(origin, message?)` 新增 **additive 第二参**:**只在** `ORIGIN_PREFERS_ENGINE_MESSAGE`
5895
+ (闭集,今天单员 `rule_store_unavailable`)的词上优先,其余词一字不读。缺席 / 非串 / 空白串 ⇒ 行为与本参
5896
+ 出现之前**逐字节相同**。
5897
+ 🔴 **不是「有 message 就用 message」**:绝大多数出身词的那一句是**定义句**(对每一只同出身的 ask 都成立),
5898
+ 而引擎的 `message` 是**这一只**调用的散文 —— 无差别地顶掉定义句会把「谁问的」换成「引擎这一次写了什么」。
5899
+ 本集只收**一个词盖了多种机制**的那一类。
5900
+ 🔴 `message` 是引擎/工具产文:**只渲不回喂模型**;本铸点**不截断不改写**它,显示封顶归端。
5901
+
5902
+ ⚠️ **`unresolvable` → `ancestor_marked` 的换字不在本批**(随 core 7.14.0 到货批);`ASK_ORIGIN_WORDS`
5903
+ 与 core `ASK_ORIGINS` 的逐字同源门照跑,本批只改那一句人话。
5904
+
5905
+ ---
5906
+
5907
+ ### 30l. ⚠️ 订正:`classifierUnavailable` 的**两条腿枚不枚举,是两件事**(§29e 的射程收窄)
5908
+
5909
+ §29e 与 §27h2 写过「集外成因词**逐字上 wire**」。亲核后如实收窄:**那句话只对活卡帧腿成立**。
5910
+
5911
+ | 腿 | 枚不枚举 | 直证 |
5912
+ |---|---|---|
5913
+ | **活卡帧 / `card_json`**(`approval_request` 呈卡帧、落库、断连重放) | **不枚举**,只判非空串形门 | server `sema-server/src/approval-card.ts:554` `z.object({ cause: z.string().min(1).max(MAX_IDENT) }).strict()`;同处顶注逐字「本仓**刻意不枚举**它 … 判据只到『非空串』这一层形门」 |
5914
+ | **耐久腿**(`GET /v1/assistant/inbox` 行 / durable park 行) | **按 core 枚举,集外词缺席** | core `dist/core/checkpoint-store.js:281` `isAutoModeUnavailableCause(tool.classifierUnavailable?.cause) ? { classifierUnavailable: { cause } } : {}`;server `sema-server/src/http/routes/approvals-assistant.ts:434-435` 逐字「值**完全由 core 供**(`summarizeCheckpoint` 只在 `isAutoModeUnavailableCause` 成员时回显,**集外词读作缺席**)⇒ server 不重算、不再筛第二遍」 |
5915
+
5916
+ **对本包的影响(零行为改动,只改文档口径)**:`classifierUnavailableOf` 的**开集透传语义一个字节不变**
5917
+ (它读的是**送到它手上**的那一格,不管那一格是哪条腿供的)。要改的是**期望**:
5918
+
5919
+ - 🔴 **耐久腿上的集外成因词到不了本包** —— 它在 core 的投影口就被读作缺席。所以端在 inbox / park 行上
5920
+ **看不到新成因词**不是本包吞了,也不是「分类器没出问题」,是**上游那条腿按闭集筛过**;
5921
+ - 🔴 **两腿因此可能对同一次不可用给出不同的在场性**:活卡帧上有 `cause:"<新词>"`,而同一只 ask park 之后
5922
+ 的行上**整键缺席**。这**不是**矛盾,是两条腿的筛法不同 —— 端**不许**据此推断「park 之后分类器就好了」;
5923
+ - ⚠️ 本包 §29b 那条「两腿同值反向对照」的门段仍然成立:它对的是**同一个已知成因词**走两条腿(闭集内),
5924
+ 而不是集外词。
5925
+
5926
+ ⚠️ 本条也把 §30k② 的退役说清楚了:`breaker_open` 在 core 7.12.0 之后**两条腿都到不了**(耐久腿被
5927
+ `isAutoModeUnavailableCause` 筛掉,活卡帧腿虽不枚举但 server 7.70.0 的读面已不再产它)——
5928
+ 这正是本包可以**干净切**掉那个词的自铸解释句、而不必留兼容读的原因。
5929
+
5930
+ ---
5931
+
5932
+ ### 30m. 消费方待办
5933
+
5934
+ **cli(换装 0.65.x 后应退役 / 应跟改)**:
5935
+
5936
+ | # | 坐标 | 动作 |
5937
+ |---|---|---|
5938
+ | 1 | `sema-cli/src/sema/approvalStreamWire.ts:1030`(`if (t === 'approval_request')` 整段:`laneEngaged()` 让位臂 + `track(onApprovalRequest(...))` + `continue // 消费:绝不下游`) | **退役**:改由包管线的 chrome `approval_request` 臂驱动同一套卡口。注释里那句「client-core 投影器对它只有 dropped 一条路」**已过期**,同批删 |
5939
+ | 2 | `sema-cli/src/sema/approvalStreamWire.ts:1040-1045`(`if (t === 'approval_revoke')` 让位臂 + `onApprovalRevoke(ev)`)与 `:1485-1515` 的撤卡消费体(`retractApprovalCard` / `abort` / `notify` 归因行) | **归口**:撤卡的**判定**(窄化 / 按 `askIds` 挑键 / 零命中不多说归因行)已在包臂契约里;壳保留的是**呈现**(卡口 retract + 归因行渲染),不再自己认帧 |
5940
+ | 3 | `sema-cli/src/sema/askParkExpiry.ts:757-770`(任何 200 判 `resumed`) | **跟改**:200 只是投递受理;判「解决」改看下一条 running 臂 / 新 run 事件,或读包的 `readDecideReceipt().handoffTaskId` |
5941
+ | 4 | `sema-cli/src/sema/liveClient.ts` 的 bg 白名单(与包 `isError` 表的耦合反钉在 `a81e708d`) | **同批消费** `isTerminalNotSuccess` —— 🔴 **包一改壳当场红**(那正是反钉的用意);别在壳里补第二张三词表 |
5942
+ | 5 | `commands/doctor/axesRows.ts:458+`(Auto classifier 行的三态)/ `wiringManifestStore.ts:159`(`autoMode.breaker` 读点) | **退役**熔断那一态与那个读点(`breaker` 型位已删 ⇒ 壳侧读点编译红);同批**新增 `armed` 一臂**(§30f,词表仍是三词,成员换了一个) |
5943
+ | 6 | `askFrameNotes` 的 `QUIET_ASK_ORIGINS`(把 `unresolvable` 静音) | **复核**:修后那一句说的是「祖先标记 + 必达 park」,是**用户要知道**的事实,静音的理由(「门拿不定主意=废话」)已随旧句作废 |
5944
+ | 7 | 卡面「这次到底执行了没有」那一行 | **新增**(可选):读 `FsApprovalOutcome.receipt?.executionOutcome`;🔴 **缺席一个字都不说**,禁渲 allowed |
5945
+ | 8 | 📋 **本批登记、不修**:`normalizeTaskNotification`(`src/notifications.ts`)把**非串** `status`(缺席 / `null` / 数字)回填成 `completed` ⇒ 一条状态读不出的后台通知以「成功」收口 | 这是修前就在的诚实性缺口(异源复审 [medium] 撞获),与本件的 `blocked` 无关。去掉回填是行为面改动、且与该函数头注写明的**调用方契约**冲突(「本纯函数不做回填……落 adapt() 时必须先补齐这两个字段」)⇒ **另立一批**:要么让归一器保留未知状态、要么在 adapt 入口按原始状态判。本批只把它记在这里 |
5946
+ | 9 | 📋 **本批登记、不修**:`coerceTaskStatus('blocked')` 落 `default` ⇒ 渲成 `idle` | fleet **task** 行的 `status` 来自 sdk 的**闭集** `FleetTaskStatus`(没有 `blocked`),所以今天结构上到不了;但 run 级的 `blocked` 若哪天进了那条车道,`idle` 是一个**中性**词而不是失败词。属 B-079① 的地界(cli `seamQuery` 那一侧),本批不越界 |
5947
+
5948
+ **desktop / web 自查点**:
5949
+
5950
+ | # | 自查 |
5951
+ |---|---|
5952
+ | 1 | `CHROME_ARM_TABLE` 新增两条 **`required: true`** 的臂 —— 座位层自检遍历那张表时会**当天报缺**;不实现 = 流内审批卡整面哑掉(重连后 pending 卡恢复不了 / 撤销后卡不清) |
5953
+ | 2 | 实现时**不许**把 `frame` 直接当 v1 卡读:必须过 sdk 的两个窄化谓词;窄不下来 ⇒ 通用卡 + 人工决断,**永不 auto-deny** |
5954
+ | 3 | `ClassifierStatusView.breaker` 与 `classifierBreakerOf` **已删** ⇒ 读过它们的地方编译红,删读点即可(状态面自然回落到 §30f 的三态) |
5955
+ | 4 | fleet 行 `status` 现在可能是 `awaiting approval`(由 `parked` 折来)—— 渲染表若按旧三词穷举,补这一格 |
5956
+
5957
+ ---
5958
+
5959
+ ### 30n. 常驻门(⑦–⑩ 四件)
5960
+
5961
+ | 门 | 守什么 |
5962
+ |---|---|
5963
+ | `scripts/run-decide-receipt-test.mjs` | 🆕(B-070):四种 200 形的读数 / `handoffTaskId` 的**两件合取**判据(少一件即不铸)/ `executionOutcome` 走 `gateOutcome` 同一只读器且**缺席 ⇒ `undefined` 而不是 allowed** / 三码闭集各自一句互异人话 + `resendable` 三值 / 表外 `decide.*` 码一律 `null`(绝不按前缀猜)/ `runId` 读不出即缺席(不拿 taskId 顶)/ 🆕 **G 段**(异源复审 [high] 的回归钉):换挂那一拍 `led.forgetRunScopedState()` 把**跟着 run 走**的三张表(已渲 call 集 + 两张 args 快照)连同 seq 一起清掉,而「这一只 ask 的历史」(已决身份 / 扣留帧 / 同因计数)刻意留着 —— 病形自证在门里:不清的话,新 run 复用同一个 `toolCallId` 会被渲染闸挡住,于是卡面渲**旧 run 的入参**而 decide 回显**新 pending 行**的 D-1 绑定(人看见 A、批准的是 B) |
5964
+ | `scripts/run-approval-frame-chrome-arms-test.mjs` | 🆕(B-078):两臂不再 `dropped` / 载荷是**信封原样**(v1 与非 v1 两形都过境、键一个不摘)/ `schemaVersion` 非有限数 ⇒ `dropped('malformed')` 而不是静默 `none` / `CHROME_ARM_TABLE` 两行 `required: true` / 端到端(AgentEvent → chrome 事件)/ 反向判别力自证 |
5965
+ | `scripts/run-terminal-status-vocabulary-test.mjs` | 🆕(L-215①②):`coerceWorkflowStatus('parked') === 'awaiting approval'` 且与 `coerceTaskStatus` 同落点 / 两只谓词的闭集成员与**非成员**(尤其 `suspended`/`needs_review` **不在**表里)/ 三处同形存量**零内联两词**的源码扫描(族扫反钉:再内联一处当天红) |
5966
+ | `scripts/run-retired-vocabulary-census-test.mjs` | 🆕(B-080②):`src/` 全树对熔断族四个符号 + `breaker_open` 词的**代码位置**零命中(注释里的退役说明不算数,剥注释后扫)—— clean-cut 的反钉:任何人补一条兼容别名当天红 |
5967
+ | `scripts/run-auto-mode-unavailable-test.mjs` | 🔁 随 core 7.12.0 改口:成因表**两词**双向等值;熔断表与它的镜像**整段删除**;排除集从「差集派生」改成「单员表 + 出处」,`parse_error` 判缺席的**行为**逐字不变(判别力自证照旧) |
5968
+ | `scripts/run-classifier-status-test.mjs` | 🔁 删 `breaker_open` 一态、熔断记录相关段整段删除;与 §30f 的 `armed` 合成后是**三态**;新增「表外态(含已退役的 `breaker_open`)渲兜底句不冒充三句里的任何一句」的负控 |
5969
+ | `scripts/run-gate-vocabulary-test.mjs` | 🔁 三句订正后的逐字断言 + `message` 让位臂的**四格**(让位词 × 有/无 message、非让位词有 message 时**一字不读**);D2 uplift 锚按 §30n 的处置改口(见下) |
5970
+ | `scripts/run-public-surface-test.mjs` | 🔁 公面导出基线(熔断三件删除、本批新增件登记;精确集合双向门) |
5971
+ | `scripts/run-client-core-typeshape-test.mjs` | 🔁 `unknown` 出境棘轮随 `classifierBreakerOf` 删除 / 新读器新增**逐件**记账 |
5972
+ | `scripts/run-integration-doc-freshness-test.mjs` | 🔁 本节新增坐标在盘 + 入库 |
5973
+
5974
+ **D2 uplift 锚的处置(devDep 抬版后当场红的那一条)**:`run-gate-vocabulary-test.mjs` 的 `D2` 断言
5975
+ 「core 的 `DECISION_REASONS` 尚无 `read_only`」—— core 7.11.0 起真有了(现 11 词),所以它按设计红了。
5976
+ 处置**不是**删锚:D1(sdk 端仍无 `read_only`)**继续守着**,D2 改成**两侧断言** ——
5977
+ ①core 侧已到货(它若又消失,说明镜像口径错了,照样红);②本包**没有** `DecisionReason` 的措辞面
5978
+ (源码扫描零铸点)⇒ 加词对本包**零落点**。归属登记:**候 sdk 镜像**(D1 是它的到货哨兵);
5979
+ 哪天 sdk 镜像了,D1 红 ⇒ 那一批同时铸措辞表并把 D2 退役。
5980
+