@sema-agent/server 7.149.0 → 7.151.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 (441) hide show
  1. package/MIGRATION.md +307 -9
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +92 -40
  5. package/deploy/sema-up/README.md +7 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  9. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  10. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  11. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  12. package/deploy/sema-up/chart/values.yaml +8 -1
  13. package/deploy/sema-up/cluster-up.sh +1 -0
  14. package/deploy/sema-up/kube-up.sh +1 -1
  15. package/deploy/sema-up/lib/flagshape.sh +1 -1
  16. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  17. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  18. package/dist/adoption/import.js +3 -3
  19. package/dist/approval-ask-machine.d.ts +1 -1
  20. package/dist/approval-card.d.ts +3 -3
  21. package/dist/approval-gate-currency.d.ts +2 -2
  22. package/dist/audit.d.ts +1 -1
  23. package/dist/audit.js +2 -2
  24. package/dist/auth-bridge.d.ts +20 -0
  25. package/dist/auth-bridge.js +9 -0
  26. package/dist/background-session-reap.d.ts +2 -2
  27. package/dist/bake-runner/main.d.ts +4 -2
  28. package/dist/bind-host.d.ts +2 -3
  29. package/dist/bind-host.js +2 -4
  30. package/dist/boot/budget-tracing.js +1 -1
  31. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  32. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  33. package/dist/boot/engine-lease.d.ts +5 -0
  34. package/dist/boot/engine-lease.js +1 -0
  35. package/dist/boot/execution-env.d.ts +8 -14
  36. package/dist/boot/execution-env.js +54 -17
  37. package/dist/boot/execution-lane.js +32 -5
  38. package/dist/boot/late-binds.d.ts +8 -4
  39. package/dist/boot/late-binds.js +7 -1
  40. package/dist/boot/memory-consolidation.d.ts +3 -2
  41. package/dist/boot/memory-consolidation.js +6 -6
  42. package/dist/boot/parked-revive-gate.d.ts +5 -5
  43. package/dist/boot/parked-revive-gate.js +2 -3
  44. package/dist/boot/reapers.d.ts +5 -0
  45. package/dist/boot/reapers.js +12 -1
  46. package/dist/boot/resolve-spec.d.ts +7 -8
  47. package/dist/boot/resolve-spec.js +80 -35
  48. package/dist/boot/retention-lane.d.ts +1 -1
  49. package/dist/boot/runner-deps.d.ts +9 -2
  50. package/dist/boot/runner-deps.js +3 -3
  51. package/dist/boot/session-age-out.d.ts +36 -0
  52. package/dist/boot/session-age-out.js +101 -0
  53. package/dist/boot/session-faces.d.ts +5 -14
  54. package/dist/boot/session-faces.js +28 -24
  55. package/dist/boot/stage-01-config.js +2 -0
  56. package/dist/boot/stage-03-store-backend.js +2 -2
  57. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  58. package/dist/boot/stage-05-execution-env.js +2 -2
  59. package/dist/boot/stage-06-runners.d.ts +7 -4
  60. package/dist/boot/stage-06-runners.js +16 -8
  61. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  62. package/dist/boot/stage-07-capability-layer.js +3 -2
  63. package/dist/boot/stage-08-reapers.d.ts +7 -4
  64. package/dist/boot/stage-08-reapers.js +4 -2
  65. package/dist/boot/stage-09-leader.d.ts +11 -5
  66. package/dist/boot/stage-09-leader.js +12 -3
  67. package/dist/boot/stage-10-http-server.d.ts +44 -6
  68. package/dist/boot/stage-10-http-server.js +12 -10
  69. package/dist/boot/web-admin.d.ts +1 -1
  70. package/dist/boot/web-admin.js +3 -1
  71. package/dist/boot/workflow-orchestration.d.ts +7 -2
  72. package/dist/boot/workflow-orchestration.js +24 -7
  73. package/dist/bounded-rotation.d.ts +29 -0
  74. package/dist/bounded-rotation.js +24 -0
  75. package/dist/capability-facts.d.ts +84 -66
  76. package/dist/capability-facts.js +58 -41
  77. package/dist/center-credential.d.ts +25 -6
  78. package/dist/center-credential.js +25 -5
  79. package/dist/config-catalog.d.ts +26 -7
  80. package/dist/config-catalog.js +15 -12
  81. package/dist/config-invariants.d.ts +2 -1
  82. package/dist/config-invariants.js +4 -4
  83. package/dist/config-types.d.ts +22 -15
  84. package/dist/config.d.ts +51 -2
  85. package/dist/config.js +35 -24
  86. package/dist/deployment-governance.d.ts +7 -28
  87. package/dist/deployment-governance.js +1 -14
  88. package/dist/deployment-shape.d.ts +9 -1
  89. package/dist/deployment-shape.js +2 -1
  90. package/dist/device-protocol.d.ts +5 -4
  91. package/dist/device-protocol.js +1 -1
  92. package/dist/device-ws-hub.d.ts +1 -0
  93. package/dist/device-ws-hub.js +66 -29
  94. package/dist/device-ws-protocol.d.ts +79 -12
  95. package/dist/device-ws-protocol.js +64 -26
  96. package/dist/engine-identity.d.ts +23 -5
  97. package/dist/engine-identity.js +13 -0
  98. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  99. package/dist/execution-env-refusal.d.ts +23 -0
  100. package/dist/execution-env-refusal.js +5 -0
  101. package/dist/execution-lane-caps.d.ts +3 -1
  102. package/dist/field-conflict.d.ts +3 -3
  103. package/dist/file-history-capture.d.ts +11 -4
  104. package/dist/file-history-capture.js +9 -6
  105. package/dist/file-history-disclosure.d.ts +7 -5
  106. package/dist/file-history-disclosure.js +7 -5
  107. package/dist/fleet/drain-entry.d.ts +4 -0
  108. package/dist/fleet/engine-signal.d.ts +14 -1
  109. package/dist/fleet/engine-signal.js +5 -1
  110. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  111. package/dist/fleet/serving-lease.d.ts +18 -3
  112. package/dist/fleet/serving-lease.js +81 -35
  113. package/dist/fleet-client.d.ts +13 -11
  114. package/dist/fleet-client.js +53 -33
  115. package/dist/history-anchor.js +1 -1
  116. package/dist/hitl-delivery.d.ts +1 -3
  117. package/dist/hitl-delivery.js +1 -1
  118. package/dist/hooks/hook-runner.js +2 -2
  119. package/dist/host-lsp-manager.d.ts +2 -2
  120. package/dist/http/active-run-conflict.d.ts +3 -7
  121. package/dist/http/active-run-conflict.js +2 -2
  122. package/dist/http/admission.js +19 -4
  123. package/dist/http/approval-sweeps.js +7 -6
  124. package/dist/http/caller-trust.d.ts +2 -2
  125. package/dist/http/caller-trust.js +3 -3
  126. package/dist/http/checkpoint-ctx.d.ts +20 -63
  127. package/dist/http/checkpoint-ctx.js +2 -24
  128. package/dist/http/claim-heartbeat.d.ts +4 -4
  129. package/dist/http/claim-heartbeat.js +3 -3
  130. package/dist/http/dispatch.d.ts +2 -1
  131. package/dist/http/dispatch.js +36 -29
  132. package/dist/http/durable-run-leg.js +17 -17
  133. package/dist/http/health-self-report.d.ts +9 -1
  134. package/dist/http/health-self-report.js +2 -0
  135. package/dist/http/owner-access.d.ts +264 -20
  136. package/dist/http/owner-access.js +215 -5
  137. package/dist/http/readiness.d.ts +4 -2
  138. package/dist/http/resume-ctx-read.js +38 -1
  139. package/dist/http/resume-legs.d.ts +2 -1
  140. package/dist/http/resume-legs.js +273 -89
  141. package/dist/http/route-ctx.d.ts +41 -19
  142. package/dist/http/route-table.d.ts +1 -1
  143. package/dist/http/routes/a2a-serve.js +15 -14
  144. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  145. package/dist/http/routes/agents-roster.js +2 -3
  146. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  147. package/dist/http/routes/approvals-assistant.js +12 -12
  148. package/dist/http/routes/background.d.ts +3 -3
  149. package/dist/http/routes/capabilities.js +10 -6
  150. package/dist/http/routes/config-catalog.d.ts +1 -1
  151. package/dist/http/routes/fleet.js +10 -8
  152. package/dist/http/routes/mcp-reconnect.js +2 -2
  153. package/dist/http/routes/memory-origin.d.ts +1 -1
  154. package/dist/http/routes/notify-wake.js +2 -3
  155. package/dist/http/routes/projects.d.ts +4 -2
  156. package/dist/http/routes/projects.js +7 -6
  157. package/dist/http/routes/retention-ops.d.ts +1 -1
  158. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  159. package/dist/http/routes/run-permission-mode.js +2 -2
  160. package/dist/http/routes/runs.d.ts +1 -1
  161. package/dist/http/routes/runs.js +125 -66
  162. package/dist/http/routes/session-memory-sync.js +4 -5
  163. package/dist/http/routes/session-sync.d.ts +4 -3
  164. package/dist/http/routes/session-sync.js +174 -83
  165. package/dist/http/routes/sessions-list.js +13 -7
  166. package/dist/http/routes/sessions.d.ts +1 -1
  167. package/dist/http/routes/sessions.js +26 -48
  168. package/dist/http/routes/tasks.js +38 -23
  169. package/dist/http/routes/trace-usage.js +14 -14
  170. package/dist/http/routes/workflows.d.ts +1 -0
  171. package/dist/http/routes/workflows.js +20 -38
  172. package/dist/http/server.d.ts +28 -30
  173. package/dist/http/server.js +7 -3
  174. package/dist/http/stored-body-replay.d.ts +3 -24
  175. package/dist/http/stored-body-replay.js +2 -12
  176. package/dist/http/submit-ctx.d.ts +1 -2
  177. package/dist/http/submit-ctx.js +8 -6
  178. package/dist/http/submit-replay.d.ts +15 -2
  179. package/dist/http/submit-replay.js +10 -4
  180. package/dist/http/wire-types.d.ts +19 -6
  181. package/dist/identity-source.d.ts +20 -3
  182. package/dist/identity-source.js +14 -0
  183. package/dist/index.d.ts +4 -0
  184. package/dist/lane-home-probe.d.ts +3 -7
  185. package/dist/lane-home-probe.js +0 -1
  186. package/dist/leader/endpoint.js +9 -8
  187. package/dist/leader/leader.d.ts +2 -1
  188. package/dist/leg-facts.d.ts +19 -5
  189. package/dist/leg-facts.js +3 -1
  190. package/dist/mcp-authorization-face.d.ts +18 -14
  191. package/dist/mcp-authorization-face.js +3 -2
  192. package/dist/memory-scope.d.ts +5 -4
  193. package/dist/memory-scope.js +4 -4
  194. package/dist/memory-store-refusal.d.ts +1 -1
  195. package/dist/memory-sync-client.d.ts +30 -2
  196. package/dist/memory-sync-client.js +16 -9
  197. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  198. package/dist/observability/err-text.d.ts +7 -0
  199. package/dist/observability/err-text.js +5 -0
  200. package/dist/observability/fail-open.d.ts +12 -8
  201. package/dist/observability/fail-open.js +12 -8
  202. package/dist/observability/logger.d.ts +7 -0
  203. package/dist/observability/logger.js +3 -1
  204. package/dist/observability/metrics.js +1 -0
  205. package/dist/observability/run-terminal.d.ts +1 -1
  206. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  207. package/dist/orchestration/workflow-notify-journal.js +12 -1
  208. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  209. package/dist/orchestration/workflow-park-decision.js +49 -10
  210. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  211. package/dist/orchestration/workflow-park-holder.js +98 -0
  212. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  213. package/dist/orchestration/workflow-record-fence.js +42 -0
  214. package/dist/owner-faces.d.ts +28 -4
  215. package/dist/owner-faces.js +2 -0
  216. package/dist/parked-decide.d.ts +104 -53
  217. package/dist/parked-decide.js +153 -117
  218. package/dist/peer-directory.d.ts +2 -2
  219. package/dist/peer-inbound-face.d.ts +2 -6
  220. package/dist/peer-inbound-face.js +0 -3
  221. package/dist/peer-seat.d.ts +1 -1
  222. package/dist/peer-seat.js +52 -59
  223. package/dist/permission-mode-admission.d.ts +41 -5
  224. package/dist/permission-mode-admission.js +29 -3
  225. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  226. package/dist/plugins/adoption-log-sql.js +7 -1
  227. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  228. package/dist/plugins/approval-ask-store-file.js +8 -0
  229. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  230. package/dist/plugins/approval-ask-store-memory.js +28 -9
  231. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  232. package/dist/plugins/approval-ask-store-sql.js +34 -5
  233. package/dist/plugins/approval-exemption-store.js +3 -0
  234. package/dist/plugins/approval-nonce-store.js +2 -0
  235. package/dist/plugins/breaker-state-sql.js +2 -0
  236. package/dist/plugins/caching-session-store.d.ts +9 -15
  237. package/dist/plugins/caching-session-store.js +6 -0
  238. package/dist/plugins/device-store-sql.js +6 -0
  239. package/dist/plugins/error-origin.d.ts +18 -0
  240. package/dist/plugins/error-origin.js +10 -0
  241. package/dist/plugins/exec-path-law.d.ts +34 -0
  242. package/dist/plugins/exec-path-law.js +13 -0
  243. package/dist/plugins/execution-placement-sql.js +6 -6
  244. package/dist/plugins/file-run-store.js +1 -1
  245. package/dist/plugins/image-bake-store-sql.js +6 -0
  246. package/dist/plugins/image-index-sql.js +4 -0
  247. package/dist/plugins/landed-attendants.d.ts +212 -0
  248. package/dist/plugins/landed-attendants.js +161 -0
  249. package/dist/plugins/leader-run-store-sql.js +4 -0
  250. package/dist/plugins/local-checkpoint-store.d.ts +4 -1
  251. package/dist/plugins/local-checkpoint-store.js +3 -0
  252. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  253. package/dist/plugins/local-session-live-reference.js +39 -0
  254. package/dist/plugins/local-session-store.d.ts +71 -33
  255. package/dist/plugins/local-session-store.js +129 -27
  256. package/dist/plugins/memory-engine-pg.js +4 -0
  257. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  258. package/dist/plugins/memory-engine-tidb.js +4 -0
  259. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  260. package/dist/plugins/memory-run-store.js +1 -1
  261. package/dist/plugins/memory-sync-store-pg.js +5 -0
  262. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  263. package/dist/plugins/one-time-migrations.d.ts +80 -61
  264. package/dist/plugins/one-time-migrations.js +241 -104
  265. package/dist/plugins/org-delivery-quota-store.js +4 -1
  266. package/dist/plugins/outcome-ledger-sql.js +2 -0
  267. package/dist/plugins/permission-rule-store-sql.js +11 -4
  268. package/dist/plugins/pg-cost-quota.js +4 -0
  269. package/dist/plugins/pg-pool.js +28 -1
  270. package/dist/plugins/pg-rate-limiter.js +2 -0
  271. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  272. package/dist/plugins/posix-shell-fs.js +8 -3
  273. package/dist/plugins/remote-env-adb.d.ts +19 -15
  274. package/dist/plugins/remote-env-adb.js +44 -17
  275. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  276. package/dist/plugins/remote-env-connect-seat.js +72 -0
  277. package/dist/plugins/remote-env-device.d.ts +22 -5
  278. package/dist/plugins/remote-env-device.js +114 -14
  279. package/dist/plugins/remote-env-e2b.d.ts +18 -7
  280. package/dist/plugins/remote-env-e2b.js +53 -40
  281. package/dist/plugins/remote-env-file-error.js +6 -2
  282. package/dist/plugins/remote-env-host.d.ts +18 -1
  283. package/dist/plugins/remote-env-host.js +48 -47
  284. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  285. package/dist/plugins/remote-env-k8s.js +56 -32
  286. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  287. package/dist/plugins/remote-env-local-docker.js +37 -43
  288. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  289. package/dist/plugins/remote-env-ssh.js +64 -62
  290. package/dist/plugins/remote-shell.d.ts +101 -2
  291. package/dist/plugins/remote-shell.js +221 -3
  292. package/dist/plugins/replica-registration.d.ts +35 -0
  293. package/dist/plugins/replica-registration.js +48 -0
  294. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  295. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  296. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  297. package/dist/plugins/retention-lane-store-sql.js +4 -0
  298. package/dist/plugins/retention-sql.d.ts +20 -2
  299. package/dist/plugins/retention-sql.js +11 -0
  300. package/dist/plugins/run-store-sql.d.ts +22 -3
  301. package/dist/plugins/run-store-sql.js +33 -9
  302. package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
  303. package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
  304. package/dist/plugins/schema-consistency.d.ts +9 -5
  305. package/dist/plugins/schema-consistency.js +48 -18
  306. package/dist/plugins/schema-drift-sentence.js +1 -1
  307. package/dist/plugins/send-file-ledger.js +3 -0
  308. package/dist/plugins/serving-requirement.d.ts +68 -0
  309. package/dist/plugins/serving-requirement.js +60 -0
  310. package/dist/plugins/session-birth.d.ts +6 -2
  311. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  312. package/dist/plugins/session-ext-table.d.ts +14 -1
  313. package/dist/plugins/session-ext-table.js +5 -1
  314. package/dist/plugins/session-row-sql.d.ts +49 -2
  315. package/dist/plugins/session-row-sql.js +56 -13
  316. package/dist/plugins/session-store-sql.d.ts +34 -18
  317. package/dist/plugins/session-store-sql.js +98 -17
  318. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  319. package/dist/plugins/shared-memory-store-sql.js +6 -2
  320. package/dist/plugins/sql-driver.d.ts +2 -1
  321. package/dist/plugins/sql-driver.js +18 -3
  322. package/dist/plugins/sql-errors.d.ts +11 -6
  323. package/dist/plugins/sql-errors.js +5 -6
  324. package/dist/plugins/stop-then-start-sentence.d.ts +48 -3
  325. package/dist/plugins/stop-then-start-sentence.js +48 -0
  326. package/dist/plugins/stop-then-start.d.ts +109 -0
  327. package/dist/plugins/stop-then-start.js +104 -0
  328. package/dist/plugins/store-backend.d.ts +40 -13
  329. package/dist/plugins/store-backend.js +169 -27
  330. package/dist/plugins/store-boundary.d.ts +57 -0
  331. package/dist/plugins/store-boundary.js +139 -0
  332. package/dist/plugins/store-contracts.d.ts +29 -2
  333. package/dist/plugins/store-contracts.js +3 -0
  334. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  335. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  336. package/dist/plugins/store-fault.d.ts +26 -7
  337. package/dist/plugins/store-fault.js +18 -2
  338. package/dist/plugins/task-attachment-store.js +9 -0
  339. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  340. package/dist/plugins/task-list-store-sql.js +10 -8
  341. package/dist/plugins/tidb-cost-quota.js +4 -0
  342. package/dist/plugins/tidb-pool.js +6 -1
  343. package/dist/plugins/tidb-rate-limiter.js +4 -0
  344. package/dist/plugins/user-input-ledger-sql.js +4 -0
  345. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  346. package/dist/plugins/workflow-run-store-sql.js +64 -4
  347. package/dist/plugins/workspace-fill.d.ts +4 -7
  348. package/dist/plugins/workspace-fill.js +2 -1
  349. package/dist/plugins/write-behind-counter.js +5 -0
  350. package/dist/process-instance.d.ts +3 -0
  351. package/dist/process-instance.js +7 -0
  352. package/dist/project-context.d.ts +64 -0
  353. package/dist/project-context.js +66 -0
  354. package/dist/project-registry.d.ts +46 -0
  355. package/dist/project-registry.js +44 -0
  356. package/dist/question.d.ts +9 -21
  357. package/dist/question.js +28 -19
  358. package/dist/request-key-closure.js +1 -1
  359. package/dist/request-value-closure.d.ts +4 -0
  360. package/dist/request-value-closure.js +10 -0
  361. package/dist/run-acceptance.d.ts +3 -2
  362. package/dist/run-acceptance.js +4 -6
  363. package/dist/run-cancel-card.d.ts +1 -1
  364. package/dist/run-cancel-card.js +2 -1
  365. package/dist/run-local.js +1 -0
  366. package/dist/runs.d.ts +37 -8
  367. package/dist/runs.js +53 -12
  368. package/dist/runtime-governance.d.ts +5 -4
  369. package/dist/security.d.ts +31 -33
  370. package/dist/security.js +41 -7
  371. package/dist/server-secret-env.d.ts +12 -10
  372. package/dist/server-secret-env.js +24 -15
  373. package/dist/session-agent.d.ts +1 -10
  374. package/dist/session-agent.js +0 -6
  375. package/dist/session-bindings.d.ts +82 -0
  376. package/dist/session-bindings.js +18 -0
  377. package/dist/session-children-retire.d.ts +2 -2
  378. package/dist/session-children-retire.js +2 -6
  379. package/dist/session-deletion.d.ts +16 -1
  380. package/dist/session-error-wire.d.ts +3 -3
  381. package/dist/session-error-wire.js +3 -3
  382. package/dist/session-incarnation.d.ts +28 -4
  383. package/dist/session-incarnation.js +14 -2
  384. package/dist/session-kind.d.ts +57 -0
  385. package/dist/session-kind.js +22 -0
  386. package/dist/session-notify-door.d.ts +4 -4
  387. package/dist/session-notify-door.js +5 -6
  388. package/dist/session-row.d.ts +21 -1
  389. package/dist/session-row.js +7 -1
  390. package/dist/session-rules-seat.d.ts +4 -3
  391. package/dist/session-rules-seat.js +3 -11
  392. package/dist/session-sync-kernel.d.ts +24 -14
  393. package/dist/session-sync-kernel.js +3 -6
  394. package/dist/session-sync.d.ts +4 -98
  395. package/dist/session-sync.js +4 -74
  396. package/dist/session-titler.d.ts +10 -3
  397. package/dist/session-titler.js +19 -6
  398. package/dist/ssh-host-key.d.ts +5 -0
  399. package/dist/ssh-host-key.js +3 -0
  400. package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
  401. package/dist/stores-sql/checkpoint-store-sql.js +106 -18
  402. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  403. package/dist/stores-sql/file-history-store-sql.js +108 -70
  404. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  405. package/dist/stores-sql/pg-session-storage.js +37 -13
  406. package/dist/stores-sql/retention-store-sql.d.ts +2 -10
  407. package/dist/stores-sql/retention-store-sql.js +2 -10
  408. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  409. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  410. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  411. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  412. package/dist/stores-sql/tidb-session-store.js +37 -13
  413. package/dist/submission-exit.d.ts +3 -2
  414. package/dist/submission-exit.js +9 -1
  415. package/dist/task-cwd.d.ts +6 -5
  416. package/dist/task-settings.d.ts +19 -5
  417. package/dist/task-settings.js +13 -7
  418. package/dist/terminal.d.ts +33 -2
  419. package/dist/terminal.js +139 -9
  420. package/dist/tool-approval.d.ts +147 -12
  421. package/dist/tool-approval.js +206 -109
  422. package/dist/trace/engine-notice-wire.d.ts +14 -0
  423. package/dist/trace/engine-notice-wire.js +18 -1
  424. package/dist/trace/project.d.ts +4 -3
  425. package/dist/trace/project.js +3 -2
  426. package/dist/trace/projection-table.d.ts +33 -2
  427. package/dist/trace/self-minted-wire.d.ts +422 -26
  428. package/dist/trace/self-minted-wire.js +149 -23
  429. package/dist/trace/tool-card.d.ts +3 -0
  430. package/dist/trace/tool-card.js +24 -0
  431. package/dist/trace/tool-output-media.d.ts +2 -1
  432. package/dist/unattended-permission-mode.d.ts +1 -1
  433. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  434. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  435. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  436. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
  437. package/package.json +3 -3
  438. package/wire-changes/server@7.150.0.json +335 -0
  439. package/wire-changes/server@7.151.0.json +762 -0
  440. package/dist/http/session-inherit-env.d.ts +0 -36
  441. package/dist/http/session-inherit-env.js +0 -6
@@ -1,9 +1,11 @@
1
1
  import http from "node:http";
2
2
  import type { MemoryComplianceFaces, MemoryOriginFaces, SessionMemoryStatusFace } from "../memory-operator-faces.js";
3
3
  import type { SideQueryAccounting } from "../budget.js";
4
- import type { SessionPurgeOutcome } from "../session-deletion.js";
4
+ import type { SessionAgeOutExpectation, SessionPurgeOutcome } from "../session-deletion.js";
5
5
  import type { IncomingMessage } from "node:http";
6
6
  import { type Runner, type RunnerDeps, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
7
+ import type { ProjectContext } from "../project-context.js";
8
+ import type { MemorySeed } from "../project-registry.js";
7
9
  import type { TaskRequestBody } from "./wire-types.js";
8
10
  import type { ServiceConfig } from "../config-types.js";
9
11
  import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
@@ -11,7 +13,7 @@ import type { RestartSignal } from "@sema-agent/settings-schema/fleet";
11
13
  import { type AuthorizeInput, type OwnerAwareSessionStore } from "../security.js";
12
14
  import type { PeerDesk, PeerLease } from "../peer-seat.js";
13
15
  import type { ExecutionRoot, ResolvedTaskSpec } from "./execution-context.js";
14
- import type { RunStore, ImageIndex, ImageBake, CheckpointStoreFull, ResumeAnchorStore, ApprovalExemptionStore, ApprovalNonceStore, ServiceSessionPolicyStore, ServiceFileHistoryStore, ToolResultStoreFull, StoreBackend } from "../plugins/store-backend.js";
16
+ import type { RunStore, ImageIndex, ImageBake, CheckpointStoreFull, ApprovalExemptionStore, ApprovalNonceStore, ToolResultStoreFull, StoreBackend } from "../plugins/store-backend.js";
15
17
  import type { RuleConsentLane } from "../rules-consent.js";
16
18
  import { type MemorySyncAnswer, type MemorySyncRequest } from "../memory-sync.js";
17
19
  import type { MemorySyncRunner } from "../memory-sync-client.js";
@@ -57,9 +59,9 @@ export interface RequestAuth {
57
59
  sessionId: string;
58
60
  memoryScope?: string;
59
61
  /** 142-S4:the SHAPE-VALIDATED **且已归一(小写)** 的 `body.projectId`(authorizer 的 core
60
- * `PROJECT_ID_REGEX` 门通过后折小写回传;[ref]/[ref] 宽读严写)。main.ts 拿它查 config.projects 的
61
- * defaultScopes(memory.scopes 种子)。resume 腿(checkpoint 重建 auth)缺席 — 回落持久化的
62
- * body.projectId(原始提交已验形),那条回落腿自己再折一次小写,两腿查同一个键。 */
62
+ * `PROJECT_ID_REGEX` 门通过后折小写回传;[ref]/[ref] 宽读严写)。装配器拿它判 memory.scopes 种子项目(对提交者可见才算,
63
+ * `project-registry.ts`)与这条腿的项目。resume 腿(checkpoint 重建 auth)缺席 — 项目回落持久化的
64
+ * body.projectId(原始提交已验形,那条回落腿自己再折一次小写);种子不回落,读冻结的种子项目。 */
63
65
  resolvedProjectId?: string;
64
66
  /** authorizer 判过的头(`security.ts` `createAuthorizer` 交出;语义见 `AuthContext.head`)⇒ fresh 执行上下文的 `judged`。自建 authorizer 不给 = 解析器不比住客。 */
65
67
  head?: import("@sema-agent/core").SessionHead;
@@ -130,7 +132,11 @@ export interface ServiceCoreDeps {
130
132
  * 已过期,按新行为改。
131
133
  * `opts.unattendedLeg`([ref] 候裁 18,codex r3 F1;[ref] ① 改形):续跑家族在 ctx 带无人值守标(`CheckpointCtx.unattendedLeg`)时递 `true` ——
132
134
  * 装配器在**全部折叠之后**经首跑同一只合并口 `withUnattendedLeg` 重挂那条腿(`default` + 按类作答的 onAsk)。只由续跑腿
133
- * 按服务端写的 ctx 位递,绝不从请求体读。 */
135
+ * 按服务端写的 ctx 位递,绝不从请求体读。
136
+ * `opts.projectContext`(项目上下文继承):续跑家族把提交腿冻结的那一份(`CheckpointCtx.projectContext`,服务端写)原样递回 —— 装配器在续跑腿上只重放它、不读登记簿;
137
+ * 新提交腿不递(装配器自己在头部判)。同样只由续跑腿按服务端写的 ctx 位递,绝不从请求体读。
138
+ * `opts.memorySeed`(登记簿默认读层种子):续跑家族把提交腿冻结的种子(`CheckpointCtx.memorySeed`:种子项目 + 判出它的那一位观者,服务端写)原样递回 —— 装配器在续跑腿上
139
+ * 只认它(以冻结的观者经同一只可见性判读此刻的登记)、不推观者、不按存体的 `projectId` 现查;新提交腿不递(装配器自己在头部判)。只由续跑腿按服务端写的 ctx 位递,绝不从请求体读。 */
134
140
  /** `opts.execution`(必填):这条腿的执行上下文(`http/execution-context.ts`;只 `fresh` / `continuation` 两形,`root` 恒在)。装配器要用这条腿的根会话
135
141
  * (场景设施的分区键、受理见证)读 `opts.execution.root` —— 它与 server 随后盖进 spec 的根是同一个值,装配器自己不写根。 */
136
142
  /** `opts.lease`(必填):这条腿的**宿主租约** —— 装配在它之下登记本腿交给引擎的对端声明(`peerDesk.declare(草稿, opts.lease)`)。
@@ -141,6 +147,8 @@ export interface ServiceCoreDeps {
141
147
  liveStream?: boolean;
142
148
  onNotice?: (notice: EngineNotice) => void;
143
149
  unattendedLeg?: true;
150
+ projectContext?: ProjectContext;
151
+ memorySeed?: MemorySeed | null;
144
152
  lease: PeerLease;
145
153
  execution: ExecutionRoot;
146
154
  }) => ResolvedTaskSpec | Promise<ResolvedTaskSpec>;
@@ -192,9 +200,6 @@ export interface ServiceCoreDeps {
192
200
  export interface ServiceStoreDeps {
193
201
  /** Durable async-run registry + event log (S1/S2). Enables /v1/runs when present. */
194
202
  runStore?: RunStore;
195
- /** E18 resume-at: the eventId→entryId anchor map (tidb/pg/local). Present whenever a backend is — resolveSpec
196
- * resolves body.resumeAt(eventId)→entryId, the run lifecycle captures per-turn anchors, E21 purges them. */
197
- resumeAnchorStore?: ResumeAnchorStore;
198
203
  /** Per-session approval exemption store — enables decide body `remember:"session"` + the
199
204
  * exemptions list/revoke surfaces on /v1/approvals. The ask-gate probe is wired separately (main.ts). */
200
205
  approvalExemptionStore?: ApprovalExemptionStore;
@@ -211,9 +216,6 @@ export interface ServiceStoreDeps {
211
216
  * 封不了就不落,没有「明文照写」的第二种装配。嵌入方:`checkpointCtxSealing: await ensureCheckpointCtxSealing(sealedKeyDir)`
212
217
  * (保管目录要跨重启持久、多副本各副本是同一份钥匙,否则封它的那把钥匙不在 ⇒ 409 `conflict.checkpoint_ctx_unsealable` `reason:"key_not_held"`)。 */
213
218
  checkpointCtxSealing?: import("./checkpoint-ctx.js").CheckpointCtxSealing;
214
- /** E6 durable SessionPolicyStore (operator-tightened per-session tool rules). Enables PUT/GET /v1/sessions/:id/policy
215
- * when present; core reads the rules at prepare-time (subtract-only) via RunnerDeps.sessionPolicyStore (wired separately). */
216
- sessionPolicyStore?: ServiceSessionPolicyStore;
217
219
  /** [ref] tool-results 读面([ref] 请求,core [ref] `buildToolResultRef` 到货):`GET /v1/tasks/:id/
218
220
  * tool-results/:ref` 的数据源 —— 与 RunnerDeps 侧的 offload 店**同实例**(main.ts 的 `toolResultStore`,
219
221
  * 即「durable 后端在场」那一只;无 backend 部署里 Runner 用的内存兜底 `runnerOffloadStore` **不接**这里)。
@@ -221,14 +223,6 @@ export interface ServiceStoreDeps {
221
223
  * 与 unknown-ref / 归属不符两臂**同形** 404 才是防 oracle 的收口([ref] 的「另定」项按防 oracle 收紧)。
222
224
  * 这是本组「absent ⇒ 501 诚实缺席」通例的**唯一具名例外**,例外理由即上一句。 */
223
225
  toolResultStore?: ToolResultStoreFull;
224
- /** [ref] per-edited-file rewind history store. Present ⇒ the rewind capabilities are advertised; core uses it
225
- * via RunnerDeps.fileHistoryStore (first-touch tracking + per-turn boundaries + tracked-set restore, ANY
226
- * env). Also the 2c history-transfer store (exportHistory/importHistory + blob negotiation faces).
227
- * 🔴 [ref]:这是装配单点 `assembleFileHistory` 的**店**(后端在即在,与 `FILE_HISTORY_CAPTURE` 无关 —— 旋钮只关捕获,
228
- * 落在 core 的 `RunnerDeps.fileHistoryCapture` 上)。rewind 族四位与 2c sync 路由族跟它走;能力词 `fileHistoryCapture`
229
- * = `fileHistoryCaptureOf(本键, config.fileHistoryCapture)`(与 core 捕获位同一只判定)。
230
- * 擦除(E21 / 孤儿 blob GC)不读本键,读 boot 侧的擦除脸。 */
231
- fileHistoryStore?: ServiceFileHistoryStore;
232
226
  /** D-1 通用文件上传(clay 拍 2026-07-27:独立附件 store,不骑 snapshot blob 面):enables
233
227
  * POST/GET/DELETE /v1/attachments*。缺席 ⇒ 501(与其他可选 store 面同姿)。绑定/物化半场在
234
228
  * main.ts(resolveSpec + env factory 包装);本面只管上传/取回/删除三动词 + server 权威上限。 */
@@ -419,11 +413,11 @@ export interface ServiceSeamDeps {
419
413
  */
420
414
  deviceEnrollment?: import("../device-enrollment.js").DeviceEnrollment;
421
415
  /**
422
- * [ref] × 7.106.0 合并复审 X1:host 车道会话登记簿的 `inheritEnv` **写口**(`boot/execution-env.ts` 的 `setSessionInheritEnv`)。
423
- * 唯一调用者 = `http/session-inherit-env.ts` 的 `commitSessionInheritEnv`(四个 run 认领点在认领之后调;判据与残余见那只文件)。
424
- * 缺席 = 本部署不是 host 车道(没有工厂读这一格)⇒ 提交点 no-op。装配 = `boot/stage-10-http-server.ts`(host 车道才给)。
416
+ * 会话登记簿的**绑定写座**(`boot/execution-env.ts` `createSessionScopedRegistries`:cwd / shellEnv / inheritEnv 三格写一笔、按回执撤一笔)。
417
+ * 唯一写者 = `session-bindings.ts` 的 `commitLegBindings`(四个 run 认领点在认领之后调);唯一撤回者 = 提交出口(`submission-exit.ts`,
418
+ * 写了之后才收场 `refused` 的提交)。律与残余见 `session-bindings.ts` 头注。缺席(夹具 / 嵌入方没接)= 没有登记簿 ⇒ 提交点 no-op。
425
419
  */
426
- bindSessionInheritEnv?: import("./session-inherit-env.js").SessionInheritEnvCommitCtx["bindSessionInheritEnv"];
420
+ sessionBindings?: import("../session-bindings.js").SessionBindingSeat;
427
421
  /**
428
422
  * 会话登记簿四表(cwd / shellEnv / inheritEnv / 属主,`boot/execution-env.ts` `createSessionScopedRegistries` 的 `dropSessionOf`)按**住客**清掉一只 ——
429
423
  * 记下的住客恰是交来的化身才清、答 `true`。读者只有提交出口(`submission-exit.ts`):被拒提交铸下的会话撤回之后清(同 id 的下一位已登记、写下的条目不动)。
@@ -438,12 +432,14 @@ export interface ServiceSeamDeps {
438
432
  } & Record<string, unknown>) | undefined>;
439
433
  /** E21 删除协调器(会话三态 活 → 在删 → 没了,`session-deletion.ts`):删会话的对话史与服务自己的 run 账 / 检查点 / 卸载结果等全部挂靠行,一次调用。
440
434
  * 结局 = {@link SessionPurgeOutcome}(删了 / 不在 · 围栏判到认领 · 子代预检拒 · 被接管)。点亮 DELETE /v1/sessions/:id。 */
441
- purgeSession?: (sessionId: string, owner: string | null) => Promise<SessionPurgeOutcome>;
435
+ purgeSession?: (sessionId: string, owner: string | null, opts?: {
436
+ readonly ageOut?: SessionAgeOutExpectation;
437
+ }) => Promise<SessionPurgeOutcome>;
442
438
  /** [ref]③(b): read a BACKGROUND agent-handle child's final report / current status out of the core
443
439
  * TaskRegistry (the same face the TaskOutput tool reads — agent handles are NEVER in the run store).
444
440
  * Wired in main.ts to `defaultTaskRegistry.pollTask` (non-blocking). Access is the REGISTRATION tuple:
445
441
  * owner = the parent run's taskId (resume legs register children under the sessionId — the registry's
446
- * sessionScoped arm matches via `access.sessionId`), scope = the run's principal ?? "default". */
442
+ * sessionScoped arm matches via `access.sessionId`), scope = the run owner's engine-identity cell (`engineScopeOfOwner`). */
447
443
  subagentTaskOutput?: (handle: string, access: {
448
444
  owner: string;
449
445
  scope: string;
@@ -720,7 +716,7 @@ export interface ServiceDeploymentDeps {
720
716
  */
721
717
  deploymentModPackages?: number;
722
718
  /**
723
- * 会话 → 调用方登记的工作目录(提交体 `cwd` 的唯一写口 `setSessionCwd` 写的那一张进程内表,`boot/execution-env.ts` `createSessionScopedRegistries`)。
719
+ * 会话 → 登记的工作目录(受理的提交经绑定写座 {@link ServiceDeps.sessionBindings} 写的那一张进程内表,`boot/execution-env.ts` `createSessionScopedRegistries`)。
724
720
  * **只读**,读者只有 run 外回退口(`POST /v1/sessions/:id/rewind-files`):host 工厂按 `effectiveHostWorkspace(本表.get(会话), ctx)` 定根(`execution-env.ts`
725
721
  * host 臂),口在交引擎之前用**同一只函数、同一份入参**问「工厂这一次会不会落到一只用完即删的临时目录」—— 会 ⇒ 拒,不让台账说恢复了而项目没动。
726
722
  * 缺席(夹具 / 嵌入方没接)⇒ 读作「没有登记」⇒ host 车道上口拒(fail-closed)。
@@ -755,8 +751,8 @@ export interface ServiceDeploymentDeps {
755
751
  * 缺席(嵌入方 / 夹具)= 两项恒 0,两个读数逐字同 7.145.x。
756
752
  */
757
753
  sessionResidentBackground?: () => SessionResidentCounts;
758
- /** 编排器片 2 件 3:服务租约此刻的读数(`fleet/serving-lease.ts` 的客户端交出;引擎信号铸点与计费准入判同读)。缺席 = 没装租约客户端
759
- * (非 fleet 成员 / 没接中心 / 测试夹具)⇒ `none`(与没有租约的引擎逐字同)。 */
754
+ /** 编排器片 2 件 3:服务租约此刻的读数(`fleet/serving-lease.ts` 的客户端交出;唯一读者 `fleet/engine-signal.ts` 的 `memberLeaseOf` —— 引擎信号铸点
755
+ * 与计费准入判经它同读,只在 `config.fleetGeneration` 在场〔成员〕时读)。缺席 = 没装租约客户端(非 fleet 成员 / 测试夹具)⇒ `none`。 */
760
756
  servingLease?: () => import("../fleet/engine-signal.js").ServingLeaseView;
761
757
  /** boot ready 门(b):false = 布防(`CONFIG_REQUIRE_ROSTER=true`)且首次 effective pull 尚未落 roster
762
758
  * (worker 只有占位模型)。就绪原因 `model_roster_pending`(`http/readiness.ts`):计费提交 503 + `/readyz` 503 +
@@ -800,7 +796,7 @@ export interface ServiceDeploymentDeps {
800
796
  /** [ref] 追加件:`POST /v1/admin/config/refresh` 的实现面 —— 触发**一次既有**的 refresh 拍(在飞则 join)。
801
797
  * 缺席 / 回 `"not-wired"` = 本部署没有配置管道 ⇒ 该口诚实 4xx(绝不吞成 200)。 */
802
798
  configRefreshNow?: () => Promise<"triggered" | "not-wired" | "failed">;
803
- /** DESIGN-278 §5 S2([ref]):center **当前在管**的 ServiceConfig 键集 —— `GET /v1/config/catalog`
799
+ /** [ref] §5 S2([ref]):center **当前在管**的 ServiceConfig 键集 —— `GET /v1/config/catalog`
804
800
  * 判 `effectiveLane`(env 占位/center 在管/默认)的 center 半场。缺席或返回 undefined = 本部署
805
801
  * 没有配置管道(纯 env worker / 测试夹具)⇒ 目录把每条 center 腿如实标「不在管」(additive)。 */
806
802
  webAdminManagedKeys?: () => ReadonlySet<string> | undefined;
@@ -946,6 +942,8 @@ export declare function createHttpServer(rawDeps: ServiceDeps): http.Server & {
946
942
  redeemParkedAsk: ParkedAskRedeem;
947
943
  /** 会话通知门(装配层把它接进场景层后台完成 sink 的晚绑座;门与律见 `session-notify-door.ts`)。 */
948
944
  sessionNotifyDoor: SessionNotifyDoor;
945
+ /** run 收场送达的转交(装配层把它接进 workflow 编排面完成送达的晚绑座;律见 `resume-legs.ts` 的 `handOverRunEndedDecisions`)。 */
946
+ handOverRunEndedDecisions: (runId: string) => Promise<void>;
949
947
  };
950
948
  /** SSE: replay durable events after Last-Event-ID, then tail until the run is terminal (or stale). */
951
949
  /**
@@ -26,6 +26,7 @@ import { createRunConcurrencyGate, liveRunIdsOf } from "./run-concurrency-cap.js
26
26
  import { sqlEngineSeatIssue } from "../sql-engine-posture.js";
27
27
  import { parkDecisionStoreRefusal } from "../orchestration/workflow-park-decision.js";
28
28
  import { CHECKPOINT_CTX_SEALING_REQUIRED } from "./checkpoint-ctx.js";
29
+ import { SERVING_LEASE_MEMBERSHIP_REQUIRED } from "../fleet/engine-signal.js";
29
30
  import { PARKED_REVIVE_EXECUTION_SEAT_REQUIRED } from "../parked-decide.js";
30
31
  import { a2aAudienceVerifiedSourceRefusal, operatorDeclarationRefusal } from "../config-invariants.js";
31
32
  import { retiredServiceDepsRefusal } from "./retired-service-deps.js";
@@ -148,6 +149,8 @@ export function createHttpServer(rawDeps) {
148
149
  throw new Error(`createHttpServer: ${CHECKPOINT_CTX_SEALING_REQUIRED}`);
149
150
  if (deps.parkedReviveSurface !== undefined && deps.sessionStorage?.executionPlacement === undefined)
150
151
  throw new Error(`createHttpServer: ${PARKED_REVIVE_EXECUTION_SEAT_REQUIRED}`);
152
+ if (deps.servingLease !== undefined && deps.config.fleetGeneration === undefined)
153
+ throw new Error(`createHttpServer: ${SERVING_LEASE_MEMBERSHIP_REQUIRED}`);
151
154
  const idemCache = new IdempotencyCache();
152
155
  const inflightRuns = new Map();
153
156
  const preemptableRuns = new DrainYieldingPreemptBook(() => deps.drainState?.draining === true);
@@ -183,7 +186,7 @@ export function createHttpServer(rawDeps) {
183
186
  if (deps.drainState)
184
187
  deps.drainState.yieldInflight = () => preemptableRuns.yieldAll();
185
188
  if (deps.hookWakeBus) {
186
- deps.hookWakeBus.deliver = async (sessionId, text) => {
189
+ const deliverHookWake = async (sessionId, text) => {
187
190
  try {
188
191
  validatePendingSteer({ text, trusted: false });
189
192
  }
@@ -218,11 +221,12 @@ export function createHttpServer(rawDeps) {
218
221
  return false;
219
222
  }
220
223
  };
224
+ deps.hookWakeBus.deliver = deliverHookWake;
221
225
  }
222
226
  const { quotaExceeded, ownerCostQuotaDenied, ownerFleetLeaseDenied, ownerLeaseDenied, ownerQuotaDenied, leaseDenied, usageWindowDenialFor, usageWindowDenied, rateLimited, safeDecode, readJson, readRawBody } = createRequestGuards({ deps });
223
227
  const { prepareSpec } = createAdmission({ deps, readJson, runnerFor });
224
228
  const { admitRun } = createRunConcurrencyGate({ deps, inflightRuns, steerableRuns });
225
- const { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg, decisionRowAdmits, resumePreempted, startFreshHostTurn, resumeWake, sessionNotifyDoor } = createResumeLegs({ deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode, prepareSpec, finalizeTaskResult, ownerCostQuotaDenied, ownerFleetLeaseDenied, usageWindowDenialFor });
229
+ const { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg, decisionRowAdmits, resumePreempted, startFreshHostTurn, resumeWake, sessionNotifyDoor, handOverRunEndedDecisions } = createResumeLegs({ deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode, prepareSpec, finalizeTaskResult, ownerCostQuotaDenied, ownerFleetLeaseDenied, usageWindowDenialFor });
226
230
  const { denyExpiredApprovals, redeemParkedAsk } = createApprovalSweeps({ deps, resumeCheckpoint, decisionRowAdmits });
227
231
  const { handle } = createDispatch({ deps, noteActivity, routeCtxBase, counters });
228
232
  const server = http.createServer((req, res) => {
@@ -285,6 +289,6 @@ export function createHttpServer(rawDeps) {
285
289
  deps.planCacheProbe?.record(principal, objective, result.terminal.kind === "completed");
286
290
  }
287
291
  const isRunLiveOnThisReplica = (taskId) => liveRunIdsOf(inflightRuns, steerableRuns).has(taskId);
288
- return Object.assign(server, { denyExpiredApprovals, isRunLiveOnThisReplica, redeemParkedAsk, sessionNotifyDoor });
292
+ return Object.assign(server, { denyExpiredApprovals, isRunLiveOnThisReplica, redeemParkedAsk, sessionNotifyDoor, handOverRunEndedDecisions });
289
293
  }
290
294
  //# sourceMappingURL=server.js.map
@@ -1,29 +1,9 @@
1
- /**
2
- * 「这条停驻行的持久化体在本版上能否重放」—— **唯一**判据(四问一只,外加 `settings.env` 凭据一臂;五个问点同调:续跑驱动段 `resume-legs.ts` `resolveResumeSpecOrBlocked`、
3
- * plan_review 的 prepare 段、SLA 拒扫腿的跳过臂 `approval-sweeps.ts`、终态 run 的 steer 铸唤醒卡之前 `routes/runs.ts`;`resolveSpec` 本身留作提交腿的拒点)。
4
- * 四问的规则、记号、拒句与删除条件的属主 = `http/checkpoint-ctx.ts` 顶注;答复 = 那里的 `storedBodyReplayAnswer`。
5
- *
6
- * 为什么判据住在这里而不是 `checkpoint-ctx.ts`:模式词问要读体的**生效模式词**(`task-settings.ts` `storedBodyPermissionMode`,请求设置的解析层)与本部署此刻的
7
- * **入口地板**(`runtime-governance.ts` `autonomyModeFloor`)—— 这两只属主带着配置层的包外依赖;`checkpoint-ctx.ts` 被随包的本地排空脚本经编译产物 import,
8
- * 它的闭包只许 node 内建 / 引擎包根(`test/drain-check-local.test.ts` 的闭包门)。判据只有这一只,allow 读法问、工具名清单问与退役请求键问的谓词照旧住在各自属主里。
9
- */
10
- import type { PermissionMode } from "@sema-agent/core";
11
- import { type Autonomy } from "../runtime-governance.js";
12
1
  import { type InertToolListEntry } from "../rule-entry-list.js";
13
2
  import { type ExecutionConfigRootDeployment } from "../execution-config-root.js";
14
3
  import { type UnreadMembersDeployment } from "../unread-request-members.js";
15
4
  import { type ModelApiKeyEnvTable } from "../server-secret-env.js";
16
5
  import { type StoredBodyReplayRefusal } from "./checkpoint-ctx.js";
17
6
  import type { CheckpointCtx } from "./route-ctx.js";
18
- /**
19
- * 模式词问:本行体里的模式词能否按当前读法重放。不能 ⇔ 本部署此刻有入口地板 ∧ 行上没有当前的模式词读法记号 ∧ 体的生效词进这块地板会变
20
- * (`runtime-governance.ts` `entryPermissionMode`,与提交入口的盖章同一只函数;判的是「词变不变」而不是 `clamped` —— 体无词的旧行进地板取地板本身,
21
- * 那也是变)⇒ 返回拒因的两个事实(体的词、地板);能 ⇒ `undefined`。
22
- */
23
- export declare function permissionModeReadingUnstated(ctx: CheckpointCtx, floor: PermissionMode | undefined): {
24
- stored: PermissionMode | undefined;
25
- floor: PermissionMode;
26
- } | undefined;
27
7
  /**
28
8
  * 存体里 `settings.permissions.deny` / `ask`(规则编译器读的收紧表)有永远不生效的条目(名字层:退役名 / 短名 / 铸不出的段 / 近似名;core 的规则文法:括号 / 内容文法 / 主字段……;
29
9
  * `~/` 形而这个部署解不出 home),或三桶里 user 层的 `/` 形规则而这个部署读不出执行环境的配置根 —— 拒点是 `applyTaskSettings`(422,在 `resolveSpec` 里),那一拍 plan_review 的一次性 nonce 已烧、终态 steer 的唤醒卡已铸、SLA 拒扫跳不过;所以预判也问一遍。
@@ -36,17 +16,16 @@ export declare function permissionModeReadingUnstated(ctx: CheckpointCtx, floor:
36
16
  */
37
17
  export declare function ruleTablesRefusalWithoutTaskRoot(body: unknown, deployment: ExecutionConfigRootDeployment): InertToolListEntry | undefined;
38
18
  /**
39
- * 预判读的部署配置:`autonomy`(模式词问的模式词地板)、执行车道的 home 两位(`~/` 形规则那一问)、配置根的几位(user 设置层 `/` 规则那一问)与「请求成员读不出」那一问的
19
+ * 预判读的部署配置:执行车道的 home 两位(`~/` 形规则那一问)、配置根的几位(user 设置层 `/` 规则那一问)与「请求成员读不出」那一问的
40
20
  * 租户轴 / 两只注入闸的否决位。`ServiceConfig` 结构上满足,四个问点传 `deps.config` 整份。
41
21
  */
42
22
  export type StoredReplayDeployment = ExecutionConfigRootDeployment & UnreadMembersDeployment & {
43
- readonly autonomy?: Autonomy | undefined;
44
23
  /** 生效配置模型条目 name → `apiKeyEnv`(`settings.env` 凭据判据的名单一臂;缺席 = 没有模型条目,与 `serverCredentialValueSources` 的缺省同读)。 */
45
24
  readonly modelApiKeyEnv?: ModelApiKeyEnvTable | undefined;
46
25
  };
47
26
  /**
48
- * 四问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法(体里带非空 `allow` 而写者版本证不出 ≥ 7.117.0;常设,按写者版本)→ 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ 请求成员读不出〔hooks / env / MCP transport / A2A headers …,判据 `unread-request-members.ts`〕→ deny / ask 的名字层 + 规则文法)→ 模式词读法记号 → 体里的退役请求键(几问同中时答先中的那一问 ——
49
- * 任一问中都不重放,句子只需一句)。`deployment` = 本部署**此刻**的 `config`(活 config:热改即生效):`autonomy` 的地板由它的唯一属主算,`~/` 形规则的 home 由 `executionLaneHomeDir` 算,问点都不自己算。
27
+ * 三问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法(体里带非空 `allow` 而写者版本证不出 ≥ 7.117.0;常设,按写者版本)→ 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ 请求成员读不出〔hooks / env / MCP transport / A2A headers …,判据 `unread-request-members.ts`〕→ deny / ask 的名字层 + 规则文法)→ 体里的退役请求键(几问同中时答先中的那一问 ——
28
+ * 任一问中都不重放,句子只需一句)。`deployment` = 本部署**此刻**的 `config`(活 config:热改即生效):`~/` 形规则的 home 由 `executionLaneHomeDir` 算,问点都不自己算。
50
29
  */
51
30
  export declare function storedBodyReplayRefusal(ctx: CheckpointCtx, deployment: StoredReplayDeployment): StoredBodyReplayRefusal | undefined;
52
31
  //# sourceMappingURL=stored-body-replay.d.ts.map
@@ -1,7 +1,6 @@
1
- import { REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_PERMISSION_BUCKETS, SETTINGS_RULE_REFUSAL_CODE, neverAutoNamesRefusal, readSettingsEnv, rulePolicyBucketsRefusal, settingsEnvCredentialIssue, settingsPermissionBucketIssue, storedBodyPermissionMode } from "../task-settings.js";
1
+ import { REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_PERMISSION_BUCKETS, SETTINGS_RULE_REFUSAL_CODE, neverAutoNamesRefusal, readSettingsEnv, rulePolicyBucketsRefusal, settingsEnvCredentialIssue, settingsPermissionBucketIssue } from "../task-settings.js";
2
2
  import { readTightenOnlySeats, tightenOnlySeatField, tightenOnlySeatIssue } from "../tighten-only-seats.js";
3
3
  import { entryProblemsFacts } from "../entry-problems.js";
4
- import { autonomyModeFloor, entryPermissionMode } from "../runtime-governance.js";
5
4
  import { inertToolListEntryOf, replayInertEntry } from "../rule-entry-list.js";
6
5
  import { executionLaneHomeDir } from "../execution-lane-caps.js";
7
6
  import { executionConfigRootOf } from "../execution-config-root.js";
@@ -10,13 +9,7 @@ import { storedEnvCredentialsDropM38 } from "../stored-request-env-credentials-m
10
9
  import { storedToolAxesRereadM19 } from "../stored-request-tool-axes-m19.js";
11
10
  import { MAX_NAMED_MEMBERS, unreadRequestMembers, unreadRequestMembersRefusal } from "../unread-request-members.js";
12
11
  import { serverCredentialValueSources } from "../server-secret-env.js";
13
- import { allowListWriterUnproven, permissionModeReadingStated, retiredRequestKeyOf } from "./checkpoint-ctx.js";
14
- export function permissionModeReadingUnstated(ctx, floor) {
15
- if (floor === undefined || permissionModeReadingStated(ctx))
16
- return undefined;
17
- const stored = storedBodyPermissionMode(ctx.body);
18
- return entryPermissionMode(stored, floor).effective === stored ? undefined : { stored, floor };
19
- }
12
+ import { allowListWriterUnproven, retiredRequestKeyOf } from "./checkpoint-ctx.js";
20
13
  const RETIRED_KEY_REWRITE_MIGRATION = { promptProfile: "M30" };
21
14
  const BUCKET_GATE_CODE = "request.field_invalid";
22
15
  const BUCKET_SIDE = {
@@ -87,9 +80,6 @@ export function storedBodyReplayRefusal(ctx, deployment) {
87
80
  const entry = ruleTablesRefusalWithoutTaskRoot(ctx.body, deployment);
88
81
  if (entry !== undefined)
89
82
  return { kind: "inert_tool_list", entry };
90
- const mode = permissionModeReadingUnstated(ctx, autonomyModeFloor(deployment.autonomy));
91
- if (mode !== undefined)
92
- return { kind: "permission_mode_reading", ...mode, ...writer };
93
83
  const retiredKey = retiredRequestKeyOf(ctx.body);
94
84
  if (retiredKey !== undefined)
95
85
  return { kind: "retired_request_key", key: retiredKey, rewriteWindowEnd: migrationWindowEnd(RETIRED_KEY_REWRITE_MIGRATION[retiredKey]), ...writer };
@@ -31,7 +31,6 @@ export declare function persistSubmitCtx(store: SubmitCtxStore, deps: {
31
31
  readonly logger?: Logger | undefined;
32
32
  readonly metrics?: Metrics | undefined;
33
33
  readonly checkpointCtxSealing?: CheckpointCtxSealer | undefined;
34
- readonly instanceId?: string | undefined;
35
34
  }, claim: {
36
35
  readonly runStore: RunStore;
37
36
  readonly taskId: string;
@@ -41,7 +40,7 @@ export declare function persistSubmitCtx(store: SubmitCtxStore, deps: {
41
40
  * 提交腿写续跑输入的入口(三个调用点同调这一只):体与标记按受理座提交时交出的那一份定(见文件头「体里的目标按哪一份写」),只写这一笔。
42
41
  * 写不进的处置与答复 = {@link persistSubmitCtx}(本函数只定体、不另判)。
43
42
  */
44
- export declare function persistSubmissionCtx(store: SubmitCtxStore, deps: Parameters<typeof persistSubmitCtx>[1], claim: Parameters<typeof persistSubmitCtx>[2], prepared: Pick<PreparedTaskSubmission, "body" | "auth" | "verify" | "acceptance" | "bodyFromScreenedCtx"> & {
43
+ export declare function persistSubmissionCtx(store: SubmitCtxStore, deps: Parameters<typeof persistSubmitCtx>[1], claim: Parameters<typeof persistSubmitCtx>[2], prepared: Pick<PreparedTaskSubmission, "body" | "auth" | "verify" | "acceptance" | "bodyFromScreenedCtx"> & Partial<Pick<PreparedTaskSubmission, "legFacts">> & {
45
44
  readonly spec: Pick<PreparedTaskSubmission["spec"], "sessionId" | "model">;
46
45
  }): Promise<SubmitCtxRefusal | typeof SUBMIT_CTX_CLAIM_LOST | undefined>;
47
46
  //# sourceMappingURL=submit-ctx.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { StoreRowTooLargeError } from "../plugins/sql-errors.js";
2
2
  import { withdrawClaimedRun } from "./claimed-run.js";
3
- import { runProvenElsewhere } from "../plugins/store-contracts.js";
3
+ import { createLegCtxClaim } from "../plugins/store-contracts.js";
4
4
  import { buildCheckpointCtx, CheckpointCtxUnsealableError } from "./checkpoint-ctx.js";
5
5
  import { refusalBody } from "./refusal-body.js";
6
6
  import { limitFactsUnmeasured } from "../limit-refusal.js";
@@ -29,11 +29,11 @@ function unsealableRefusal(e) {
29
29
  function rowTooLargeRefusal(tooLarge) {
30
30
  switch (tooLarge.wall) {
31
31
  case "row":
32
- return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than the database keeps in one row (${tooLarge.dbMessage}) — nothing was run; shrink the inline images / userAttachments, or ask the operator to raise the database's single-row limit (TiDB performance.txn-entry-size-limit)`, facts: limitFactsUnmeasured("body", "bytes") }) };
32
+ return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than the database keeps in one row — nothing was run; shrink the inline images / userAttachments, or ask the operator to raise the database's single-row limit (TiDB performance.txn-entry-size-limit)`, facts: limitFactsUnmeasured("body", "bytes") }) };
33
33
  case "statement":
34
- return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than the database accepts in one statement (${tooLarge.dbMessage}) — nothing was run; shrink the inline images / userAttachments, or ask the operator to raise the database's max_allowed_packet`, facts: limitFactsUnmeasured("body", "bytes") }) };
34
+ return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than the database accepts in one statement — nothing was run; shrink the inline images / userAttachments, or ask the operator to raise the database's max_allowed_packet`, facts: limitFactsUnmeasured("body", "bytes") }) };
35
35
  case "value":
36
- return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than PostgreSQL holds in one value (${tooLarge.dbMessage}) — nothing was run; shrink the inline images / userAttachments`, facts: limitFactsUnmeasured("body", "bytes") }) };
36
+ return { status: 413, body: refusalBody({ errorCode: "request.payload_too_large", message: `the database refused to store this task: it is larger than PostgreSQL holds in one value — nothing was run; shrink the inline images / userAttachments`, facts: limitFactsUnmeasured("body", "bytes") }) };
37
37
  default: {
38
38
  const unhandled = tooLarge.wall;
39
39
  throw new Error(`row-too-large refusal without an HTTP answer: ${String(unhandled)}`);
@@ -44,7 +44,7 @@ export async function persistSubmitCtx(store, deps, claim, sessionId, fields) {
44
44
  let landed;
45
45
  try {
46
46
  const ctx = buildCheckpointCtx(fields, deps.checkpointCtxSealing, sessionId);
47
- landed = await store.putCtx(sessionId, ctx, claim === undefined ? undefined : { fence: claim.runStore, taskId: claim.taskId, legHolds: (run) => !runProvenElsewhere(run, deps.instanceId) });
47
+ landed = await store.putCtx(sessionId, ctx, claim === undefined ? undefined : createLegCtxClaim(claim.runStore, claim.taskId, claim.legId));
48
48
  }
49
49
  catch (err) {
50
50
  const tooLarge = err instanceof StoreRowTooLargeError ? err : undefined;
@@ -62,7 +62,7 @@ export async function persistSubmitCtx(store, deps, claim, sessionId, fields) {
62
62
  }
63
63
  if (tooLarge === undefined)
64
64
  throw err;
65
- deps.logger?.warn("submit_ctx_row_too_large", { sessionId, taskId: claim?.taskId, wall: tooLarge.wall, db: tooLarge.dbMessage });
65
+ deps.logger?.warn("submit_ctx_row_too_large", { sessionId, taskId: claim?.taskId, wall: tooLarge.wall });
66
66
  return rowTooLargeRefusal(tooLarge);
67
67
  }
68
68
  return landed === "claim_released" ? SUBMIT_CTX_CLAIM_LOST : undefined;
@@ -76,6 +76,8 @@ export async function persistSubmissionCtx(store, deps, claim, prepared) {
76
76
  body: screened && prepared.verify === undefined ? withheldBody(prepared.body, prepared.spec.model) : prepared.body,
77
77
  memoryScope: prepared.auth?.memoryScope,
78
78
  ...(screened || prepared.bodyFromScreenedCtx === true ? { promptScreened: true } : {}),
79
+ ...(prepared.legFacts?.projectContext !== undefined ? { projectContext: prepared.legFacts.projectContext } : {}),
80
+ ...(prepared.legFacts?.memorySeed !== undefined ? { memorySeed: prepared.legFacts.memorySeed } : {}),
79
81
  writerVersion: serviceVersion(),
80
82
  });
81
83
  }
@@ -9,7 +9,8 @@
9
9
  *
10
10
  * ## 判定(三条,按序;别的一律不放)
11
11
  * · 这次提交自带 taskId 而命中的行**不是**那一条(`Idempotency-Key` 指向别的行)⇒ 冲突;
12
- * · 调用方读不到这一行(属主门 = `qualsOf`,「这个调用方读得到这一行 run 吗」的唯一谓词,经属主存取器 `owner-access.ts` 读)⇒ 冲突;
12
+ * · 调用方读不到这一行(属主门 = `qualsOf`,「这个调用方读得到这一行 run 吗」的唯一谓词,经属主存取器 `owner-access.ts` 读与判 —— 按钥匙读行也只在那里:
13
+ * `readReplayHit`;建行撞唯一键时观察到的行经同一只判 `replayHitOf`)⇒ 冲突;
13
14
  * 冲突 ⇒ `409 conflict.run_exists`,体里**不回显**那条行的任何标识(不给跨租户预言机)。先于下一条判:读不到的行不比体。
14
15
  * · 这次提交带 `Idempotency-Key`(`caller.idem` 在场)、那一行绑的**就是这把键**,而它记着的请求体指纹与这次不同 ⇒
15
16
  * `409 conflict.idempotency_payload_mismatch`(同形 `{ error, errorCode }`,不回显键与那一行);**不**回放首发、不新建、那一行不动。
@@ -33,6 +34,7 @@ import type { RunIdemBinding, RunRecord } from "../plugins/store-contracts.js";
33
34
  import type { RunStore } from "../plugins/store-backend.js";
34
35
  import type { ServiceConfig } from "../config-types.js";
35
36
  import type { SubmitOutcome } from "./idempotency.js";
37
+ import { type ReplayHit } from "./owner-access.js";
36
38
  import type { Subject } from "../owner-brands.js";
37
39
  /** 提交腿的回执形(闭集;穷举 `switch`,加一形不写这里 = 编译红)。 */
38
40
  export type SubmitReplayFace = "durable" | "sync";
@@ -56,7 +58,18 @@ export declare function isReplayedOutcome(outcome: SubmitOutcome): boolean;
56
58
  /** 一份提交回执是不是 {@link replayOfExistingRun} 铸的**冲突**体(判别位 = 机器码;铸点就在下面,码与它同文件)—— 把回执渲成别的协议形的
57
59
  * 调用方(A2A)按它分句,不另抄码。 */
58
60
  export declare function isRunExistsConflictBody(body: unknown): boolean;
61
+ /** 进门按一把提交钥匙(`Idempotency-Key` 铸的键 / 调用方自铸的 `body.taskId`)读行作答:没命中 ⇒ `undefined`(这是一次新提交);命中 ⇒ 本文件的唯一回执。 */
62
+ export declare function replayOfKey(key: {
63
+ readonly idemKey: string;
64
+ } | {
65
+ readonly taskId: string;
66
+ }, caller: ReplayCaller, face: SubmitReplayFace, deps: {
67
+ config: ServiceConfig;
68
+ }, runStore: Pick<RunStore, "getRun" | "getRunByIdem" | "bindIdemBodyFingerprint" | "observeRun">): Promise<SubmitOutcome | undefined>;
69
+ /** 建行撞唯一键时观察到的那一行(店的观察臂交回的既有行)作答:与按钥匙读到的同一只判、同一张回执。 */
59
70
  export declare function replayOfExistingRun(seen: RunRecord, caller: ReplayCaller, face: SubmitReplayFace, deps: {
60
71
  config: ServiceConfig;
61
- }, runStore: RunStore): Promise<SubmitOutcome>;
72
+ }, runStore: Pick<RunStore, "bindIdemBodyFingerprint" | "observeRun">): Promise<SubmitOutcome>;
73
+ /** 一次命中的回执(判已在属主存取器里落成 {@link ReplayHit}):占用 ⇒ 冲突;读得到 ⇒ 体指纹 → 观察口 → 按提交腿的形答。 */
74
+ export declare function answerReplay(hit: ReplayHit, caller: ReplayCaller, face: SubmitReplayFace, runStore: Pick<RunStore, "bindIdemBodyFingerprint" | "observeRun">): Promise<SubmitOutcome>;
62
75
  //# sourceMappingURL=submit-replay.d.ts.map
@@ -1,5 +1,4 @@
1
- import { runRowAt, seesRunAs } from "./owner-access.js";
2
- import { claimCallerOf } from "../security.js";
1
+ import { readReplayHit, replayHitOf, runRowAt } from "./owner-access.js";
3
2
  import { syncSubmitBodyOfRow } from "./sync-submit-body.js";
4
3
  import { refusalBody } from "./refusal-body.js";
5
4
  export function replayedOutcome(outcome) {
@@ -15,11 +14,18 @@ export function isReplayedOutcome(outcome) {
15
14
  export function isRunExistsConflictBody(body) {
16
15
  return typeof body === "object" && body !== null && body.errorCode === "conflict.run_exists";
17
16
  }
17
+ export async function replayOfKey(key, caller, face, deps, runStore) {
18
+ const hit = await readReplayHit(caller.subject, deps.config, runStore, key, caller.clientTaskId);
19
+ return hit === undefined ? undefined : answerReplay(hit, caller, face, runStore);
20
+ }
18
21
  export async function replayOfExistingRun(seen, caller, face, deps, runStore) {
19
- const sameRun = caller.clientTaskId === undefined || caller.clientTaskId === seen.taskId;
20
- if (!sameRun || !seesRunAs("run.replay", claimCallerOf(caller.subject, deps.config), seen.owner)) {
22
+ return answerReplay(replayHitOf(caller.subject, deps.config, seen, caller.clientTaskId), caller, face, runStore);
23
+ }
24
+ export async function answerReplay(hit, caller, face, runStore) {
25
+ if (hit.kind === "occupied") {
21
26
  return { status: 409, body: refusalBody({ errorCode: "conflict.run_exists", message: "a run already exists for this submission's taskId or Idempotency-Key" }) };
22
27
  }
28
+ const seen = hit.row;
23
29
  if (caller.idem !== undefined) {
24
30
  const held = await runStore.bindIdemBodyFingerprint(seen.taskId, caller.idem);
25
31
  if (held !== null && held !== caller.idem.bodyFingerprint) {
@@ -41,6 +41,14 @@ export interface TaskRequestAttachments {
41
41
  export interface TaskRequestBody {
42
42
  objective: string;
43
43
  sessionId?: string;
44
+ /**
45
+ * 这一次提交建的会话是哪一**种**(闭集一词 `"sidechain"` = 客户端放置的子代对话;缺席 = 顶层对话;律在 `session-kind.ts`)。
46
+ * 只在**建这只会话的那一笔**写下(不带 `sessionId` / 带一只还不存在的 id),此后终身不改:带键提交到一只既有的会话 ⇒ 种类相等照常、不等 409
47
+ * `conflict.session_kind_mismatch`(会话一字节不变,体上机读位 `sessionKind` = 行上的词,顶层行缺席);不带键 = 不声明(续轮不必重发)。
48
+ * 词表外 ⇒ 400 `request.field_invalid`;部署记不了种类(能力位 `sessionKinds` 为空)⇒ 400 `request.precondition_unmet`,都在任何写之前。
49
+ * 续跑腿不读不判(键随存体留着)。
50
+ */
51
+ sessionKind?: "sidechain";
44
52
  /** Which deployment SCENARIO assembles this task's tools/prompt/skills (the keys of the worker's scenario
45
53
  * table — e.g. "default"/"code"/"code-review"/"scan"/"cowork"). An INTENT bounded by the deployment's own table AND,
46
54
  * on a governed worker, by the principal's center-resolved allowlist: an unknown name is a typed 400
@@ -109,7 +117,8 @@ export interface TaskRequestBody {
109
117
  * `RunnerDeps.loadProjectMemory` —— 项目层、声明的指令文件、它们喂的那几处一并缺席(引擎自己的 git 状态车道、记忆引擎、技能 / hooks / MCP 不受影响)。
110
118
  * 原样投给引擎;拼写门与 `fileHistory` 同一张单成员关断词表(`request-value-closure.ts`:别的值 fresh 400 `request.field_invalid`、续跑重放同判),
111
119
  * 引擎读到的恒是这一个词;子代随父继承(引擎的夹紧表)。
112
- * 本服务自铸的 `wiring_manifest.instructions` 段在这样的腿上缺席(loader 没被调就没有陈述)。能力位 `projectMemory`。 */
120
+ * 本服务自铸的 `wiring_manifest.instructions` 段在这样的腿上缺席(loader 没被调就没有陈述)。能力位 `projectMemory`。
121
+ * 7.150.0 起同一个词也关掉这条 run 从项目登记簿继承的项目简报(`project-context.ts`;继承来的 `cwd` 不受它管 —— 位置不是上下文内容)。 */
113
122
  projectMemory?: TaskSpec["projectMemory"];
114
123
  /** Explicit model selection (CLI `/model` picker + `run --model <ref>`). An INTENT by catalog
115
124
  * name (e.g. "deepseek-pro") — resolveSpec gates it against the SAME allow-list as an inline `@name` mention
@@ -239,7 +248,9 @@ export interface TaskRequestBody {
239
248
  * (unknown ⇒ 404 `rewind_files_to.unknown_event`). Honored ONLY when `resumeAt` is ABSENT (the two modes are mutually
240
249
  * exclusive). Requires the anchor map + a FileHistoryStore + the session store's head read (capability
241
250
  * `rewindFilesTo`). Its out-of-run twin — no run, no model call — is `POST /v1/sessions/:id/rewind-files` with the same
242
- * handle in `to` (capability `sessionRewindFiles`). */
251
+ * handle in `to` (capability `sessionRewindFiles`). Not accepted together with `cascade: true` — the ladder's rungs
252
+ * run on sessions the engine mints, so there is no history of this session to restore from ⇒ 400 `request.field_conflict`
253
+ * (`reason: "cascade_verify"`, `fields: ["rewindFilesTo", "cascade"]`) at admission, before any side effect. */
243
254
  rewindFilesTo?: string;
244
255
  /** [ref](core 7.31.0 [ref] `TaskSpec.fileHistory`)—— 请求级的**文件历史关断词**,唯一词 `"disabled"`(core 的拼法,
245
256
  * 与 `checkpointStore` 同;没有 `"enabled"` —— 缺席就是「部署说了算」的唯一形,声明只能单向收紧)。`"disabled"` ⇒
@@ -448,9 +459,11 @@ export interface TaskRequestBody {
448
459
  * authorizer(core `PROJECT_ID_REGEX`,不合形状=422 typed `invalid_project_id`)。**大小写不敏感收、
449
460
  * 归一小写用**([ref]/[ref]:词法与 core 的格式单源对齐,带 /i;收下后折小写再派生 scope/查表 ——
450
461
  * 同一个 id 的两种大小写写法落同一只记忆盘)。多租户 DB 记忆面下它把派生
451
- * scope 从 user 盘切到项目盘(`proj:<tenant>/<projectId>`)并以 config.projects[projectId].defaultScopes
452
- * 作 memory.scopes 种子;单用户部署忽略派生(memoryScopeFor 不变),仅 defaultScopes 种子生效。
453
- * Rides the persisted body onto resume legs(与 memoryWrite 同姿势)。 */
462
+ * scope 从 user 盘切到项目盘(`proj:<tenant>/<projectId>`);它对提交者**可见**时(`project-registry.ts`,与 `GET /v1/projects/:id` 同一只判)
463
+ * 那只登记的 defaultScopes 作 memory.scopes 种子(看不见 / 未登记 ⇒ 无种子,同答);单用户部署忽略派生(memoryScopeFor 不变),仅种子生效。
464
+ * Rides the persisted body onto resume legs(与 memoryWrite 同姿势)—— 种子不随体:续跑腿只认提交腿冻结的种子(`CheckpointCtx.memorySeed`,以冻结的观者重判)。
465
+ * 7.150.0 起它(或会话行上声明过的项目)也选这条 run **继承的项目上下文**(`project-context.ts`;能力位 `projectInheritance`):登记对提交者可见且带内容证明 ⇒
466
+ * 项目简报进系统提示追加折叠的中段、射程内第一条 folder 填缺席的 `cwd`;判一次、随 run 冻结。项目继承来的成员参与的拒,`fields` 以本键为坐标。 */
454
467
  projectId?: string;
455
468
  /** [#40 / TOC cwd seam, SDK 0.0.36] The TOC client's launch directory — the agent's HOST execution-env workspace
456
469
  * runs HERE (CC-parity: `sema` in a project dir operates on THAT project). An ABSOLUTE host path. 🔒 honored ONLY
@@ -572,7 +585,7 @@ export interface TaskRequestBody {
572
585
  * `transport.env`(stdio)/ `transport.headers`(http)是这台 server 的**件**:server 交给引擎的声明里不带它们,件由部署的对端座在起子进程 / 发请求时按原字节作答
573
586
  * (只对胜出部署同名判的条目登记;件的名与值由引擎在每次发送时判,不合 ⇒ 那一台不连、兄弟照挂)。 */
574
587
  mcpServers?: RequestMcpServerSpec[];
575
- /** [DESIGN-269 车1] Caller-supplied per-request A2A peers (remote agents this task may call), aligned to
588
+ /** [[ref] 车1] Caller-supplied per-request A2A peers (remote agents this task may call), aligned to
576
589
  * core `A2aServerSpec`. 🔒 honored on a SINGLE-USER deployment (task-a2a.ts `a2aInjectionHonored`, the same
577
590
  * predicate `capabilities.a2aInjection` advertises) — the requester is the super-admin of their OWN worker,
578
591
  * on ANY execution lane (an A2A call is a plain outbound HTTPS request from the worker, so the lane where
@@ -2,7 +2,7 @@
2
2
  * **身份来源闭集 + run 行身份元组** —— 叶子模块(零依赖):凭据门(`http/principal-gate.ts`)、run 店契约(`plugins/store-contracts.ts`)、
3
3
  * 三只 run 店与 leader run 店(`plugins/leader-run-store-sql.ts`)、中央建表语句(`plugins/tidb-pool.ts` / `plugins/pg-pool.ts`)与 `/health` 自报位读同一份。
4
4
  *
5
- * ## 律(三句;全仓只在这里写一次)
5
+ * ## 律(五条;全仓只在这里写一次)
6
6
  * 1. **一张表、一个次序**:{@link IDENTITY_SOURCES} 的序 = 凭据门的判定次序(`verifiedIdentitySource` 答表里第一个验得过的词)= `/health.auth.kinds` 的出现序。
7
7
  * 出示了部署的 service 凭据就是 `service_token` —— 哪怕同一枚 Bearer 也被鉴权桥验成登录令牌、哪怕运维给这枚凭据起的系统名叫 `sso`;
8
8
  * 验不过 service 凭据而鉴权桥挂了身份 ⇒ `sso`;都没有而直连门 principal 令牌验过 ⇒ `direct_door_jwt`。
@@ -15,6 +15,10 @@
15
15
  * 4. **令牌声明装不进它的列就不记**(不截断:截断 = 两个不同的值折成一个):`sso` 臂从验过的令牌铸元组时,某一格装不进它的列宽({@link RUN_IDENTITY_CLAIM_COLUMNS})
16
16
  * ⇒ 那一格「未记录」—— 可空的格(化身号)记 `null`;必填的格(scope)装不下就铸不出合形元组 ⇒ 无元组。两格结果不同来自元组的型,不是两条规则:
17
17
  * 同一只判({@link runIdentityClaimOverflow})、同一行告警 `run_identity_claim_unrecorded { claim, chars, max }`(凭据门的铸点发;只名与长度,不带值)。
18
+ * 5. **凭据门认哪几类来源,一列答**({@link passesCredentialGate}):service 凭据与鉴权桥验过的登录令牌过门,直连门 principal 令牌不过(它只证审批决定者是谁)。
19
+ * 两道门读这同一列、各问各的事:全局凭据门(401)只在部署配了 service 凭据时武装({@link hasServiceAuth});fail-closed 写门(503:计费提交 / bake / 改写门 /
20
+ * 破坏性会话写 / 停驻赎回开新腿)恒武装,问的是**这次请求**带没带过门的凭据,`ALLOW_UNAUTHED_WRITES` 是它唯一的逃生口 —— 写门不读任何部署级布尔:
21
+ * 部署接没接过门的来源,落在「这次请求验不验得出」里(没接 ⇒ 没有一次请求验得出 ⇒ 照拒)。
18
22
  *
19
23
  * 化身号 `principalInc`:令牌 `sub_inc` 声明原样(契约包 `VerifiedIdentity.principalInc`)。来源链只有一条 —— 验证器读出 → 注入边界再判形(`auth-bridge.ts` 的
20
24
  * `admitBridgeIdentity`)→ 入口预认证挂 request-local(`security.ts` 的 `setSsoPrincipalInc`)→ 凭据门 `admitRunIdentity` 的 `sso` 臂铸进元组(律 4)→ 建行原样写入。
@@ -46,9 +50,22 @@ export declare function authBridgeIssuerOf(config: Pick<IdentitySourceConfig, "a
46
50
  readonly issuer: string;
47
51
  readonly source: "explicit" | "fallback";
48
52
  } | undefined;
49
- /** 「这台部署配了任何一把 service 凭证吗」—— fail-closed 写门族的真值源,也是身份来源 `service_token` 接没接线的那一句。**单一属主**:全局凭据门(`http/dispatch.ts`)、
50
- * 停驻行的赎回席(`http/approval-sweeps.ts`)、记忆整理阀门的启动期告警(`boot/stage-06-runners.ts`)、以及 {@link configuredIdentitySources} 读同一句(手抄迟早只改一处,而这条判据决定的是「无凭证部署上写口开不开」)。 */
53
+ /**
54
+ * 「这台部署配了任何一把 service 凭证吗」—— 身份来源 `service_token` 接没接线的那一句,也是**全局凭据门的武装谓词**(配了 ⇒ 门后各口不带过门凭据就 401;
55
+ * 没配 ⇒ 门不武装,写门照样只认过门的凭据,见文件头律 5)。**单一属主**(手抄迟早只改一处):全局凭据门的武装(`http/dispatch.ts`)、门前读路谓词与 `/health` 读者档
56
+ * (同文件 `readCredentialOk` / `healthReaderOf`,问的都是「门武装没有」)、监听收窄与两条单用户边界不变量(`bind-host.ts` 的 `bindMustNarrow`,`config-invariants.ts`)、
57
+ * 多租无 fleet 凭据的启动期告警(`boot/stage-07-capability-layer.ts`)、以及 {@link configuredIdentitySources} 读同一句。**不是**写门的判据(写门问请求,律 5)。
58
+ */
51
59
  export declare function hasServiceAuth(config: Pick<IdentitySourceConfig, "authToken" | "authTokens">): boolean;
60
+ /** 凭据门认的那几类来源(律 5;{@link passesCredentialGate} 收窄到它)。 */
61
+ export type CredentialGateSource = Extract<IdentitySource, "service_token" | "sso">;
62
+ /**
63
+ * 🔴 **律 5 的那一列:这一类来源过不过凭据门**(缺席 = 这次请求没有验过的来源 ⇒ 不过)。service 凭据是部署发的凭据;鉴权桥验过的登录令牌由本部署信任的签发方签、
64
+ * 主体就是令牌里的那一位(主体头盖不过它);直连门 principal 令牌只证审批决定者是谁,从来不替代凭据。穷举:加一个来源不接这里 ⇒ 编译红。
65
+ * 读者:全局凭据门的 401 与 fail-closed 写门的 503(`http/dispatch.ts`,读同一次 `verifiedIdentitySource` 的答案)、停驻赎回席(`http/approval-sweeps.ts`)、
66
+ * 以及它在部署上的投影 —— 部署形表行 `credentialGateSource`(`deployment-shape.ts`;请求面不读那一行,写门问的是请求)。
67
+ */
68
+ export declare function passesCredentialGate(kind: IdentitySource | undefined): kind is CredentialGateSource;
52
69
  /**
53
70
  * 🔴 **「这台部署能回哪几个身份来源」的唯一读法**({@link IDENTITY_SOURCES} 里配置接了线的那几个词,序同表)。读者:部署形表的 `identity` 轴
54
71
  * (`deployment-shape.ts`,「有没有身份边界」那一行由它答)、`/health.auth`(自报位,`http/health-self-report.ts`)、server-as-peer 受众门(`http/server.ts`)。
@@ -23,6 +23,20 @@ function identitySourceConfigured(kind, config) {
23
23
  }
24
24
  }
25
25
  }
26
+ export function passesCredentialGate(kind) {
27
+ switch (kind) {
28
+ case "service_token":
29
+ case "sso":
30
+ return true;
31
+ case "direct_door_jwt":
32
+ case undefined:
33
+ return false;
34
+ default: {
35
+ const unknownKind = kind;
36
+ throw new Error(`identity sources: unknown identity source ${String(unknownKind)}`);
37
+ }
38
+ }
39
+ }
26
40
  export function configuredIdentitySources(config) {
27
41
  return IDENTITY_SOURCES.filter((k) => identitySourceConfigured(k, config));
28
42
  }
package/dist/index.d.ts CHANGED
@@ -41,5 +41,9 @@ export { judgeServedModelRoute, type ServedModelRouteView, type ServedModelRoute
41
41
  export type { UserInputLedgerStore, UserInputAcceptance, NewUserInputAcceptance, OpenScanCursor, OpenScanPage, SettleHow, WriterGoneEvidence } from "./user-input-ledger.js";
42
42
  export type { OrgDeliveryQuotaStore, OrgDeliveryQuotaPolicy, OrgDeliveryQuotaVerdict } from "./plugins/org-delivery-quota-store.js";
43
43
  export type { ServerOrgDeliveryGate, ServerOrgDeliveryOutcome } from "./org-delivery-gate.js";
44
+ export type { LandedAttendantSeat, LandedAnchor, FileHistoryReplayResult, FileHistoryReplayFailure } from "./plugins/landed-attendants.js";
45
+ export type { LandedOutcome } from "./session-row.js";
46
+ export type { SessionFace } from "./session-incarnation.js";
47
+ export type { BlobGetter } from "./session-sync.js";
44
48
  export { APPROVAL_GATE_KINDS, type ApprovalGateKind } from "./approval-content-kind.js";
45
49
  //# sourceMappingURL=index.d.ts.map