@sema-agent/server 7.70.0 → 7.72.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 (110) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/USAGE.md +8 -4
  4. package/dist/approval-card.d.ts +16 -17
  5. package/dist/approval-card.js +0 -9
  6. package/dist/approval-content-kind.d.ts +13 -7
  7. package/dist/approval-content-kind.js +3 -1
  8. package/dist/approval.js +3 -2
  9. package/dist/bench/s1/live-deps.js +2 -0
  10. package/dist/boot/execution-env.js +12 -2
  11. package/dist/boot/memory-consolidation.d.ts +2 -1
  12. package/dist/boot/parked-revive-gate.d.ts +2 -0
  13. package/dist/boot/parked-revive-gate.js +5 -1
  14. package/dist/boot/resolve-spec.js +8 -3
  15. package/dist/boot/runner-deps.d.ts +48 -59
  16. package/dist/boot/runner-deps.js +10 -4
  17. package/dist/brain.d.ts +3 -1
  18. package/dist/brain.js +2 -8
  19. package/dist/budget.d.ts +12 -1
  20. package/dist/budget.js +1 -1
  21. package/dist/config-catalog.js +13 -11
  22. package/dist/config-center/apply-effective.js +2 -4
  23. package/dist/config-center/facade.d.ts +1 -1
  24. package/dist/config-center/restart-signal.js +2 -2
  25. package/dist/config-center/skills-mcp.js +15 -0
  26. package/dist/config-types.d.ts +86 -4
  27. package/dist/config-types.js +19 -0
  28. package/dist/config.d.ts +42 -0
  29. package/dist/config.js +71 -22
  30. package/dist/deployment-governance.d.ts +6 -3
  31. package/dist/deployment-governance.js +2 -1
  32. package/dist/execution-lane-caps.d.ts +51 -37
  33. package/dist/execution-lane-caps.js +23 -0
  34. package/dist/fleet/fleet-bus.d.ts +22 -1
  35. package/dist/fleet/fleet-bus.js +2 -1
  36. package/dist/http/durable-run-leg.d.ts +64 -0
  37. package/dist/http/durable-run-leg.js +63 -0
  38. package/dist/http/route-ctx.d.ts +14 -0
  39. package/dist/http/route-ctx.js +3 -0
  40. package/dist/http/routes/approvals-assistant.js +3 -3
  41. package/dist/http/routes/capabilities.js +2 -2
  42. package/dist/http/routes/runs.js +10 -58
  43. package/dist/http/routes/workflows.js +1 -0
  44. package/dist/http/server.js +72 -22
  45. package/dist/index.d.ts +1 -1
  46. package/dist/leader/wire.js +4 -3
  47. package/dist/main.js +8 -3
  48. package/dist/memory-operator-faces.d.ts +1 -1
  49. package/dist/memory-scope.d.ts +24 -0
  50. package/dist/memory-scope.js +12 -3
  51. package/dist/observability/fail-open.d.ts +1 -1
  52. package/dist/observability/fail-open.js +1 -1
  53. package/dist/observability/metrics.d.ts +4 -0
  54. package/dist/observability/metrics.js +3 -1
  55. package/dist/observability/run-terminal-log.d.ts +4 -3
  56. package/dist/observability/run-terminal-log.js +4 -15
  57. package/dist/observability/tool-trace.d.ts +18 -1
  58. package/dist/observability/tool-trace.js +4 -3
  59. package/dist/orchestration/workflow-agent-session-index.d.ts +85 -2
  60. package/dist/orchestration/workflow-agent-session-index.js +38 -5
  61. package/dist/parked-decide.d.ts +40 -1
  62. package/dist/parked-decide.js +22 -4
  63. package/dist/plugins/checkpoint-store-sql.js +5 -5
  64. package/dist/plugins/e2b-orphan-reclaim.d.ts +4 -4
  65. package/dist/plugins/e2b-orphan-reclaim.js +18 -20
  66. package/dist/plugins/local-checkpoint-store.js +3 -3
  67. package/dist/plugins/remote-env-adb.d.ts +11 -0
  68. package/dist/plugins/remote-env-adb.js +2 -0
  69. package/dist/plugins/remote-env-device.d.ts +9 -0
  70. package/dist/plugins/remote-env-device.js +3 -0
  71. package/dist/plugins/remote-env-e2b.d.ts +11 -0
  72. package/dist/plugins/remote-env-e2b.js +2 -0
  73. package/dist/plugins/remote-env-host.d.ts +11 -0
  74. package/dist/plugins/remote-env-host.js +2 -0
  75. package/dist/plugins/remote-env-k8s.d.ts +11 -0
  76. package/dist/plugins/remote-env-k8s.js +2 -0
  77. package/dist/plugins/remote-env-local-docker.d.ts +11 -0
  78. package/dist/plugins/remote-env-local-docker.js +2 -0
  79. package/dist/plugins/remote-env-ssh.d.ts +11 -0
  80. package/dist/plugins/remote-env-ssh.js +2 -0
  81. package/dist/plugins/store-backend.d.ts +34 -12
  82. package/dist/plugins/store-backend.js +12 -3
  83. package/dist/plugins/store-contracts.d.ts +81 -18
  84. package/dist/plugins/store-contracts.js +18 -30
  85. package/dist/plugins/workflow-run-store-sql.d.ts +31 -9
  86. package/dist/plugins/workflow-run-store-sql.js +28 -1
  87. package/dist/run-cancel-context.js +1 -1
  88. package/dist/run-local.js +7 -1
  89. package/dist/runs.d.ts +16 -2
  90. package/dist/runs.js +2 -1
  91. package/dist/runtime-caps-resolver.js +5 -3
  92. package/dist/task-a2a.js +2 -1
  93. package/dist/task-mcp.js +2 -1
  94. package/dist/task-settings.d.ts +21 -8
  95. package/dist/task-settings.js +2 -2
  96. package/dist/tool-approval.d.ts +26 -21
  97. package/dist/tool-approval.js +2 -2
  98. package/dist/trace/core-keyset-guard.d.ts +136 -10
  99. package/dist/trace/engine-notice-wire.d.ts +1 -1
  100. package/dist/trace/engine-notice-wire.js +1 -0
  101. package/dist/trace/ledger-events.d.ts +5 -1
  102. package/dist/trace/ledger-sink.js +8 -1
  103. package/dist/trace/project.d.ts +33 -4
  104. package/dist/trace/project.js +24 -6
  105. package/dist/trace/redact.js +10 -5
  106. package/dist/usage-analytics.d.ts +9 -1
  107. package/dist/usage-analytics.js +8 -0
  108. package/dist/wire-name-bound.d.ts +14 -0
  109. package/dist/wire-name-bound.js +13 -0
  110. package/package.json +3 -3
package/dist/task-a2a.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { resolveComplianceDenies } from "@sema-agent/core";
2
+ import { isUsableWireName } from "./wire-name-bound.js";
2
3
  import { HttpError } from "./security.js";
3
4
  export const MAX_REQUEST_A2A_PEERS = 32;
4
5
  export function a2aInjectionHonored(config) {
@@ -19,7 +20,7 @@ function normalizeA2aPeer(e) {
19
20
  if (!e || typeof e !== "object")
20
21
  return null;
21
22
  const o = e;
22
- if (typeof o.name !== "string" || o.name.length === 0 || o.name.length > 128)
23
+ if (!isUsableWireName(o.name))
23
24
  return null;
24
25
  if (typeof o.url !== "string" || !HTTP_URL_RE.test(o.url))
25
26
  return null;
package/dist/task-mcp.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { mcpInjectionDroppedNotice, resolveComplianceDenies } from "@sema-agent/core";
2
+ import { isUsableWireName } from "./wire-name-bound.js";
2
3
  import { HttpError } from "./security.js";
3
4
  import { CONTENT_ORIGIN_WORDS, describeBadContentOrigin, isContentOriginWord } from "./mcp-content-origin.js";
4
5
  import { readMcpSourceLabel } from "./mcp-source-label.js";
@@ -26,7 +27,7 @@ function normalizeServer(e, noteBadOrigin) {
26
27
  if (!e || typeof e !== "object")
27
28
  return bad("entry");
28
29
  const o = e;
29
- if (typeof o.name !== "string" || o.name.length === 0 || o.name.length > 128)
30
+ if (!isUsableWireName(o.name))
30
31
  return bad("name");
31
32
  const t = o.transport;
32
33
  if (!t || typeof t !== "object")
@@ -312,15 +312,28 @@ export interface FsWriteGateWiring {
312
312
  /**
313
313
  * 🔴 S-177 / codex r2 [high](验真后修)—— **执行环境的 home**(core `PathRuleBases.home`,`~/…` 形的基)。
314
314
  *
315
- * core 对缺席的 `home` 回落 `os.homedir()` —— 那是**这个 server 进程**的 home。引擎与执行同机时它就是
316
- * 对的;**远端车道**(SSH / 容器 / 沙箱)上执行用户的 home 与 server 的 home 是两个目录,于是
317
- * `deny Edit(~/.sema/**)` 编译成功、却拿 server 的 home 去匹配远端的目标 ⇒ 一条收紧规则**静默失效**
318
- * (与 `taskRoot` 那条哨兵病同族、同方向)。
315
+ * 🔴 **S-213④ 起本字段在远端车道上也可以有值**:四只远端 adapter 此前一个都不声明 `ExecutionEnv.homeDir`,
316
+ * 而本字段那时只在 `remoteExec` 整个缺席时才铸 —— 于是**每一条远端部署的 `~/` 规则都恒 422**(接入审计
317
+ * M13)。修法不是放松下面那道门,而是让部署**真的知道** home:`execution-lane-caps.ts` 的
318
+ * `executionLaneHomeDir` 是唯一属主,`boot/execution-env.ts` 把它递给 adapter 的 `homeDir` 座、
319
+ * `boot/resolve-spec.ts` / `boot/parked-revive-gate.ts` 把**同一个值**递成本字段。两处同源是承重的:
320
+ * 各算一份就会出现「422 门放行而引擎判 unreadable」或反过来。
319
321
  *
320
- * ⇒ 本字段只在 home **真知道**时在场(引擎与执行同机)。缺席时,`~/` 形的规则由
321
- * {@link rejectUnmatchableSettingsNames} **响亮拒**(422),绝不回落到 server 的 home。
322
- * ⚠️ 上游缺口如实登记:core 今天没有「这条规则需要哪些 base」的查询口,也不把 `home` 当必答项 ——
323
- * 所以「这条规则用了 `~/` 吗」由本仓读**core 自己解析出的规范 command**(`~/` 前缀)来判,不自铸文法。
322
+ * 🔴 **S-213⑦ 改真话**(亲读 core 7.12.0 `dist/core/permission-rule-model.js:365-372` /
323
+ * `:340-350`,推翻本注此前的两句):
324
+ * · core 对缺席的 `home` **不**回落 `os.homedir()` —— `resolvePathPattern` 走
325
+ * `lexicalNormalAbsolutePathOf(baseValueOf("home", bases) ?? "")`,base 缺席 ⇒ `undefined` ⇒ 直接回
326
+ * `{missingBase:"home"}`,该调用的射程判 `unreadable`(fail-closed 的 ask,人来清),从不猜一个目录。
327
+ * 换言之引擎侧本来就没有「拿 server 的 home 去匹配远端目标」这条静默腿(那句旧注是本仓自己的推断)。
328
+ * · core **有**「这条规则需要哪些 base」的查询口 —— 根导出的 `ruleBasesNeeded(rule)`
329
+ * (`//abs` ⇒ 空、`~/` ⇒ `["home"]`、`/x` ⇒ `["root"]`、其余 ⇒ `["cwd"]`),`resolvePathPattern`
330
+ * 自己也读它。本仓的判据腿今天读的是 core 解析出的规范 command 前缀,与该查询口**同一分类**、
331
+ * 不是第二套文法;两者哪天分叉由这条注负责被人看见。
332
+ *
333
+ * ⇒ 本字段在**这条部署的执行车道 home 已知**时在场(`executionLaneHomeDir`,见 `execution-lane-caps.ts`)。
334
+ * 缺席时 `~/` 形规则由 {@link rejectUnmatchableSettingsNames} **响亮拒**(422),而不是让它编译成一条
335
+ * core 只会判 `unreadable` 的规则 —— 两道门同向(都不猜目录),422 只是把同一个拒挪到更早、更响的地方:
336
+ * 运维在**下单那一刻**就知道这条规则这条车道读不了,而不是等到跑起来每次都弹一张 ask。
324
337
  */
325
338
  taskHome?: string;
326
339
  /** The session scratchpad dir (envFacts.scratchpadDir, [ref]③) — writes there are always auto-allowed. */
@@ -279,8 +279,8 @@ function rejectUnmatchableSettingsNames(perms, pathBases) {
279
279
  const parsed = parseRuleText(name, behavior);
280
280
  if ("rule" in parsed && ruleToolGrammarOf(parsed.rule.tool) === "path" && parsed.rule.command.startsWith("~/")) {
281
281
  throw new Error(`${field} has a home-relative path rule (${name}) but this deployment cannot resolve the EXECUTION environment's home directory — ` +
282
- `on a remote lane the engine's own home is a different user's directory, so the rule would compile and then match nothing that runs. ` +
283
- `Spell the path absolutely (${"Edit(//abs/path/**)"} form), or run the task on a lane whose home this worker knows.`);
282
+ `the engine never guesses one: without a home base the rule resolves to "unreadable" and every matching call stops to ask, so it guards nothing. ` +
283
+ `Spell the path absolutely (${"Edit(//abs/path/**)"} form), declare the lane's home with REMOTE_EXEC_HOME_DIR, or run the task on a lane whose home this worker knows.`);
284
284
  }
285
285
  }
286
286
  }
@@ -126,11 +126,16 @@ export interface ToolApprovalFrame {
126
126
  requiresRealApproval?: true;
127
127
  /**
128
128
  * **S-125③/[ref]**(core 7.5.0;**ADDITIVE**,`"tool_approval"` only)—— 这只 ask 的**出身**:
129
- * 谁提的这一问,一个 core 闭集词(`ASK_ORIGINS` **11 员**,core 7.9.0 现值:content_question /
130
- * unresolvable / org_unavailable / org_rule / rule_store_unavailable / hook / ask_rule /
129
+ * 谁提的这一问,一个 core 闭集词(`ASK_ORIGINS` **11 员**,core 7.14.0 现值:content_question /
130
+ * ancestor_marked / org_unavailable / org_rule / rule_store_unavailable / hook / ask_rule /
131
131
  * denial_limit_fallback / shell_gate_tighten / safety_tighten / policy)。引擎在门上盖章(core d.ts:
132
132
  * 「engine-stamped at the gate, never a policy's claim」),`AskRequest.origin` 逐字透传。
133
133
  *
134
+ * ⚠️ **core 7.14.0 [ref] C2 BREAKING**:`unresolvable` → `ancestor_marked`,**无别名**。server 侧零形变
135
+ * (本键一直是 `string` 逐字透传),但**消费端的 switch 要改词**;7.14.0 之前 park 下来、行上存着
136
+ * `unresolvable` 的老记录,在 core 每一道 `isAskOrigin` 筛上自此都是非成员(投影处不回显 ⇒ 本键缺席),
137
+ * 而那一行的 `org` 事实不受影响。
138
+ *
134
139
  * 🔴 **echo-only,零消费**:自动车道的资格判据全在 core(`classifierMayAnswer` 的闭表),server
135
140
  * **不许**据本键自铸第二张资格表 —— 那是同一语义面两个写者(源头修复纪律),与
136
141
  * `denialLimitFallback` 顶注那条「不据 autoDenyAfterMs 自铸第二只定时器」同一条禁令。
@@ -144,26 +149,26 @@ export interface ToolApprovalFrame {
144
149
  */
145
150
  origin?: string;
146
151
  /**
147
- * **S-185 / [ref]**(core 7.10.0;**ADDITIVE**,`"tool_approval"` only)—— 这一问**为什么**到了人手上:
148
- * 分类器被咨询过、而它**跑不了**。`cause` = core 的闭集词
149
- * (`AUTO_MODE_UNAVAILABLE_CAUSES`;core 7.12.0 起 = `error` / `timeout`),`AskRequest.classifierUnavailable`
150
- * 逐字透传。core 7.12.0 / [ref] 起 ask 上这一位只由**策略层自声明**铸(引擎自己的那份改骑 deny —— 全文
151
- * 在 `approval-card.ts` 同名键的顶注)。
152
- *
153
- * 🔴 **缺席 ≠「分类器好着呢」**:缺席同时覆盖三形 —— 分类器答上了 / 这只 ask 没资格走分类器
154
- * (`classifierMayAnswer` 的闭表)/ 本部署压根没接分类器。消费端**禁**把缺席读成对分类器健康的断言。
155
- * 另注:`parse_error`(分类器跑了但答得出格)**不盖这一位** —— 那是另一句话,core 顶注逐字。
156
- *
157
- * 🔴 **不枚举词表**(值形是 `{cause: string}` 而不是本仓自铸的联合):词表单一属主在 core,抄一份会把
158
- * core 加的新词吞成缺席。窄读只判「对象 ∧ `cause` 非空串 ∧ 无多余成员」(`readClassifierUnavailable`,
159
- * 帧与卡的**唯一**铸造点 ⇒ 两面结构性同值)。
160
- *
161
- * 🔴 **echo-only,零消费**:熔断/超时的处置全在 core 的分类器站,server 不许据本键自铸第二套回落判据
162
- * —— 同 `origin` / `denialLimitFallback` 两条顶注的同一条禁令(同一语义面两个写者)。
152
+ * **[ref] C3**(core 7.14.0;**ADDITIVE**,`"tool_approval"` only)—— `origin: "rule_store_unavailable"`
153
+ * 的**机制判别位**:持久规则车道这一次**读不下来的是哪一半**。core 闭二词
154
+ * (`RULE_STORE_UNREADABLE_KINDS`):`"store"` = 接上的规则店读不了(读失败 / 超时);`"call"` = 店读到了,
155
+ * 但**这条命令**按人的 deny/ask 行读不出来(收紧 lexer 的 `unreadable`:展开里含规则词、引号没闭、语法
156
+ * 错——具体那句在 `message` 里)。`AskRequest.ruleStoreUnreadable` 逐字透传。
157
+ *
158
+ * 🔴 **在场 ⇔ `origin === "rule_store_unavailable"`**(core 顶注逐字)。两词对审批人是两件事:`store`
159
+ * 指向「去看规则店 / 网络」,`call` 指向「这条命令的写法让规则判不了」——一个 origin 词对这两件事同形。
160
+ * 缺席 = 车道把店和这条命令都读通了,**或**本部署没接规则车道;消费端禁把缺席读成对规则店健康的断言。
161
+ *
162
+ * 🔴 **不枚举词表**(值形是 `string` 而不是本仓自铸的联合):词表单一属主在 core
163
+ * (`isRuleStoreUnreadable` 是它的成员判),抄一份会把 core 加的新词吞成缺席 —— 与 {@link origin} 逐字同规。
164
+ *
165
+ * 🔴 **echo-only,零消费**:策略自声明的值在 core 的**唯一**盖章点就被抹掉了,server 不重算、不再筛第二遍,
166
+ * 更不许据本键自铸第二张车道资格表 —— 同 `origin` / `denialLimitFallback` 两条顶注的同一条禁令。
167
+ *
168
+ * ⚰️ 本键的前任 `classifierUnavailable`(S-185 / [ref])随 core 7.14.0 [ref] **整族退役**:引擎那份事实改骑
169
+ * `GateDisposition.denied.cause`(`tool_end.gate` / `permissionDenied.gate`),ask 面自此没有这一位。
163
170
  */
164
- classifierUnavailable?: {
165
- cause: string;
166
- };
171
+ ruleStoreUnreadable?: string;
167
172
  /**
168
173
  * **E-14**([ref]② Trojan Source 族;**ADDITIVE**,`"tool_approval"` only)—— 这只 ask 的**工具输入**
169
174
  * (`AskRequest.args`)里含 bidi 控制符(LRM/RLM、嵌入/覆写、隔离符;字符类属主 `text-bidi.ts`)。
@@ -8,7 +8,7 @@ import { approvalPayloadFingerprint } from "./plugins/approval-payload-fingerpri
8
8
  import { createLogger } from "./observability/logger.js";
9
9
  import { recordFailOpen } from "./observability/fail-open.js";
10
10
  import { deriveAskId, deriveBatchId, MAX_DECISION_NOTE_CHARS } from "./approval-ask-machine.js";
11
- import { ApprovalCardEnvelopeSchema, MAX_RULE_OFFERS, buildApprovalCard, buildApprovalCardEnvelope, buildApprovalRequestFrame, buildRevokeFrame, readDenialLimitFallback, readClassifierUnavailable, readProbeCause, readRuleEvidence, readRuleOffersAbsence, RuleOfferRawSchema, backfillLegacyBatchMemberKind, screenUncoveredDetailSeat, } from "./approval-card.js";
11
+ import { ApprovalCardEnvelopeSchema, MAX_RULE_OFFERS, buildApprovalCard, buildApprovalCardEnvelope, buildApprovalRequestFrame, buildRevokeFrame, readDenialLimitFallback, readProbeCause, readRuleEvidence, readRuleOffersAbsence, RuleOfferRawSchema, backfillLegacyBatchMemberKind, screenUncoveredDetailSeat, } from "./approval-card.js";
12
12
  import { projectAskTerminalClaimTruth } from "./plugins/approval-ask-store-sql.js";
13
13
  import { governanceAskMarksFor, runWithGovernanceAskScope } from "./governance-ask-marks.js";
14
14
  const defaultLogger = createLogger();
@@ -844,7 +844,7 @@ export class ToolApprovalCoordinator {
844
844
  ...(ruleLaneMaterial !== undefined ? { ruleOffers: ruleLaneMaterial.offers } : {}),
845
845
  ...((a) => (a !== undefined ? { ruleOffersAbsence: a } : {}))(readRuleOffersAbsence(req)),
846
846
  ...((f) => (f !== undefined ? { denialLimitFallback: f } : {}))(readDenialLimitFallback(req)),
847
- ...((c) => (c !== undefined ? { classifierUnavailable: c } : {}))(readClassifierUnavailable(req)),
847
+ ...(typeof req.ruleStoreUnreadable === "string" && req.ruleStoreUnreadable.length > 0 ? { ruleStoreUnreadable: req.ruleStoreUnreadable } : {}),
848
848
  ...((c) => (c !== undefined ? { probeCause: c } : {}))(readProbeCause(req)),
849
849
  ...((c) => (c !== undefined ? { ruleEvidence: c } : {}))(readRuleEvidence(req)),
850
850
  ...(bounded.omitted ? { argsOmitted: true } : { args: bounded.args }),
@@ -17,7 +17,8 @@
17
17
  * ⑨⑩([ref],2026-08-31)把两个最大的 wire 面也纳入:TaskSpec 按「server 有无写点」记 Wired/Unwired,
18
18
  * TaskResult 按「转发/摘除」记 Forwarded/Stripped —— 谁改 resolve-spec.ts / runs.ts 的发射点谁同步本文件。
19
19
  */
20
- import type { TaskNotificationPayload, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, GateOutcome, Settlement, PausedCause } from "@sema-agent/core";
20
+ import type { TaskNotificationPayload, SemaProvenance, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, WiringManifest, GateOutcome, GateDisposition, Settlement, PausedCause } from "@sema-agent/core";
21
+ import type { ToolApprovalFrame } from "../tool-approval.js";
21
22
  /** 编译期断言:T 必须收敛到 never(有残余键 = tsc 红)。
22
23
  * 🔴 **导出**([ref] U1/U2):本仓「词表闭集,未处置成员=编译红」的钉法只许有**一个**形 ——
23
24
  * `observability/run-terminal-log.ts` 的三张叶表 + 结果顶层键表用同一只断言,而不是各自再抄一份
@@ -27,20 +28,87 @@ export type AssertAllKeysHandled<T extends never> = T;
27
28
  type NotificationProjected = "task_id" | "task_type" | "toolUseId" | "status" | "summary" | "result" | "output_file" | "usage" | "sessionId" | "seq" | "lines" | "stoppedBy" | "source" | "exitCode" | "partial" | "diagnostics" | "recentSteps" | "editedFiles" | "resumable" | "completionId" | "error" | "errorCode" | "apiFailure" | "agentMessage" | "_sema_provenance";
28
29
  type NotificationExcluded = "peer" | "crossSessionMessage" | "crossSessionNotice";
29
30
  type _GuardNotification = AssertAllKeysHandled<Exclude<keyof TaskNotificationPayload, NotificationProjected | NotificationExcluded>>;
31
+ type _GuardNotificationReverse = AssertAllKeysHandled<Exclude<NotificationProjected | NotificationExcluded, keyof TaskNotificationPayload>>;
32
+ type ProvenanceProjected = "kind" | "from" | "taskId" | "seq" | "agentType";
33
+ type ProvenanceExcluded = "peerMeta";
34
+ type _GuardProvenance = AssertAllKeysHandled<Exclude<keyof SemaProvenance, ProvenanceProjected | ProvenanceExcluded>>;
35
+ type _GuardProvenanceReverse = AssertAllKeysHandled<Exclude<ProvenanceProjected | ProvenanceExcluded, keyof SemaProvenance>>;
36
+ type AgentMessageProjected = "from" | "body";
37
+ type _GuardAgentMessage = AssertAllKeysHandled<Exclude<keyof NonNullable<TaskNotificationPayload["agentMessage"]>, AgentMessageProjected>>;
38
+ type _GuardAgentMessageReverse = AssertAllKeysHandled<Exclude<AgentMessageProjected, keyof NonNullable<TaskNotificationPayload["agentMessage"]>>>;
30
39
  type BgNotifProjected = "taskId" | "sessionId" | "seq" | "status" | "summary" | "stoppedBy" | "resumable" | "recentSteps" | "editedFiles" | "usage" | "transcriptId" | "rootSessionId" | "parentTaskId" | "parentToolCallId" | "completionId";
31
40
  type BgNotifExcluded = "kind" | "sessionScoped" | "owner" | "scope" | "description" | "agentType" | "name" | "currentAction" | "currentTool" | "parentSessionId" | "startedAt" | "workflowRunId" | "progressTaskId" | "progressParentTaskId" | "model";
32
41
  type _GuardBgNotif = AssertAllKeysHandled<Exclude<keyof BackgroundChildEvent, BgNotifProjected | BgNotifExcluded>>;
42
+ type _GuardBgNotifReverse = AssertAllKeysHandled<Exclude<BgNotifProjected | BgNotifExcluded, keyof BackgroundChildEvent>>;
33
43
  type RosterProjected = "name" | "agentId" | "sessionId" | "toolUseId" | "owner" | "scope" | "sessionScoped" | "rootSessionId" | "model" | "modelFallback" | "createdAt";
34
44
  type _GuardRoster = AssertAllKeysHandled<Exclude<keyof RosterEntry, RosterProjected>>;
35
- type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "persistedRuleShadowed" | "probeCause" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "classifierUnavailable";
45
+ type _GuardRosterReverse = AssertAllKeysHandled<Exclude<RosterProjected, keyof RosterEntry>>;
46
+ type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "persistedRuleShadowed" | "probeCause" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "ruleStoreUnreadable";
36
47
  type AskExcluded = "preview" | "principal" | "riskAxes" | "boundInputHash" | "isDelegatedChild" | "probeReason" | "hasBidiControls" | "previewWithheld" | "execCwd";
37
48
  type _GuardAsk = AssertAllKeysHandled<Exclude<keyof AskRequest, AskProjected | AskExcluded>>;
49
+ type _GuardAskReverse = AssertAllKeysHandled<Exclude<AskProjected | AskExcluded, keyof AskRequest>>;
50
+ type AskFrameServerMinted = "type" | "approvalId" | "argsOmitted" | "outcome" | "governanceForced" | "expiresAtMs" | "expiresInMs" | "serverNowMs" | "parked" | "inputHasBidi";
51
+ type _GuardAskFrame = AssertAllKeysHandled<Exclude<keyof ToolApprovalFrame, AskProjected | AskFrameServerMinted>>;
52
+ type _GuardAskFrameReverse = AssertAllKeysHandled<Exclude<AskProjected | AskFrameServerMinted, keyof ToolApprovalFrame>>;
38
53
  type TaskEventHandled = "text_delta" | "reasoning_delta" | "tool_start" | "tool_end" | "turn_end" | "compacted" | "diagnostics" | "message_committed" | "status" | "task_notification" | "task_progress" | "steering_injected" | "workspace_changed" | "done" | "context_usage" | "compaction_outcome" | "human_input" | "wiring_manifest" | "text_end" | "tool_roster_delta";
39
54
  type _GuardTaskEvent = AssertAllKeysHandled<Exclude<TaskEvent["type"], TaskEventHandled>>;
55
+ type _GuardTaskEventReverse = AssertAllKeysHandled<Exclude<TaskEventHandled, TaskEvent["type"]>>;
40
56
  type MailboxProjected = "seq" | "from" | "content" | "sentAt" | "hopChain" | "peerMeta";
41
57
  type _GuardMailbox = AssertAllKeysHandled<Exclude<keyof MailboxMessage, MailboxProjected>>;
58
+ type _GuardMailboxReverse = AssertAllKeysHandled<Exclude<MailboxProjected, keyof MailboxMessage>>;
42
59
  type MailboxAppendProjected = "from" | "content" | "sentAt" | "hopChain" | "peerMeta";
43
60
  type _GuardMailboxAppend = AssertAllKeysHandled<Exclude<keyof MailboxAppendMessage, MailboxAppendProjected>>;
61
+ type _GuardMailboxAppendReverse = AssertAllKeysHandled<Exclude<MailboxAppendProjected, keyof MailboxAppendMessage>>;
62
+ type WiringSectionProjected = "schemaVersion" | "leg" | "ask" | "question" | "interaction" | "elicit" | "parkLane" | "session" | "fleet" | "permissionRules" | "modelGate" | "autoMode" | "mcp" | "tools";
63
+ type WiringSectionExcluded = "governance" | "configFingerprint";
64
+ type _GuardWiringSections = AssertAllKeysHandled<Exclude<keyof WiringManifest, WiringSectionProjected | WiringSectionExcluded>>;
65
+ type _GuardWiringSectionsReverse = AssertAllKeysHandled<Exclude<WiringSectionProjected | WiringSectionExcluded, keyof WiringManifest>>;
66
+ type WiringSection<K extends keyof WiringManifest> = NonNullable<WiringManifest[K]>;
67
+ type WiringLegHandled = "kind";
68
+ type _GuardWiringLeg = AssertAllKeysHandled<Exclude<keyof WiringSection<"leg">, WiringLegHandled>>;
69
+ type _GuardWiringLegReverse = AssertAllKeysHandled<Exclude<WiringLegHandled, keyof WiringSection<"leg">>>;
70
+ type WiringAskHandled = "form" | "provenance" | "effective";
71
+ type _GuardWiringAsk = AssertAllKeysHandled<Exclude<keyof WiringSection<"ask">, WiringAskHandled>>;
72
+ type _GuardWiringAskReverse = AssertAllKeysHandled<Exclude<WiringAskHandled, keyof WiringSection<"ask">>>;
73
+ type WiringQuestionHandled = "wired" | "provenance" | "interactiveToolsWithoutDeliveryFace";
74
+ type _GuardWiringQuestion = AssertAllKeysHandled<Exclude<keyof WiringSection<"question">, WiringQuestionHandled>>;
75
+ type _GuardWiringQuestionReverse = AssertAllKeysHandled<Exclude<WiringQuestionHandled, keyof WiringSection<"question">>>;
76
+ type WiringInteractionHandled = "posture";
77
+ type _GuardWiringInteraction = AssertAllKeysHandled<Exclude<keyof WiringSection<"interaction">, WiringInteractionHandled>>;
78
+ type _GuardWiringInteractionReverse = AssertAllKeysHandled<Exclude<WiringInteractionHandled, keyof WiringSection<"interaction">>>;
79
+ type WiringElicitHandled = "seamWired" | "serversOptedIn";
80
+ type _GuardWiringElicit = AssertAllKeysHandled<Exclude<keyof WiringSection<"elicit">, WiringElicitHandled>>;
81
+ type _GuardWiringElicitReverse = AssertAllKeysHandled<Exclude<WiringElicitHandled, keyof WiringSection<"elicit">>>;
82
+ type WiringParkLaneHandled = "capable" | "effective" | "reasons" | "checkpointDurability";
83
+ type _GuardWiringParkLane = AssertAllKeysHandled<Exclude<keyof WiringSection<"parkLane">, WiringParkLaneHandled>>;
84
+ type _GuardWiringParkLaneReverse = AssertAllKeysHandled<Exclude<WiringParkLaneHandled, keyof WiringSection<"parkLane">>>;
85
+ type WiringSessionHandled = "store";
86
+ type _GuardWiringSession = AssertAllKeysHandled<Exclude<keyof WiringSection<"session">, WiringSessionHandled>>;
87
+ type _GuardWiringSessionReverse = AssertAllKeysHandled<Exclude<WiringSessionHandled, keyof WiringSection<"session">>>;
88
+ type WiringToolsHandled = "schemaVersion" | "count" | "entries" | "digest";
89
+ type _GuardWiringTools = AssertAllKeysHandled<Exclude<keyof WiringSection<"tools">, WiringToolsHandled>>;
90
+ type _GuardWiringToolsReverse = AssertAllKeysHandled<Exclude<WiringToolsHandled, keyof WiringSection<"tools">>>;
91
+ type FleetExcluded = "subagentTranscripts";
92
+ type WiringFleetHandled = "backgroundAgentStore" | "hostChildEventSink" | FleetExcluded;
93
+ type _GuardWiringFleet = AssertAllKeysHandled<Exclude<keyof WiringSection<"fleet">, WiringFleetHandled>>;
94
+ type _GuardWiringFleetReverse = AssertAllKeysHandled<Exclude<WiringFleetHandled, keyof WiringSection<"fleet">>>;
95
+ type WiringMcpEntry = WiringSection<"mcp">[number];
96
+ type WiringMcpExcluded = "error";
97
+ type WiringMcpHandled = "name" | "source" | "status" | "errorCode" | "delivered" | "httpStatus" | "toolCount" | WiringMcpExcluded;
98
+ type _GuardWiringMcp = AssertAllKeysHandled<Exclude<keyof WiringMcpEntry, WiringMcpHandled>>;
99
+ type _GuardWiringMcpReverse = AssertAllKeysHandled<Exclude<WiringMcpHandled, keyof WiringMcpEntry>>;
100
+ type WiringRulesHandled = "storeWired" | "syncWired" | "orgGoverned";
101
+ type _GuardWiringRules = AssertAllKeysHandled<Exclude<keyof WiringSection<"permissionRules">, WiringRulesHandled>>;
102
+ type _GuardWiringRulesReverse = AssertAllKeysHandled<Exclude<WiringRulesHandled, keyof WiringSection<"permissionRules">>>;
103
+ type WiringModelGateHandled = "class" | "removed" | "restore";
104
+ type _GuardWiringModelGate = AssertAllKeysHandled<Exclude<keyof WiringSection<"modelGate">, WiringModelGateHandled>>;
105
+ type _GuardWiringModelGateReverse = AssertAllKeysHandled<Exclude<WiringModelGateHandled, keyof WiringSection<"modelGate">>>;
106
+ type WiringAutoModeHandled = "armed" | "reason" | "deniedSource";
107
+ type _GuardWiringAutoMode = AssertAllKeysHandled<Exclude<keyof WiringSection<"autoMode">, WiringAutoModeHandled>>;
108
+ type _GuardWiringAutoModeReverse = AssertAllKeysHandled<Exclude<WiringAutoModeHandled, keyof WiringSection<"autoMode">>>;
109
+ type WiringGovernanceHandled = "audience" | "lockedConfig" | "compliance" | "memoryAdmission" | "retention";
110
+ type _GuardWiringGovernance = AssertAllKeysHandled<Exclude<keyof WiringSection<"governance">, WiringGovernanceHandled>>;
111
+ type _GuardWiringGovernanceReverse = AssertAllKeysHandled<Exclude<WiringGovernanceHandled, keyof WiringSection<"governance">>>;
44
112
  type PermissionTraceKind = Extract<TraceEvent["kind"], `permission.${string}`>;
45
113
  export type PermissionTraceProjected = "permission.persisted_rule_allowed" | "permission.rule_store_unreadable" | "permission.read_only_allowed";
46
114
  type PermissionTraceDropped = "permission.sandbox_admitted" | "permission.rule_sync_resurrected" | "permission.rule_sync_dropped" | "permission.org_snapshot_unavailable";
@@ -49,9 +117,10 @@ type _GuardPermissionTraceReverse = AssertAllKeysHandled<Exclude<PermissionTrace
49
117
  /** `T` 非 `never` 时收敛到 `never`(空集 ⇒ 残留 `"EMPTY"` ⇒ tsc 红)。 */
50
118
  type AssertNonEmpty<T> = [T] extends [never] ? "EMPTY" : never;
51
119
  type _GuardPermissionTraceNonEmpty = AssertAllKeysHandled<AssertNonEmpty<PermissionTraceKind>>;
52
- type SummaryProjected = "sessionId" | "scope" | "createdAt" | "gateKind" | "severity" | "spentMicroUsd" | "deadline" | "hasBidiControls" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "classifierUnavailable";
120
+ type SummaryProjected = "sessionId" | "scope" | "createdAt" | "gateKind" | "severity" | "spentMicroUsd" | "deadline" | "hasBidiControls" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "ruleStoreUnreadable";
53
121
  type SummaryExcluded = "token" | "toolInput" | "toolName" | "toolCallId" | "preview" | "principal" | "sourceTaskId" | "contentKind" | "restoreMode" | "checkpointId" | "previewWithheld";
54
122
  type _GuardInboxSummary = AssertAllKeysHandled<Exclude<keyof CheckpointSummary, SummaryProjected | SummaryExcluded>>;
123
+ type _GuardInboxSummaryReverse = AssertAllKeysHandled<Exclude<SummaryProjected | SummaryExcluded, keyof CheckpointSummary>>;
55
124
  type TaskSpecWired = "objective" | "principal" | "images" | "sessionId" | "requireExistingSession" | "oneShot" | "clientContext" | "resumeAt" | "resumeAtMode" | "model" | "compactionModel" | "thinking" | "systemPrompt" | "appendSystemPrompt" | "promptProvider" | "memory" | "suggestNextPrompts" | "restoreFiles" | "acceptPartialRestore" | "rewindFilesTo" | "tools" | "excludeTools" | "deferTools" | "toolMaterializeStrategy" | "promptProfile" | "toolPolicy" | "onAsk" | "onQuestion" | "hooks" | "durableApproval" | "resourceSuspend" | "resilience" | "finalVerification" | "checkpointStore" | "handsReadOnly" | "memoryPersistenceCapable" | "additionalDirectories" | "additionalReadDirectories" | "enablePlanMode" | "interactiveTools" | "enableFork" | "shellGate" | "mcp" | "a2a" | "skills" | "backgroundScope" | "envFacts" | "limits" | "configOverrides" | "forwardSubagentEvents" | "retainSubagentSessions" | "retainBackgroundProcesses" | "outputSchema" | "outputRetries" | "compaction" | "attachments" | "selfOrchestration" | "getApiKeyAndHeaders" | "interactionPosture" | "agents" | "taskId" | "signal" | "preemptSignal" | "modelRole" | "enableBlockedReport" | "maxSuspends" | "autoModeRequested";
56
125
  type TaskSpecUnwired = "excludeAllTools" | "actor" | "roles" | "lspManager" | "tracer" | "readFace" | "readDenyPatterns" | "interactiveQuestionFallback" | "alwaysLoadTools" | "restoreGatedTools" | "deferSelfResolve" | "basePolicyForResumeEdit" | "lspDiagnostics" | "streamingToolExecution" | "toolResultThresholdChars";
57
126
  type _GuardTaskSpec = AssertAllKeysHandled<Exclude<keyof TaskSpec, TaskSpecWired | TaskSpecUnwired>>;
@@ -63,35 +132,92 @@ type _GuardTaskResultReverse = AssertAllKeysHandled<Exclude<TaskResultForwarded
63
132
  type PausedCauseForwarded = "kind" | "gate" | "checkpointId" | "restoreMode";
64
133
  type PausedCauseStripped = "token";
65
134
  type _GuardPausedCause = AssertAllKeysHandled<Exclude<keyof PausedCause, PausedCauseForwarded | PausedCauseStripped>>;
66
- type _NoDoubleBookPausedCause = AssertAllKeysHandled<Extract<PausedCauseForwarded, PausedCauseStripped>>;
67
135
  type _GuardPausedCauseReverse = AssertAllKeysHandled<Exclude<PausedCauseForwarded | PausedCauseStripped, keyof PausedCause>>;
68
136
  type SettlementKeys = Settlement extends infer S ? (S extends object ? keyof S : never) : never;
69
137
  type SettlementWhoKeys = Settlement["who"] extends infer W ? (W extends object ? keyof W : never) : never;
70
- type _GuardGateOutcome = AssertAllKeysHandled<Exclude<keyof GateOutcome, "disposition" | "settlement" | "origin">>;
71
- type _GuardSettlement = AssertAllKeysHandled<Exclude<SettlementKeys, "kind" | "who" | "when" | "note">>;
72
- type _GuardSettlementWho = AssertAllKeysHandled<Exclude<SettlementWhoKeys, "party" | "approver" | "window">>;
138
+ type GateOutcomeProjected = "disposition" | "settlement" | "origin";
139
+ type _GuardGateOutcome = AssertAllKeysHandled<Exclude<keyof GateOutcome, GateOutcomeProjected>>;
140
+ type _GuardGateOutcomeReverse = AssertAllKeysHandled<Exclude<GateOutcomeProjected, keyof GateOutcome>>;
141
+ type GateDispositionKeys = GateDisposition extends infer D ? (D extends object ? keyof D : never) : never;
142
+ type GateDispositionProjected = "kind" | "deniedBy" | "cause";
143
+ type _GuardGateDisposition = AssertAllKeysHandled<Exclude<GateDispositionKeys, GateDispositionProjected>>;
144
+ type _GuardGateDispositionReverse = AssertAllKeysHandled<Exclude<GateDispositionProjected, GateDispositionKeys>>;
145
+ type SettlementProjected = "kind" | "who" | "when" | "note";
146
+ type _GuardSettlement = AssertAllKeysHandled<Exclude<SettlementKeys, SettlementProjected>>;
147
+ type _GuardSettlementReverse = AssertAllKeysHandled<Exclude<SettlementProjected, SettlementKeys>>;
148
+ type SettlementWhoProjected = "party" | "approver" | "window";
149
+ type _GuardSettlementWho = AssertAllKeysHandled<Exclude<SettlementWhoKeys, SettlementWhoProjected>>;
150
+ type _GuardSettlementWhoReverse = AssertAllKeysHandled<Exclude<SettlementWhoProjected, SettlementWhoKeys>>;
73
151
  export type CoreKeysetGuards = [
74
152
  _GuardNotification,
153
+ _GuardNotificationReverse,
154
+ _GuardProvenance,
155
+ _GuardProvenanceReverse,
156
+ _GuardAgentMessage,
157
+ _GuardAgentMessageReverse,
75
158
  _GuardBgNotif,
159
+ _GuardBgNotifReverse,
76
160
  _GuardRoster,
161
+ _GuardRosterReverse,
77
162
  _GuardAsk,
163
+ _GuardAskReverse,
164
+ _GuardAskFrame,
165
+ _GuardAskFrameReverse,
78
166
  _GuardTaskEvent,
167
+ _GuardTaskEventReverse,
79
168
  _GuardMailbox,
169
+ _GuardMailboxReverse,
80
170
  _GuardMailboxAppend,
171
+ _GuardMailboxAppendReverse,
172
+ _GuardWiringSections,
173
+ _GuardWiringSectionsReverse,
174
+ _GuardWiringLeg,
175
+ _GuardWiringLegReverse,
176
+ _GuardWiringAsk,
177
+ _GuardWiringAskReverse,
178
+ _GuardWiringQuestion,
179
+ _GuardWiringQuestionReverse,
180
+ _GuardWiringInteraction,
181
+ _GuardWiringInteractionReverse,
182
+ _GuardWiringElicit,
183
+ _GuardWiringElicitReverse,
184
+ _GuardWiringParkLane,
185
+ _GuardWiringParkLaneReverse,
186
+ _GuardWiringSession,
187
+ _GuardWiringSessionReverse,
188
+ _GuardWiringTools,
189
+ _GuardWiringToolsReverse,
190
+ _GuardWiringFleet,
191
+ _GuardWiringFleetReverse,
192
+ _GuardWiringMcp,
193
+ _GuardWiringMcpReverse,
194
+ _GuardWiringRules,
195
+ _GuardWiringRulesReverse,
196
+ _GuardWiringModelGate,
197
+ _GuardWiringModelGateReverse,
198
+ _GuardWiringAutoMode,
199
+ _GuardWiringAutoModeReverse,
200
+ _GuardWiringGovernance,
201
+ _GuardWiringGovernanceReverse,
81
202
  _GuardPermissionTrace,
82
203
  _GuardPermissionTraceReverse,
83
204
  _GuardPermissionTraceNonEmpty,
84
205
  _GuardInboxSummary,
206
+ _GuardInboxSummaryReverse,
85
207
  _GuardTaskSpec,
86
208
  _GuardTaskSpecReverse,
87
209
  _GuardTaskResult,
88
210
  _GuardTaskResultReverse,
211
+ _GuardPausedCause,
212
+ _GuardPausedCauseReverse,
89
213
  _GuardGateOutcome,
214
+ _GuardGateOutcomeReverse,
215
+ _GuardGateDisposition,
216
+ _GuardGateDispositionReverse,
90
217
  _GuardSettlement,
218
+ _GuardSettlementReverse,
91
219
  _GuardSettlementWho,
92
- _GuardPausedCause,
93
- _NoDoubleBookPausedCause,
94
- _GuardPausedCauseReverse
220
+ _GuardSettlementWhoReverse
95
221
  ];
96
222
  export {};
97
223
  //# sourceMappingURL=core-keyset-guard.d.ts.map
@@ -16,7 +16,7 @@
16
16
  * 同文件 G1 e2e 的全码扇出夹具、以及契约文档附录 D.3 那张表(含**小节标题里的码数** —— 那道门本批
17
17
  * 刚立,立完就在下一次加码时自己咬住了)。
18
18
  */
19
- export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable"];
19
+ export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed"];
20
20
  export type EngineNoticeWireCode = (typeof ENGINE_NOTICE_WIRE_CODES)[number];
21
21
  /** 白名单谓词(单点):路由与门都读这一个,不许第二处手抄码串。 */
22
22
  export declare function isEngineNoticeWireCode(code: string): code is EngineNoticeWireCode;
@@ -22,6 +22,7 @@ export const ENGINE_NOTICE_WIRE_CODES = [
22
22
  "classifier.denial_limit",
23
23
  "mcp.injection_dropped",
24
24
  "delegation.ask_unresolvable",
25
+ "task.interrupt_unconsumed",
25
26
  ];
26
27
  const WIRE_CODES = new Set(ENGINE_NOTICE_WIRE_CODES);
27
28
  export function isEngineNoticeWireCode(code) {
@@ -31,7 +31,11 @@
31
31
  * 的 `switch (ev.type)` 白名单臂(差集门 `test/durable-append-arm-parity.test.ts` 看守两腿一致);
32
32
  * · **腿自己的带外行**:park/终局/失败/建议/用量/装配自证(不来自流事件)。
33
33
  */
34
- export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome" | "workspace_changed" | "wiring_manifest" | "human_input" | "task_progress" | "task_notification" | "turn_end"
34
+ export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome" | "workspace_changed" | "wiring_manifest"
35
+ /** S-212(7.71.0):运行期名册变更(core 7.8.0 [ref] ⑪)。**快照语义**——`delta.roster` 是整只
36
+ * 变更后名册,消费端收到即整只替换,所以回放不需要任何合并;它的耐久面因此不是 `wiring_manifest.tools`
37
+ * 的重复,而是那份开腿快照**之后**的每一次改动(修前两条 durable 腿零 case ⇒ 回放只见开头一版)。 */
38
+ | "tool_roster_delta" | "human_input" | "task_progress" | "task_notification" | "turn_end"
35
39
  /** park 行名**两个**(`appendParked(kind)` 逐字取自 `result.status`)—— 运行期闭集见
36
40
  * {@link PARK_LEDGER_EVENT_TYPES}(本联合是它的类型面,两者由下方的双向断言锁步)。 */
37
41
  | "suspended" | "needs_review" | "done" | "failed" | "suggestions" | "model_usage" | "prompt_assembled" | "config_assembled" | "file_link"
@@ -1,6 +1,6 @@
1
1
  import { terminalProjection } from "@sema-agent/core";
2
2
  import { redactSecrets } from "./redact.js";
3
- import { toolStartEventData, toolEndEventData, taskProgressEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
3
+ import { toolStartEventData, toolEndEventData, taskProgressEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
4
4
  import { NotifiedKeys, taskNotificationStreamKey } from "../orchestration/workflow-completion-inbox.js";
5
5
  import { isParkLedgerEventType } from "./ledger-events.js";
6
6
  export function createSerialLedgerAppend(appendEvent, startSeq) {
@@ -99,6 +99,13 @@ export function createLedgerSink(opts) {
99
99
  await flush();
100
100
  await append("wiring_manifest", wiringManifestEventData(ev));
101
101
  break;
102
+ case "tool_roster_delta": {
103
+ await flush();
104
+ const rosterDelta = toolRosterDeltaEventData(ev);
105
+ if (rosterDelta !== undefined)
106
+ await append("tool_roster_delta", rosterDelta);
107
+ break;
108
+ }
102
109
  case "human_input":
103
110
  await flush();
104
111
  await append("human_input", humanInputEventData(ev));
@@ -120,6 +120,18 @@ export declare function toolStartEventData(ev: {
120
120
  parentToolCallId?: string;
121
121
  }): Record<string, unknown>;
122
122
  export declare function screenedGate(v: unknown): GateOutcome | undefined;
123
+ /**
124
+ * 🔴 **耐久行的**门记录读口(7.72.0;`screenedGate` 的读腿孪生)—— 先把本仓自己写过的**旧拼法**读成它
125
+ * 今天的名字({@link RETIRED_ASK_ORIGIN_SPELLINGS}),再走与写腿**同一只**筛子。
126
+ *
127
+ * 为什么读腿要多这一步而写腿不要:读到的字节可能是**本仓上一个版本**写下的(账本回放、park 行的
128
+ * `resolvedOutcome`),而 core 7.14.0 [ref] C2 把 `ASK_ORIGINS` 的一个词改了名 —— 不认旧拼法,那些行就整条
129
+ * withhold,连 `disposition` / `settlement`(谁拒的、人怎么结的)一起在回放面上消失。写腿面对的则是**当下**
130
+ * 引擎铸的记录,它铸不出退役词,所以那里出现退役词 = producer 契约漂了 = 要 report + withhold 的事。
131
+ *
132
+ * 不改原对象(调用方与账本共享引用):归一时换一只信封,原记录一个字节不动。
133
+ */
134
+ export declare function screenedStoredGate(v: unknown): GateOutcome | undefined;
123
135
  /** The durable `tool_end` payload (shared by both append sites). E1: the model-facing `output` is UNTRUSTED RAW
124
136
  * from core (file/shell/API bodies) — core only SIZE-bounds it (`truncated`), REDACTION is ours (same contract as
125
137
  * `tool_start.args`); never re-fed to a model. E2: identity. Absent `output` ⇒ the tool produced no content body.
@@ -424,6 +436,11 @@ export declare function workspaceChangedEventData(ev: {
424
436
  * 的那一点订阅腿的名册增量座,一次改变名册的 refresh ⇒ **恰一帧**(序在 manifest 之后、那次 refresh 自己的
425
437
  * `tool_end` 之前),`delta.fromDigest` = 消费端手上那份名册的 digest。7.66.0 写下的「前瞻接线」披露随本版
426
438
  * 退役:本臂现在会真的触发,消费端可以依赖它了。
439
+ *
440
+ * 🔴 **三腿共用本构造器(S-212,7.71.0)**:live 腿(`routes/tasks.ts`)+ 两条 durable 腿
441
+ * (`trace/ledger-sink.ts` 的 `onEvent` / `http/server.ts` 的 resume switch)。返回 `undefined` 的那一格在
442
+ * 三腿上是同一件事 ——**整帧不发 / 整帧不落账**,绝不半张名册上 wire 或落库。落账的正当性(旧裁定
443
+ * 「不落账」为何在 7.71.0 撤销)逐字记在 `core-keyset-guard.ts` ⑪ 段。
427
444
  */
428
445
  export declare function toolRosterDeltaEventData(ev: {
429
446
  delta?: unknown;
@@ -549,10 +566,17 @@ export interface TraceTurn {
549
566
  * verbatim 转发——`in` 刻意保持它历史上的「总量」语义不变(旧帧/新帧读端零伤),不随 core 的
550
567
  * `promptTokens`/`turn_end.usage.inputTokens` 翻转为 cache-MISS。新增 `uncachedIn` 承接 core 3.0.0 才有的
551
568
  * cache-MISS 分量(命名取自 core `uncachedInputTokensOf`),只在能确认自己踩在新契约帧上时才发
552
- * (见 {@link toContractTokens})。 */
569
+ * (见 {@link toContractTokens})。
570
+ *
571
+ * 🔴 **S-213⑥:五个子键**全部按同族 OMIT 契约走 —— 引擎那一侧报了才铸,没报就**缺席**,恒不折 `0`。
572
+ * `in`/`out` 此前是必填座、缺一键时写 `?? 0`:读端拿到的 `in:0` 与「这一轮真的零输入」逐字节同形,
573
+ * 于是一次 usage 半缺(某些 provider 只回 output 侧)在面板上显示成一个可核对的真数字。
574
+ * 0 是一个数,未知不是 —— 两者同形正是本仓 `boundCallId`/`gateKind`/`contentKind` 一族一直在防的事。
575
+ * ⚠️ wire 面(`GET /v1/tasks/:id/turns` 与 trace SSE 的 `turn` 事件)因此可能给出**只有一侧**的
576
+ * `tokens`;做算术的消费端要按「键可能缺席」读(`tokens` 整只可缺席早就是契约的一部分)。 */
553
577
  tokens?: {
554
- in: number;
555
- out: number;
578
+ in?: number;
579
+ out?: number;
556
580
  uncachedIn?: number;
557
581
  cacheRead?: number;
558
582
  cacheWrite?: number;
@@ -601,7 +625,12 @@ export declare function turnEndEventData(ev: {
601
625
  * 的投影契约,不是 wire verbatim——`in` 保持它一直以来的**总量**语义,3.0.0 起改取 `totalInputTokens`
602
626
  * (归一化总输入含 cache)优先,`inputTokens` 回落(旧帧/尚未升级的 core 下 `totalInputTokens` 缺席时,
603
627
  * `in` 落回旧值,读端零伤)。`uncachedIn` 只在**能确认自己踩在新契约帧上**(`totalInputTokens` 在场)时
604
- * 才发——旧帧的 `inputTokens` 是族依赖的旧语义,标成「uncachedIn(cache-MISS)」会是谎言。 */
628
+ * 才发——旧帧的 `inputTokens` 是族依赖的旧语义,标成「uncachedIn(cache-MISS)」会是谎言。
629
+ *
630
+ * 🔴 S-213⑥:**一条规则管五个子键** —— 源侧在场就铸、缺席就不铸,没有 `?? 0`。此前 `in`/`out` 两座
631
+ * 各带一个默认 0,于是 usage 半缺(provider 只回 output 侧)被投影成 `in:0` = 一个看起来可核对的真
632
+ * 数字;`uncachedIn`/`cacheRead`/`cacheWrite` 三键从第一天起就是缺席制,`in`/`out` 只是漏进了默认值。
633
+ * 早退分支语义不变:输入两键(择一)与 `outputTokens` 全缺 ⇒ 整只 `tokens` 缺席(不铸空对象)。 */
605
634
  export declare function toContractTokens(usage: unknown): TraceTurn["tokens"] | undefined;
606
635
  /** [ref]C-13:tool_start/tool_end 的**共享挑键**——`projectEvents`(turns 面)与 `mapTraceEvent`
607
636
  * (trace SSE 面)对同一账本行的字段选择逐字同构,此前两处独立手写,structured/totalChars/label
@@ -86,6 +86,9 @@ export function toolStartEventData(ev) {
86
86
  return { toolCallId: ev.toolCallId, toolName: ev.toolName, ...(ev.label !== undefined ? { label: ev.label } : {}), args: redactDeep(ev.args), ...identityFields(ev) };
87
87
  }
88
88
  const SETTLEMENT_NOTE_MAX = 500;
89
+ const RETIRED_ASK_ORIGIN_SPELLINGS = {
90
+ unresolvable: "ancestor_marked",
91
+ };
89
92
  export function screenedGate(v) {
90
93
  if (v === null || typeof v !== "object")
91
94
  return undefined;
@@ -96,6 +99,7 @@ export function screenedGate(v) {
96
99
  return undefined;
97
100
  }
98
101
  const shapeDefect = (d.kind === "denied" && typeof d.deniedBy !== "string" && "disposition.deniedBy is not a string") ||
102
+ (d.kind === "denied" && d.cause !== undefined && typeof d.cause !== "string" && "disposition.cause is not a string") ||
99
103
  (g.settlement !== undefined && (g.settlement === null || typeof g.settlement !== "object") && "settlement is not an object") ||
100
104
  (g.settlement !== undefined && g.settlement !== null && typeof g.settlement.kind !== "string" && "settlement.kind is not a string") ||
101
105
  (g.origin !== undefined && typeof g.origin !== "string" && "origin is not a string") ||
@@ -115,11 +119,20 @@ export function screenedGate(v) {
115
119
  return undefined;
116
120
  }
117
121
  return {
118
- disposition: d.kind === "denied" ? { kind: "denied", deniedBy: d.deniedBy } : { kind: "allowed" },
122
+ disposition: d.kind === "denied"
123
+ ? { kind: "denied", deniedBy: d.deniedBy, ...(d.cause === undefined ? {} : { cause: d.cause }) }
124
+ : { kind: "allowed" },
119
125
  ...(settlement === undefined ? {} : { settlement }),
120
126
  ...(g.origin === undefined ? {} : { origin: g.origin }),
121
127
  };
122
128
  }
129
+ export function screenedStoredGate(v) {
130
+ if (v === null || typeof v !== "object")
131
+ return undefined;
132
+ const g = v;
133
+ const renamed = typeof g.origin === "string" ? RETIRED_ASK_ORIGIN_SPELLINGS[g.origin] : undefined;
134
+ return screenedGate(renamed === undefined ? g : { ...g, origin: renamed });
135
+ }
123
136
  const SETTLEMENT_PARTIES = new Set(["person", "engine", "host", "none"]);
124
137
  function projectSettlement(st) {
125
138
  const whoV = st.who;
@@ -329,7 +342,10 @@ export function wiringManifestEventData(ev) {
329
342
  const reason = str(autoIn.reason);
330
343
  if (armed === undefined || reason === undefined)
331
344
  return undefined;
332
- return armed === (reason === "armed") ? { armed, reason } : undefined;
345
+ if (armed !== (reason === "armed"))
346
+ return undefined;
347
+ const deniedSource = str(autoIn.deniedSource);
348
+ return { armed, reason, ...(deniedSource === undefined ? {} : { deniedSource }) };
333
349
  })();
334
350
  const toolsIn = m.tools;
335
351
  const tools = toolsIn === undefined ? undefined : Value.Check(ToolRoster, toolsIn) ? toolsIn : (recordFailOpen("server.trace.tool-roster-malformed", "wiring_manifest.tools did not fit core ToolRoster"), undefined);
@@ -493,11 +509,12 @@ export function toContractTokens(usage) {
493
509
  if (!usage || typeof usage !== "object")
494
510
  return undefined;
495
511
  const u = usage;
496
- if (u.inputTokens == null && u.totalInputTokens == null && u.outputTokens == null)
512
+ const inTokens = u.totalInputTokens ?? u.inputTokens;
513
+ if (inTokens == null && u.outputTokens == null)
497
514
  return undefined;
498
515
  return {
499
- in: u.totalInputTokens ?? u.inputTokens ?? 0,
500
- out: u.outputTokens ?? 0,
516
+ ...(inTokens != null ? { in: inTokens } : {}),
517
+ ...(u.outputTokens != null ? { out: u.outputTokens } : {}),
501
518
  ...(u.totalInputTokens != null && u.inputTokens != null ? { uncachedIn: u.inputTokens } : {}),
502
519
  ...(u.cacheReadTokens != null ? { cacheRead: u.cacheReadTokens } : {}),
503
520
  ...(u.cacheWriteTokens != null ? { cacheWrite: u.cacheWriteTokens } : {}),
@@ -513,7 +530,7 @@ export function toolCallFieldsOf(d) {
513
530
  };
514
531
  }
515
532
  export function toolResultFieldsOf(d) {
516
- const gate = d.gate === undefined ? undefined : screenedGate(d.gate);
533
+ const gate = d.gate === undefined ? undefined : screenedStoredGate(d.gate);
517
534
  return {
518
535
  callId: String(d.toolCallId ?? ""),
519
536
  ...(typeof d.label === "string" ? { label: d.label } : {}),
@@ -650,6 +667,7 @@ function mapTraceEventInner(type, seq, data) {
650
667
  case "compaction_outcome":
651
668
  case "wiring_manifest":
652
669
  case "human_input":
670
+ case "tool_roster_delta":
653
671
  return null;
654
672
  default:
655
673
  return null;