@sema-agent/server 7.142.0 → 7.143.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 (258) hide show
  1. package/MIGRATION.md +442 -0
  2. package/USAGE.md +41 -24
  3. package/dist/adoption/plan.js +22 -0
  4. package/dist/approval-ask-audit-store.d.ts +7 -5
  5. package/dist/approval-ask-audit-store.js +12 -6
  6. package/dist/approval-ask-machine.d.ts +15 -7
  7. package/dist/approval-ask-machine.js +10 -4
  8. package/dist/approval-card.d.ts +124 -25
  9. package/dist/approval-card.js +103 -23
  10. package/dist/approval-queue-kind.d.ts +27 -0
  11. package/dist/approval-queue-kind.js +6 -0
  12. package/dist/approval-reconciler.d.ts +8 -8
  13. package/dist/approval-reconciler.js +3 -3
  14. package/dist/audit.js +4 -2
  15. package/dist/boot/budget-tracing.d.ts +1 -1
  16. package/dist/boot/governance-seams.d.ts +26 -41
  17. package/dist/boot/governance-seams.js +61 -28
  18. package/dist/boot/late-binds.d.ts +7 -4
  19. package/dist/boot/late-binds.js +3 -1
  20. package/dist/boot/leader.js +2 -4
  21. package/dist/boot/memory-consolidation.d.ts +0 -8
  22. package/dist/boot/memory-consolidation.js +3 -3
  23. package/dist/boot/reapers.js +5 -4
  24. package/dist/boot/resolve-spec.d.ts +1 -1
  25. package/dist/boot/resolve-spec.js +8 -8
  26. package/dist/boot/runner-deps.d.ts +10 -7
  27. package/dist/boot/runner-deps.js +5 -17
  28. package/dist/boot/shutdown.d.ts +9 -0
  29. package/dist/boot/shutdown.js +16 -2
  30. package/dist/boot/stage-02-web-admin-pull.js +3 -0
  31. package/dist/boot/stage-03-store-backend.d.ts +4 -1
  32. package/dist/boot/stage-03-store-backend.js +1 -2
  33. package/dist/boot/stage-04-stores.d.ts +5 -2
  34. package/dist/boot/stage-04-stores.js +3 -5
  35. package/dist/boot/stage-05-execution-env.d.ts +5 -2
  36. package/dist/boot/stage-06-runners.d.ts +5 -2
  37. package/dist/boot/stage-06-runners.js +1 -3
  38. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  39. package/dist/boot/stage-07-capability-layer.js +5 -1
  40. package/dist/boot/stage-08-reapers.d.ts +5 -2
  41. package/dist/boot/stage-09-leader.d.ts +5 -2
  42. package/dist/boot/stage-10-http-server.d.ts +5 -2
  43. package/dist/boot/stage-10-http-server.js +9 -1
  44. package/dist/boot/stores.d.ts +5 -2
  45. package/dist/boot/stores.js +7 -7
  46. package/dist/boot/web-admin.d.ts +5 -1
  47. package/dist/boot/web-admin.js +31 -19
  48. package/dist/capabilities/hands-lane.d.ts +9 -39
  49. package/dist/capabilities/hands-lane.js +8 -13
  50. package/dist/capabilities/mcp-probe.d.ts +3 -2
  51. package/dist/capabilities/scenarios.d.ts +11 -1
  52. package/dist/capabilities/scenarios.js +1 -0
  53. package/dist/capabilities/skills.d.ts +1 -17
  54. package/dist/capabilities/skills.js +0 -8
  55. package/dist/capability-facts.d.ts +8 -8
  56. package/dist/capability-facts.js +4 -4
  57. package/dist/card-void.d.ts +6 -9
  58. package/dist/config-catalog.js +1 -1
  59. package/dist/config-dir-trust.js +58 -29
  60. package/dist/config-invariants.d.ts +7 -1
  61. package/dist/config-invariants.js +7 -0
  62. package/dist/config-provider.d.ts +10 -0
  63. package/dist/config-provider.js +15 -4
  64. package/dist/config-root-migration.d.ts +13 -0
  65. package/dist/config-root-migration.js +99 -0
  66. package/dist/config-types.d.ts +5 -5
  67. package/dist/config.d.ts +4 -3
  68. package/dist/config.js +1 -1
  69. package/dist/delegated-session-owner.d.ts +5 -3
  70. package/dist/delegated-session-owner.js +1 -1
  71. package/dist/device-ws-protocol.d.ts +1 -0
  72. package/dist/device-ws-protocol.js +2 -1
  73. package/dist/env-model-table-gate.d.ts +53 -0
  74. package/dist/env-model-table-gate.js +53 -0
  75. package/dist/fleet/fleet-bus.d.ts +28 -52
  76. package/dist/fleet/fleet-bus.js +35 -100
  77. package/dist/fleet/fleet-reconciler.d.ts +4 -4
  78. package/dist/fleet/fleet-reconciler.js +1 -1
  79. package/dist/fleet/subagent-tail-bus.d.ts +14 -11
  80. package/dist/fleet/subagent-tail-bus.js +15 -28
  81. package/dist/hooks/hook-runner.js +28 -7
  82. package/dist/host-decision.d.ts +54 -20
  83. package/dist/host-decision.js +42 -14
  84. package/dist/http/admission.d.ts +1 -1
  85. package/dist/http/admission.js +7 -3
  86. package/dist/http/approval-sweeps.js +11 -8
  87. package/dist/http/caller-trust.d.ts +1 -1
  88. package/dist/http/durable-run-leg.js +2 -2
  89. package/dist/http/engine-refusal.d.ts +16 -0
  90. package/dist/http/engine-refusal.js +17 -0
  91. package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
  92. package/dist/http/memory-compliance-failure-reply.js +4 -6
  93. package/dist/http/owner-access.d.ts +11 -0
  94. package/dist/http/owner-access.js +13 -0
  95. package/dist/http/resume-legs.d.ts +21 -7
  96. package/dist/http/resume-legs.js +71 -49
  97. package/dist/http/resume-restatement.d.ts +39 -0
  98. package/dist/http/resume-restatement.js +25 -0
  99. package/dist/http/route-ctx.d.ts +35 -10
  100. package/dist/http/route-ctx.js +1 -1
  101. package/dist/http/routes/approvals-assistant.d.ts +9 -1
  102. package/dist/http/routes/approvals-assistant.js +142 -31
  103. package/dist/http/routes/capabilities.js +11 -2
  104. package/dist/http/routes/memory-policy.d.ts +2 -2
  105. package/dist/http/routes/memory-policy.js +1 -1
  106. package/dist/http/routes/notify-wake.js +23 -25
  107. package/dist/http/routes/rules.js +48 -13
  108. package/dist/http/routes/runs.js +9 -8
  109. package/dist/http/routes/session-memory-sync.d.ts +34 -6
  110. package/dist/http/routes/session-memory-sync.js +27 -10
  111. package/dist/http/routes/session-sync.js +13 -20
  112. package/dist/http/routes/sessions.d.ts +2 -2
  113. package/dist/http/routes/sessions.js +22 -23
  114. package/dist/http/routes/tasks.js +27 -49
  115. package/dist/http/server.d.ts +13 -7
  116. package/dist/http/server.js +2 -2
  117. package/dist/http/stored-body-replay.js +15 -4
  118. package/dist/http/wire-types.d.ts +17 -7
  119. package/dist/leader/leader.js +5 -2
  120. package/dist/leader/wire.d.ts +7 -1
  121. package/dist/leader/wire.js +6 -5
  122. package/dist/leg-facts.d.ts +37 -0
  123. package/dist/leg-facts.js +15 -0
  124. package/dist/memory-bundle-engine.d.ts +1 -4
  125. package/dist/memory-bundle-engine.js +2 -2
  126. package/dist/memory-operator-faces.d.ts +30 -66
  127. package/dist/memory-operator-faces.js +17 -88
  128. package/dist/memory-scope-stores.d.ts +38 -40
  129. package/dist/memory-scope-stores.js +51 -36
  130. package/dist/memory-scope.d.ts +0 -9
  131. package/dist/memory-scope.js +0 -9
  132. package/dist/memory-sync-client.js +14 -3
  133. package/dist/memory-sync.d.ts +20 -4
  134. package/dist/memory-sync.js +23 -4
  135. package/dist/model-plane-face.d.ts +13 -7
  136. package/dist/model-plane-face.js +2 -1
  137. package/dist/observability/fail-open.d.ts +20 -4
  138. package/dist/observability/fail-open.js +17 -4
  139. package/dist/observability/run-terminal.js +4 -0
  140. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
  141. package/dist/orchestration/workflow-completion-inbox.js +0 -12
  142. package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
  143. package/dist/orchestration/workflow-park-decision.d.ts +8 -3
  144. package/dist/orchestration/workflow-park-decision.js +5 -3
  145. package/dist/org-delivery-gate.d.ts +11 -0
  146. package/dist/org-delivery-gate.js +19 -1
  147. package/dist/parked-decide.d.ts +13 -9
  148. package/dist/parked-decide.js +7 -7
  149. package/dist/parked-revive-surface.js +1 -1
  150. package/dist/peer-inbound-face.d.ts +127 -0
  151. package/dist/peer-inbound-face.js +158 -0
  152. package/dist/permission-rule-list.d.ts +13 -9
  153. package/dist/permission-rule-list.js +7 -3
  154. package/dist/plugins/approval-ask-store-file.js +18 -6
  155. package/dist/plugins/approval-ask-store-memory.js +8 -6
  156. package/dist/plugins/approval-ask-store-sql.d.ts +28 -13
  157. package/dist/plugins/approval-ask-store-sql.js +30 -11
  158. package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
  159. package/dist/plugins/checkpoint-store-sql.js +9 -7
  160. package/dist/plugins/file-history-store-sql.d.ts +24 -18
  161. package/dist/plugins/file-history-store-sql.js +24 -19
  162. package/dist/plugins/file-run-store.d.ts +29 -0
  163. package/dist/plugins/file-run-store.js +97 -8
  164. package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
  165. package/dist/plugins/imported-layer-root-retirement.js +96 -0
  166. package/dist/plugins/local-checkpoint-store.d.ts +1 -1
  167. package/dist/plugins/local-checkpoint-store.js +2 -2
  168. package/dist/plugins/local-session-store.d.ts +6 -2
  169. package/dist/plugins/local-session-store.js +8 -2
  170. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
  171. package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
  172. package/dist/plugins/mailbox-store-sql.d.ts +12 -8
  173. package/dist/plugins/mailbox-store-sql.js +76 -7
  174. package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
  175. package/dist/plugins/memory-sync-store-pg.js +21 -0
  176. package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
  177. package/dist/plugins/memory-sync-store-tidb.js +13 -1
  178. package/dist/plugins/one-time-migrations.d.ts +32 -2
  179. package/dist/plugins/one-time-migrations.js +106 -3
  180. package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
  181. package/dist/plugins/org-delivery-quota-store.js +2 -12
  182. package/dist/plugins/park-commit-watch.d.ts +1 -1
  183. package/dist/plugins/permission-rule-store-file.d.ts +10 -1
  184. package/dist/plugins/permission-rule-store-file.js +15 -2
  185. package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
  186. package/dist/plugins/permission-rule-store-sql.js +35 -2
  187. package/dist/plugins/remote-env-device.d.ts +8 -11
  188. package/dist/plugins/remote-env-device.js +6 -3
  189. package/dist/plugins/remote-env-k8s.d.ts +37 -24
  190. package/dist/plugins/remote-env-k8s.js +50 -17
  191. package/dist/plugins/retention-store-sql.d.ts +2 -2
  192. package/dist/plugins/sandbox-read-floor.d.ts +5 -7
  193. package/dist/plugins/sandbox-read-floor.js +2 -7
  194. package/dist/plugins/sql-errors.d.ts +10 -1
  195. package/dist/plugins/sql-errors.js +13 -0
  196. package/dist/plugins/store-backend.d.ts +23 -28
  197. package/dist/plugins/store-backend.js +9 -1
  198. package/dist/plugins/store-contracts.d.ts +29 -5
  199. package/dist/plugins/store-contracts.js +4 -1
  200. package/dist/plugins/task-attachment-store.d.ts +2 -2
  201. package/dist/plugins/task-attachment-store.js +37 -52
  202. package/dist/plugins/tool-result-store-sql.d.ts +9 -8
  203. package/dist/plugins/tool-result-store-sql.js +23 -2
  204. package/dist/plugins/wiring-section-codec.d.ts +32 -0
  205. package/dist/plugins/wiring-section-codec.js +55 -0
  206. package/dist/plugins/workspace-fill.d.ts +1 -1
  207. package/dist/rule-entry-list.d.ts +3 -2
  208. package/dist/rule-entry-list.js +5 -1
  209. package/dist/rules-consent.d.ts +28 -5
  210. package/dist/rules-consent.js +40 -28
  211. package/dist/run-local.js +9 -5
  212. package/dist/runs.d.ts +12 -8
  213. package/dist/runs.js +6 -7
  214. package/dist/runtime-governance.d.ts +1 -1
  215. package/dist/server-secret-env.d.ts +4 -0
  216. package/dist/session-error-wire.d.ts +12 -0
  217. package/dist/session-error-wire.js +6 -0
  218. package/dist/session-incarnation.d.ts +1 -1
  219. package/dist/session-notify-door.d.ts +106 -0
  220. package/dist/session-notify-door.js +93 -0
  221. package/dist/session-sync.d.ts +9 -14
  222. package/dist/session-sync.js +5 -5
  223. package/dist/session-workspace.d.ts +3 -13
  224. package/dist/session-workspace.js +0 -9
  225. package/dist/standing-answer-grant.d.ts +5 -0
  226. package/dist/standing-answer-grant.js +10 -0
  227. package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
  228. package/dist/stores-sql/session-policy-store-sql.js +3 -13
  229. package/dist/task-mcp.d.ts +1 -1
  230. package/dist/task-settings.d.ts +11 -8
  231. package/dist/task-settings.js +31 -11
  232. package/dist/tool-approval.d.ts +52 -34
  233. package/dist/tool-approval.js +66 -57
  234. package/dist/trace/core-keyset-guard.d.ts +11 -8
  235. package/dist/trace/engine-notice-wire.d.ts +1 -1
  236. package/dist/trace/engine-notice-wire.js +3 -1
  237. package/dist/trace/exit-seat.d.ts +7 -1
  238. package/dist/trace/exit-seat.js +1 -0
  239. package/dist/trace/ledger-sink.d.ts +2 -2
  240. package/dist/trace/model-segment.d.ts +55 -25
  241. package/dist/trace/model-segment.js +101 -33
  242. package/dist/trace/project.d.ts +7 -4
  243. package/dist/trace/project.js +6 -0
  244. package/dist/trace/redact.d.ts +61 -9
  245. package/dist/trace/redact.js +1490 -468
  246. package/dist/trace/self-minted-wire.d.ts +510 -38
  247. package/dist/trace/self-minted-wire.js +165 -17
  248. package/dist/trace/wire-projection-faces.d.ts +1 -1
  249. package/dist/trace/wire-projection-faces.js +1 -1
  250. package/dist/verifier-pause-card.d.ts +33 -5
  251. package/dist/verifier-pause-card.js +15 -10
  252. package/dist/web-admin-client/apply-effective.d.ts +12 -16
  253. package/dist/web-admin-client/apply-effective.js +90 -10
  254. package/dist/workspace-space.d.ts +19 -3
  255. package/dist/workspace-space.js +8 -4
  256. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
  257. package/package.json +3 -2
  258. package/wire-changes/server@7.143.0.json +1167 -0
@@ -79,7 +79,7 @@ export type GateMatchOutcome =
79
79
  kind: "hash_mismatch";
80
80
  candidates: number;
81
81
  }
82
- /** 三元组身份就对不上(不是摘要的事):别的 sourceTaskId / 别的 callId / 早于本 ask 的 park。 */
82
+ /** 三元组身份就对不上(不是摘要的事):别的 sourceSessionId / 别的 callId / 早于本 ask 的 park。 */
83
83
  | {
84
84
  kind: "identity_miss";
85
85
  };
@@ -91,8 +91,8 @@ export type GateMatchOutcome =
91
91
  * `delegation.parentToolCallId` 是必填字段,铸行时逐字透传进 `parent_tool_call_id` 列 ⇒ **列非 NULL
92
92
  * ⇔ delegation 在场**(不需要新列,也不需要回 `req` 里再读一次)。
93
93
  *
94
- * 第二维 `sourceTaskId !== sessionId` 把「根腿」摘出去:根腿的 `sourceTaskId` 恒等于会话锚(core 给
95
- * `AskRequest.sourceTaskId` 填的就是该腿 sessionId),它根本不在任何 fold 里,`parent_tool_call_id`
94
+ * 第二维 `sourceSessionId !== sessionId` 把「根腿」摘出去:根腿的 `sourceSessionId` 恒等于会话锚(core 给
95
+ * `AskRequest.sourceSessionId` 填的就是该腿 sessionId),它根本不在任何 fold 里,`parent_tool_call_id`
96
96
  * 为 NULL 是它的常态而不是信号。
97
97
  *
98
98
  * 命中 ⇒ 退出硬相等(判据 1 结构上不命中,行落 ②③④⑤)。实测(test AI 围栏)checkpoint 存的摘要**逐字
@@ -105,11 +105,11 @@ export declare function isAncestorFoldMint(ask: AskRow): boolean;
105
105
  * 逐条:
106
106
  * - 祖先层 fold 中途铸点 ⇒ 直接退出(见 {@link isAncestorFoldMint});
107
107
  * - `unparseable` 候选直接出局(读不出 ⇒ 不确定 ⇒ 不命中);
108
- * - **身份三元组**:`sourceTaskId` **相等** ∧ `toolCallId` **相等** ∧ 时间维的**因果下界**
108
+ * - **身份三元组**:`sourceSessionId` **相等** ∧ `toolCallId` **相等** ∧ 时间维的**因果下界**
109
109
  * `candidate.createdAtMs >= ask.createdAtMs`(⚠️ 第三维**不是等式** —— 把它读成等式会让合法的 park
110
110
  * 几乎命不中,行随后落 ②③⑤ 被误判)—— 摘要**不是**身份([ref]③①:
111
111
  * 同 args 的两次调用摘要天然相同,只靠摘要硬相等会把第二次投递并进第一次的票);任一维在候选侧
112
- * 缺席(读不出的 blob 没有 `sourceTaskId`)即身份不成立;
112
+ * 缺席(读不出的 blob 没有 `sourceSessionId`)即身份不成立;
113
113
  * - **hash 双等**:两侧都必须在场且相等,任一侧缺席一律不 bind;禁「能取到时才比」的可选谓词。
114
114
  * 归因分两级(顺序即代码顺序):身份这一层先判 —— 同身份候选为空**且**候选集非空 ⇒ `identity_miss`;
115
115
  * 走到 hash 这一层才把缺席记成**单铸** `single_mint`(见 {@link GateMatchOutcome})。
@@ -178,10 +178,10 @@ export interface ReconcileStats {
178
178
  *
179
179
  * 🔴 **今天恒零,而且是结构性的**(扫描P2,2026-08-12 亲读验真;登记而不假称已解):读口
180
180
  * `findCheckpointCandidatesForAsk` 按 `session_id = ask.sessionId` 查,`session_id` 列写的是
181
- * `cp.sessionId`,而 core 每个 checkpoint 铸点都填 `sourceTaskId: sessionId`
181
+ * `cp.sessionId`,而 core 每个 checkpoint 铸点都填 `sourceSessionId: sessionId`
182
182
  * (`runner/prepare-task.js` 四处;`checkpoint-store.d.ts` 逐字「= sessionId at the mint」)⇒ 读口
183
- * 返回的候选恒满足 `c.sourceTaskId === ask.sessionId`;而判据 1 命中要 `c.sourceTaskId ===
184
- * ask.sourceTaskId`,祖先层否决要 `ask.sourceTaskId !== ask.sessionId` —— 两者互斥,这一臂在生产
183
+ * 返回的候选恒满足 `c.sourceSessionId === ask.sessionId`;而判据 1 命中要 `c.sourceSessionId ===
184
+ * ask.sourceSessionId`,祖先层否决要 `ask.sourceSessionId !== ask.sessionId` —— 两者互斥,这一臂在生产
185
185
  * 接线下一次也不会被返回。
186
186
  *
187
187
  * 所以**别把零读数当健康信号**(与 {@link unmatchableNoHash} 的「恒零才是健康态」正相反:那条能非零,
@@ -21,7 +21,7 @@ function withDeadline(op, label, timeoutMs = RECONCILE_STORE_TIMEOUT_MS) {
21
21
  });
22
22
  }
23
23
  export function isAncestorFoldMint(ask) {
24
- return ask.parentToolCallId === null && ask.sourceTaskId !== ask.sessionId;
24
+ return ask.parentToolCallId === null && ask.sourceSessionId !== ask.sessionId;
25
25
  }
26
26
  export function classifyGateMatch(ask, candidates) {
27
27
  const outcome = classifyGateMatchBeforeFoldVeto(ask, candidates);
@@ -30,7 +30,7 @@ export function classifyGateMatch(ask, candidates) {
30
30
  return outcome;
31
31
  }
32
32
  function classifyGateMatchBeforeFoldVeto(ask, candidates) {
33
- const sameIdentity = candidates.filter((c) => c.unparseable !== true && c.sourceTaskId !== null && c.sourceTaskId === ask.sourceTaskId && c.boundCallId === ask.toolCallId && c.createdAtMs >= ask.createdAtMs);
33
+ const sameIdentity = candidates.filter((c) => c.unparseable !== true && c.sourceSessionId !== null && c.sourceSessionId === ask.sourceSessionId && c.boundCallId === ask.toolCallId && c.createdAtMs >= ask.createdAtMs);
34
34
  const askHash = ask.boundInputHash;
35
35
  if (sameIdentity.length === 0) {
36
36
  if (candidates.length > 0)
@@ -96,7 +96,7 @@ export async function bindParkingAskAtGate(deps, ask, nowMs, deadlineMs) {
96
96
  taskId: ask.taskId,
97
97
  toolCallId: ask.toolCallId,
98
98
  candidates: gateMatch.candidates,
99
- reason: "ask and checkpoint minted the same bound input under the same (sourceTaskId, toolCallId) identity but the digests differ — " +
99
+ reason: "ask and checkpoint minted the same bound input under the same (sourceSessionId, toolCallId) identity but the digests differ — " +
100
100
  "the known causes are deployment-side (a hook/policy mutating an object it still holds a reference to between the two mints, " +
101
101
  "or a stateful getter returning a fresh value per read), not out-of-band interference; this ask keeps its fail-safe route (no park, no denial)",
102
102
  });
package/dist/audit.js CHANGED
@@ -129,8 +129,9 @@ const MESSAGE_READ_TREATMENT = {
129
129
  runOrigin: "verbatim",
130
130
  taskId: "verbatim",
131
131
  attachment: "verbatim",
132
+ rewrittenBy: "verbatim",
132
133
  },
133
- custom: { role: "verbatim", customType: "verbatim", content: "verbatim", display: "verbatim", details: "verbatim", provenance: "verbatim", timestamp: "verbatim" },
134
+ custom: { role: "verbatim", customType: "verbatim", content: "verbatim", display: "verbatim", details: "verbatim", provenance: "verbatim", timestamp: "verbatim", rewrittenBy: "verbatim" },
134
135
  assistant: {
135
136
  role: "verbatim", content: "parts", errorMessage: "text", diagnostics: "structure", repetition: "structure",
136
137
  api: "verbatim", provider: "verbatim", model: "verbatim", responseModel: "verbatim", responseId: "verbatim", requestId: "verbatim",
@@ -139,8 +140,9 @@ const MESSAGE_READ_TREATMENT = {
139
140
  staticReasoningCut: "verbatim", timestamp: "verbatim",
140
141
  providerCondition: "verbatim", providerConditionSource: "verbatim", providerResetAtMs: "verbatim", apiErrorRoute: "verbatim",
141
142
  errorBodyIncomplete: "verbatim", modelOutputInvalid: "verbatim", finishReasonUnknown: "verbatim", streamEndIgnored: "verbatim",
143
+ refusedTool: "verbatim", rewrittenBy: "verbatim",
142
144
  },
143
- toolResult: { role: "verbatim", toolCallId: "verbatim", toolName: "verbatim", content: "parts", details: "toolCard", isError: "verbatim", timestamp: "verbatim" },
145
+ toolResult: { role: "verbatim", toolCallId: "verbatim", toolName: "verbatim", content: "parts", details: "toolCard", isError: "verbatim", timestamp: "verbatim", rewrittenBy: "verbatim" },
144
146
  bashExecution: {
145
147
  role: "verbatim", command: "text", output: "text", exitCode: "verbatim", cancelled: "verbatim", truncated: "verbatim",
146
148
  fullOutputPath: "verbatim", timestamp: "verbatim", excludeFromContext: "verbatim",
@@ -45,7 +45,7 @@ export declare function createBudgetAndTracing(ctx: BudgetTracingCtx): {
45
45
  fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
46
46
  tracer: import("@sema-agent/core").TracerHook;
47
47
  sideQueryAccounting: import("../budget.js").SideQueryAccounting;
48
- toolResultStore: import("../plugins/store-backend.js").ToolResultStoreFull | undefined;
48
+ toolResultStore: import("@sema-agent/core").ToolResultStore | undefined;
49
49
  sessionPolicyStore: import("@sema-agent/core").SessionPolicyStore | undefined;
50
50
  fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
51
51
  fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
@@ -29,15 +29,22 @@
29
29
  * 补偿是这条 env 旋钮本身:要档位的部署显式写下它。将来 center 真有了档位下发面,「多租户必须能解析出
30
30
  * 档位」才是一条有对象可指的判据,那时再立。
31
31
  *
32
- * ## 件C 的两条**装配相容性**判据(本仓特有,见 {@link assertLockAssemblable})
32
+ * ## 装配相容性:一条判据、一个时点(见 {@link assertGovernanceAssemblable})
33
33
  *
34
- * core 的锁按「spec 是否占了这个字段」判,而本仓是**部署自己**在铸那两个 spec 字段:
35
- * · `spec.toolPolicy` —— 治理拍(`applyRuntimeGovernance`)在**任何**客户端表态下都会铸出它(敏感路径
36
- * 守卫集默认非空);于是 `toolPolicy` 锁会让 core 的 preflight **整拒每一条腿**。
37
- * · `spec.mcp` —— 部署自带的 MCP 基线(场景/center 下发)同样经 `spec.mcp` 进 core;部署配了 MCP 又锁
38
- * `mcp`,同样是每条腿必拒。
39
- * 两者都在**启动期**拒(安全控件不得半开 §3.4 C 行),而不是让运维在每条任务腿上各撞一次
40
- * `config.locked_key` 去猜。
34
+ * core 的锁按「spec 是否占了这个字段」判、合规否决按「被禁能力是否已在 spec 上」判 —— 占了 / 在场都是**整拒 prepare**
35
+ * (`config.locked_key` / `config.compliance_denied`),不是「不挂载」。而本仓有几张 spec 面是**部署自己**在铸:
36
+ * · `spec.toolPolicy` —— 治理拍(`applyRuntimeGovernance`)在**任何**客户端表态下都铸(敏感路径守卫集默认非空)⇒ 恒在;
37
+ * · `spec.mcp` / `spec.a2a` —— 部署自带的 MCP 服务器 / A2A 对端(config.d 或中心下发)经同一字段进 core(引擎没有部署级的服务器 / 对端席)⇒ 配了就在;
38
+ * · WebFetch 工具面 —— 单用户花名册恒挂(多租户 roster 才摘)。
39
+ * 判据只有一条:**锁住的键 / 否决的能力所守的面 ∩ 本部署装配的面 ≠ ∅ ⇒ 起服拒**(安全控件不得半开 §3.4 C 行)—— 那不是「配得比较严」,
40
+ * 是这台部署的每条腿(或某场景的每条腿)必失败,而运维手里没有任何线索指向那把锁 / 那条否决。两张对照表是 core 两个闭集的 `Record`:
41
+ * 引擎加一个锁键或合规能力 ⇒ 这里缺行 ⇒ tsc 红,逼人当场判它守不守本部署铸的面(修前是两只 `has()` 判据,引擎后加的 `a2a` 锁与
42
+ * `a2a_peers` 否决静默不判)。
43
+ *
44
+ * **时点**:部署 MCP / A2A 基线在能力层才物化(server = 第 7 段的 `applyCenterCapabilities`;run-local = 候选采纳段的同一行),所以这道门
45
+ * 在**物化之后**由每个起服入口调恰好一次,出口只有一个:抛 ⇒ 起服拒(退出码 1)。座席铸点 {@link createGovernanceSeams}(第 6 段)**不判**:
46
+ * 那一刻两格基线恒空(修前判据就跑在那里,于是 `mcp` 锁 / `mcp_servers` 否决对 config.d 与中心声明的服务器从不拒启,任务腿各自在引擎门口
47
+ * 撞拒);它的 config 窄口里也就没有那两格 —— 「物化之前判」这一形在编译期就写不出来。没有运行期补判:不留每腿 400 臂、不留静默卸臂。
41
48
  *
42
49
  * ## 件D 的边界(成文,别读成「数据会被删」)
43
50
  *
@@ -62,7 +69,8 @@ export interface GovernanceSeams {
62
69
  }
63
70
  /** 依赖收窄到真实消费面(接口隔离 —— 测试用真形字面量,零铸形)。 */
64
71
  export interface GovernanceSeamsCtx {
65
- config: Pick<ServiceConfig, "compliancePosture" | "lockedConfigKeys" | "retentionPolicy" | "retentionSweep" | "mcpServers" | "requirePrincipal">;
72
+ /** 没有 `mcpServers` / `a2aPeers`:座席铸在部署基线物化之前,装配相容性判据不在这里(见文件头「时点」)。 */
73
+ config: Pick<ServiceConfig, "compliancePosture" | "lockedConfigKeys" | "retentionPolicy" | "retentionSweep">;
66
74
  logger: Pick<Logger, "info" | "warn">;
67
75
  /**
68
76
  * core 留存能力校验的对象集(名字进拒启文案)。喂的是**装配现场的真店**,不是「我以为装了什么」——
@@ -79,41 +87,18 @@ export interface GovernanceSeamsCtx {
79
87
  */
80
88
  retentionExecutor: ManagedRetentionCapability | null;
81
89
  }
90
+ /** 装配相容性门的输入 = **装配完成后**的部署事实(部署 MCP / A2A 基线物化之后读;见文件头「时点」)。 */
91
+ export type GovernanceAssemblyFacts = Pick<ServiceConfig, "lockedConfigKeys" | "compliancePosture" | "mcpServers" | "a2aPeers" | "requirePrincipal">;
82
92
  /**
83
- * 件C 的装配相容性判据(纯,可单测)——见文件头「两条判据」。
84
- *
85
- * 🔴 失败方向朝**拒启**:一把在本部署上必然把每条腿都拒掉的锁,不是「配得比较严」,是配错了;继续启动
86
- * 只会让服务对每一个请求说 `config.locked_key`,而运维手里没有任何线索指向那把锁。
93
+ * **装配相容性门**(见文件头「一条判据、一个时点」):锁住的键 / 否决的能力所守的面撞上本部署装配的面 ⇒ 抛(起服拒)。
94
+ * 🔴 时点即契约:调用方必须在部署 MCP / A2A 基线**物化之后**调它(server 第 7 段紧跟 `applyCenterCapabilities`;run-local 在候选采纳段之后),
95
+ * 每个起服入口恰好一次。中心侧后来加了 MCP 服务器 / A2A 对端:那一族是 restart-to-apply 面,变更翻 `restartRequired` 让编排器滚动重启 ——
96
+ * 重启就撞上这道门,所以没有第二条热路径判据。
87
97
  */
88
- export declare function assertLockAssemblable(input: {
89
- lockedKeys: ReadonlySet<LockedKey>;
90
- deploymentMcpConfigured: boolean;
91
- }): void;
92
- /**
93
- * 治理面的**装配相容性**总判据(codex 交叉复审 R2-F2 起扩面)——锁与合规档位在这条轴上是同一件事:
94
- * 两者都可能把「本部署自己的装配」判成 core 门口的违规,而那不是「配得更严」,是**这台从此每条腿必失败**。
95
- *
96
- * 合规半场的判据来自亲核 core 的 prepare 门(`prepare-task` 的 compliance 段):被否决的能力若**已在
97
- * spec 上**,core 是**整拒 prepare**(`config.compliance_denied`),不是「不挂载」。于是:
98
- * · `mcp_servers` 被禁 ∧ 部署自带 MCP 基线 ⇒ 每条腿的 `spec.mcp` 都在 ⇒ 必拒;
99
- * · `web_fetch` 被禁 ∧ 花名册挂了 WebFetch ⇒ 必拒。⚠️ `hipaa` 的**内建 floor 就含 `web_fetch`**,而本仓
100
- * 的单用户花名册**恒挂** WebFetch(`capabilities/scenarios.ts` 的 roster 过滤只在多租户下摘它)——
101
- * 也就是说「单用户 + hipaa」在本仓是一个每条腿必失败的组合。这条判据的全部价值就在这儿:让它在
102
- * 启动期说出来,而不是让运维看着一台"启动成功、任务全失败"的 worker 猜。
103
- * · `workflows` 被禁只在 `spec.selfOrchestration === true` 的腿上拒(per-task,不是部署恒真)⇒ 不在本
104
- * 判据内,由那条腿自己响亮拒;`org_memory_mount` 走件A 的准入面。**成文定界,不留白。**
105
- */
106
- export declare function assertGovernanceAssemblable(input: {
107
- lockedKeys: ReadonlySet<LockedKey>;
108
- /** 已解析的合规否决集(空集 = 无档位)。 */
109
- complianceDenies: ReadonlySet<string>;
110
- deploymentMcpConfigured: boolean;
111
- /** 本部署的花名册是否会挂 WebFetch(= 单用户形;多租户下 roster 过滤掉它)。 */
112
- webFetchMounted: boolean;
113
- }): void;
98
+ export declare function assertGovernanceAssemblable(facts: GovernanceAssemblyFacts): void;
114
99
  /**
115
- * 装配三座席。**拒启口即装配口**:相容性判据与 core 的留存能力校验都在这里跑,调用方不必记得再调一次
116
- * (件A 的 C12 探测同姿势)。
100
+ * 装配三座席(件B/C/D)与 core 的留存能力校验 —— **不**判装配相容性:座席铸在部署 MCP / A2A 基线物化之前,那道门由起服入口在物化之后调
101
+ * {@link assertGovernanceAssemblable}(见文件头「时点」)。
117
102
  */
118
103
  export declare function createGovernanceSeams(ctx: GovernanceSeamsCtx): GovernanceSeams;
119
104
  //# sourceMappingURL=governance-seams.d.ts.map
@@ -1,44 +1,77 @@
1
1
  import { assertRetentionCapability, resolveComplianceDenies, resolveLockedKeys } from "@sema-agent/core";
2
- export function assertLockAssemblable(input) {
3
- if (input.lockedKeys.has("toolPolicy")) {
4
- throw new Error('LOCKED_CONFIG_KEYS contains "toolPolicy", which this server cannot arm: it COMPOSES the effective tool policy itself on ' +
2
+ import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
3
+ const FACE_ASSEMBLED = {
4
+ toolPolicy: () => true,
5
+ mcp: (facts) => (facts.mcpServers?.servers.length ?? 0) > 0,
6
+ a2a: (facts) => (facts.a2aPeers?.length ?? 0) > 0,
7
+ webFetch: (facts) => !DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(facts),
8
+ };
9
+ const LOCK_CONFLICTS = {
10
+ toolPolicy: {
11
+ face: "toolPolicy",
12
+ refusal: 'LOCKED_CONFIG_KEYS contains "toolPolicy", which this server cannot arm: it COMPOSES the effective tool policy itself on ' +
5
13
  "every leg (deployment approval baseline + the tighten-only governance pass over the sensitive-path guard set), so " +
6
14
  "`TaskSpec.toolPolicy` is always present at the engine's prepare door and the lock would refuse EVERY task with " +
7
15
  "config.locked_key. The policy is already deployment-owned and no request can loosen it (the fold is deny-wins), so " +
8
- "this lock has nothing to guard here — remove it from LOCKED_CONFIG_KEYS.");
9
- }
10
- if (input.lockedKeys.has("mcp") && input.deploymentMcpConfigured) {
11
- throw new Error('LOCKED_CONFIG_KEYS contains "mcp" while this deployment configures MCP servers of its own (scenario/center MCP): the ' +
16
+ "this lock has nothing to guard here — remove it from LOCKED_CONFIG_KEYS.",
17
+ },
18
+ mcp: {
19
+ face: "mcp",
20
+ refusal: 'LOCKED_CONFIG_KEYS contains "mcp" while this deployment configures MCP servers of its own (config.d/mcp.json or the center\'s mcp domain): the ' +
12
21
  "deployment's servers ride the SAME `TaskSpec.mcp` field the lock guards (the engine has no deployment-level MCP seat), " +
13
22
  "so every task would be refused at prepare with config.locked_key. Either drop the `mcp` lock, or remove the configured " +
14
- "MCP servers — a locked deployment mounts no MCP at all.");
15
- }
16
- }
17
- export function assertGovernanceAssemblable(input) {
18
- assertLockAssemblable({ lockedKeys: input.lockedKeys, deploymentMcpConfigured: input.deploymentMcpConfigured });
19
- if (input.complianceDenies.has("mcp_servers") && input.deploymentMcpConfigured) {
20
- throw new Error('the compliance posture denies "mcp_servers" while this deployment configures MCP servers of its own: the engine REFUSES ' +
23
+ "MCP servers — a locked deployment mounts no MCP at all.",
24
+ },
25
+ a2a: {
26
+ face: "a2a",
27
+ refusal: 'LOCKED_CONFIG_KEYS contains "a2a" while this deployment configures A2A peers of its own (the center\'s a2a domain): the ' +
28
+ "deployment's peers ride the SAME `TaskSpec.a2a` field the lock guards (the engine has no deployment-level A2A peer seat), " +
29
+ "so every task would be refused at prepare with config.locked_key. Either drop the `a2a` lock, or remove the configured " +
30
+ "A2A peers — a locked deployment dials no A2A peer at all.",
31
+ },
32
+ compliancePosture: null,
33
+ retentionPolicy: null,
34
+ };
35
+ const DENY_CONFLICTS = {
36
+ mcp_servers: {
37
+ face: "mcp",
38
+ refusal: 'the compliance posture denies "mcp_servers" while this deployment configures MCP servers of its own: the engine REFUSES ' +
21
39
  "(not silently narrows) every prepare whose TaskSpec.mcp is non-empty, so every task would fail with config.compliance_denied. " +
22
- "Remove the configured MCP servers, or drop mcp_servers from the posture.");
23
- }
24
- if (input.complianceDenies.has("web_fetch") && input.webFetchMounted) {
25
- throw new Error('the compliance posture denies "web_fetch" while this deployment mounts the WebFetch tool: the engine REFUSES every prepare ' +
40
+ "Remove the configured MCP servers, or drop mcp_servers from the posture.",
41
+ },
42
+ a2a_peers: {
43
+ face: "a2a",
44
+ refusal: 'the compliance posture denies "a2a_peers" while this deployment configures A2A peers of its own: the engine REFUSES ' +
45
+ "(not silently narrows) every prepare whose TaskSpec.a2a is non-empty, so every task would fail with config.compliance_denied. " +
46
+ "Remove the configured A2A peers, or drop a2a_peers from the posture.",
47
+ },
48
+ web_fetch: {
49
+ face: "webFetch",
50
+ refusal: 'the compliance posture denies "web_fetch" while this deployment mounts the WebFetch tool: the engine REFUSES every prepare ' +
26
51
  "whose roster carries it, so every task on the default roster would fail with config.compliance_denied. This server drops " +
27
52
  "WebFetch from the roster only on a MULTI-TENANT deployment (REQUIRE_PRINCIPAL=true) — a single-user deployment cannot " +
28
- "currently honor a web_fetch denial. Run the posture multi-tenant, or drop the profile/deny.");
29
- }
53
+ "currently honor a web_fetch denial. Run the posture multi-tenant, or drop the profile/deny.",
54
+ },
55
+ workflows: null,
56
+ org_memory_mount: null,
57
+ };
58
+ function resolveGovernanceDeclarations(config) {
59
+ return {
60
+ lockedKeys: resolveLockedKeys(config.lockedConfigKeys !== undefined ? { keys: config.lockedConfigKeys } : undefined),
61
+ complianceDenies: config.compliancePosture !== undefined ? resolveComplianceDenies(config.compliancePosture) : new Set(),
62
+ };
63
+ }
64
+ export function assertGovernanceAssemblable(facts) {
65
+ const { lockedKeys, complianceDenies } = resolveGovernanceDeclarations(facts);
66
+ const conflicts = [...[...lockedKeys].map((key) => LOCK_CONFLICTS[key]), ...[...complianceDenies].map((cap) => DENY_CONFLICTS[cap])];
67
+ for (const conflict of conflicts)
68
+ if (conflict !== null && FACE_ASSEMBLED[conflict.face](facts))
69
+ throw new Error(conflict.refusal);
30
70
  }
31
71
  export function createGovernanceSeams(ctx) {
32
72
  const { config, logger, retentionStores } = ctx;
33
- const lockedKeys = resolveLockedKeys(config.lockedConfigKeys !== undefined ? { keys: config.lockedConfigKeys } : undefined);
73
+ const { lockedKeys, complianceDenies } = resolveGovernanceDeclarations(config);
34
74
  const posture = config.compliancePosture;
35
- const complianceDenies = posture !== undefined ? resolveComplianceDenies(posture) : new Set();
36
- assertGovernanceAssemblable({
37
- lockedKeys,
38
- complianceDenies,
39
- deploymentMcpConfigured: (config.mcpServers?.servers.length ?? 0) > 0,
40
- webFetchMounted: config.requirePrincipal !== true,
41
- });
42
75
  const lockedConfig = config.lockedConfigKeys !== undefined && config.lockedConfigKeys.length > 0 ? { keys: config.lockedConfigKeys } : undefined;
43
76
  if (lockedConfig)
44
77
  logger.info("locked_config_enabled", { keys: [...lockedKeys].sort() });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 晚绑席([ref] 十段切分的**唯一**跨段可变面)—— 四只 cell,读点在前段、写点在后段。
2
+ * 晚绑席([ref] 十段切分的**唯一**跨段可变面)—— 五只 cell,读点在前段、写点在后段。
3
3
  *
4
4
  * 为什么是模块级 live binding 而不是 ctx 字段:读点的原文是**裸标识符**(`() => runStore`、
5
5
  * `() => parkedAskRedeem`),而 ctx 字段是**快照** —— 把读点改成 `ctx.runStore` 就是正文改写,
@@ -8,9 +8,10 @@
8
8
  * · `runStore` / `rateLimiter` —— 声明行留在第 7 段原位,紧随一行 `bindX(...)` 把值交过来;
9
9
  * · `parkedAskRedeem` / `runDenySweep` —— 它们的**声明行本身**就是 `let`(逐字搬进本文件,含缩进),
10
10
  * 赋值点(server 造出来之后那两处)也随之搬进 `bindServerLateSeats` —— 跨模块给 import 赋值是非法的,
11
- * 所以 cell 与它的写点必须同居一个模块。
11
+ * 所以 cell 与它的写点必须同居一个模块;
12
+ * · `sessionNotifyDoor` —— 同上一形(server 的产物,写点在 `bindServerLateSeats`)。
12
13
  *
13
- * 时序与修前逐字相同:四只 cell 的读点全是 `() => x` 取值闭包(boot 期不求值,最早的求值发生在
14
+ * 时序与修前逐字相同:五只 cell 的读点全是 `() => x` 取值闭包(boot 期不求值,最早的求值发生在
14
15
  * listen 之后的请求/tick 上),写点仍在各自原来的那一拍。未绑窗内取值得到 `undefined` —— 这正是
15
16
  * 各消费座既有的 fail-closed 臂(device 限速座:`gate()` 取不到就抛,见 boot/device-lane.ts:68)。
16
17
  */
@@ -20,11 +21,13 @@ import type { RateGate } from "../observability/rate-limit.js";
20
21
  import type { ServiceConfig } from "../config.js";
21
22
  import type { StoreBackend } from "../plugins/store-backend.js";
22
23
  import type { createHttpServer } from "../http/server.js";
24
+ import type { SessionNotifyDoor } from "../session-notify-door.js";
23
25
  declare let runStore: ReturnType<StoreBackend["run"]> | undefined;
24
26
  declare let rateLimiter: RateGate | undefined;
25
27
  declare let parkedAskRedeem: ParkedAskRedeem | undefined;
26
28
  declare let runDenySweep: ((now: number) => Promise<void>) | undefined;
27
- export { runStore, rateLimiter, parkedAskRedeem, runDenySweep };
29
+ declare let sessionNotifyDoor: SessionNotifyDoor | undefined;
30
+ export { runStore, rateLimiter, parkedAskRedeem, runDenySweep, sessionNotifyDoor };
28
31
  export declare function bindRunStore(v: ReturnType<StoreBackend["run"]> | undefined): void;
29
32
  export declare function bindRateLimiter(v: RateGate): void;
30
33
  export declare function bindServerLateSeats(ctx: {
@@ -2,7 +2,8 @@ let runStore;
2
2
  let rateLimiter;
3
3
  let parkedAskRedeem;
4
4
  let runDenySweep;
5
- export { runStore, rateLimiter, parkedAskRedeem, runDenySweep };
5
+ let sessionNotifyDoor;
6
+ export { runStore, rateLimiter, parkedAskRedeem, runDenySweep, sessionNotifyDoor };
6
7
  export function bindRunStore(v) {
7
8
  runStore = v;
8
9
  }
@@ -12,6 +13,7 @@ export function bindRateLimiter(v) {
12
13
  export function bindServerLateSeats(ctx) {
13
14
  const { config, logger, server } = ctx;
14
15
  runDenySweep = server.denyExpiredApprovals;
16
+ sessionNotifyDoor = server.sessionNotifyDoor;
15
17
  if (!config.directDoorActive)
16
18
  parkedAskRedeem = server.redeemParkedAsk;
17
19
  else
@@ -45,7 +45,7 @@ export function createLeaderFace(ctx) {
45
45
  (leaderProvider === "k8s" && "s3" in leaderMinio && executionEnvFactory) ||
46
46
  (leaderProvider === "host" && executionEnvFactory))
47
47
  ? createLeaderEndpoint(createLeaderRunner({
48
- brain, models: config.models, roles: config.roles, pricing, logger,
48
+ brain, models: config.models, roles: config.roles, tiers: config.tiers, pricing, logger,
49
49
  governance: {
50
50
  compliancePostureResolver: governanceSeams.compliancePostureResolver,
51
51
  lockedConfig: governanceSeams.lockedConfig,
@@ -61,9 +61,7 @@ export function createLeaderFace(ctx) {
61
61
  ...(ctx.onError ? { onError: ctx.onError } : {}),
62
62
  mods: ctx.deploymentMods,
63
63
  fanoutEnabled: config.leaderFanoutEnabled,
64
- ...((process.env.MODEL_ROUTER_ID || process.env.MODEL_CHEAP_ID)
65
- ? { routerModel: (process.env.MODEL_ROUTER_ID || process.env.MODEL_CHEAP_ID) }
66
- : {}),
64
+ ...(process.env.MODEL_ROUTER_ID ? { routerModel: process.env.MODEL_ROUTER_ID } : {}),
67
65
  ...(leaderProvider === "e2b" ? { e2bApiKey: config.remoteExec.apiKey } : {}),
68
66
  ...(executionEnvFactory ? { envFactory: executionEnvFactory } : {}),
69
67
  ...leaderMinio,
@@ -1,6 +1,5 @@
1
1
  import { type LaneHomeDeployment } from "../execution-lane-caps.js";
2
2
  import { type MemoryScopeStores } from "../memory-scope-stores.js";
3
- import type { SessionCaptureRecordSource } from "../plugins/store-backend.js";
4
3
  import type { RestartSliceCtx } from "../web-admin-client/restart-signal.js";
5
4
  import type { MemoryConsolidationDriverConfig, ServiceConfig } from "../config-types.js";
6
5
  import { resolveMemoryConsolidationDriver, type ConsolidationWriteJudge, type ConsolidationWriteJudgeInput, type EngineNotice, type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type MemoryConsolidationDriverDeps, type PermissionRuleStoreProvider } from "@sema-agent/core";
@@ -500,13 +499,6 @@ export declare function createMemoryConsolidationFaces(stores: MemoryScopeStores
500
499
  /** 停因自由文本的**运维日志**座(缺席 = 没人听,不影响任何行为)。载荷由 {@link buildStopDetailAudit}
501
500
  * 铸,调用点在单飞回调**之内** ⇒ 一轮真 run 一行,并入的等待者不各落一行。 */
502
501
  onStopDetail?: (audit: ReturnType<typeof buildStopDetailAudit>) => void;
503
- /** [ref]②(383 §2.1b):capture opt-out 记录的按平面取用源(main.ts 取一次,与 Runner 同源;每只引擎按它那只店的控制面取)。
504
- * 🔴 这只引擎是四只 operator 面里**真读名册**的那只:`consolidationEligibility` 第四臂
505
- * (engine.js `listCaptureOptOutSessions`)拿它筛掉 opt-out 会话的贡献条目 —— SQL 部署上漏喂
506
- * = 驱动器读文件空名册 ⇒ 蒸馏器放大用户明说不要记的内容(S-5 真实失效形;全站同批注入律,
507
- * 机器钉 capture-optout-lane ②)。[ref] 起 local 车道在引擎接线时也供(core 文件三腿,同一只控制面);
508
- * 缺席 ⇒ 记忆面暗(引擎未接线),与 Runner 同本。 */
509
- captureRecords?: SessionCaptureRecordSource;
510
502
  /** core 7.50.0:整理跑的**写判官座**(必填 —— 缺席不是「没有规则」,core 也拒)。操作面不判任何东西,只把它原样递给驱动动词:
511
503
  * 早问库目录一次、应用时问每个产物文件,答 `no_objection` 以外一律拒写。装配层给哪一只见 {@link createOperatorValveWriteJudge}。 */
512
504
  writeJudge: ConsolidationWriteJudge;
@@ -4,8 +4,8 @@ import { buildOperatorRosterWayOut } from "../http/principal-gate.js";
4
4
  import { memoryMountRootOf } from "../memory-scope.js";
5
5
  import { executionLaneHomeDir } from "../execution-lane-caps.js";
6
6
  import { DEFAULT_MODEL_REF, resolveMainModel } from "../model-select.js";
7
- import { backendOwnsControlPlane, captureRecordStoreOf } from "../memory-operator-faces.js";
8
- import { memoryStoreForRequest } from "../memory-scope-stores.js";
7
+ import { captureRecordStoreOf } from "../memory-operator-faces.js";
8
+ import { backendOwnsControlPlane, memoryStoreForRequest } from "../memory-scope-stores.js";
9
9
  import { createConsolidationWriteJudge, deliverWriteRefusal, expandTiers, MemoryEngine, modelOriginOf, readConsolidationDriverRun, resolveMemoryConsolidationDriver, runMemoryConsolidationDriver, } from "@sema-agent/core";
10
10
  import { seatText } from "../trace/exit-seat.js";
11
11
  export function resolveConsolidationDriverSeat(deps) {
@@ -342,7 +342,7 @@ export function createMemoryConsolidationFaces(stores, input) {
342
342
  const known = engines.get(store);
343
343
  if (known !== undefined)
344
344
  return known;
345
- const records = captureRecordStoreOf(input.captureRecords, store);
345
+ const records = captureRecordStoreOf(stores.captureRecords, store);
346
346
  const engine = new MemoryEngine({
347
347
  backend: store,
348
348
  memoryDir: memoryMountRootOf(store, stores.root),
@@ -91,7 +91,7 @@ export function startReapers(ctx) {
91
91
  const runDenySweepGuard = createThrottledReaperCatch("run_deny_sweep", logger);
92
92
  const runsReapSuspendedGuard = createThrottledReaperCatch("runs_reap_suspended", logger);
93
93
  const checkpointReapCtxGuard = createThrottledReaperCatch("checkpoint_reap_ctx", logger);
94
- const toolResultReapOlderThanGuard = createThrottledReaperCatch("tool_result_reap_older_than", logger);
94
+ const toolResultReapGuard = createThrottledReaperCatch("tool_result_reap", logger);
95
95
  const fileHistorySweepOrphanBlobsGuard = createThrottledReaperCatch("file_history_sweep_orphan_blobs", logger);
96
96
  const legacySnapshotBlobSweepGuard = createThrottledReaperCatch("legacy_snapshot_blob_sweep", logger);
97
97
  const attachmentReapUnboundGuard = createThrottledReaperCatch("attachment_reap_unbound", logger);
@@ -244,9 +244,10 @@ export function startReapers(ctx) {
244
244
  rateLimiter?.sweep();
245
245
  if (costQuota instanceof CostQuota)
246
246
  costQuota.reap();
247
- leg(toolResultStore
248
- ?.reapOlderThan?.(Date.now() - config.toolResultTtlSec * 1000)
249
- ?.then(() => toolResultReapOlderThanGuard.onSuccess(), toolResultReapOlderThanGuard.onError));
247
+ const reapToolResults = toolResultStore?.reap?.bind(toolResultStore);
248
+ leg(reapToolResults && Promise.resolve()
249
+ .then(() => reapToolResults(Date.now(), { maxAgeMs: config.toolResultTtlSec * 1000 }))
250
+ .then(() => toolResultReapGuard.onSuccess(), toolResultReapGuard.onError));
250
251
  leg(fileHistoryErasure
251
252
  ?.sweepOrphanBlobs?.()
252
253
  .then(() => fileHistorySweepOrphanBlobsGuard.onSuccess(), fileHistorySweepOrphanBlobsGuard.onError));
@@ -1,7 +1,7 @@
1
1
  import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilities/select-environment-tool.js";
2
2
  import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
3
3
  import { selectScenario } from "../capabilities/scenarios.js";
4
- import { type LoadedSkill } from "../capabilities/skills.js";
4
+ import type { LoadedSkill } from "../capabilities/skills.js";
5
5
  import type { ServiceConfig } from "../config.js";
6
6
  import { type LiveQuestionFace } from "../deployment-governance.js";
7
7
  import { FleetEventBus } from "../fleet/fleet-bus.js";
@@ -6,8 +6,8 @@ import { recordFailOpen } from "../observability/fail-open.js";
6
6
  import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilities/select-environment-tool.js";
7
7
  import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
8
8
  import { buildExcludeToolsSeat, buildPromptSeats, buildRunSkills, createScenarioGate, selectScenario } from "../capabilities/scenarios.js";
9
- import { stampRunSkills } from "../capabilities/skills.js";
10
- import { stampHandsLane, toolPolicyForHands } from "../capabilities/hands-lane.js";
9
+ import { toolPolicyForHands } from "../capabilities/hands-lane.js";
10
+ import { mintLegFacts } from "../leg-facts.js";
11
11
  import { applyLongtailDefer } from "../capabilities/tool-defer.js";
12
12
  import { assertGuardPatternsUsable, buildApprovalGrantNotice, buildOnlySensitiveBaselineWarning, createApprovalBaselinePolicy, createDeploymentGovernanceInputs } from "../deployment-governance.js";
13
13
  import { createDeploymentListExemption, gateIntentUnserviceableReason, singleUserAutoAcceptBaselineApplies } from "../approval.js";
@@ -28,7 +28,7 @@ import { tightenGoverned } from "../governance-overrides.js";
28
28
  import { applyRuntimeGovernance } from "../runtime-governance.js";
29
29
  import { HttpError, createCodedHttpError, encodeCheckpointScope } from "../security.js";
30
30
  import { headReadOf, sessionFaceOfHead } from "../session-incarnation.js";
31
- import { legProjectIdOf, sessionWorkspaceStoreOf, stampLegSessionWitness } from "../session-workspace.js";
31
+ import { legProjectIdOf, sessionWorkspaceStoreOf } from "../session-workspace.js";
32
32
  import { memorySpecForRequest } from "../memory-scope.js";
33
33
  import { createMemoryProjectLayers } from "../memory-project-layer.js";
34
34
  import { inheritEnvFacts, inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
@@ -177,13 +177,13 @@ export function createResolveSpec(ctx) {
177
177
  scratchpadDir: folded.scratchpadDir,
178
178
  hostSemanticsLane: folded.hostSemanticsLane,
179
179
  });
180
- const stamped = stampHandsLane(final, gated.hands);
181
- return stampLegSessionWitness(stampRunSkills(stamped, runSkills.roster), gated.sessionWitness);
180
+ return { spec: final, facts: { hands: gated.hands, skills: runSkills.roster, sessionWitness: gated.sessionWitness } };
182
181
  };
183
182
  const gateScenarioAndAppend = async (body, auth, opts) => {
184
183
  const scenarioName = await scenarioGate(auth?.principal, body.scenario);
185
184
  const root = opts.execution.root;
186
- const sessionWitness = { sessionId: root, incarnation: (sessionHeadOf === undefined ? undefined : sessionFaceOfHead(root, await sessionHeadOf(root)))?.incarnation ?? null };
185
+ const rootFace = sessionHeadOf === undefined ? undefined : sessionFaceOfHead(root, await sessionHeadOf(root));
186
+ const sessionWitness = { sessionId: root, owner: rootFace?.owner ?? null, incarnation: rootFace?.incarnation ?? null };
187
187
  const cap = selectScenario(scenarios, scenarioName)(body, auth?.principal, { sessionId: sessionWitness.sessionId, delegationRoot: sessionWitness });
188
188
  const acceptedAppend = acceptAppendSystemPrompt(body.appendSystemPrompt, (detail) => logger.warn("append_system_prompt_dropped", { detail, sessionId: auth?.sessionId ?? null }));
189
189
  const objective = typeof body.objective === "string" ? body.objective : "";
@@ -680,8 +680,8 @@ export function createResolveSpec(ctx) {
680
680
  return governed;
681
681
  };
682
682
  const resolveSpecForLeg = async (body, req, auth, opts) => {
683
- const spec = await resolveSpec(body, req, auth, opts);
684
- return unrooted(opts.unattendedLeg !== true ? spec : withUnattendedLeg(spec));
683
+ const { spec, facts } = await resolveSpec(body, req, auth, opts);
684
+ return mintLegFacts(unrooted(opts.unattendedLeg !== true ? spec : withUnattendedLeg(spec)), facts);
685
685
  };
686
686
  return resolveSpecForLeg;
687
687
  }
@@ -7,7 +7,7 @@
7
7
  * ⚠️ **位置即契约**:必须晚于 stores/exec-env/coordinators/workflow 段(所有键都是它们的产物),
8
8
  * 且早于 `new Runner(runnerDeps)` —— Runner 构造时展开 tier 表成私有目录副本(之后的换代经
9
9
  * `Runner.swapDeps` 换进,见 boot/stage-08-reapers.ts)。
10
- * `getRunStore()` 是唯一的晚绑取值(runStore 在本段之后才构造),原文靠同作用域前向引用。
10
+ * runStore 在本段之后才构造 ⇒ 本段不读它(本段没有晚绑取值)。
11
11
  */
12
12
  import { type CacheBreakFinding, type CrossBoundaryPosture, type RunnerDeps, type WorkflowRunStore, type AskOutcome } from "@sema-agent/core";
13
13
  import type { createBrain } from "../brain.js";
@@ -19,13 +19,13 @@ import type { Logger } from "../observability/logger.js";
19
19
  import type { Metrics } from "../observability/metrics.js";
20
20
  import { type ConsolidationDriverSeat } from "./memory-consolidation.js";
21
21
  import { WorkflowAgentRegistry } from "../orchestration/workflow-agent-steer.js";
22
- import { type WorkflowCompletionInbox } from "../orchestration/workflow-completion-inbox.js";
23
22
  import { type EngineNoticeRouter } from "../trace/engine-notice-wire.js";
24
23
  import { WorkflowNotifyGate, type WorkflowCompletionPayload } from "../orchestration/workflow-notify-journal.js";
25
24
  import type { ServiceWorkflowJournalStore, SessionCaptureRecordSource, StoreBackend, ToolResultStoreFull } from "../plugins/store-backend.js";
26
25
  import type { createSessionStore } from "../plugins/session-store.js";
27
26
  import type { QuestionCoordinator } from "../question.js";
28
27
  import type { ToolApprovalCoordinator } from "../tool-approval.js";
28
+ import { type PeerInboundFace } from "../peer-inbound-face.js";
29
29
  import type { MemoryBackend } from "@sema-agent/core";
30
30
  import type { MemorySyncRunner } from "../memory-sync-client.js";
31
31
  import type { MailboxRecipientLifecycle } from "../plugins/mailbox-recipient-lifecycle.js";
@@ -68,7 +68,10 @@ export declare function createRunnerDepsOnAsk(toolApproval: ToolApprovalCoordina
68
68
  * `classificationKnown:false`(指标标签折 `unknown`),不吞不编;与安装包的锁步由 test/boot-runner-deps-shared-base.test.ts
69
69
  * 的 dist 扫描格钉住(两种发射写法都读;读不出词的经变量发射点本身红;core 加词/收进 d.ts 那天先红)。
70
70
  * 第七词 `peer-seat-hold`(runtask 的 `holdDeclarations`,字面量):对端座的三员对象里 `hold` / `release` 抛了 ⇒ 引擎报一次、该引用
71
- * 不被持有;座是本仓的 desk,所以这是部署自己的故障,与其余六词同走 warn + 计数。 */
71
+ * 不被持有;座是本仓的 desk,所以这是部署自己的故障,与其余六词同走 warn + 计数。
72
+ * 第八词 `input-author-unreadable`(core 7.61.0 `run-leg.js` 的 `objectiveAuthorOf` 回调,字面量):宿主经 `RunInternals.objectiveAuthor`
73
+ * 递了一个不在 `INPUT_AUTHORS` 里的词 ⇒ 引擎报一次、该目标按操作者的输入筛。本服务不递这个字段(src 零读写),只有嵌入方手铸时才发射,
74
+ * 仍是部署侧的故障,同走 warn + 计数。 */
72
75
  export declare const CONFIG_ADVISORY_CLASSIFICATIONS: ReadonlySet<string>;
73
76
  /** [ref]:core 的 [ref] 前缀缓存**断裂**探测器交给宿主的根因**闭集**,以及每个词的日志级别。
74
77
  * 闭集**不抄词**:词源直接取 core 公开导出的 `CacheBreakFinding["cause"]`(`@sema-agent/core` 根导出,
@@ -240,10 +243,7 @@ export interface RunnerDepsCtx {
240
243
  workflowJournalStore: ServiceWorkflowJournalStore | undefined;
241
244
  workflowAgentRegistry: WorkflowAgentRegistry | undefined;
242
245
  workflowNotifyGate: WorkflowNotifyGate | undefined;
243
- workflowCompletionInbox: WorkflowCompletionInbox | undefined;
244
246
  deliverWorkflowCompletion: (p: WorkflowCompletionPayload) => Promise<void>;
245
- /** 晚绑(runStore 在本段之后构造)——见文件头「位置即契约」。 */
246
- getRunStore: () => ReturnType<StoreBackend["run"]> | undefined;
247
247
  }
248
248
  /** [ref] A10 留档发现②:main runner `RunnerDeps` 与 main.ts subRunner 字面量之间此前手工重复
249
249
  * 的 ~15 个键,类型标注见 {@link createSharedRunnerDeps} 头注。 */
@@ -281,7 +281,10 @@ export interface EngineNoticeMetricsSeat {
281
281
  }
282
282
  export declare function createEngineNoticeForwarder(logger: {
283
283
  warn: (msg: string, fields?: Record<string, unknown>) => void;
284
- }, router?: EngineNoticeRouter, metrics?: EngineNoticeMetricsSeat): NonNullable<RunnerDeps["onNotice"]>;
284
+ }, router?: EngineNoticeRouter, metrics?: EngineNoticeMetricsSeat,
285
+ /** [ref]:收信方决断面的坐标表(进程单例,与 core 的 held 队列注册表同寿命;它只读两条 peer 通告的坐标,见 `peer-inbound-face.ts`)。
286
+ * 默认值与 `router` 同一条理由:装配点多,必填会让「新车道忘了传」变成被扣的信静默不列。 */
287
+ peerInbound?: Pick<PeerInboundFace, "observe">): NonNullable<RunnerDeps["onNotice"]>;
285
288
  /**
286
289
  * `onNotice` **席**的装配判据本身 —— 「`warn` 真在场才铸席」这一条从此是**一个可直接调用的函数**,
287
290
  * 不是散在装配点、只能靠扫源码文本去猜的一行三元(codex 交叉复审 R1-[medium],验真后修)。