@sema-agent/server 7.136.0 → 7.138.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 (327) hide show
  1. package/MIGRATION.md +501 -139
  2. package/README.md +1 -0
  3. package/README.zh-CN.md +1 -0
  4. package/USAGE.md +149 -34
  5. package/deploy/sema-up/README.md +14 -0
  6. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +7 -1
  7. package/deploy/sema-up/stack/sema-stack-cluster.yaml +7 -1
  8. package/dist/approval-card.d.ts +21 -14
  9. package/dist/approval-card.js +1 -0
  10. package/dist/approval-content-kind.d.ts +6 -0
  11. package/dist/approval-content-kind.js +7 -0
  12. package/dist/approval-gate-currency.d.ts +48 -6
  13. package/dist/approval-gate-currency.js +16 -9
  14. package/dist/approval-hmac.d.ts +13 -1
  15. package/dist/approval-hmac.js +1 -1
  16. package/dist/approval.js +3 -3
  17. package/dist/audit.js +1 -0
  18. package/dist/auth-bridge.js +2 -2
  19. package/dist/background-agent-name.d.ts +5 -0
  20. package/dist/background-agent-name.js +5 -0
  21. package/dist/boot/budget-tracing.d.ts +1 -12
  22. package/dist/boot/deployment-mods.d.ts +46 -16
  23. package/dist/boot/deployment-mods.js +82 -6
  24. package/dist/boot/execution-env.d.ts +24 -1
  25. package/dist/boot/execution-env.js +69 -6
  26. package/dist/boot/governance-seams.d.ts +10 -17
  27. package/dist/boot/governance-seams.js +5 -17
  28. package/dist/boot/leader.d.ts +3 -0
  29. package/dist/boot/leader.js +1 -0
  30. package/dist/boot/org-delivery.js +15 -2
  31. package/dist/boot/reapers.d.ts +3 -0
  32. package/dist/boot/reapers.js +15 -1
  33. package/dist/boot/resolve-spec.d.ts +7 -0
  34. package/dist/boot/resolve-spec.js +36 -26
  35. package/dist/boot/retention-lane.d.ts +11 -5
  36. package/dist/boot/retention-lane.js +2 -2
  37. package/dist/boot/runner-deps.d.ts +7 -3
  38. package/dist/boot/runner-deps.js +1 -0
  39. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  40. package/dist/boot/stage-04-stores.d.ts +2 -13
  41. package/dist/boot/stage-05-execution-env.d.ts +6 -13
  42. package/dist/boot/stage-05-execution-env.js +17 -5
  43. package/dist/boot/stage-06-runners.d.ts +6 -13
  44. package/dist/boot/stage-06-runners.js +10 -3
  45. package/dist/boot/stage-07-capability-layer.d.ts +7 -13
  46. package/dist/boot/stage-07-capability-layer.js +3 -3
  47. package/dist/boot/stage-08-reapers.d.ts +7 -13
  48. package/dist/boot/stage-08-reapers.js +2 -1
  49. package/dist/boot/stage-09-leader.d.ts +7 -13
  50. package/dist/boot/stage-09-leader.js +2 -2
  51. package/dist/boot/stage-10-http-server.d.ts +7 -13
  52. package/dist/boot/stage-10-http-server.js +6 -3
  53. package/dist/boot/stores.d.ts +1 -1
  54. package/dist/boot/web-admin.d.ts +5 -2
  55. package/dist/boot/web-admin.js +3 -3
  56. package/dist/brain.js +5 -5
  57. package/dist/broker/broker.d.ts +89 -0
  58. package/dist/broker/broker.js +287 -0
  59. package/dist/broker/constants.d.ts +39 -0
  60. package/dist/broker/constants.js +15 -0
  61. package/dist/broker/http1.d.ts +111 -0
  62. package/dist/broker/http1.js +256 -0
  63. package/dist/broker/lease-book.d.ts +87 -0
  64. package/dist/broker/lease-book.js +142 -0
  65. package/dist/broker/lease-file.d.ts +60 -0
  66. package/dist/broker/lease-file.js +127 -0
  67. package/dist/broker/main.d.ts +2 -0
  68. package/dist/broker/main.js +20 -0
  69. package/dist/budget.d.ts +17 -15
  70. package/dist/budget.js +2 -2
  71. package/dist/capabilities/composite-members.d.ts +2 -1
  72. package/dist/capabilities/composite-members.js +2 -1
  73. package/dist/capabilities/engine-capabilities.js +1 -0
  74. package/dist/capabilities/mcp-probe.d.ts +36 -11
  75. package/dist/capabilities/mcp-probe.js +44 -5
  76. package/dist/capabilities/scenarios.d.ts +23 -8
  77. package/dist/capabilities/scenarios.js +13 -8
  78. package/dist/capabilities/skills.d.ts +28 -5
  79. package/dist/capabilities/skills.js +8 -0
  80. package/dist/capability-facts.d.ts +6 -0
  81. package/dist/capability-facts.js +5 -0
  82. package/dist/center-credential-renewer.js +5 -1
  83. package/dist/checkpoint-ctx-seal-m28.d.ts +3 -10
  84. package/dist/checkpoint-ctx-seal-m28.js +1 -1
  85. package/dist/checkpoint-identity.d.ts +13 -6
  86. package/dist/config-catalog.js +16 -7
  87. package/dist/config-types.d.ts +24 -7
  88. package/dist/config.d.ts +1 -1
  89. package/dist/config.js +42 -13
  90. package/dist/deployment-governance.d.ts +2 -2
  91. package/dist/deployment-governance.js +7 -9
  92. package/dist/deployment-shape.d.ts +6 -6
  93. package/dist/device-ws-protocol.d.ts +1 -0
  94. package/dist/device-ws-protocol.js +2 -1
  95. package/dist/file-history-disclosure.d.ts +4 -2
  96. package/dist/file-history-disclosure.js +2 -0
  97. package/dist/gate-settlement.d.ts +71 -0
  98. package/dist/gate-settlement.js +40 -0
  99. package/dist/hooks/classic-stations.d.ts +12 -54
  100. package/dist/hooks/classic-stations.js +1 -0
  101. package/dist/hooks/command-spawn.d.ts +2 -2
  102. package/dist/hooks/hook-runner.js +14 -14
  103. package/dist/http/admission.js +14 -9
  104. package/dist/http/approval-sweeps.js +4 -3
  105. package/dist/http/caller-trust.d.ts +2 -1
  106. package/dist/http/caller-trust.js +1 -3
  107. package/dist/http/checkpoint-ctx.d.ts +48 -7
  108. package/dist/http/checkpoint-ctx.js +40 -0
  109. package/dist/http/dispatch.d.ts +4 -0
  110. package/dist/http/dispatch.js +18 -10
  111. package/dist/http/durable-run-leg.d.ts +5 -1
  112. package/dist/http/durable-run-leg.js +5 -3
  113. package/dist/http/health-self-report.d.ts +2 -2
  114. package/dist/http/memory-compliance-failure-reply.js +3 -0
  115. package/dist/http/principal-gate.d.ts +15 -10
  116. package/dist/http/principal-gate.js +48 -9
  117. package/dist/http/resume-legs.d.ts +7 -31
  118. package/dist/http/resume-legs.js +185 -126
  119. package/dist/http/route-ctx.d.ts +38 -53
  120. package/dist/http/route-ctx.js +2 -5
  121. package/dist/http/routes/a2a-serve.js +10 -4
  122. package/dist/http/routes/agents-roster.d.ts +1 -1
  123. package/dist/http/routes/agents-roster.js +5 -1
  124. package/dist/http/routes/approvals-assistant.js +24 -10
  125. package/dist/http/routes/capabilities.js +23 -11
  126. package/dist/http/routes/mcp-reconnect.d.ts +3 -2
  127. package/dist/http/routes/mcp-reconnect.js +7 -7
  128. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  129. package/dist/http/routes/memory-origin.d.ts +1 -1
  130. package/dist/http/routes/rules.js +3 -3
  131. package/dist/http/routes/runs.js +13 -8
  132. package/dist/http/routes/session-sync.js +42 -6
  133. package/dist/http/routes/sessions.js +6 -3
  134. package/dist/http/routes/side-query.js +2 -3
  135. package/dist/http/routes/tasks.js +794 -780
  136. package/dist/http/server.d.ts +35 -25
  137. package/dist/http/stored-body-replay.d.ts +3 -3
  138. package/dist/http/stored-body-replay.js +6 -1
  139. package/dist/http/wire-types.d.ts +66 -33
  140. package/dist/identity-source.d.ts +65 -0
  141. package/dist/identity-source.js +45 -0
  142. package/dist/index.d.ts +2 -0
  143. package/dist/index.js +1 -0
  144. package/dist/leader/wire.d.ts +7 -0
  145. package/dist/leader/wire.js +5 -4
  146. package/dist/mcp-assertion-header.d.ts +51 -40
  147. package/dist/mcp-assertion-header.js +10 -11
  148. package/dist/mcp-authorization-face.d.ts +27 -0
  149. package/dist/mcp-authorization-face.js +15 -0
  150. package/dist/memory-operator-faces.d.ts +13 -4
  151. package/dist/memory-operator-faces.js +1 -17
  152. package/dist/memory-store-refusal.d.ts +3 -3
  153. package/dist/memory-sync-client.js +72 -57
  154. package/dist/memory-sync.d.ts +1 -1
  155. package/dist/model-entry-refusal.d.ts +2 -0
  156. package/dist/model-entry-refusal.js +11 -0
  157. package/dist/model-route-gap.d.ts +6 -22
  158. package/dist/model-route-gap.js +7 -5
  159. package/dist/model-select.d.ts +6 -17
  160. package/dist/model-select.js +0 -3
  161. package/dist/mods-declaration.d.ts +110 -0
  162. package/dist/mods-declaration.js +109 -0
  163. package/dist/namespaced-rule-name.d.ts +1 -1
  164. package/dist/observability/err-text.d.ts +5 -0
  165. package/dist/observability/err-text.js +9 -0
  166. package/dist/observability/fail-open.d.ts +17 -1
  167. package/dist/observability/fail-open.js +17 -1
  168. package/dist/observability/metrics.js +1 -1
  169. package/dist/observability/run-terminal.js +1 -0
  170. package/dist/observability/secret-env-scrub.d.ts +1 -1
  171. package/dist/observability/secret-env-scrub.js +1 -1
  172. package/dist/operator-ask.d.ts +2 -2
  173. package/dist/org-delivery-gate.js +1 -1
  174. package/dist/org-memory-admission.d.ts +2 -2
  175. package/dist/org-memory-admission.js +39 -2
  176. package/dist/parked-decide.d.ts +15 -2
  177. package/dist/parked-decide.js +17 -10
  178. package/dist/peer-directory.js +2 -0
  179. package/dist/peer-seat.d.ts +150 -0
  180. package/dist/peer-seat.js +239 -0
  181. package/dist/permission-rule-list.d.ts +2 -2
  182. package/dist/permission-rule-vocab.d.ts +7 -7
  183. package/dist/permission-rule-vocab.js +3 -3
  184. package/dist/plain-string-record.d.ts +38 -0
  185. package/dist/plain-string-record.js +38 -0
  186. package/dist/plugins/background-agent-store-sql.js +6 -3
  187. package/dist/plugins/caching-session-store.d.ts +5 -0
  188. package/dist/plugins/caching-session-store.js +6 -0
  189. package/dist/plugins/checkpoint-store-sql.d.ts +34 -29
  190. package/dist/plugins/checkpoint-store-sql.js +14 -14
  191. package/dist/plugins/file-history-store-sql.js +10 -16
  192. package/dist/plugins/file-run-store.js +8 -2
  193. package/dist/plugins/k8s-exec-protocol.d.ts +69 -13
  194. package/dist/plugins/k8s-exec-protocol.js +116 -28
  195. package/dist/plugins/k8s-pod-delete-failure.d.ts +25 -0
  196. package/dist/plugins/k8s-pod-delete-failure.js +17 -0
  197. package/dist/plugins/k8s-pod-reaper.d.ts +106 -0
  198. package/dist/plugins/k8s-pod-reaper.js +122 -0
  199. package/dist/plugins/local-checkpoint-store.d.ts +4 -17
  200. package/dist/plugins/local-checkpoint-store.js +3 -4
  201. package/dist/plugins/local-session-store.d.ts +66 -27
  202. package/dist/plugins/local-session-store.js +60 -28
  203. package/dist/plugins/mailbox-store-sql.d.ts +11 -3
  204. package/dist/plugins/mailbox-store-sql.js +103 -15
  205. package/dist/plugins/memory-run-store.js +2 -0
  206. package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
  207. package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
  208. package/dist/plugins/one-time-migrations.d.ts +34 -12
  209. package/dist/plugins/one-time-migrations.js +51 -9
  210. package/dist/plugins/permission-rule-store-file.js +2 -2
  211. package/dist/plugins/permission-rule-store-sql.d.ts +17 -17
  212. package/dist/plugins/permission-rule-store-sql.js +37 -30
  213. package/dist/plugins/pg-pool.js +4 -0
  214. package/dist/plugins/pg-session-storage.d.ts +10 -2
  215. package/dist/plugins/pg-session-storage.js +20 -7
  216. package/dist/plugins/remote-env-adb.d.ts +6 -1
  217. package/dist/plugins/remote-env-adb.js +2 -1
  218. package/dist/plugins/remote-env-device.d.ts +6 -1
  219. package/dist/plugins/remote-env-device.js +5 -1
  220. package/dist/plugins/remote-env-e2b.d.ts +5 -0
  221. package/dist/plugins/remote-env-e2b.js +2 -1
  222. package/dist/plugins/remote-env-file-error.d.ts +8 -1
  223. package/dist/plugins/remote-env-file-error.js +7 -1
  224. package/dist/plugins/remote-env-host.d.ts +10 -2
  225. package/dist/plugins/remote-env-host.js +8 -2
  226. package/dist/plugins/remote-env-k8s.d.ts +140 -11
  227. package/dist/plugins/remote-env-k8s.js +277 -15
  228. package/dist/plugins/remote-env-local-docker.d.ts +5 -0
  229. package/dist/plugins/remote-env-local-docker.js +2 -1
  230. package/dist/plugins/remote-env-ssh.d.ts +6 -1
  231. package/dist/plugins/remote-env-ssh.js +2 -1
  232. package/dist/plugins/retention-store-sql.d.ts +14 -2
  233. package/dist/plugins/retention-store-sql.js +6 -0
  234. package/dist/plugins/run-store-sql.js +10 -4
  235. package/dist/plugins/session-fork.d.ts +10 -13
  236. package/dist/plugins/session-fork.js +5 -25
  237. package/dist/plugins/session-ownership.d.ts +24 -3
  238. package/dist/plugins/session-ownership.js +24 -5
  239. package/dist/plugins/session-workspace-cell.d.ts +17 -0
  240. package/dist/plugins/session-workspace-cell.js +38 -0
  241. package/dist/plugins/sql-errors.d.ts +23 -2
  242. package/dist/plugins/sql-errors.js +15 -0
  243. package/dist/plugins/store-backend.js +7 -7
  244. package/dist/plugins/store-contracts.d.ts +10 -1
  245. package/dist/plugins/store-fault.d.ts +2 -2
  246. package/dist/plugins/store-fault.js +4 -2
  247. package/dist/plugins/tidb-pool.js +13 -0
  248. package/dist/plugins/tidb-session-store.d.ts +17 -2
  249. package/dist/plugins/tidb-session-store.js +18 -7
  250. package/dist/plugins/tool-result-store-sql.d.ts +13 -6
  251. package/dist/plugins/tool-result-store-sql.js +8 -7
  252. package/dist/plugins/worktree-isolation.d.ts +3 -2
  253. package/dist/plugins/worktree-isolation.js +1 -7
  254. package/dist/project-identity.d.ts +1 -14
  255. package/dist/project-identity.js +0 -4
  256. package/dist/request-key-closure.js +1 -1
  257. package/dist/request-value-closure.d.ts +31 -2
  258. package/dist/request-value-closure.js +7 -1
  259. package/dist/rule-entry-list.d.ts +3 -2
  260. package/dist/rule-entry-list.js +2 -2
  261. package/dist/rules-consent.js +12 -7
  262. package/dist/run-local.d.ts +2 -2
  263. package/dist/run-local.js +12 -6
  264. package/dist/runs.d.ts +7 -1
  265. package/dist/runs.js +8 -2
  266. package/dist/runtime-governance.d.ts +5 -5
  267. package/dist/sandbox-git-lease.d.ts +49 -0
  268. package/dist/sandbox-git-lease.js +60 -0
  269. package/dist/sandbox-git-plane.d.ts +84 -0
  270. package/dist/sandbox-git-plane.js +105 -0
  271. package/dist/security.d.ts +16 -4
  272. package/dist/security.js +8 -3
  273. package/dist/server-secret-env.d.ts +12 -3
  274. package/dist/server-secret-env.js +18 -2
  275. package/dist/session-error-wire.d.ts +14 -6
  276. package/dist/session-error-wire.js +2 -1
  277. package/dist/session-incarnation.d.ts +4 -5
  278. package/dist/session-incarnation.js +2 -2
  279. package/dist/session-policy-wire.d.ts +1 -1
  280. package/dist/session-policy-wire.js +2 -2
  281. package/dist/session-sync.d.ts +1 -1
  282. package/dist/session-workspace.d.ts +130 -0
  283. package/dist/session-workspace.js +83 -0
  284. package/dist/spec-fields.d.ts +44 -14
  285. package/dist/spec-fields.js +33 -12
  286. package/dist/standing-answer-grant.d.ts +2 -13
  287. package/dist/standing-answer-grant.js +0 -7
  288. package/dist/stored-request-prompt-profile-m30.d.ts +49 -0
  289. package/dist/stored-request-prompt-profile-m30.js +25 -0
  290. package/dist/task-a2a.d.ts +44 -14
  291. package/dist/task-a2a.js +46 -20
  292. package/dist/task-mcp.d.ts +34 -21
  293. package/dist/task-mcp.js +46 -22
  294. package/dist/task-settings.d.ts +2 -2
  295. package/dist/tool-approval.d.ts +43 -9
  296. package/dist/tool-approval.js +57 -15
  297. package/dist/tool-rule-names.d.ts +5 -0
  298. package/dist/trace/core-keyset-guard.d.ts +34 -19
  299. package/dist/trace/engine-notice-wire.d.ts +1 -1
  300. package/dist/trace/engine-notice-wire.js +4 -0
  301. package/dist/trace/exit-seat.d.ts +20 -1
  302. package/dist/trace/exit-seat.js +5 -2
  303. package/dist/trace/extension-call-face.d.ts +33 -0
  304. package/dist/trace/extension-call-face.js +39 -0
  305. package/dist/trace/ledger-sink.d.ts +4 -5
  306. package/dist/trace/ledger-sink.js +3 -7
  307. package/dist/trace/project.d.ts +62 -10
  308. package/dist/trace/project.js +49 -9
  309. package/dist/trace/redact.d.ts +18 -6
  310. package/dist/trace/redact.js +154 -60
  311. package/dist/trace/self-minted-wire.d.ts +500 -7
  312. package/dist/trace/self-minted-wire.js +182 -1
  313. package/dist/trace/wire-projection-faces.d.ts +7 -5
  314. package/dist/trace/wire-projection-faces.js +9 -4
  315. package/dist/user-authored-text.d.ts +2 -2
  316. package/dist/user-authored-text.js +16 -1
  317. package/dist/web-admin-client/apply-effective.js +0 -1
  318. package/dist/web-admin-client/center-request.d.ts +23 -4
  319. package/dist/web-admin-client/center-request.js +42 -8
  320. package/dist/web-admin-client/http-client.js +6 -6
  321. package/dist/web-admin-client/skills-mcp.d.ts +8 -4
  322. package/dist/web-admin-client/skills-mcp.js +31 -18
  323. package/dist/web-admin-client/types.d.ts +10 -5
  324. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +11 -5
  325. package/package.json +3 -3
  326. package/wire-changes/server@7.137.0.json +825 -0
  327. package/wire-changes/server@7.138.0.json +446 -0
@@ -1,11 +1,14 @@
1
1
  import http from "node:http";
2
+ import type { MemoryComplianceFaces } from "../memory-operator-faces.js";
3
+ import type { SideQueryAccounting } from "../budget.js";
2
4
  import type { IncomingMessage } from "node:http";
3
- import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type EntryProvenanceAccount, type MemoryErasureAttestation, type MemoryEntryOrigin, type OriginClearanceRow, type SessionMemoryStatus, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
5
+ import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type EntryProvenanceAccount, type MemoryEntryOrigin, type OriginClearanceRow, type SessionMemoryStatus, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
4
6
  import type { TaskRequestBody } from "./wire-types.js";
5
7
  import type { ServiceConfig } from "../config-types.js";
6
8
  import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
7
9
  import type { RestartSignal } from "@sema-agent/settings-schema/fleet";
8
10
  import { type OwnerAwareSessionStore } from "../security.js";
11
+ import type { PeerDesk, PeerLease } from "../peer-seat.js";
9
12
  import type { RunStore, ImageIndex, ImageBake, CheckpointStoreFull, ResumeAnchorStore, ApprovalExemptionStore, ApprovalNonceStore, ServiceSessionPolicyStore, ServiceFileHistoryStore, ToolResultStoreFull, StoreBackend } from "../plugins/store-backend.js";
10
13
  import type { RuleConsentLane } from "../rules-consent.js";
11
14
  import { type MemorySyncRequest, type MemorySyncResponse } from "../memory-sync.js";
@@ -57,7 +60,7 @@ export interface RequestAuth {
57
60
  * 平铺形的直接后果 = main.ts 一个上千行的装配字面量,键与键之间没有任何「属于同一件事」的编译期表达,
58
61
  * 键落错家/从未接线只能靠源码钉逐个盯(1.300/1.301/1.304/1.307/1.310 五起真缺陷都是这个病族)。
59
62
  *
60
- * 药:七个**窄**接口 + 顶层必填五件。装配点按组构造(每组一个带类型标注的中间 const ⇒ 受 TS 多余
63
+ * 药:七个**窄**接口 + 顶层必填七件。装配点按组构造(每组一个带类型标注的中间 const ⇒ 受 TS 多余
61
64
  * 属性检查保护),键放错组当场编译红。
62
65
  *
63
66
  * 兼容形(本批**不动消费点**):`ServiceDeps` = 平铺视图 ∩ 组槽。旧的平铺构造(96 个测试文件 +
@@ -65,8 +68,8 @@ export interface RequestAuth {
65
68
  * 入口摊平回平铺视图,server.ts 内的 ~700 处 `deps.x` 消费点原样保留。消费点迁移是后批的事——
66
69
  * 一步到位需要同批改 ~700 处 src + ~800 处 test 键位,与「先立形、后搬家」相比没有额外收益。
67
70
  */
68
- /** createHttpServer 的**必填五件**——引擎、部署配置、请求→TaskSpec 的映射、side-query 执行席、读口场景门。
69
- * 五者恒在场,故留在顶层(不进任何可选组):没有它们 server 根本起不来,包一层可选组只会把编译期
71
+ /** createHttpServer 的**必填七件**——引擎、部署配置、请求→TaskSpec 的映射、选路席、side-query 执行席、读口场景门、对端座的 desk。
72
+ * 七者恒在场,故留在顶层(不进任何可选组):没有它们 server 根本起不来,包一层可选组只会把编译期
70
73
  * 错误推迟到运行期(本仓 E-HIGH-1 病族的成因就是「可选键从未接线、编译期无声」)。 */
71
74
  export interface ServiceCoreDeps {
72
75
  runner: Runner;
@@ -105,11 +108,15 @@ export interface ServiceCoreDeps {
105
108
  * `opts.unattendedLeg`([ref] 候裁 18,codex r3 F1;[ref] ① 改形):续跑家族在 ctx 带无人值守标(`CheckpointCtx.unattendedLeg`)时递 `true` ——
106
109
  * 装配器在**全部折叠之后**经首跑同一只合并口 `withUnattendedLeg` 重挂那条腿(`default` + 按类作答的 onAsk)。只由续跑腿
107
110
  * 按服务端写的 ctx 位递,绝不从请求体读。 */
108
- resolveSpec: (body: TaskRequestBody, req: IncomingMessage | undefined, auth?: RequestAuth, opts?: {
111
+ /** `opts.lease`(必填):这条腿的**宿主租约** —— 装配在它之下登记本腿交给引擎的对端声明(`peerDesk.declare(草稿, opts.lease)`)。
112
+ * 租约由两只漏斗(受理 `prepareSpec` / 续跑 `resolveResumeSpecOrBlocked`)在调用本函数**之前**开、由漏斗的失败出口或拿到产物的那段作用域放;
113
+ * 装配只借用,不放、不留。实现方自铸的声明归自己的 desk 时可以不理它。 */
114
+ resolveSpec: (body: TaskRequestBody, req: IncomingMessage | undefined, auth: RequestAuth | undefined, opts: {
109
115
  leg?: "fresh" | "resume";
110
116
  liveStream?: boolean;
111
117
  onNotice?: (notice: EngineNotice) => void;
112
118
  unattendedLeg?: true;
119
+ lease: PeerLease;
113
120
  }) => TaskSpec | Promise<TaskSpec>;
114
121
  /**
115
122
  * [ref] 场景 hands lane 选路:按 `resolveSpec` 刚产出的 TaskSpec 取本任务的执行 Runner。
@@ -134,6 +141,16 @@ export interface ServiceCoreDeps {
134
141
  * `createScenarioGate` / `ScenarioGate` / `ScenarioGateLeg` / `ScenarioGateSources`)。
135
142
  */
136
143
  scenarioGate: import("../capabilities/scenarios.js").ScenarioGate;
144
+ /**
145
+ * 对端座的 desk(`peer-seat.ts`):MCP http 请求的凭据头 / stdio 子进程的环境 / A2A 发送的头,发送时只有它一只作答者;登记一条活到它的 holder 都空。
146
+ * 本层用它开**宿主租约**:受理与续跑两只漏斗在装配之前各开一只(`lease("fresh")` / `lease("resume")`),经 `resolveSpec` 的 `opts.lease` 交给装配,
147
+ * 随产物(`PreparedTaskSubmission.peerLease` / 续跑结果)交给拿到它的那段作用域,在那段作用域的 `finally` 放;活过那段作用域的驱动经 `heldFor` 自持一只。
148
+ * 这只 desk 另有三处用法,不止这两只漏斗:① 探测口 `POST /v1/capabilities/mcp/probe` 的调用方臂在走查里开一只 `probe` 租约(三道前置拒之后开,拨号落地才放);
149
+ * ② 两张会话面板(`GET /v1/sessions/:id/mcp` · `…/a2a`)与探测走查拨名册声明时递它的座(`desk.seat.answer`),不开租约;③ 名册声明在起服时登记在一只进程寿命的 `roster` 租约下
150
+ * (stage-07 / run-local 开,从不放),并且每只 Runner 的 `peerSeat` 是它的座。登记表的两个读数是 `/metrics` 的 `peer_registry_entries` / `peer_registry_holders`。
151
+ * 🔴 **必填**:没有 MCP / A2A 凭据的嵌入也给一只 `createPeerDesk()`(零 IO)—— 一个部署只有一张登记表,缺席不是「没有座」的另一种读法。
152
+ */
153
+ peerDesk: PeerDesk;
137
154
  }
138
155
  /** **durable 持久面**:每个键 present ⇔ 对应路由/能力位在场,absent ⇒ 501(诚实缺席),
139
156
  * 绝不静默降级。装配点 = main.ts 的 store backend 开箱段。 */
@@ -471,12 +488,7 @@ export interface ServiceSeamDeps {
471
488
  * 🔴 `erase` 的入参是 `unknown` 而不是 `EraseMemoryEntriesInput`:HTTP 层拿到的是一个**未校验**的对象,
472
489
  * 三选一选择子的整体判决是 core 的单一属主面(`erasureRequestInvalid`)。写成具体类型就得在路由里断言
473
490
  * 一次「它是合法输入」——那句断言是假的,而且正好把类型检查关灯。 */
474
- memoryCompliance?: {
475
- provenanceOf: (entryId: string) => Promise<EntryProvenanceAccount>;
476
- erase: (input: unknown, opts?: {
477
- allowedScopes?: readonly string[];
478
- }) => Promise<MemoryErasureAttestation>;
479
- };
491
+ memoryCompliance?: MemoryComplianceFaces;
480
492
  /** [ref] seam①([ref] §S-7,core 7.0.2 [ref] 件1):**会话记忆状态读面**。启用
481
493
  * `GET /v1/sessions/:id/memory-status`(owner 门,tenant 自助读 —— 不是 operator 面)。
482
494
  * main.ts 把它接到 `createSessionMemoryStatusFace` 的产物上(单实例引擎,SQL capture 店同座喂入)。
@@ -592,19 +604,7 @@ export interface ServiceSeamDeps {
592
604
  /** [ref] side-query 记账 seam(budget.ts createSideQueryAccountant——与 createTracer 同一装配点、
593
605
  * 同一组 sink 实例:costQuota/model_cost 指标/fleetUsage/fleetLease,四路同语义)。缺席=零记账
594
606
  * (手搭测试 deps;生产 main.ts 恒传)。 */
595
- sideQueryAccounting?: (principal: string | undefined, r: {
596
- model: string;
597
- family?: "input-includes-cached" | "input-excludes-cached";
598
- usage?: {
599
- input?: number;
600
- output?: number;
601
- cacheRead?: number;
602
- cacheWrite?: number;
603
- cost?: {
604
- total?: number;
605
- };
606
- };
607
- }) => void;
607
+ sideQueryAccounting?: SideQueryAccounting;
608
608
  /** [ref](core 7.32.0):parked 赎回面工厂(按行解析驱动哪只 Agent 工具 + 同出一张列表的继承座;属主 `parked-revive-surface.ts`)。
609
609
  * 缺席 = 这台部署没有 park 底座(checkpointStore / backgroundAgentStore 任一缺席),bg 赎回臂不接线。 */
610
610
  parkedReviveSurface?: import("../parked-revive-surface.js").ParkedReviveSurfaceFactory;
@@ -695,6 +695,16 @@ export interface ServiceDeploymentDeps {
695
695
  /** [ref] ②:caps `centerWiring` 的读面(`capabilities/center-wiring.ts` `createCenterWiringReader`;入参 = 请求的已验 principal)。
696
696
  * 缺席 = 没接中心(或测试夹具)⇒ 键整个缺席。 */
697
697
  centerWiring?: (principal: string | undefined) => import("../capabilities/center-wiring.js").CenterWiring;
698
+ /** The member git-credential plane's one reading (`sandbox-git-plane.ts`; stage 5 computes it once — config premises + the boot's secret
699
+ * seat answer + the static patch judge). Caps `credentialPlane.sandboxGit` projects it as is. Absent = not built by the composition root
700
+ * (a fixture) ⇒ the same judge on config alone, the seat counted as not asked. */
701
+ sandboxGitPlane?: import("../sandbox-git-plane.js").SandboxGitPlane;
702
+ /**
703
+ * 本进程起服装上的**运维声明** mod 包数(部署座装配口 `assembleDeploymentMods` 的 `loaded.length`;本服务自铸的注册不算)。一个事实两个出口,同读这一格:
704
+ * `/health` 的 `mods: { deploymentPackages }` 与 `/v1/capabilities` 的 `modsDeploymentPackages: true` —— 都只在 > 0 时在场;0 / 缺席(没声明,或不是由
705
+ * composition root 装起来的夹具)⇒ 两键都缺席,两面与没有声明的部署逐字节同。
706
+ */
707
+ deploymentModPackages?: number;
698
708
  /**
699
709
  * Graceful drain — shared mutable state between main.ts (flips `draining` on SIGTERM) and this server:
700
710
  * • while `draining`, NEW model-running submissions (the billable submit paths) get 503 + Retry-After, so an
@@ -857,7 +867,7 @@ export interface ServiceDepGroups {
857
867
  deployment?: ServiceDeploymentDeps;
858
868
  knobs?: ServiceKnobDeps;
859
869
  }
860
- /** 平铺视图 = 必填五件 + 其余七组的全可选并集。**派生**自组接口,故与分组形永不漂。 */
870
+ /** 平铺视图 = 必填七件 + 其余七组的全可选并集。**派生**自组接口,故与分组形永不漂。 */
861
871
  export type FlatServiceDeps = ServiceCoreDeps & Partial<ServiceStoreDeps & ServiceCoordinatorDeps & ServiceSeamDeps & ServiceObservabilityDeps & ServiceGovernanceDeps & ServiceDeploymentDeps & ServiceKnobDeps>;
862
872
  /** createHttpServer 的入参:两形皆可(平铺=存量,分组=推荐)。同名键两形都给时,**顶层显式键赢**
863
873
  * (含显式 `undefined`)——一处装配点只该用一形,混用时以肉眼最近的那个为准。 */
@@ -1,7 +1,7 @@
1
1
  /**
2
- * 「这条停驻行的持久化体在本版上能否重放」—— **唯一**判据(三问一只;五个问点同调:续跑驱动段 `resume-legs.ts` `resolveResumeSpecOrBlocked`、
2
+ * 「这条停驻行的持久化体在本版上能否重放」—— **唯一**判据(四问一只;五个问点同调:续跑驱动段 `resume-legs.ts` `resolveResumeSpecOrBlocked`、
3
3
  * plan_review 的 prepare 段、SLA 拒扫腿的跳过臂 `approval-sweeps.ts`、终态 run 的 steer 铸唤醒卡之前 `routes/runs.ts`;`resolveSpec` 本身留作提交腿的拒点)。
4
- * 三问的规则、记号、拒句与删除条件的属主 = `http/checkpoint-ctx.ts` 顶注;答复 = 那里的 `storedBodyReplayAnswer`。
4
+ * 四问的规则、记号、拒句与删除条件的属主 = `http/checkpoint-ctx.ts` 顶注;答复 = 那里的 `storedBodyReplayAnswer`。
5
5
  *
6
6
  * 为什么判据住在这里而不是 `checkpoint-ctx.ts`:第三问要读体的**生效模式词**(`task-settings.ts` `storedBodyPermissionMode`,请求设置的解析层)与本部署此刻的
7
7
  * **入口地板**(`runtime-governance.ts` `autonomyModeFloor`)—— 这两只属主带着配置层的包外依赖;`checkpoint-ctx.ts` 被随包的本地排空脚本经编译产物 import,
@@ -28,7 +28,7 @@ export type StoredReplayDeployment = LaneHomeDeployment & {
28
28
  readonly autonomy?: Autonomy | undefined;
29
29
  };
30
30
  /**
31
- * 三问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法记号 → 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ deny / ask 的名字层 + 规则文法)→ 模式词读法记号(几问同中时答先中的那一问 ——
31
+ * 四问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法记号 → 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ deny / ask 的名字层 + 规则文法)→ 模式词读法记号 → 体里的退役请求键(几问同中时答先中的那一问 ——
32
32
  * 任一问中都不重放,句子只需一句)。`deployment` = 本部署**此刻**的 `config`(活 config:热改即生效):`autonomy` 的地板由它的唯一属主算,`~/` 形规则的 home 由 `executionLaneHomeDir` 算,问点都不自己算。
33
33
  */
34
34
  export declare function storedBodyReplayRefusal(ctx: CheckpointCtx, deployment: StoredReplayDeployment): StoredBodyReplayRefusal | undefined;
@@ -4,13 +4,15 @@ import { entryProblemsFacts } from "../entry-problems.js";
4
4
  import { autonomyModeFloor, entryPermissionMode } from "../runtime-governance.js";
5
5
  import { inertToolListEntryOf, replayInertEntry } from "../rule-entry-list.js";
6
6
  import { executionLaneHomeDir } from "../execution-lane-caps.js";
7
- import { allowListReadingEraOf, allowListReadingUnstated, permissionModeReadingStated } from "./checkpoint-ctx.js";
7
+ import { migrationWindowEnd } from "../plugins/one-time-migrations.js";
8
+ import { allowListReadingEraOf, allowListReadingUnstated, permissionModeReadingStated, retiredRequestKeyOf } from "./checkpoint-ctx.js";
8
9
  export function permissionModeReadingUnstated(ctx, floor) {
9
10
  if (floor === undefined || permissionModeReadingStated(ctx))
10
11
  return undefined;
11
12
  const stored = storedBodyPermissionMode(ctx.body);
12
13
  return entryPermissionMode(stored, floor).effective === stored ? undefined : { stored, floor };
13
14
  }
15
+ const RETIRED_KEY_REWRITE_MIGRATION = { promptProfile: "M30" };
14
16
  const BUCKET_GATE_CODE = "request.field_invalid";
15
17
  function storedPermissions(body) {
16
18
  const permissions = body?.settings?.permissions;
@@ -52,6 +54,9 @@ export function storedBodyReplayRefusal(ctx, deployment) {
52
54
  const mode = permissionModeReadingUnstated(ctx, autonomyModeFloor(deployment.autonomy));
53
55
  if (mode !== undefined)
54
56
  return { kind: "permission_mode_reading", ...mode, ...writer };
57
+ const retiredKey = retiredRequestKeyOf(ctx.body);
58
+ if (retiredKey !== undefined)
59
+ return { kind: "retired_request_key", key: retiredKey, rewriteWindowEnd: migrationWindowEnd(RETIRED_KEY_REWRITE_MIGRATION[retiredKey]), ...writer };
55
60
  return undefined;
56
61
  }
57
62
  //# sourceMappingURL=stored-body-replay.js.map
@@ -6,11 +6,37 @@
6
6
  * cut: ONLY TaskRequestBody (its field types are inline or core imports — no other server.ts-local satellites);
7
7
  * sibling request/response shapes can migrate here later on the same pattern.
8
8
  */
9
- import type { A2aServerSpec, AgentDefinition, ApprovalReach, PermissionMode, SkillSpec, TaskSpec } from "@sema-agent/core";
9
+ import type { AgentDefinition, ApprovalReach, PermissionMode, SkillSpec, TaskSpec } from "@sema-agent/core";
10
10
  import type { RequestMcpServerSpec } from "../mcp-assertion-header.js";
11
+ import type { RequestA2aPeer } from "../task-a2a.js";
11
12
  import type { wiringManifestFaceEventData } from "../trace/project.js";
12
13
  import type { buildSyncSubmitBody } from "./sync-submit-body.js";
13
14
  import type { EntryProblem } from "../entry-problems.js";
15
+ /**
16
+ * 请求面上的一条技能 = core 的 `SkillSpec` 去掉 `mods`(core 7.56.0 [ref] 的技能座扩展注册:带 `register` 函数的代码对象,不是 wire 数据)。
17
+ * 带 `mods` 的请求技能受理门 400(`http/admission.ts` 的 `validateUserSkills`);本服务不编技能 hooks(能力位 `mods.skill_seat` 恒假)。
18
+ * 键集仍由 core 本体派生([ref]:core 加键,本型同批跟上;删 `mods` 是唯一的一处减法)。
19
+ */
20
+ export type RequestSkill = Omit<SkillSpec, "mods">;
21
+ /**
22
+ * `TaskRequestBody.attachments` 的子键集。本类型是这十个键在导出类型面上的**唯一**声明处;受理门(`http/admission.ts`)与重放翻译口
23
+ * (`spec-fields.ts` 的 `normalizeAttachments`)读 `spec-fields.ts` 的 `ATTACHMENT_KEY_KINDS` 那一张表,表与本接口互为差集门
24
+ * (`_GuardAttachmentKeys*`,漏一边 ⇒ tsc 红)。加 / 删一个键:本接口、那张表、`normalizeAttachments` 的逐键赋值三处同批改。
25
+ */
26
+ export interface TaskRequestAttachments {
27
+ todoReminder?: boolean;
28
+ todoReminderMode?: "baseline" | "off";
29
+ changedFiles?: boolean | {
30
+ maxFiles?: number;
31
+ };
32
+ budgetUsd?: true;
33
+ backgroundTasks?: boolean;
34
+ toolsDelta?: boolean;
35
+ mcpInstructions?: true;
36
+ agentListing?: boolean;
37
+ skillsListing?: boolean;
38
+ mcpUnavailable?: boolean;
39
+ }
14
40
  export interface TaskRequestBody {
15
41
  objective: string;
16
42
  sessionId?: string;
@@ -114,20 +140,20 @@ export interface TaskRequestBody {
114
140
  jobId?: string;
115
141
  /** Personalization seam: the caller's OWN skills for this task, threaded into core's
116
142
  * `TaskSpec.skills`. Merged AFTER the scenario's skills with SCENARIO-WINS on a name clash (the security
117
- * baseline can never be shadowed by user content — see mergeUserSkills). User skills are user-authored
143
+ * baseline can never be shadowed by user content — see buildRunSkills). User skills are user-authored
118
144
  * content in the user's OWN principal-isolated task (self-harm surface, not privilege widening);
119
145
  * scenario/center skills remain the only trusted layer.
120
146
  *
121
147
  * 🔴 **类型 = core 的 `SkillSpec` 本体,不是它的手抄子集**([ref]):这里曾写死
122
148
  * `{ name; description; content }` —— core 闭集六位里的三位,而 `manifest` / `files` / `baseDir`
123
- * 三位在运行期一直是**收的**(受理门 `validateUserSkills` 不判未知键,`mergeUserSkills` 原样透传到
149
+ * 三位在运行期一直是**收的**(受理门 `validateUserSkills` 不判未知键,`buildRunSkills` 原样透传到
124
150
  * `TaskSpec.skills`)。一份会漂的手抄 = 声明面比真受理面**窄**,SDK 消费方按声明写代码就以为发不了,
125
151
  * 而 core 加键(7.20.0 [ref] 的 `baseDir`)时这里连红都不会红。改成 core 本体后,闭集由 tsc 看守。
126
152
  * ⚠️ 受理**判据**(形/尺寸)仍在 `validateUserSkills` + `spec-fields.ts` 的 `SKILL_FIELD_SHAPES`——
127
153
  * 类型说「哪些键存在」,门说「值合不合法」,两者不是一件事。
128
154
  * (旧注里的「Caps: ≤10 skills, content ≤32KB each」两条帽早已随 [ref] / core 1.293 退役,一并纠正:
129
155
  * 今天只剩 `content ≤ 1 MiB` 这一条 core 加载门孪生。) */
130
- skills?: SkillSpec[];
156
+ skills?: RequestSkill[];
131
157
  /** §7 P0.5 (用户按需选像): the sandbox image PROFILE this task wants (e.g.
132
158
  * "code-full" / "code-python"). An INTENT, never a digest — the service resolves it to a published digest with
133
159
  * the caller's principal (fail-closed visibility re-admit) and applies it per-pod. Only supported on the k8s
@@ -247,19 +273,7 @@ export interface TaskRequestBody {
247
273
  * boolean 透传(core DEFAULT-ON,explicit false 才关);budgetUsd/mcpInstructions 只认 literal true;
248
274
  * limits 三个 opt-out 只认 literal false(normalizer 同判)。 */
249
275
  /** core 7.39.0 [ref]:`planModeReminder` 退役(硬破坏,零别名)—— 提交即 400 点名退役;plan 姿态由引擎从 `permissionMode:"plan"` 自己陈述。 */
250
- attachments?: {
251
- todoReminder?: boolean;
252
- todoReminderMode?: "baseline" | "off";
253
- changedFiles?: boolean | {
254
- maxFiles?: number;
255
- };
256
- budgetUsd?: true;
257
- backgroundTasks?: boolean;
258
- toolsDelta?: boolean;
259
- mcpInstructions?: true;
260
- agentListing?: boolean;
261
- skillsListing?: boolean;
262
- };
276
+ attachments?: TaskRequestAttachments;
263
277
  /** C1 (core 1.219, subagent viewing pane): opt-in — forward a delegated child's live CONTENT events
264
278
  * (text_delta/text_end/reasoning_delta/tool_start/tool_end, each stamped `parentToolCallId`) onto this run's stream/durable
265
279
  * log, so a shell can render the child's transcript live ("enter 看详情"). Default OFF = progress-only (prior
@@ -337,9 +351,13 @@ export interface TaskRequestBody {
337
351
  /** [ref]② (core 1.314): [ref] 延迟披露清单(占位上 wire,ToolSearch 激活)——cli「Workflow 默认开
338
352
  * 不暴露」的承载位。同 excludeTools 的校验/继承姿势。 */
339
353
  deferTools?: string[];
340
- /** [ref]/[ref] (core 1.328 R2): 提示词双形轴——simple(CC 212 短形,引擎缺省)| classic(长形,可按
341
- * 任务/模型试分)。纯呈现轴无租户门;枚举 fail-loud at submit;缺省不挂键。 */
342
- promptProfile?: "simple" | "classic";
354
+ /** core 7.56.0([ref]):提示词形的**唯一**任务开关 —— `true` 加 `lean_prompt` 特征(短形)、`false` 去掉它(长的 classic 形)、
355
+ * 缺省 = 模型目录条目自己的声明(引擎缺省 lean)。只动这一个特征,不碰其余特征;原样透传进 `TaskSpec.promptLean`,随引擎铸的每个子代走。
356
+ * 纯呈现轴无租户门;非布尔 400 fail-loud at submit;缺省不挂键。
357
+ * 退役键 `promptProfile`(7.136.x 及以前的 `"simple" | "classic"`)整键删、零别名:fresh 提交体仍带它 ⇒ 键闭集门 400 `request.body_shape`
358
+ * (`unknownKeys:["promptProfile"]`);迁移 = `"classic"` ⇒ `promptLean: false`,`"simple"` ⇒ 不带键。续跑重放不过那道门:盘上 7.136.x 体里的旧键由一次性迁移 M30 在起服时按同一张映射原地改写(`stored-request-prompt-profile-m30.ts`;M30 · 窗口见 `plugins/one-time-migrations.ts` 登记表),
359
+ * 改写不到的残留行续跑 409(`http/stored-body-replay.ts` 第四问)—— 续跑腿不读旧键。 */
360
+ promptLean?: boolean;
343
361
  /** [ref]②(core 5.14.0 座已在,`TaskSpec.toolMaterializeStrategy`):deferred 工具在**激活之后**怎么给
344
362
  * 模型供 schema。`static` = 占位符形不变(激活只改可调用性,广告的 schema 仍是空对象);`swap` = 激活
345
363
  * 后下一轮把占位符换成真 schema。
@@ -352,7 +370,7 @@ export interface TaskRequestBody {
352
370
  * core 把 `"static"` 重新定性为「a strict explicit opt-in」)。本注上一版还写着 `?? "static"`,照它推
353
371
  * 「不挂键 ⇒ 落 static」会反。缺省词的属主是 core,本仓不复述第二份——要确认取值去读 core 的
354
372
  * `prepare-task` 与其 CHANGELOG。
355
- * 缺省不挂键(交给 core 的 env/缺省链);未知词 400 fail-loud(与 promptProfile/permissionMode 同姿势 ——
373
+ * 缺省不挂键(交给 core 的 env/缺省链);未知词 400 fail-loud(与 permissionMode 同姿势 ——
356
374
  * 静默折缺省会让调用方以为切了策略却没切)。 */
357
375
  toolMaterializeStrategy?: "static" | "swap";
358
376
  /** R4 (CC parity): the LIGHT top-level per-turn permission-mode intent (CC `permissionMode`). The shell sends
@@ -363,7 +381,7 @@ export interface TaskRequestBody {
363
381
  * `deniedBy:"mode"`); none can subtract from deployment/operator policy or the request's own deny / ask rules (tightenTaskSpec
364
382
  * deny-wins). The top-level word wins over `settings.permissions.defaultMode` (the heavier bundle) — one precedence, read in one place.
365
383
  * [ref]-②: CLOSED enum on the wire — an unknown word 400s at submit (`request.field_invalid`, sibling of
366
- * promptProfile) instead of silently coercing to `default`; resume replay of a stored body stays lenient
384
+ * toolMaterializeStrategy) instead of silently coercing to `default`; resume replay of a stored body stays lenient
367
385
  * (coercePermissionMode).
368
386
  * 🔴 型与闭集的属主是 core 的 `PermissionMode` / `PERMISSION_MODES`(受理腿 `isPermissionMode` 与三句 400 文案同读那一份)—— 本仓不持词表。 */
369
387
  permissionMode?: PermissionMode;
@@ -432,7 +450,7 @@ export interface TaskRequestBody {
432
450
  cwd?: string;
433
451
  /**
434
452
  * [ref](7.106.0,core [ref] [ref] ②)—— 模型驱动的 host shell **继承多少用户环境**,由调用方按请求声明。
435
- * 闭集两词(词表外 ⇒ 400 `request.field_invalid`,两腿同判,判据属主 `request-value-closure.ts` 的 `inheritEnvFieldIssue`):
453
+ * 闭集两词(词表外 ⇒ 400 `request.field_invalid` + 机读位 `field: "inheritEnv"` / `reason`〔`unknown_word` | `not_a_string`〕,两腿同判,判据与机读位的属主 `request-value-closure.ts` 的 `inheritEnvFieldIssue`):
436
454
  * · `"all"` —— 整份用户环境**减本服务自有凭据名**(配置目录 secret 名 / 名单型旋钮名 / 模型条目 `apiKeyEnv`,起服向引擎声明一次,判在引擎;7.129.0 起,CC 交互形);只在**单用户**部署兑现,射程 = 写容纳面那一只
437
455
  * 部署形表行 `taskHostPostureDeclarations`(`deployment-shape.ts`)⇒ 托管部署(`REQUIRE_PRINCIPAL=true`)响亮拒
438
456
  * 422 `request.host_posture_refused`;
@@ -440,7 +458,7 @@ export interface TaskRequestBody {
440
458
  * **缺席 = 缺省清洗**:不带键的请求把本会话的绑定清掉(不继承上一条请求的声明 —— 这一位是「本条请求要什么」,
441
459
  * 粘到下一条上就是替一个没说话的请求放宽)。名单形(`string[]`)**不上 wire**(那是嵌入方构造执行环境的选项)。
442
460
  * 🔒 **只有 host 车道有消费点**:别的车道(e2b / k8s / local-docker / ssh / adb / device / in-process)带 `"all"` ⇒
443
- * 400 `request.field_invalid`「applies to the host lane only」,不静默忽略、不映射到别的车道的 env 名单;`"scrub"` 在那些车道上照受理(无消费点,无害)。
461
+ * 400 `request.field_invalid`(`reason: lane_not_host`)「applies to the host lane only」,不静默忽略、不映射到别的车道的 env 名单;`"scrub"` 在那些车道上照受理(无消费点,无害)。
444
462
  * Rides the persisted body onto resume legs:重放照射程与车道重判(部署由单用户改托管后 revive ⇒ 同一只拒,
445
463
  * resume-legs 折成 `409 resume_blocked_by_policy`)。
446
464
  */
@@ -537,22 +555,29 @@ export interface TaskRequestBody {
537
555
  * 与 `principalHeader` **互斥**:同设 ⇒ 新提交腿同步 400 `request.body_shape`(拒句与契约包解析期那一句逐字相同);值不是字符串 ⇒ 400
538
556
  * `request.field_invalid`。耐久 resume 腿不拒(重放存量 body),也**不摘 server**(摘了,park 在它工具审批上的任务批准后撞 `resume.tool_unavailable`
539
557
  * 且每次重试重放同一份 body):降级到升级前的读法 —— server 照挂、`principalHeader` 胜、`assertionHeader` 不生效,一行 warn `mcp_assertion_header_ignored`。
540
- * ⚠️ 本版**只承载、不发送**:引擎的 http 传输尚无断言头座,
541
- * 声明被接收、server 照常挂载但不带断言头,并有一行运维 info `mcp_assertion_header_not_sent { server }`;发送随引擎座。 */
558
+ * ⚠️ **只承载、不发送**:引擎的断言头是固定的名、值由部署的对端座作答,本部署没有断言来源 ——
559
+ * 声明被接收、server 照常挂载但不带断言头,并有一行运维 info `mcp_assertion_header_not_sent { server }`。
560
+ *
561
+ * `transport.env`(stdio)/ `transport.headers`(http)是这台 server 的**件**:server 交给引擎的声明里不带它们,件由部署的对端座在起子进程 / 发请求时按原字节作答
562
+ * (只对胜出部署同名判的条目登记;件的名与值由引擎在每次发送时判,不合 ⇒ 那一台不连、兄弟照挂)。 */
542
563
  mcpServers?: RequestMcpServerSpec[];
543
564
  /** [DESIGN-269 车1] Caller-supplied per-request A2A peers (remote agents this task may call), aligned to
544
565
  * core `A2aServerSpec`. 🔒 honored on a SINGLE-USER deployment (task-a2a.ts `a2aInjectionHonored`, the same
545
566
  * predicate `capabilities.a2aInjection` advertises) — the requester is the super-admin of their OWN worker,
546
567
  * on ANY execution lane (an A2A call is a plain outbound HTTPS request from the worker, so the lane where
547
568
  * tool calls run is irrelevant); IGNORED on multi-tenant (a tenant can't point the shared worker at an
548
- * agent of their choosing). A2A has no operator lock and no compliance capability today. A new submission
569
+ * agent of their choosing). The gate also closes under the operator lock `a2a` and under a compliance posture that denies `a2a_peers`
570
+ * (the engine refuses a task that declares a peer under either): under the lock a request that carries `a2aPeers` is refused
571
+ * 400 `config.locked_key` at the head of the request (the same code and status table as the MCP lock); on a multi-tenant
572
+ * deployment or under a compliance denial the list is ignored and said (`a2a_injection_ignored`). A new submission
549
573
  * with a malformed list or entry is refused 400 (`assertRequestA2aEntries`: not an array / over the 32-entry
550
574
  * cap / an entry that is not an object / a key outside {@link A2A_PEER_ENTRY_KEYS} / a key whose value is
551
575
  * unusable / a url or cardUrl carrying a credential) — the same refusal shape as `mcpServers`, whatever the lane.
552
576
  * 🔴 Every skill a peer advertises mounts `egress:true` + `effect:"write"` (core's ruling) — declaring a
553
577
  * peer is declaring an outbound WRITE channel, not a data source. Validated + gated downstream; the
554
- * center/config baseline wins on a name clash (the peer name IS the tool namespace). */
555
- a2aPeers?: A2aServerSpec[];
578
+ * center/config baseline wins on a name clash (the peer name IS the tool namespace). `headers` are the peer's PIECES: the declaration the
579
+ * server hands the engine carries none of them — the deployment's peer seat answers them, as written, at each send to the declared origins. */
580
+ a2aPeers?: RequestA2aPeer[];
556
581
  /** CC parity (Workflow super-set): per-task activation of the LLM-authored workflow engine (core `run_workflow`).
557
582
  * `true` → `spec.selfOrchestration` (the engine mounts run_workflow), gated on the deployment's `selfOrchestrationEnabled`
558
583
  * (else a harmless no-op) + core's `allowWorkflows` per-principal entitlement on multi-tenant (single-user honors
@@ -586,12 +611,20 @@ export type DecideBinding = {
586
611
  * mints carry it verbatim when present — the engine owns what counts as written (blank = nothing) and judges it again pre-CAS. */
587
612
  feedback?: string;
588
613
  };
589
- /** [ref]([ref]④→[ref] 坐标轮换判定):409 `approval_stale` 拒体上的 additive 机读指路 ——
614
+ /** 409 `approval_stale` 拒体的 additive 机读指路 `currentPending`:**本会话此刻在这道门上待决的那道门**的回显坐标 = 这道门的决断体回显的那几位
615
+ * (一条规则,两道决断门各一形):`/decide` ⇒ {@link DecideStaleCurrentPending};计划审阅([ref])⇒ {@link PlanReviewStaleCurrentPending}。
616
+ * 🔴 恒**不含** checkpointToken(resume 凭证从不外发);只在当前门在场、属这道门的门型、且已过属主门的域内铸 —— 否则键缺席(不造键)。 */
617
+ export type ApprovalStaleCurrentPending = DecideStaleCurrentPending | PlanReviewStaleCurrentPending;
618
+ /** [ref]:计划审阅门的回显坐标 = 门身份 `checkpointId`(过信任边界的那个值;当前门说不出身份 ⇒ 整个 `currentPending` 缺席)。 */
619
+ export type PlanReviewStaleCurrentPending = {
620
+ /** 当前待决 plan_review 门的非秘密身份 —— 壳据此重取那道门的计划给人看,再带它决。 */
621
+ checkpointId: string;
622
+ };
623
+ /** [ref]([ref]④→[ref] 坐标轮换判定):`/decide` 那一形 ——
590
624
  * **本会话当前 pending** 的 D-1 回显坐标,让持旧坐标的壳一跳重定位(免重拉列表)。
591
625
  * 键名/键形与 GET /v1/approvals 的 pending 行逐字同名(壳复用同一解析)。
592
- * 🔴 恒**不含** checkpointToken(runs.ts §12-C:resume 凭证从不外发);只在当前 pending **在场**、
593
- * 属 tool_approval、且已过路由级 owner 门的域内铸 —— 无 pending / 非工具门 / 读失败 ⇒ 键缺席(不造键)。 */
594
- export type ApprovalStaleCurrentPending = {
626
+ * 只在当前 pending 属 tool_approval 时铸 —— 无 pending / 非工具门 / 读失败 ⇒ 键缺席(不造键)。 */
627
+ export type DecideStaleCurrentPending = {
595
628
  /** 当前 pending 被门住的工具名(与 pending 行的 `toolName` 同源同值)。 */
596
629
  toolName: string;
597
630
  /** 当前 pending 的 `pendingAction.toolCallId` —— 壳重定位后 decide 时回显的 D-1 锚。 */
@@ -0,0 +1,65 @@
1
+ /**
2
+ * **身份来源闭集 + run 行身份元组** —— 叶子模块(零依赖):凭据门(`http/principal-gate.ts`)、run 店契约(`plugins/store-contracts.ts`)、
3
+ * 三只 run 店、中央建表语句(`plugins/tidb-pool.ts` / `plugins/pg-pool.ts`)与 `/health` 自报位读同一份。
4
+ *
5
+ * ## 律(三句;全仓只在这里写一次)
6
+ * 1. **一张表、一个次序**:{@link IDENTITY_SOURCES} 的序 = 凭据门的判定次序(`verifiedIdentitySource` 答表里第一个验得过的词)= `/health.auth.kinds` 的出现序。
7
+ * 出示了部署的 service 凭据就是 `service_token` —— 哪怕同一枚 Bearer 也被鉴权桥验成登录令牌、哪怕运维给这枚凭据起的系统名叫 `sso`;
8
+ * 验不过 service 凭据而鉴权桥挂了身份 ⇒ `sso`;都没有而直连门 principal 令牌验过 ⇒ `direct_door_jwt`。
9
+ * 2. **一只元组、受理时铸一次**:run 行的身份元组 {@link RunIdentity}(三列 `identity_source` / `identity_scope` / `identity_principal_inc`)在凭据门上随来源
10
+ * 一起定下(`principal-gate.ts` 的 `admitRunIdentity`,唯一调用点是凭据门),建行处原样写入,之后只读 —— 续跑认领、挂起、终局、重启都不改它,
11
+ * 没有任何读者按当前状态重推它。`RunRecord.source`(系统名 / `"sso"` / null)只作归因,不是认证来源。
12
+ * 3. **缺席一种读法**:`null` = 这一行**没有「属主在受理时验过的凭据」的记录** —— 三列存在之前写下的行、没有任何验过凭据的受理(无鉴权写面
13
+ * `ALLOW_UNAUTHED_WRITES`)、以及别人替属主按下的那一跑(受理请求验过的主体不是这一行的属主:唤醒 / 决定投递铸的新一跑)。读者一律按「不合格」处置
14
+ * (fail-closed),不分辨三种成因;存量行不回填(没有事实可回填)。
15
+ *
16
+ * 化身号 `principalInc`:令牌 `sub_inc` 声明原样,经契约包 `VerifiedIdentity.principalInc` 读(settings-schema 14.7.0 加的可选字段,已提货:验证腿随身份带出);本版接线未做 ⇒ 恒 `null`,
17
+ * 接线点在 `admitRunIdentity` 的 `sso` 臂(不在本仓另定一份读法)。
18
+ */
19
+ /** 验过的身份来源的**闭集**(序 = 判定次序 = `/health.auth.kinds` 的出现序;加一个来源 = 加一个词,读它的各只穷举 `switch` 不接就编译红)。 */
20
+ export declare const IDENTITY_SOURCES: readonly ["service_token", "sso", "direct_door_jwt"];
21
+ export type IdentitySource = (typeof IDENTITY_SOURCES)[number];
22
+ /**
23
+ * run 行身份元组(受理时铸、持久、之后只读;律见文件头)。三键恒在、与三列一一对应:`scope` / `principalInc` 只随 `sso` 有值 ——
24
+ * service 凭据与直连门令牌不带登录令牌的 scope / 化身号,判别联合让「`service_token` 带 scope」这种形写不出来。
25
+ */
26
+ export type RunIdentity = {
27
+ readonly source: "sso";
28
+ readonly scope: string;
29
+ readonly principalInc: string | null;
30
+ } | {
31
+ readonly source: "service_token" | "direct_door_jwt";
32
+ readonly scope: null;
33
+ readonly principalInc: null;
34
+ };
35
+ /** `identity_scope` 的列宽(字符;两方言 VARCHAR 同口径数码点)。与主体列同宽:scope 来自验过签名的令牌,契约的 scope id 形最长 64,读口不判形 ⇒ 留余量。 */
36
+ export declare const RUN_IDENTITY_SCOPE_MAX_CHARS = 190;
37
+ /** `identity_principal_inc` 的列宽(字符):化身号是签发方插入时铸的不透明随机串(与会话化身同宽)。 */
38
+ export declare const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
39
+ /**
40
+ * `task_run` 三列的列定义 —— 两方言各一段,**唯一属主**:中央建表语句(`tidb-pool.ts` / `pg-pool.ts` 的 `CREATE TABLE task_run`)内插这同一段;
41
+ * 存量库缺列时起服列册对账(`schema-consistency.ts`)拒启,拒句里的 `ALTER TABLE task_run ADD COLUMN …` 由同一份建表语句解析生成 ⇒
42
+ * 「新库建出来的列」与「运维按拒句 / MIGRATION 补上的列」逐字同形。三列都可空(存量行与律 3 的三种成因都是 NULL);PG 钉 `COLLATE "C"`
43
+ * (身份键按字节判等,与 MySQL 协议表级 `utf8mb4_bin` 同形)。
44
+ */
45
+ export declare const RUN_IDENTITY_COLUMNS: {
46
+ readonly tidb: string;
47
+ readonly pg: string;
48
+ };
49
+ /** 元组落盘的三格(SQL 三列 / File 车道 run.json 的三键,同名同义)。 */
50
+ export interface RunIdentityCells {
51
+ readonly identitySource: IdentitySource | null;
52
+ readonly identityScope: string | null;
53
+ readonly identityPrincipalInc: string | null;
54
+ }
55
+ /** 元组 → 三格(写口;三只 run 店同一只)。 */
56
+ export declare function runIdentityCells(identity: RunIdentity | null): RunIdentityCells;
57
+ /**
58
+ * 三格 → 元组(读口;SQL 两方言的行映射与 File 车道的 run.json 读回同一只)。读不出一只**合形**元组的三格一律读成 `null`(律 3:不合格,fail-closed),
59
+ * 这是运行期无法避免的缺省臂,明写在这里:
60
+ * · 来源格缺席 ⇒ 没有记录(三列之前的行 / 律 3 的另两种成因);
61
+ * · 来源格不是闭集里的词(更新的版本写下、回滚到本版读到的词,或手改的行)⇒ 本版认不得的来源不合格;
62
+ * · `sso` 却没有 scope、化身号不是非空串,或别的来源带着 scope / 化身号 ⇒ 不是本仓写口写得出的形(手改 / 半截写),不合格。
63
+ */
64
+ export declare function readRunIdentityCells(source: unknown, scope: unknown, principalInc: unknown): RunIdentity | null;
65
+ //# sourceMappingURL=identity-source.d.ts.map
@@ -0,0 +1,45 @@
1
+ export const IDENTITY_SOURCES = ["service_token", "sso", "direct_door_jwt"];
2
+ export const RUN_IDENTITY_SCOPE_MAX_CHARS = 190;
3
+ export const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
4
+ export const RUN_IDENTITY_COLUMNS = {
5
+ tidb: [
6
+ "identity_source VARCHAR(32) NULL",
7
+ `identity_scope VARCHAR(${RUN_IDENTITY_SCOPE_MAX_CHARS}) NULL`,
8
+ `identity_principal_inc VARCHAR(${RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS}) NULL`,
9
+ ].join(",\n "),
10
+ pg: [
11
+ `identity_source VARCHAR(32) COLLATE "C"`,
12
+ `identity_scope VARCHAR(${RUN_IDENTITY_SCOPE_MAX_CHARS}) COLLATE "C"`,
13
+ `identity_principal_inc VARCHAR(${RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS}) COLLATE "C"`,
14
+ ].join(",\n "),
15
+ };
16
+ export function runIdentityCells(identity) {
17
+ return identity === null
18
+ ? { identitySource: null, identityScope: null, identityPrincipalInc: null }
19
+ : { identitySource: identity.source, identityScope: identity.scope, identityPrincipalInc: identity.principalInc };
20
+ }
21
+ const isNonEmptyString = (v) => typeof v === "string" && v !== "";
22
+ const isAbsent = (v) => v === null || v === undefined;
23
+ export function readRunIdentityCells(source, scope, principalInc) {
24
+ if (isAbsent(source) || typeof source !== "string")
25
+ return null;
26
+ const word = IDENTITY_SOURCES.find((w) => w === source);
27
+ if (word === undefined)
28
+ return null;
29
+ switch (word) {
30
+ case "sso":
31
+ if (!isNonEmptyString(scope))
32
+ return null;
33
+ if (isAbsent(principalInc))
34
+ return { source: word, scope, principalInc: null };
35
+ return isNonEmptyString(principalInc) ? { source: word, scope, principalInc } : null;
36
+ case "service_token":
37
+ case "direct_door_jwt":
38
+ return isAbsent(scope) && isAbsent(principalInc) ? { source: word, scope: null, principalInc: null } : null;
39
+ default: {
40
+ const unknownWord = word;
41
+ throw new Error(`readRunIdentityCells: identity source ${String(unknownWord)} has no reading`);
42
+ }
43
+ }
44
+ }
45
+ //# sourceMappingURL=identity-source.js.map
package/dist/index.d.ts CHANGED
@@ -26,6 +26,8 @@ export type { TaskRequestBody } from "./http/wire-types.js";
26
26
  export { ensureCheckpointCtxSealing } from "./sealed-key.js";
27
27
  export type { CheckpointCtxSealing } from "./http/checkpoint-ctx.js";
28
28
  export { createHttpServer, type ServiceDeps, type RequestAuth, type FlatServiceDeps, type ServiceDepGroups, type ServiceCoreDeps, type ServiceStoreDeps, type ServiceCoordinatorDeps, type ServiceSeamDeps, type ServiceObservabilityDeps, type ServiceGovernanceDeps, type ServiceDeploymentDeps, type ServiceKnobDeps, } from "./http/server.js";
29
+ export { createPeerDesk } from "./peer-seat.js";
30
+ export type { PeerDesk, PeerLease, McpDraft, A2aDraft } from "./peer-seat.js";
29
31
  export { createSideQueryLane, type KeyResolver, type SideQueryLane, type SideQueryLaneCtx } from "./boot/side-query-lane.js";
30
32
  export { createKeyResolver, resolveModelApiKey, type ModelKeyRef } from "./key-resolver.js";
31
33
  export { isModelKeyPoison, ModelKeyPoisonedError, type ModelKeyPoison, type ModelKeyPoisonReason } from "./key-resolver.js";
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ export { createAuthorizer, principalFrom, HttpError, } from "./security.js";
22
22
  export { memoryScopeFor, memoryEngineBackendFor } from "./memory-scope.js";
23
23
  export { ensureCheckpointCtxSealing } from "./sealed-key.js";
24
24
  export { createHttpServer, } from "./http/server.js";
25
+ export { createPeerDesk } from "./peer-seat.js";
25
26
  export { createSideQueryLane } from "./boot/side-query-lane.js";
26
27
  export { createKeyResolver, resolveModelApiKey } from "./key-resolver.js";
27
28
  export { isModelKeyPoison, ModelKeyPoisonedError } from "./key-resolver.js";
@@ -91,6 +91,13 @@ export interface LeaderWireConfig {
91
91
  * 分租户,只补席不包裹 = 归因恒 undefined = 假绿。缺席 ⇒ 展开空对象(与接线前逐字相同)。
92
92
  */
93
93
  tracer?: RunnerDeps["tracer"];
94
+ /**
95
+ * **部署座**(`RunnerDeps.mods`),原样递给本车道的每一只 Runner。唯一铸点 = 起服第 5 段的装配口 `assembleDeploymentMods`(本服务自铸的注册在前、
96
+ * 运维声明的 mod 包在后、整列过引擎准入);主 / 无手 / hook 代理 / 子代经共享基座吃的就是它,`boot/leader.ts` 搬的是**同一份**。
97
+ * leader 不自铸、不自己装配(一个进程两份部署注册 = 主车道与 leader 车道各按一套扩展跑)。缺失时整个部署座在这条车道上缺席:运维声明的守卫包
98
+ * 管不到 leader 派出的腿,拒绝计量 / 工具追踪也漏这条腿。缺席 ⇒ 展开空对象。
99
+ */
100
+ mods?: RunnerDeps["mods"];
94
101
  /**
95
102
  * [ref]([ref],[ref]-T1)—— **部署级 token 治理窗**两键,**成对**递给本车道的每一只 Runner。
96
103
  * 属主 = `config.usageWindows`(声明)+ `boot/stores.ts` 造的账本店(两者同真同假,与
@@ -166,6 +166,7 @@ export function createLeaderRunner(cfg) {
166
166
  const governanceSeat = cfg.governance ?? {};
167
167
  const deploymentPostureSeat = () => cfg.deploymentPosture?.() ?? {};
168
168
  const tracerSeat = cfg.tracer ? { tracer: cfg.tracer } : {};
169
+ const modsSeat = cfg.mods ? { mods: cfg.mods } : {};
169
170
  const usageWindowSeat = cfg.usageWindows && cfg.usageWindowStore ? { usageWindows: cfg.usageWindows, usageWindowStore: cfg.usageWindowStore } : {};
170
171
  const promptSourceSeat = cfg.promptSource ? { promptSource: cfg.promptSource } : {};
171
172
  const onErrorSeat = cfg.onError ? { onError: cfg.onError } : {};
@@ -186,7 +187,7 @@ export function createLeaderRunner(cfg) {
186
187
  throw new Error(`oracle still present after remove (${f.path}) — refusing repair (measurement integrity)`);
187
188
  }
188
189
  try {
189
- const runner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, executionEnv: rawEnv, rootPath: repoDir });
190
+ const runner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...modsSeat, executionEnv: rawEnv, rootPath: repoDir });
190
191
  const objective = [
191
192
  `The integrated project at ${repoDir} fails its build/test. Make the MINIMAL change to the working tree so this command exits 0 (cd into the repo and run it yourself to confirm):`,
192
193
  ` ${testCmd}`,
@@ -253,7 +254,7 @@ export function createLeaderRunner(cfg) {
253
254
  if (Array.isArray(body.subtasks) && body.subtasks.length > 0) {
254
255
  return validateSubtasks(body.subtasks);
255
256
  }
256
- const planRunner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat });
257
+ const planRunner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...modsSeat });
257
258
  const runRoute = async (prompt) => {
258
259
  const res = await planRunner.runTaskStream({
259
260
  objective: prompt,
@@ -347,7 +348,7 @@ export function createLeaderRunner(cfg) {
347
348
  workerId: sub.workerId, sessionId, branch: sub.branch,
348
349
  baseSha,
349
350
  runner: keepCtxWarm(new Runner({
350
- brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat,
351
+ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...modsSeat,
351
352
  ...(cfg.toolResultStore ? { toolResultStore: cfg.toolResultStore } : {}),
352
353
  ...(cfg.sessionStore ? { sessionStore: cfg.sessionStore } : {}),
353
354
  executionEnvFactory: async (ctx) => {
@@ -372,7 +373,7 @@ export function createLeaderRunner(cfg) {
372
373
  const baseSha = await sh(env)(`cd ${repo} && git rev-parse HEAD`);
373
374
  return {
374
375
  workerId: sub.workerId, sessionId, branch: sub.branch, baseSha,
375
- runner: keepCtxWarm(new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...(cfg.toolResultStore ? { toolResultStore: cfg.toolResultStore } : {}), ...(cfg.sessionStore ? { sessionStore: cfg.sessionStore } : {}), executionEnv: env })),
376
+ runner: keepCtxWarm(new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...modsSeat, ...(cfg.toolResultStore ? { toolResultStore: cfg.toolResultStore } : {}), ...(cfg.sessionStore ? { sessionStore: cfg.sessionStore } : {}), executionEnv: env })),
376
377
  diffEnv: env,
377
378
  destroy: () => env.destroy().then(() => { }),
378
379
  spec: withLeaderLeg({ ...workerLimits, ...sub.spec, ...durableSpec, ...resourceSpec, ...principalSpec() }, resumeBody),