@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
@@ -15,6 +15,10 @@ import { acceptShellScratchpadDir, buildEnvFacts, egressForRemoteExec, ensureScr
15
15
  import { FleetEventBus } from "../fleet/fleet-bus.js";
16
16
  import { createSettingsHooksRegistrations, settingsHooksBudgetMs } from "../hooks/hook-runner.js";
17
17
  import { headerStr } from "../http/principal-gate.js";
18
+ import { routeListFilter } from "../http/owner-access.js";
19
+ import { projectRegistry } from "../capability-facts.js";
20
+ import { projectContextOf } from "../project-context.js";
21
+ import { memorySeedOf, memorySeedScopesOf } from "../project-registry.js";
18
22
  import { explicitOperatorOk } from "../http/server.js";
19
23
  import { isAtMentionable, matchCatalogModel, pickUserModel, refusedCatalogEntry, terminalCatalogName } from "../model-select.js";
20
24
  import { echoModelRef, modelNotAllowedMessage, modelUnavailableMessage, refusedNameLogField } from "../model-entry-refusal.js";
@@ -48,7 +52,7 @@ import { storedToolAxesRereadM19 } from "../stored-request-tool-axes-m19.js";
48
52
  import { storedHooksRereadM20 } from "../stored-request-hooks-m20.js";
49
53
  import { storedEnvCredentialsDropM38 } from "../stored-request-env-credentials-m38.js";
50
54
  import { serverCredentialValueSources } from "../server-secret-env.js";
51
- import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_RULE_REFUSAL_CODE, SettingsRuleRefusalError, acceptAppendSystemPrompt, applyTaskSettings, createWorkflowAskPolicy, effectivePermissionMode, effectiveThinking, parseTaskSettings, readSettingsEnv, taskHooksHonored, settingsEnvCredentialIssue, settingsPermissionBucketIssue, withoutKeys } from "../task-settings.js";
55
+ import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_RULE_REFUSAL_CODE, SettingsRuleRefusalError, acceptAppendSystemPrompt, acceptOutputStyle, appendFold, applyTaskSettings, createWorkflowAskPolicy, effectivePermissionMode, effectiveThinking, parseTaskSettings, readSettingsEnv, taskHooksHonored, settingsEnvCredentialIssue, settingsPermissionBucketIssue, withoutKeys } from "../task-settings.js";
52
56
  import { tightenOnlySeatIssue } from "../tighten-only-seats.js";
53
57
  import { buildNeverAutoRetiredNotice } from "../retired-name-host-notice.js";
54
58
  import { entryProblemsFacts } from "../entry-problems.js";
@@ -60,6 +64,7 @@ import { DeferredSandboxPathEnv, sandboxPathEnvSlots } from "./deferred-sandbox-
60
64
  import { executionLaneHomeDir, executionLaneOf, laneIsolated, laneWiresExecutionEnv } from "../execution-lane-caps.js";
61
65
  import { executionConfigRootOf } from "../execution-config-root.js";
62
66
  import { withUnattendedLeg } from "../unattended-permission-mode.js";
67
+ import { bindingsOf } from "../session-bindings.js";
63
68
  import { fieldConflictFacts } from "../field-conflict.js";
64
69
  function identityAxesOf(auth) {
65
70
  const subject = auth?.subject === undefined ? undefined : recoveredSubject(auth.subject);
@@ -71,7 +76,7 @@ function unrooted(spec) {
71
76
  return resolved;
72
77
  }
73
78
  export function createResolveSpec(ctx) {
74
- const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, belowTaskChainPatterns, fleetBus, hookWakeBus, historyAnchors, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, loadedSkills, peerDesk, } = ctx;
79
+ const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, fenceSessionOwner, hookLlm, hookAgent, belowTaskChainPatterns, fleetBus, hookWakeBus, historyAnchors, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection, questionSeat, approverSeat, lockedKeys, loadedSkills, peerDesk, } = ctx;
75
80
  const deploymentSkillSources = new Map(loadedSkills.map((k) => [k.spec.name, k.source]));
76
81
  const scenarioGate = createScenarioGate({ config, scenarios, principalCaps, logger }, "enforce");
77
82
  const sessionHeadOf = headReadOf(ownerAware);
@@ -82,10 +87,10 @@ export function createResolveSpec(ctx) {
82
87
  approvalSeat: durableEnabled ? "durable" : "absent",
83
88
  singleUserAutoAcceptBaseline: singleUserAutoAcceptBaselineApplies(config),
84
89
  });
85
- const realTaskRootOf = (root) => {
90
+ const realTaskRootOf = (legSessionCwd) => {
86
91
  if (DEPLOYMENT_SHAPE_PREDICATES.sandboxPathAdjudication.holds(config))
87
92
  return undefined;
88
- const sessionCwd = effectiveHostWorkspace(perSessionCwd.get(root), {});
93
+ const sessionCwd = effectiveHostWorkspace(legSessionCwd, {});
89
94
  return sessionCwd ?? (laneWiresExecutionEnv(config.remoteExec.provider) ? undefined : process.cwd());
90
95
  };
91
96
  const memoryProjectLayers = createMemoryProjectLayers({ stores: memoryEngine, syncRunner: memorySyncRunner, log: logger });
@@ -109,9 +114,45 @@ export function createResolveSpec(ctx) {
109
114
  }
110
115
  if (opts?.leg === "fresh")
111
116
  assertRequestMcpEntries(body.mcpServers);
117
+ const submittedProjectId = auth?.resolvedProjectId ?? (typeof body.projectId === "string" && body.projectId ? body.projectId.toLowerCase() : undefined);
118
+ const legProjectId = await legProjectIdOf(submittedProjectId, sessionWorkspace, root);
119
+ const registryFact = projectRegistry({ config });
120
+ const registry = registryFact.available ? registryFact.registry : undefined;
121
+ const projectViewer = opts?.leg === "fresh" && req !== undefined ? routeListFilter(req, { config }, "project-get") : undefined;
122
+ const memorySeed = opts?.leg === "fresh" ? memorySeedOf(registry, submittedProjectId, projectViewer) : opts?.memorySeed;
123
+ if (opts?.leg !== "fresh" && memorySeed === undefined && submittedProjectId !== undefined)
124
+ logger.warn("resume_memory_seed_unjudged", { sessionId: root, projectId: submittedProjectId, note: "this continuation's stored rebuild input carries no memory-seed judgment (it was parked before this server version judged one), so the project registry's default read layers are not applied to it; submit the work again as a new task to have them" });
125
+ let projectContext;
126
+ if (opts?.leg === "fresh") {
127
+ const decision = projectContextOf({
128
+ projectId: legProjectId,
129
+ registry,
130
+ viewer: projectViewer,
131
+ pathsHonored: DEPLOYMENT_SHAPE_PREDICATES.callerOwnsWorkerDisk.holds(config),
132
+ requestCwd: typeof body.cwd === "string" && body.cwd.length > 0,
133
+ projectMemoryOff: body.projectMemory === "disabled",
134
+ });
135
+ projectContext = decision.context;
136
+ if (decision.withheldPathItems > 0)
137
+ logger.warn("task_project_paths_ignored", { lane: config.remoteExec.provider, pathItems: decision.withheldPathItems, sessionId: root });
138
+ if (projectContext?.brief !== undefined) {
139
+ const append = acceptAppendSystemPrompt(body.appendSystemPrompt);
140
+ const style = acceptOutputStyle(body.settings?.outputStyle);
141
+ const fold = appendFold([append, projectContext.brief, style]);
142
+ if (fold.chars > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
143
+ const members = append !== undefined ? ["appendSystemPrompt", "projectId"] : ["projectId"];
144
+ if (style !== undefined)
145
+ members.push("settings.outputStyle");
146
+ throw new HttpError(400, `the project brief this run inherits from project ${projectContext.projectId} (its goal, notes and context items) folds into one system-prompt block with appendSystemPrompt and settings.outputStyle — combined they must be at most ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} characters (including the 2-char joiners), and they are ${fold.chars}. Shorten what you send, send projectMemory: "disabled" to run without the project's context, or have the project's goal / notes shortened in the registry.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("system_prompt_fold", members, { count: fold.chars, cap: MAX_SETTINGS_OUTPUT_STYLE_CHARS }) } });
147
+ }
148
+ }
149
+ }
150
+ else
151
+ projectContext = opts?.projectContext;
152
+ const legCwd = projectContext?.cwd ?? body.cwd;
112
153
  if (opts?.leg === "fresh") {
113
154
  const conflict = scratchpadCoveringTaskRoot({
114
- cwd: body.cwd,
155
+ cwd: legCwd,
115
156
  shellScratchpadDir: body.scratchpadDir,
116
157
  localDataRoot: config.localDataRoot ?? localRoot,
117
158
  sessionId: root,
@@ -119,7 +160,11 @@ export function createResolveSpec(ctx) {
119
160
  callerOwnsWorkerDisk: DEPLOYMENT_SHAPE_PREDICATES.callerOwnsWorkerDisk.holds(config),
120
161
  });
121
162
  if (conflict) {
122
- throw new HttpError(400, `cwd "${conflict.cwd.asSpelled}" is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Point cwd at the project directory instead (or send no cwd and let the session keep the one it has): this session registers the cwd you send, so a task that happens not to mount the write gate would still leave every LATER task on this session rooted in the exemption. A workflow that really is meant to write without prompts says so with a knob that means it (a permission mode, an open write face) and still keeps its root outside the scratchpad — those knobs do not lift this refusal, because the conflict is between two fields of this request, not a permission level.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("scratchpad_root", body.scratchpadDir === conflict.scratchpadDir.asSpelled ? ["cwd", "scratchpadDir"] : ["cwd"]), cwd: conflict.cwd, scratchpadDir: conflict.scratchpadDir } });
163
+ const cwdCoordinate = projectContext?.cwd !== undefined ? "projectId" : "cwd";
164
+ const fields = body.scratchpadDir === conflict.scratchpadDir.asSpelled ? [cwdCoordinate, "scratchpadDir"] : [cwdCoordinate];
165
+ throw new HttpError(400, cwdCoordinate === "projectId"
166
+ ? `the working directory "${conflict.cwd.asSpelled}" this run inherits from project ${projectContext?.projectId} (its first folder) is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Send a cwd outside the scratchpad with this request, or have the project's first folder moved out of it in the registry.`
167
+ : `cwd "${conflict.cwd.asSpelled}" is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Point cwd at the project directory instead (or send no cwd and let the session keep the one it has): this session registers the cwd you send, so a task that happens not to mount the write gate would still leave every LATER task on this session rooted in the exemption. A workflow that really is meant to write without prompts says so with a knob that means it (a permission mode, an open write face) and still keeps its root outside the scratchpad — those knobs do not lift this refusal, because the conflict is between two fields of this request, not a permission level.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("scratchpad_root", fields), cwd: conflict.cwd, scratchpadDir: conflict.scratchpadDir } });
123
168
  }
124
169
  }
125
170
  const offFieldIssue = singleMemberOffFieldIssue(body);
@@ -191,12 +236,12 @@ export function createResolveSpec(ctx) {
191
236
  const gated = await gateScenarioAndAppend(body, auth, root, opts, settingsEnv);
192
237
  const effMode = effectivePermissionMode(body, gated.parsedSettings.settings);
193
238
  assertWriteFaceAdmitted(effMode, config);
194
- const lane = bindSettingsCwdEnvAndModel(body, auth, root, gated, opts);
195
- const anchors = await resolveHistoryAnchors(body, req, auth, root);
196
- const projectKey = memoryEngine ? await memoryProjectLayers.prepare(config, auth?.memoryScope, realTaskRootOf(root)) : undefined;
239
+ const lane = judgeSettingsCwdEnvAndModel(body, auth, root, gated, opts, legCwd);
240
+ const anchors = await resolveHistoryAnchors(body, req, auth, root, memorySeedScopesOf(registry, memorySeed), legProjectId);
241
+ const projectKey = memoryEngine ? await memoryProjectLayers.prepare(config, auth?.memoryScope, realTaskRootOf(lane.sessionCwd)) : undefined;
197
242
  const runSkills = buildRunSkills({ scenario: gated.cap.skills, request: body.skills, disable: body.disableSkills === true, deploymentSources: deploymentSkillSources }, logger);
198
- const spec = assembleSpecLiteral(body, auth, root, req, opts, { ...gated, ...lane, ...anchors, projectKey, a2aPeers, storedToolAxes, runSkills }, effMode);
199
- const folded = await foldGovernanceAndSettings(body, auth, root, spec, gated);
243
+ const spec = assembleSpecLiteral(body, auth, root, req, opts, { ...gated, ...lane, ...anchors, projectKey, a2aPeers, storedToolAxes, runSkills, projectBrief: projectContext?.brief }, effMode);
244
+ const folded = await foldGovernanceAndSettings(body, auth, root, spec, gated, projectContext?.brief, lane.sessionCwd);
200
245
  const retiredNotice = opts.onNotice !== undefined ? buildNeverAutoRetiredNotice(gated.parsedSettings.settings?.tightenOnly?.neverAuto, root) : undefined;
201
246
  if (retiredNotice !== undefined)
202
247
  opts.onNotice?.(retiredNotice);
@@ -205,8 +250,7 @@ export function createResolveSpec(ctx) {
205
250
  scratchpadDir: folded.scratchpadDir,
206
251
  hostSemanticsLane: folded.hostSemanticsLane,
207
252
  });
208
- const registeredCwd = perSessionCwd.get(root);
209
- return { spec: final, facts: { hands: gated.hands, skills: runSkills.roster, sessionWitness: gated.sessionWitness, ...(registeredCwd !== undefined ? { registeredCwd } : {}) } };
253
+ return { spec: final, facts: { hands: gated.hands, skills: runSkills.roster, sessionWitness: gated.sessionWitness, sessionBindings: lane.sessionBindings, ...(projectContext !== undefined ? { projectContext } : {}), ...(memorySeed !== undefined ? { memorySeed } : {}) } };
210
254
  };
211
255
  const gateScenarioAndAppend = async (body, auth, root, opts, settingsEnv) => {
212
256
  const { parts: subjectParts, person } = identityAxesOf(auth);
@@ -264,22 +308,24 @@ export function createResolveSpec(ctx) {
264
308
  }
265
309
  return { scenarioName, cap, hands: cap.hands, acceptedAppend, objective, parsedSettings, attachmentNotice, sessionWitness };
266
310
  };
267
- const bindSettingsCwdEnvAndModel = (body, auth, root, gated, opts) => {
311
+ const judgeSettingsCwdEnvAndModel = (body, auth, root, gated, opts, cwd) => {
268
312
  const { objective, parsedSettings } = gated;
269
313
  const cwdWriteGate = DEPLOYMENT_SHAPE_PREDICATES.callerCwd.holds(config);
270
314
  const execLane = config.remoteExec.provider;
271
315
  fenceSessionOwner(root, auth?.subject ?? null, opts.execution.occupant?.incarnation);
272
- if (typeof body.cwd === "string" && body.cwd.length > 0) {
273
- if (cwdWriteGate && isAbsoluteHostPath(body.cwd))
274
- setSessionCwd(root, body.cwd);
275
- else if (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config) && isAbsoluteHostPath(body.cwd) && satisfiedByProcessCwd(body.cwd, realpathSync))
316
+ let boundCwd;
317
+ if (typeof cwd === "string" && cwd.length > 0) {
318
+ if (cwdWriteGate && isAbsoluteHostPath(cwd))
319
+ boundCwd = cwd;
320
+ else if (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config) && isAbsoluteHostPath(cwd) && satisfiedByProcessCwd(cwd, realpathSync))
276
321
  logger.debug("task_cwd_inherited", { lane: execLane, sessionId: root });
277
322
  else
278
323
  logger.warn("task_cwd_ignored", { honored: cwdWriteGate, lane: execLane, sessionId: root });
279
324
  }
325
+ let boundShellEnv;
280
326
  if (parsedSettings.settings?.shellEnv) {
281
327
  if (cwdWriteGate)
282
- setSessionShellEnv(root, parsedSettings.settings.shellEnv);
328
+ boundShellEnv = parsedSettings.settings.shellEnv;
283
329
  else if (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config)) {
284
330
  const requested = parsedSettings.settings.shellEnv;
285
331
  const mismatched = shellEnvMismatchCount(requested, process.env);
@@ -291,6 +337,8 @@ export function createResolveSpec(ctx) {
291
337
  else
292
338
  logger.warn("task_shell_env_ignored", { honored: false, lane: execLane, sessionId: root });
293
339
  }
340
+ const sessionCwd = boundCwd ?? perSessionCwd.get(root);
341
+ const sessionBindings = bindingsOf(sessionCwd, boundShellEnv, body.inheritEnv);
294
342
  const taskHooks = (() => {
295
343
  const hc = parsedSettings.settings?.hooks;
296
344
  if (!hc)
@@ -302,7 +350,7 @@ export function createResolveSpec(ctx) {
302
350
  return createSettingsHooksRegistrations(hc, {
303
351
  logger,
304
352
  sessionId: root,
305
- cwd: perSessionCwd.get(root) ?? process.cwd(),
353
+ cwd: sessionCwd ?? process.cwd(),
306
354
  hookEnvAllow: config.hookEnvAllow,
307
355
  ...(parsedSettings.settings?.shellEnv ? { shellEnv: parsedSettings.settings.shellEnv } : {}),
308
356
  httpHookAllowlistLayers: parsedSettings.settings?.httpHookAllowlist !== undefined ? [parsedSettings.settings.httpHookAllowlist] : [],
@@ -352,9 +400,9 @@ export function createResolveSpec(ctx) {
352
400
  metrics.inc("task_model_unknown_fallback_total");
353
401
  logger.warn("task_model_unknown_fallback", { requested: echoModelRef(picked.unknownExplicit), fallback: picked.model, sessionId: root });
354
402
  }
355
- return { taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked };
403
+ return { taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, sessionBindings, sessionCwd };
356
404
  };
357
- const resolveHistoryAnchors = async (body, req, auth, root) => {
405
+ const resolveHistoryAnchors = async (body, req, auth, root, s4DefaultScopes, legProjectId) => {
358
406
  const anchorReader = req === undefined ? undefined : anchorReaderOf(req, { config, logger }, claimCallerOf(identityAxesOf(auth).subject, config));
359
407
  let resumeAtEntryId;
360
408
  if (typeof body.resumeAt === "string" && body.resumeAt.length > 0) {
@@ -368,9 +416,6 @@ export function createResolveSpec(ctx) {
368
416
  throw new HttpError(501, "rewind-files-to is not available on this worker (no session-store backend for the anchor map)");
369
417
  rewindFilesToEntryId = await resolveHistoryAnchor("rewindFilesTo", anchorsResolvable, anchorReader, root, body.rewindFilesTo, auth?.subject ?? null, "rewindFilesTo");
370
418
  }
371
- const submittedProjectId = auth?.resolvedProjectId ?? (typeof body.projectId === "string" && body.projectId ? body.projectId.toLowerCase() : undefined);
372
- const s4DefaultScopes = submittedProjectId ? config.projects[submittedProjectId]?.defaultScopes : undefined;
373
- const legProjectId = await legProjectIdOf(submittedProjectId, sessionWorkspace, root);
374
419
  return { resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId };
375
420
  };
376
421
  const declaresInteractivePosture = (body, req, opts) => {
@@ -378,7 +423,7 @@ export function createResolveSpec(ctx) {
378
423
  return false;
379
424
  if (body.verify === true || body.cascade === true)
380
425
  return false;
381
- if (liveQuestionFace === undefined)
426
+ if (!questionSeat)
382
427
  return false;
383
428
  if (body.interactiveTools === false)
384
429
  return false;
@@ -389,15 +434,15 @@ export function createResolveSpec(ctx) {
389
434
  };
390
435
  const assembleSpecLiteral = (body, auth, root, req, opts, parts, effMode) => {
391
436
  const { parts: subjectParts, person } = identityAxesOf(auth);
392
- const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId, projectKey, a2aPeers, storedToolAxes, runSkills, } = parts;
437
+ const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId, projectKey, a2aPeers, storedToolAxes, runSkills, projectBrief, } = parts;
393
438
  const spec = {
394
439
  objective: attachmentNotice ? `${picked.cleanedObjective}\n\n${attachmentNotice}` : picked.cleanedObjective,
395
440
  ...buildPromptSeats(scenarioName, cap.prompt, typeof body.systemPrompt === "string" ? body.systemPrompt : undefined),
396
- appendSystemPrompt: acceptedAppend,
441
+ appendSystemPrompt: appendFold([acceptedAppend, projectBrief]).text,
397
442
  ...(body.outputStyle !== undefined ? { outputStyle: body.outputStyle } : {}),
398
443
  ...(body.projectMemory !== undefined ? { projectMemory: body.projectMemory } : {}),
399
444
  ...(legProjectId !== undefined ? { projectId: legProjectId } : {}),
400
- principal: taskSpecIdentityOf(subjectParts).principal,
445
+ ...taskSpecIdentityOf(subjectParts),
401
446
  images: body.images,
402
447
  ...(body.userAttachments !== undefined ? { userAttachments: body.userAttachments } : {}),
403
448
  ...(body.clientContext ? { clientContext: { timeZone: body.clientContext.timeZone, userEmail: body.clientContext.userEmail } } : {}),
@@ -522,7 +567,6 @@ export function createResolveSpec(ctx) {
522
567
  toolPolicy: toolPolicyForHands(hands, durableEnabled
523
568
  ? createApprovalBaselinePolicy(config, {
524
569
  kind: "durable",
525
- question: liveQuestionFace,
526
570
  ...(approvalExemptionStore !== undefined ? { exemption: createSessionExemptionRead(approvalExemptionStore, root, logger, "deployment_list") } : {}),
527
571
  })
528
572
  : singleUserAutoAcceptBaselineApplies(config)
@@ -543,13 +587,13 @@ export function createResolveSpec(ctx) {
543
587
  totalBudgetUsd: config.resourceSuspendTotalBudgetUsd,
544
588
  maxSlices: config.resourceSuspendMaxSlices,
545
589
  })),
546
- ...(liveQuestionFace === undefined ? { onQuestion: QUESTION_AWAITS_RESUME } : {}),
590
+ ...(questionSeat ? {} : { onQuestion: QUESTION_AWAITS_RESUME }),
547
591
  }
548
592
  : {}),
549
593
  };
550
594
  return spec;
551
595
  };
552
- const foldGovernanceAndSettings = async (body, auth, root, spec, gated) => {
596
+ const foldGovernanceAndSettings = async (body, auth, root, spec, gated, projectBrief, legSessionCwd) => {
553
597
  const { acceptedAppend, parsedSettings } = gated;
554
598
  const hostSemanticsLane = !DEPLOYMENT_SHAPE_PREDICATES.sandboxPathAdjudication.holds(config);
555
599
  const laneHomeBase = () => {
@@ -558,7 +602,7 @@ export function createResolveSpec(ctx) {
558
602
  };
559
603
  const pathAdjudication = hostSemanticsLane
560
604
  ? (() => {
561
- const realRoot = realTaskRootOf(root);
605
+ const realRoot = realTaskRootOf(legSessionCwd);
562
606
  const gateCwd = realRoot ?? join(config.localDataRoot ?? localRoot, "fs-write-gate-unrooted");
563
607
  return {
564
608
  env: new NodeExecutionEnv({ cwd: gateCwd }),
@@ -578,8 +622,9 @@ export function createResolveSpec(ctx) {
578
622
  const governedBase = applyRuntimeGovernance(spec, createDeploymentGovernanceInputs(config, pathAdjudication));
579
623
  let governed = governedBase;
580
624
  let effectiveSettings = parsedSettings.settings;
581
- if (effectiveSettings?.outputStyle && acceptedAppend && acceptedAppend.length + 2 + effectiveSettings.outputStyle.length > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
582
- logger.warn("output_style_dropped", { detail: `combined append carriers exceed the ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} cap (rider ${acceptedAppend.length} + style ${effectiveSettings.outputStyle.length}) — style dropped (pre-cap stored body on a resume leg?)`, sessionId: root });
625
+ const foldedChars = effectiveSettings?.outputStyle ? appendFold([acceptedAppend, projectBrief, effectiveSettings.outputStyle]).chars : 0;
626
+ if (effectiveSettings?.outputStyle && foldedChars > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
627
+ logger.warn("output_style_dropped", { detail: `combined append carriers exceed the ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} cap (rider ${acceptedAppend?.length ?? 0} + project brief ${projectBrief?.length ?? 0} + style ${effectiveSettings.outputStyle.length}, ${foldedChars} with joiners) — style dropped (pre-cap stored body on a resume leg?)`, sessionId: root });
583
628
  const { outputStyle: _dropped2, ...rest2 } = effectiveSettings;
584
629
  effectiveSettings = Object.keys(rest2).length > 0 ? rest2 : undefined;
585
630
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * [ref] 车2 —— 托管留存的 **sweep lane**(设计稿 `docs/DESIGN-270-retention-lane.md` v1.3 §3/§4/§7)。
2
+ * [ref] 车2 —— 托管留存的 **sweep lane**(设计稿 `docs/[ref]-retention-lane.md` v1.3 §3/§4/§7)。
3
3
  *
4
4
  * ── 为什么是独立文件、独立定时器,而不是折进 `startReapers()`(设计稿 §3 首条)───────────────────
5
5
  * `boot/reapers.ts` 里那二十条腿全都是**容忍多副本**的幂等清理:每台副本各扫各的,重复扫一遍只是浪费。
@@ -206,6 +206,13 @@ export interface RunnerDepsCtx {
206
206
  sharedMemoryStores: RunnerDeps["sharedMemoryStores"];
207
207
  toolResultStore: ToolResultStoreFull | undefined;
208
208
  sessionPolicyStore: ReturnType<StoreBackend["sessionPolicy"]> | undefined;
209
+ /**
210
+ * [ref] §K —— per-principal 运行期准入的**收紧面**(`boot/runtime-caps.ts` 一处合成;缺席 = 这条部署腿没有 per-principal 收紧,
211
+ * 部署级缺省照管)。进{@link createSharedRunnerDeps 共享基座}:引擎按腿以 `spec.principal` 解它(每条腿各解一次),委派子代的主体由引擎的
212
+ * 父 spec 座继承 —— 子腿是同一个主体,跑它的那只 Runner 不挂 = 中心对这个主体的拒位(bypass / fork / 自编排 / auto / 强制门 / 观察者 /
213
+ * 记忆 opt-out)与中心硬故障时的 fail-closed 降级项一位都到不了子腿(安全轴 fail-open)。它不是会话设施(不同于 selfOrchestration /
214
+ * scheduler / memory 那几席),所以没有「子腿刻意不给」的理由。
215
+ */
209
216
  runtimeCapsResolver: RunnerDeps["runtimeCapsResolver"];
210
217
  /** [ref] per-edited-file rewind history (core `RunnerDeps.fileHistoryStore`; replaces the retired E19
211
218
  * whole-tree snapshot seat — core 94632197 renamed the seat, not a coexistence). WIRING IS THE OPT-IN.
@@ -248,7 +255,7 @@ export interface RunnerDepsCtx {
248
255
  }
249
256
  /** [ref] A10 留档发现②:main runner `RunnerDeps` 与 main.ts subRunner 字面量之间此前手工重复
250
257
  * 的 ~15 个键,类型标注见 {@link createSharedRunnerDeps} 头注。 */
251
- export type SharedRunnerDeps = Pick<RunnerDeps, "brain" | "readFace" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readDenyFloorRequired" | "memoryDelegationEvidence" | "memoryProvenance" | "memoryCapturePolicy" | "delegationEntryCaps" | "crossSessionInbound" | "crossSessionDialogExpiry" | "writeProtectedPaths" | "memoryEngineDir" | "allowedTools" | "crossBoundaryPosture" | "models" | "roles" | "tiers" | "pricing" | "tracer" | "promptSource" | "executionEnvFactory" | "lspManager" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "mods" | "toolResultStore" | "checkpointStore" | "fileHistoryStore" | "fileHistoryCapture" | "hands" | "sessionPolicyStore" | "usageWindows" | "usageWindowStore" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "sharedMemoryStores" | "compliancePostureResolver" | "lockedConfig" | "retentionPolicy" | "onNotice" | "mcpRevocations" | "peerSeat">;
258
+ export type SharedRunnerDeps = Pick<RunnerDeps, "brain" | "readFace" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readDenyFloorRequired" | "memoryDelegationEvidence" | "memoryProvenance" | "memoryCapturePolicy" | "delegationEntryCaps" | "crossSessionInbound" | "crossSessionDialogExpiry" | "writeProtectedPaths" | "memoryEngineDir" | "allowedTools" | "crossBoundaryPosture" | "models" | "roles" | "tiers" | "pricing" | "tracer" | "promptSource" | "executionEnvFactory" | "lspManager" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "mods" | "toolResultStore" | "checkpointStore" | "fileHistoryStore" | "fileHistoryCapture" | "hands" | "sessionPolicyStore" | "usageWindows" | "usageWindowStore" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "sharedMemoryStores" | "compliancePostureResolver" | "lockedConfig" | "retentionPolicy" | "onNotice" | "mcpRevocations" | "peerSeat" | "runtimeCapsResolver">;
252
259
  /**
253
260
  * [ref] A10 留档发现②(review 2026-07-29,[ref]§三族A 同源修补的延续):main runner 的
254
261
  * `RunnerDeps` 字面量(下方 `createRunnerDeps`)与 `main.ts` 里 subRunner 的 `new Runner({...})`
@@ -275,7 +282,7 @@ export type SharedRunnerDeps = Pick<RunnerDeps, "brain" | "readFace" | "readDeny
275
282
  * 属性,比再抽一层共享基座更强的同源保证),不重复收纳进这里。
276
283
  */
277
284
  /** 基座真实消费的窄面(Pick)——subRunner 调用点(main.ts)只需凑这 13 个字段,不必造全量 ctx。 */
278
- export type SharedRunnerDepsCtx = Pick<RunnerDepsCtx, "config" | "brain" | "pricing" | "tracer" | "promptSource" | "executionEnvFactory" | "lspManager" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "deploymentMods" | "toolResultStore" | "checkpointStore" | "fileHistoryStore" | "sessionPolicyStore" | "commitCoAuthor" | "usageWindowStore" | "orgMemoryAdmission" | "sharedMemoryStores" | "logger" | "governanceSeams" | "mcpRevocations" | "metrics" | "engineDataRoot" | "peerDesk">;
285
+ export type SharedRunnerDepsCtx = Pick<RunnerDepsCtx, "config" | "brain" | "pricing" | "tracer" | "promptSource" | "executionEnvFactory" | "lspManager" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "deploymentMods" | "toolResultStore" | "checkpointStore" | "fileHistoryStore" | "sessionPolicyStore" | "commitCoAuthor" | "usageWindowStore" | "orgMemoryAdmission" | "sharedMemoryStores" | "logger" | "governanceSeams" | "mcpRevocations" | "metrics" | "engineDataRoot" | "peerDesk" | "runtimeCapsResolver">;
279
286
  /** 转发席只需要 `inc` —— 刻意窄到这一个动词,免得把整只 Metrics 拖进这条纯转发腿。 */
280
287
  export interface EngineNoticeMetricsSeat {
281
288
  inc: (name: string, labels?: Record<string, string>) => void;
@@ -133,7 +133,7 @@ export function createSharedRunnerDeps(ctx) {
133
133
  toolResultStore: ctx.toolResultStore,
134
134
  checkpointStore: ctx.checkpointStore ? ctx.checkpointStore : undefined,
135
135
  fileHistoryStore: ctx.fileHistoryStore ? ctx.fileHistoryStore : undefined,
136
- fileHistoryCapture: coreFileHistoryCaptureSeat(ctx.fileHistoryStore, ctx.config.fileHistoryCapture),
136
+ fileHistoryCapture: coreFileHistoryCaptureSeat(ctx.fileHistoryStore !== undefined, ctx.config.fileHistoryCapture),
137
137
  sessionPolicyStore: ctx.sessionPolicyStore ? ctx.sessionPolicyStore : undefined,
138
138
  memoryScopeAdmission: ctx.orgMemoryAdmission.memoryScopeAdmission ? ctx.orgMemoryAdmission.memoryScopeAdmission : undefined,
139
139
  deploymentMemoryScopes: ctx.orgMemoryAdmission.deploymentMemoryScopes && ctx.orgMemoryAdmission.deploymentMemoryScopes.length > 0 ? ctx.orgMemoryAdmission.deploymentMemoryScopes : undefined,
@@ -146,6 +146,7 @@ export function createSharedRunnerDeps(ctx) {
146
146
  retentionPolicy: ctx.governanceSeams.retentionPolicy,
147
147
  mcpRevocations: ctx.mcpRevocations ? ctx.mcpRevocations : undefined,
148
148
  peerSeat: ctx.peerDesk.seat,
149
+ runtimeCapsResolver: ctx.runtimeCapsResolver ? ctx.runtimeCapsResolver : undefined,
149
150
  };
150
151
  return shared;
151
152
  }
@@ -153,7 +154,7 @@ export function localOwnerRulesDeclared(config, permissionRuleStore) {
153
154
  return permissionRuleStore !== undefined && !DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(config);
154
155
  }
155
156
  export function createRunnerDeps(ctx) {
156
- const { config, logger, metrics, localRoot, outcomeSink, elicitation, question, toolApproval, sessionStore, memoryEngine, sessionCaptureRecords, memorySyncRunner, runtimeCapsResolver, permissionRuleStore, fleetBus, workflowRunStore, workflowJournalStore, workflowAgentRegistry, workflowNotifyGate, deliverWorkflowCompletion, } = ctx;
157
+ const { config, logger, metrics, localRoot, outcomeSink, elicitation, question, toolApproval, sessionStore, memoryEngine, sessionCaptureRecords, memorySyncRunner, permissionRuleStore, fleetBus, workflowRunStore, workflowJournalStore, workflowAgentRegistry, workflowNotifyGate, deliverWorkflowCompletion, } = ctx;
157
158
  const peerSessionLister = sessionStore.listSessionRows?.bind(sessionStore);
158
159
  const memoryEngineIncident = createMemoryEngineIncidentSink({ logger, metrics });
159
160
  const sharedRunnerDeps = createSharedRunnerDeps(ctx);
@@ -237,7 +238,6 @@ export function createRunnerDeps(ctx) {
237
238
  memorySyncRunner.trigger("harvest");
238
239
  }
239
240
  : undefined,
240
- runtimeCapsResolver: runtimeCapsResolver ? runtimeCapsResolver : undefined,
241
241
  permissionRuleStore: permissionRuleStore ? permissionRuleStore : undefined,
242
242
  localOwnerRules: localOwnerRulesDeclared(config, permissionRuleStore),
243
243
  onBackgroundChildEvent: fleetBackgroundChildPublisher(fleetBus, (msg, fields) => logger.info(msg, fields)),
@@ -0,0 +1,36 @@
1
+ import type { SessionAgeOutExpectation, SessionPurgeOutcome } from "../session-deletion.js";
2
+ import type { OwnerAwareSessionStore } from "../security.js";
3
+ import type { Logger } from "../observability/logger.js";
4
+ import type { Metrics } from "../observability/metrics.js";
5
+ /** 每拍至多碰这么多只(一拍的删除量有上界:维护拍上其余各腿不被本腿拖住)。 */
6
+ export declare const SESSION_AGE_OUT_CAP = 64;
7
+ /** 每拍的时间预算(同上一句的理由)。 */
8
+ export declare const SESSION_AGE_OUT_BUDGET_MS = 5000;
9
+ /** 跳过的理由(闭集;计数的标签):条件在锁里不再成立 / 围栏判到认领 / 子代预检拒 / 另一次删除持有它 / 抛。 */
10
+ export type SessionAgeOutSkip = "changed" | "active" | "children_alive" | "in_progress" | "failed";
11
+ /** 一拍的读数(调用方记日志;钉读它)。 */
12
+ export interface SessionAgeOutReading {
13
+ readonly deleted: number;
14
+ readonly skipped: Readonly<Record<SessionAgeOutSkip, number>>;
15
+ /** 本拍因帽或预算停下而候选还没看完。 */
16
+ readonly truncated: boolean;
17
+ }
18
+ export interface SessionAgeOutDeps {
19
+ readonly store: Required<Pick<OwnerAwareSessionStore, "listIdleOfKind">>;
20
+ readonly purge: (sessionId: string, owner: string | null, opts: {
21
+ readonly ageOut: SessionAgeOutExpectation;
22
+ }) => Promise<SessionPurgeOutcome>;
23
+ /** 视界(`BG_AGENT_RETENTION_MS`;每拍现读 —— 热改下一拍生效)。 */
24
+ readonly retentionMs: () => number;
25
+ readonly logger: Pick<Logger, "info" | "warn">;
26
+ readonly metrics: Pick<Metrics, "inc">;
27
+ readonly now?: () => number;
28
+ readonly cap?: number;
29
+ readonly budgetMs?: number;
30
+ }
31
+ /**
32
+ * 铸老化腿(一只闭包,带进程内的跨拍轮转起点与在飞守卫):每次调用跑一拍,交回读数;在飞时再调 ⇒ 立刻交回空读数(不叠拍)。
33
+ * 候选读抛 ⇒ 本拍停在那里(读数照交,下拍从同一起点再来);单行删除抛 ⇒ 计 `failed`、节流 warn,本拍继续下一行。
34
+ */
35
+ export declare function createSessionAgeOut(deps: SessionAgeOutDeps): () => Promise<SessionAgeOutReading>;
36
+ //# sourceMappingURL=session-age-out.d.ts.map
@@ -0,0 +1,101 @@
1
+ import { SESSION_KINDS, idleSessionAfter } from "../session-kind.js";
2
+ import { seatText } from "../trace/exit-seat.js";
3
+ export const SESSION_AGE_OUT_CAP = 64;
4
+ export const SESSION_AGE_OUT_BUDGET_MS = 5_000;
5
+ function outcomeOf(outcome) {
6
+ if ("deleted" in outcome)
7
+ return outcome.deleted ? "deleted" : "changed";
8
+ if ("active" in outcome)
9
+ return "active";
10
+ if ("childrenAlive" in outcome)
11
+ return "children_alive";
12
+ if ("inProgress" in outcome)
13
+ return "in_progress";
14
+ const unknownOutcome = outcome;
15
+ throw new Error(`session age-out: no arm for purge outcome ${JSON.stringify(unknownOutcome)}`);
16
+ }
17
+ export function createSessionAgeOut(deps) {
18
+ const cap = deps.cap ?? SESSION_AGE_OUT_CAP;
19
+ const budgetMs = deps.budgetMs ?? SESSION_AGE_OUT_BUDGET_MS;
20
+ const now = deps.now ?? Date.now;
21
+ const resumeAfter = new Map();
22
+ let inFlight = false;
23
+ const empty = () => ({ changed: 0, active: 0, children_alive: 0, in_progress: 0, failed: 0 });
24
+ return async () => {
25
+ if (inFlight)
26
+ return { deleted: 0, skipped: empty(), truncated: false };
27
+ inFlight = true;
28
+ const started = now();
29
+ const skipped = empty();
30
+ let deleted = 0;
31
+ let touched = 0;
32
+ let truncated = false;
33
+ try {
34
+ for (const kind of SESSION_KINDS) {
35
+ const idleBefore = new Date(now() - deps.retentionMs());
36
+ const origin = resumeAfter.get(kind);
37
+ let after = origin;
38
+ let wrapped = origin === undefined;
39
+ let circled = false;
40
+ for (;;) {
41
+ if (touched >= cap || (touched > 0 && now() - started >= budgetMs)) {
42
+ truncated = true;
43
+ break;
44
+ }
45
+ const page = await deps.store.listIdleOfKind(kind, idleBefore, { ...(after !== undefined ? { after } : {}), limit: cap - touched });
46
+ if (page.length === 0) {
47
+ if (wrapped) {
48
+ resumeAfter.delete(kind);
49
+ break;
50
+ }
51
+ wrapped = true;
52
+ after = undefined;
53
+ continue;
54
+ }
55
+ for (const row of page) {
56
+ if (wrapped && origin !== undefined && !idleSessionAfter(origin, row)) {
57
+ circled = true;
58
+ break;
59
+ }
60
+ if (touched >= cap || (touched > 0 && now() - started >= budgetMs)) {
61
+ truncated = true;
62
+ break;
63
+ }
64
+ touched++;
65
+ after = { lastActivityAt: row.lastActivityAt, sessionId: row.sessionId };
66
+ resumeAfter.set(kind, after);
67
+ let verdict;
68
+ try {
69
+ verdict = outcomeOf(await deps.purge(row.sessionId, row.owner, { ageOut: { incarnation: row.incarnation, kind, idleBefore } }));
70
+ }
71
+ catch (err) {
72
+ verdict = "failed";
73
+ deps.logger.warn("session_age_out_failed", { sessionId: row.sessionId, err: seatText("operator-log-text", String(err)), effect: "the session stays; the next maintenance tick judges it again" });
74
+ }
75
+ if (verdict === "deleted") {
76
+ deleted++;
77
+ deps.metrics.inc("sidechain_sessions_aged_out_total", {}, 1);
78
+ deps.logger.info("session_aged_out", { sessionId: row.sessionId, sessionKind: kind, lastActivityAt: row.lastActivityAt });
79
+ }
80
+ else {
81
+ skipped[verdict]++;
82
+ deps.metrics.inc("sidechain_age_out_skipped_total", { reason: verdict }, 1);
83
+ }
84
+ }
85
+ if (truncated || circled)
86
+ break;
87
+ }
88
+ if (truncated)
89
+ break;
90
+ }
91
+ }
92
+ finally {
93
+ inFlight = false;
94
+ }
95
+ if (deleted > 0 || truncated || Object.values(skipped).some((n) => n > 0)) {
96
+ deps.logger.info("reaper_swept", { metric: "sidechain_sessions_aged_out_total", count: deleted, skipped, truncated });
97
+ }
98
+ return { deleted, skipped, truncated };
99
+ };
100
+ }
101
+ //# sourceMappingURL=session-age-out.js.map
@@ -1,15 +1,3 @@
1
- /**
2
- * [ref] A10:composition root 分段 —— session 只读/删除面(审计、watch 注册表、E21 purge 协调器、
3
- * degenerate 仪表、plan-cache 探针)。
4
- *
5
- * 纯搬运:函数体逐字来自 `main.ts`(原 2967-3092 行),缩进不变;新增的只有 import 与包壳。
6
- *
7
- * ⚠️ **位置即契约**:
8
- * 1. `sessionWatchRegistry` 必须在 `purgeSession` **之前**构造 —— purge 尾部的 `dropSession` 是
9
- * 同副本租户轮转围栏(delete 即终结旧 owner 的 SSE 订阅),两者是一对;空间回收座在它**之后**起、且不在应答路径里。
10
- * 2. `setLeafAdvanceListener(...)` 是**进程级单点**装载(leaf-bus 只有一个监听位),必须与
11
- * registry 的构造同段发生,晚于它、早于任何会 append 的路由。
12
- */
13
1
  import { type SessionAuditReadOpts } from "../audit.js";
14
2
  import type { ServiceConfig } from "../config.js";
15
3
  import type { Logger } from "../observability/logger.js";
@@ -25,7 +13,7 @@ import { SessionWatchRegistry } from "../session-watch.js";
25
13
  import type { TaskListLane } from "./task-list-lane.js";
26
14
  import { type RunnerDeps } from "@sema-agent/core";
27
15
  import type { MailboxRecipientLifecycle } from "../plugins/mailbox-recipient-lifecycle.js";
28
- import { type SessionPurgeOutcome } from "../session-deletion.js";
16
+ import { type SessionAgeOutExpectation, type SessionPurgeOutcome } from "../session-deletion.js";
29
17
  import { type SessionEraser, type SessionEraseSettler } from "../session-erase.js";
30
18
  import type { UserInputLedgerStore } from "../user-input-ledger.js";
31
19
  import type { SpaceReclaimer } from "../workspace-space.js";
@@ -75,6 +63,7 @@ export interface SessionFacesCtx {
75
63
  export declare function createSessionFaces(ctx: SessionFacesCtx): {
76
64
  ownerAware: OwnerAwareSessionStore;
77
65
  sessionAudit: ((sessionId: string, opts?: SessionAuditReadOpts) => Promise<{
66
+ sessionKind?: "sidechain" | undefined;
78
67
  projectId?: string | undefined;
79
68
  agent?: import("../session-agent.js").SessionAgent | undefined;
80
69
  owner: string | null;
@@ -90,7 +79,9 @@ export declare function createSessionFaces(ctx: SessionFacesCtx): {
90
79
  promptEpoch?: import("@sema-agent/core").StoredPromptEpoch;
91
80
  } | undefined>) | undefined;
92
81
  sessionWatchRegistry: SessionWatchRegistry | undefined;
93
- purgeSession: ((sessionId: string, owner: string | null) => Promise<SessionPurgeOutcome>) | undefined;
82
+ purgeSession: ((sessionId: string, owner: string | null, opts?: {
83
+ readonly ageOut?: SessionAgeOutExpectation;
84
+ }) => Promise<SessionPurgeOutcome>) | undefined;
94
85
  recoverPendingDeletions: (() => Promise<ReadonlyArray<{
95
86
  readonly sessionId: string;
96
87
  readonly outcome: SessionPurgeOutcome | {