@sema-agent/server 7.132.0 → 7.133.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 (402) hide show
  1. package/MIGRATION.md +266 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +174 -55
  5. package/deploy/sema-up/README.md +19 -1
  6. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
  7. package/deploy/sema-up/chart/templates/server.yaml +5 -2
  8. package/deploy/sema-up/stack/compose.yaml +3 -0
  9. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  10. package/dist/adoption/plan.d.ts +3 -2
  11. package/dist/adoption/plan.js +7 -5
  12. package/dist/adoption/runner.js +3 -10
  13. package/dist/adoption/sql.d.ts +3 -2
  14. package/dist/adoption/sql.js +3 -5
  15. package/dist/adoption/wire.d.ts +4 -1
  16. package/dist/adoption/wire.js +1 -0
  17. package/dist/approval-ask-audit-store.d.ts +31 -13
  18. package/dist/approval-ask-audit-store.js +272 -74
  19. package/dist/approval-ask-machine.d.ts +15 -0
  20. package/dist/approval-ask-machine.js +6 -0
  21. package/dist/approval-ask-retention.d.ts +136 -0
  22. package/dist/approval-ask-retention.js +102 -0
  23. package/dist/approval-card.d.ts +79 -19
  24. package/dist/approval-card.js +44 -13
  25. package/dist/approval-deny-reasons.d.ts +1 -1
  26. package/dist/approval.d.ts +9 -0
  27. package/dist/approval.js +24 -3
  28. package/dist/audit.d.ts +27 -10
  29. package/dist/audit.js +12 -16
  30. package/dist/bake-runner/main.js +3 -2
  31. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  32. package/dist/boot/execution-env.js +9 -7
  33. package/dist/boot/execution-lane.js +11 -0
  34. package/dist/boot/leader.js +2 -0
  35. package/dist/boot/memory-boundary.js +2 -2
  36. package/dist/boot/memory-consolidation.d.ts +5 -4
  37. package/dist/boot/memory-consolidation.js +7 -6
  38. package/dist/boot/org-delivery.d.ts +28 -0
  39. package/dist/boot/org-delivery.js +20 -0
  40. package/dist/boot/reapers.d.ts +3 -0
  41. package/dist/boot/reapers.js +21 -1
  42. package/dist/boot/resolve-spec.d.ts +3 -0
  43. package/dist/boot/resolve-spec.js +60 -81
  44. package/dist/boot/runner-deps.js +1 -0
  45. package/dist/boot/session-faces.d.ts +1 -0
  46. package/dist/boot/session-faces.js +4 -2
  47. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  48. package/dist/boot/stage-06-runners.d.ts +2 -0
  49. package/dist/boot/stage-06-runners.js +6 -3
  50. package/dist/boot/stage-07-capability-layer.d.ts +2 -0
  51. package/dist/boot/stage-07-capability-layer.js +24 -3
  52. package/dist/boot/stage-08-reapers.d.ts +2 -0
  53. package/dist/boot/stage-08-reapers.js +2 -2
  54. package/dist/boot/stage-09-leader.d.ts +3 -0
  55. package/dist/boot/stage-10-http-server.d.ts +3 -0
  56. package/dist/boot/stage-10-http-server.js +5 -6
  57. package/dist/boot/stores.js +2 -2
  58. package/dist/boot/web-admin.d.ts +4 -0
  59. package/dist/boot/web-admin.js +151 -63
  60. package/dist/boot/workflow-orchestration.d.ts +2 -0
  61. package/dist/boot/workflow-orchestration.js +2 -1
  62. package/dist/brain.js +8 -3
  63. package/dist/breaker-key.d.ts +6 -0
  64. package/dist/breaker-key.js +29 -0
  65. package/dist/caller-text-echo.d.ts +9 -6
  66. package/dist/caller-text-echo.js +8 -11
  67. package/dist/capabilities/center-plugins.d.ts +7 -0
  68. package/dist/capabilities/center-plugins.js +1 -1
  69. package/dist/capabilities/composite-members.d.ts +1 -1
  70. package/dist/capabilities/composite-members.js +1 -1
  71. package/dist/capabilities/execution-lane.js +2 -2
  72. package/dist/capabilities/hands-lane.d.ts +21 -0
  73. package/dist/capabilities/hands-lane.js +10 -0
  74. package/dist/capabilities/mcp-probe.d.ts +36 -4
  75. package/dist/capabilities/mcp-probe.js +27 -4
  76. package/dist/capabilities/scenarios.d.ts +63 -7
  77. package/dist/capabilities/scenarios.js +39 -7
  78. package/dist/capability-facts.d.ts +34 -4
  79. package/dist/capability-facts.js +28 -2
  80. package/dist/center-config-tier.d.ts +69 -0
  81. package/dist/center-config-tier.js +42 -0
  82. package/dist/checkpoint-identity.d.ts +16 -0
  83. package/dist/checkpoint-identity.js +19 -0
  84. package/dist/config-catalog.d.ts +17 -10
  85. package/dist/config-catalog.js +43 -28
  86. package/dist/config-d-migration.d.ts +3 -1
  87. package/dist/config-d-migration.js +2 -2
  88. package/dist/config-dir-trust.d.ts +114 -0
  89. package/dist/config-dir-trust.js +388 -0
  90. package/dist/config-invariants.d.ts +18 -5
  91. package/dist/config-invariants.js +35 -3
  92. package/dist/config-provider.d.ts +6 -1
  93. package/dist/config-provider.js +6 -2
  94. package/dist/config-types.d.ts +71 -14
  95. package/dist/config-types.js +8 -0
  96. package/dist/config.d.ts +13 -0
  97. package/dist/config.js +121 -59
  98. package/dist/delegated-session-owner.d.ts +185 -0
  99. package/dist/delegated-session-owner.js +119 -0
  100. package/dist/device-protocol.d.ts +5 -3
  101. package/dist/device-protocol.js +1 -1
  102. package/dist/device-ws-hub.js +21 -2
  103. package/dist/device-ws-protocol.d.ts +70 -6
  104. package/dist/device-ws-protocol.js +50 -23
  105. package/dist/elicitation.js +3 -2
  106. package/dist/entry-problems.d.ts +34 -0
  107. package/dist/entry-problems.js +14 -0
  108. package/dist/execution-lane-caps.d.ts +49 -10
  109. package/dist/execution-lane-caps.js +43 -4
  110. package/dist/field-conflict.d.ts +43 -0
  111. package/dist/field-conflict.js +20 -0
  112. package/dist/fleet/fleet-bus.d.ts +80 -6
  113. package/dist/fleet/fleet-bus.js +41 -9
  114. package/dist/hooks/classic-stations.d.ts +10 -5
  115. package/dist/hooks/classic-stations.js +4 -4
  116. package/dist/hooks/command-spawn.d.ts +57 -0
  117. package/dist/hooks/command-spawn.js +139 -0
  118. package/dist/hooks/hook-llm.js +2 -2
  119. package/dist/hooks/hook-runner.d.ts +127 -25
  120. package/dist/hooks/hook-runner.js +668 -287
  121. package/dist/hooks/hook-source.d.ts +44 -0
  122. package/dist/hooks/hook-source.js +40 -0
  123. package/dist/http/active-run-conflict.d.ts +5 -13
  124. package/dist/http/active-run-conflict.js +17 -27
  125. package/dist/http/admission.js +103 -60
  126. package/dist/http/approval-sweeps.js +55 -18
  127. package/dist/http/caller-trust.d.ts +77 -0
  128. package/dist/http/caller-trust.js +143 -0
  129. package/dist/http/checkpoint-ctx.d.ts +16 -16
  130. package/dist/http/checkpoint-ctx.js +13 -10
  131. package/dist/http/claimed-run.d.ts +4 -3
  132. package/dist/http/device-placement.d.ts +2 -4
  133. package/dist/http/device-placement.js +2 -1
  134. package/dist/http/dispatch.js +10 -4
  135. package/dist/http/durable-run-leg.d.ts +4 -32
  136. package/dist/http/durable-run-leg.js +34 -10
  137. package/dist/http/owner-access.d.ts +56 -0
  138. package/dist/http/owner-access.js +42 -0
  139. package/dist/http/principal-gate.d.ts +48 -23
  140. package/dist/http/principal-gate.js +39 -12
  141. package/dist/http/readiness.d.ts +11 -5
  142. package/dist/http/readiness.js +10 -3
  143. package/dist/http/request-guards.d.ts +16 -23
  144. package/dist/http/request-guards.js +30 -15
  145. package/dist/http/resume-ctx-read.d.ts +2 -5
  146. package/dist/http/resume-ctx-read.js +7 -4
  147. package/dist/http/resume-legs.d.ts +3 -4
  148. package/dist/http/resume-legs.js +126 -69
  149. package/dist/http/retired-service-deps.d.ts +43 -0
  150. package/dist/http/retired-service-deps.js +18 -0
  151. package/dist/http/route-ctx.d.ts +44 -28
  152. package/dist/http/route-ctx.js +4 -0
  153. package/dist/http/route-table.js +2 -0
  154. package/dist/http/routes/a2a-serve.js +3 -4
  155. package/dist/http/routes/admin-config-refresh.js +1 -1
  156. package/dist/http/routes/admin-drain.js +1 -1
  157. package/dist/http/routes/admin-memory-optout.js +5 -1
  158. package/dist/http/routes/adoption.js +2 -9
  159. package/dist/http/routes/approvals-assistant.js +49 -48
  160. package/dist/http/routes/background.js +3 -2
  161. package/dist/http/routes/capabilities.js +20 -4
  162. package/dist/http/routes/config-catalog.d.ts +3 -3
  163. package/dist/http/routes/config-catalog.js +1 -1
  164. package/dist/http/routes/devices.js +3 -17
  165. package/dist/http/routes/diagnostics.js +5 -1
  166. package/dist/http/routes/images.js +6 -7
  167. package/dist/http/routes/leader.js +1 -8
  168. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  169. package/dist/http/routes/mcp-reconnect.js +3 -2
  170. package/dist/http/routes/memory-bundle.js +1 -1
  171. package/dist/http/routes/memory-compliance.js +1 -1
  172. package/dist/http/routes/memory-consolidation.js +1 -1
  173. package/dist/http/routes/memory-origin.js +1 -1
  174. package/dist/http/routes/memory-policy.d.ts +1 -1
  175. package/dist/http/routes/memory-policy.js +3 -2
  176. package/dist/http/routes/notify-wake.js +8 -21
  177. package/dist/http/routes/observability.js +2 -2
  178. package/dist/http/routes/principal-inbox.d.ts +39 -0
  179. package/dist/http/routes/principal-inbox.js +76 -0
  180. package/dist/http/routes/retention-ops.js +2 -9
  181. package/dist/http/routes/rules.js +5 -18
  182. package/dist/http/routes/runs.d.ts +5 -0
  183. package/dist/http/routes/runs.js +33 -106
  184. package/dist/http/routes/session-sync.js +15 -28
  185. package/dist/http/routes/sessions.js +30 -40
  186. package/dist/http/routes/side-query.js +6 -4
  187. package/dist/http/routes/tasks.js +50 -14
  188. package/dist/http/routes/workflows.d.ts +351 -0
  189. package/dist/http/routes/workflows.js +153 -119
  190. package/dist/http/send.d.ts +24 -3
  191. package/dist/http/send.js +14 -2
  192. package/dist/http/server.d.ts +17 -18
  193. package/dist/http/server.js +15 -13
  194. package/dist/http/stored-body-replay.js +17 -4
  195. package/dist/http/submit-ctx.js +4 -3
  196. package/dist/http/submit-replay.d.ts +4 -3
  197. package/dist/http/submit-replay.js +5 -4
  198. package/dist/http/wire-types.d.ts +10 -7
  199. package/dist/index.d.ts +1 -1
  200. package/dist/index.js +0 -1
  201. package/dist/lane-home-probe.d.ts +78 -9
  202. package/dist/lane-home-probe.js +78 -12
  203. package/dist/leader/endpoint.d.ts +4 -1
  204. package/dist/leader/endpoint.js +11 -10
  205. package/dist/limit-refusal.d.ts +17 -5
  206. package/dist/limit-refusal.js +4 -1
  207. package/dist/mcp-assertion-header.d.ts +31 -10
  208. package/dist/mcp-assertion-header.js +10 -3
  209. package/dist/mcp-tool-faces.js +1 -3
  210. package/dist/memory-project-layer.d.ts +37 -0
  211. package/dist/memory-project-layer.js +46 -0
  212. package/dist/memory-scope.d.ts +23 -16
  213. package/dist/memory-scope.js +24 -8
  214. package/dist/memory-sync-client.d.ts +27 -13
  215. package/dist/memory-sync-client.js +107 -18
  216. package/dist/model-entry-refusal.d.ts +9 -1
  217. package/dist/model-entry-refusal.js +6 -1
  218. package/dist/model-plane-face.d.ts +51 -0
  219. package/dist/model-plane-face.js +24 -0
  220. package/dist/model-provider.d.ts +5 -0
  221. package/dist/model-provider.js +4 -2
  222. package/dist/model-route-endpoint.d.ts +8 -11
  223. package/dist/model-route-endpoint.js +4 -7
  224. package/dist/model-route-env.d.ts +22 -0
  225. package/dist/model-route-env.js +2 -0
  226. package/dist/model-route-gap.d.ts +60 -30
  227. package/dist/model-route-gap.js +21 -15
  228. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  229. package/dist/observability/corrupt-read-seat.js +9 -0
  230. package/dist/observability/err-text.d.ts +6 -0
  231. package/dist/observability/err-text.js +18 -4
  232. package/dist/observability/fail-open.d.ts +35 -9
  233. package/dist/observability/fail-open.js +35 -9
  234. package/dist/observability/metrics.js +1 -0
  235. package/dist/observability/prompt-manifest.d.ts +3 -17
  236. package/dist/observability/prompt-manifest.js +45 -42
  237. package/dist/observability/tool-trace.js +9 -9
  238. package/dist/operator-ask.d.ts +10 -0
  239. package/dist/operator-ask.js +3 -0
  240. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  241. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  242. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  243. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  244. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  245. package/dist/orchestration/workflow-notify-journal.js +27 -34
  246. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  247. package/dist/orchestration/workflow-park-decision.js +118 -0
  248. package/dist/org-delivery-gate.d.ts +81 -0
  249. package/dist/org-delivery-gate.js +59 -0
  250. package/dist/panel-tool-names.d.ts +23 -0
  251. package/dist/panel-tool-names.js +8 -0
  252. package/dist/parked-decide.d.ts +39 -6
  253. package/dist/parked-decide.js +98 -51
  254. package/dist/parked-revive-surface.d.ts +9 -2
  255. package/dist/parked-revive-surface.js +11 -8
  256. package/dist/permission-rule-list.d.ts +1 -1
  257. package/dist/permission-rule-list.js +2 -2
  258. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  259. package/dist/plugins/approval-ask-store-file.js +21 -0
  260. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  261. package/dist/plugins/approval-ask-store-memory.js +34 -2
  262. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  263. package/dist/plugins/approval-ask-store-sql.js +37 -1
  264. package/dist/plugins/blob-backend.d.ts +38 -25
  265. package/dist/plugins/blob-backend.js +29 -19
  266. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  267. package/dist/plugins/breaker-state-sql.js +4 -4
  268. package/dist/plugins/caching-session-store.d.ts +3 -0
  269. package/dist/plugins/caching-session-store.js +3 -0
  270. package/dist/plugins/checkpoint-store-sql.d.ts +14 -0
  271. package/dist/plugins/checkpoint-store-sql.js +20 -2
  272. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  273. package/dist/plugins/file-history-store-sql.js +3 -1
  274. package/dist/plugins/file-run-store.d.ts +5 -13
  275. package/dist/plugins/file-run-store.js +9 -0
  276. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  277. package/dist/plugins/fork-routing-session-store.js +12 -1
  278. package/dist/plugins/host-platform.d.ts +2 -0
  279. package/dist/plugins/host-platform.js +2 -1
  280. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  281. package/dist/plugins/local-checkpoint-store.js +6 -1
  282. package/dist/plugins/local-session-store.d.ts +1 -1
  283. package/dist/plugins/local-session-window.d.ts +39 -0
  284. package/dist/plugins/local-session-window.js +54 -0
  285. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  286. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  287. package/dist/plugins/mailbox-store-sql.js +77 -52
  288. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  289. package/dist/plugins/memory-run-store.d.ts +5 -13
  290. package/dist/plugins/memory-run-store.js +8 -0
  291. package/dist/plugins/one-time-migrations.d.ts +110 -5
  292. package/dist/plugins/one-time-migrations.js +320 -8
  293. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  294. package/dist/plugins/org-delivery-quota-store.js +228 -0
  295. package/dist/plugins/pg-pool.js +39 -7
  296. package/dist/plugins/pg-session-storage.d.ts +17 -4
  297. package/dist/plugins/pg-session-storage.js +29 -6
  298. package/dist/plugins/remote-env-adb.d.ts +6 -12
  299. package/dist/plugins/remote-env-adb.js +12 -2
  300. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  301. package/dist/plugins/remote-env-k8s.js +23 -5
  302. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  303. package/dist/plugins/remote-env-local-docker.js +12 -9
  304. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  305. package/dist/plugins/remote-env-ssh.js +17 -11
  306. package/dist/plugins/run-store-sql.d.ts +16 -14
  307. package/dist/plugins/run-store-sql.js +22 -2
  308. package/dist/plugins/schema-indexes.js +2 -0
  309. package/dist/plugins/send-user-file.js +2 -2
  310. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  311. package/dist/plugins/session-epoch-anchor.js +2 -3
  312. package/dist/plugins/session-store.d.ts +18 -8
  313. package/dist/plugins/session-store.js +15 -4
  314. package/dist/plugins/sql-driver.d.ts +74 -11
  315. package/dist/plugins/sql-driver.js +210 -12
  316. package/dist/plugins/sql-errors.d.ts +23 -0
  317. package/dist/plugins/sql-errors.js +21 -0
  318. package/dist/plugins/store-backend.d.ts +36 -1
  319. package/dist/plugins/store-backend.js +40 -14
  320. package/dist/plugins/store-contracts.d.ts +42 -0
  321. package/dist/plugins/store-contracts.js +1 -0
  322. package/dist/plugins/tidb-pool.d.ts +6 -1
  323. package/dist/plugins/tidb-pool.js +44 -10
  324. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  325. package/dist/plugins/tidb-session-storage.js +2 -2
  326. package/dist/plugins/tidb-session-store.d.ts +24 -4
  327. package/dist/plugins/tidb-session-store.js +28 -4
  328. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  329. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  330. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  331. package/dist/plugins/workflow-run-store-sql.js +50 -9
  332. package/dist/posture-source.d.ts +18 -10
  333. package/dist/posture-source.js +4 -1
  334. package/dist/project-identity.d.ts +45 -6
  335. package/dist/project-identity.js +162 -8
  336. package/dist/project-layer-key.d.ts +28 -0
  337. package/dist/project-layer-key.js +29 -0
  338. package/dist/question.js +3 -2
  339. package/dist/read-deny-entry.d.ts +25 -0
  340. package/dist/read-deny-entry.js +12 -0
  341. package/dist/read-face-posture.d.ts +37 -11
  342. package/dist/read-face-posture.js +32 -3
  343. package/dist/request-key-closure.d.ts +7 -0
  344. package/dist/request-key-closure.js +9 -1
  345. package/dist/request-value-closure.d.ts +5 -0
  346. package/dist/request-value-closure.js +11 -3
  347. package/dist/rule-entry-list.d.ts +26 -2
  348. package/dist/rule-entry-list.js +72 -12
  349. package/dist/rules-consent.js +3 -4
  350. package/dist/run-acceptance.d.ts +19 -3
  351. package/dist/run-acceptance.js +13 -1
  352. package/dist/run-local.js +36 -6
  353. package/dist/runs.d.ts +10 -9
  354. package/dist/runs.js +21 -3
  355. package/dist/runtime-caps-resolver.d.ts +16 -6
  356. package/dist/runtime-caps-resolver.js +18 -5
  357. package/dist/sandbox-pkg-source.d.ts +19 -1
  358. package/dist/sandbox-pkg-source.js +29 -7
  359. package/dist/security.d.ts +87 -9
  360. package/dist/security.js +52 -9
  361. package/dist/session-error-wire.d.ts +19 -2
  362. package/dist/session-error-wire.js +5 -1
  363. package/dist/session-titled-frame.d.ts +33 -0
  364. package/dist/session-titled-frame.js +4 -0
  365. package/dist/session-titler.d.ts +9 -1
  366. package/dist/session-titler.js +15 -4
  367. package/dist/spec-fields.js +21 -2
  368. package/dist/sql-engine-posture.d.ts +3 -1
  369. package/dist/task-cwd.d.ts +1 -1
  370. package/dist/task-mcp.d.ts +3 -3
  371. package/dist/task-mcp.js +7 -66
  372. package/dist/task-settings.d.ts +89 -88
  373. package/dist/task-settings.js +71 -63
  374. package/dist/text-bidi.d.ts +0 -4
  375. package/dist/text-bidi.js +1 -3
  376. package/dist/tighten-only-seats.d.ts +150 -0
  377. package/dist/tighten-only-seats.js +196 -0
  378. package/dist/tool-approval.d.ts +303 -87
  379. package/dist/tool-approval.js +623 -239
  380. package/dist/trace/core-keyset-guard.d.ts +104 -22
  381. package/dist/trace/exit-seat.d.ts +28 -0
  382. package/dist/trace/exit-seat.js +76 -0
  383. package/dist/trace/ledger-events.d.ts +3 -2
  384. package/dist/trace/project.d.ts +80 -12
  385. package/dist/trace/project.js +41 -28
  386. package/dist/trace/projection-table.d.ts +100 -0
  387. package/dist/trace/projection-table.js +130 -0
  388. package/dist/trace/redact.d.ts +54 -0
  389. package/dist/trace/redact.js +778 -152
  390. package/dist/trace/self-minted-wire.d.ts +345 -1
  391. package/dist/trace/self-minted-wire.js +117 -1
  392. package/dist/trace/wire-projection-faces.d.ts +298 -2
  393. package/dist/trace/wire-projection-faces.js +154 -13
  394. package/dist/url-refusal.js +2 -0
  395. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  396. package/dist/web-admin-client/apply-effective.js +56 -5
  397. package/dist/web-admin-client/facade.d.ts +1 -1
  398. package/dist/web-admin-client/facade.js +1 -1
  399. package/dist/web-admin-client/read-face.js +5 -9
  400. package/dist/web-admin-client/skills-mcp.js +4 -5
  401. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  402. package/package.json +7 -3
@@ -20,13 +20,14 @@ import { FileSchedulerBackend, defaultSchedulerStorePath } from "../plugins/sche
20
20
  import * as facts from "../capability-facts.js";
21
21
  import { materializeAttachmentsInto } from "../plugins/task-attachment-store.js";
22
22
  import { reapOrphanWorktrees, withWorktreeIsolation } from "../plugins/worktree-isolation.js";
23
- import { customPkgSourceFromEnv, derivePkgSourceEnv } from "../sandbox-pkg-source.js";
23
+ import { derivePkgSourceEnv } from "../sandbox-pkg-source.js";
24
24
  import { effectiveHostWorkspace } from "../task-cwd.js";
25
25
  import { taskInheritEnvRefusal } from "../hosted-posture.js";
26
26
  import { createCacheMissMemory } from "../workspace-cache.js";
27
27
  import { workspaceSnapshotTimeoutOf } from "../workspace-space.js";
28
28
  import { sayEgressPolicyReading } from "../sandbox-egress-policy.js";
29
29
  import { isSandboxPathAdjudicationLane, sandboxPathEnvSlots, withSandboxPathEnvSlot } from "./deferred-sandbox-path-env.js";
30
+ import { LANE_HOME_UNDECLARED_EVENT, createLaneHomeAbsenceReporter } from "../lane-home-probe.js";
30
31
  import { REMOTE_EXEC_PROVIDER_WORDS, buildUndeclaredHomeNote, executionLaneHomeDir, executionLaneOf, isSingleMachineDefaultLane, laneBindsReads, laneIsolated } from "../execution-lane-caps.js";
31
32
  function boundedSessionSetter(map, maxEntries) {
32
33
  return (sid, value) => {
@@ -55,7 +56,7 @@ function forwardedSandboxEnvKeys(remoteExec) {
55
56
  }
56
57
  }
57
58
  function buildSandboxLaneEnv(config, explicit) {
58
- const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource, customPkgSourceFromEnv()), ...(explicit ?? {}) };
59
+ const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource, config.sandboxPkgSourceCustom), ...(explicit ?? {}) };
59
60
  return Object.keys(merged).length > 0 ? merged : undefined;
60
61
  }
61
62
  const MAX_CWD_SESSIONS = 4096;
@@ -197,6 +198,7 @@ export function createExecutionEnv(ctx) {
197
198
  const { config, logger, metrics, taskAttachmentStore } = ctx;
198
199
  const laneHomeDir = executionLaneHomeDir(config);
199
200
  const homeDirSeat = laneHomeDir !== undefined ? { homeDir: laneHomeDir } : {};
201
+ const homeAbsentNotice = { onHomeAbsent: createLaneHomeAbsenceReporter((event, fields) => logger.warn(event, fields)) };
200
202
  const perTaskImage = new PerTaskImageRegistry();
201
203
  const sessionEnvSelection = new SessionEnvironmentSelection();
202
204
  const sessionScoped = createSessionScopedRegistries();
@@ -223,7 +225,7 @@ export function createExecutionEnv(ctx) {
223
225
  else if (config.remoteExec?.provider === "k8s") {
224
226
  const k8sCfg = {
225
227
  image: config.remoteExec.image,
226
- ...homeDirSeat,
228
+ ...homeDirSeat, ...homeAbsentNotice,
227
229
  ...(config.remoteExec.apiUrl ? { apiUrl: config.remoteExec.apiUrl } : {}),
228
230
  ...(config.remoteExec.token ? { token: config.remoteExec.token } : {}),
229
231
  ...(config.remoteExec.caCert ? { caCert: config.remoteExec.caCert } : {}),
@@ -254,7 +256,7 @@ export function createExecutionEnv(ctx) {
254
256
  executionEnvFactory = sshExecutionEnvFactory({
255
257
  host: config.remoteExec.host,
256
258
  username: config.remoteExec.username,
257
- ...homeDirSeat,
259
+ ...homeDirSeat, ...homeAbsentNotice,
258
260
  privateKey: config.remoteExec.privateKey,
259
261
  ...(config.remoteExec.port != null ? { port: config.remoteExec.port } : {}),
260
262
  ...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
@@ -278,7 +280,7 @@ export function createExecutionEnv(ctx) {
278
280
  else if (config.remoteExec?.provider === "adb") {
279
281
  executionEnvFactory = adbExecutionEnvFactory({
280
282
  serial: config.remoteExec.serial,
281
- ...homeDirSeat,
283
+ ...homeDirSeat, ...homeAbsentNotice,
282
284
  ...(config.remoteExec.adbPath ? { adbPath: config.remoteExec.adbPath } : {}),
283
285
  ...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
284
286
  });
@@ -327,7 +329,7 @@ export function createExecutionEnv(ctx) {
327
329
  executionEnvFactory = localDockerExecutionEnvFactory({
328
330
  image: config.remoteExec.image,
329
331
  ...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
330
- ...homeDirSeat,
332
+ ...homeDirSeat, ...homeAbsentNotice,
331
333
  ...(config.remoteExec.dockerPath ? { dockerPath: config.remoteExec.dockerPath } : {}),
332
334
  ...(config.remoteExec.dockerHost ? { dockerHost: config.remoteExec.dockerHost } : {}),
333
335
  ...(config.remoteExec.memory ? { memory: config.remoteExec.memory } : {}),
@@ -416,7 +418,7 @@ export function createExecutionEnv(ctx) {
416
418
  logger.warn("remote_exec_real_system", { provider: config.remoteExec.provider, note: buildRealSystemNote(config.remoteExec) });
417
419
  const homeNote = buildUndeclaredHomeNote(config);
418
420
  if (homeNote !== undefined)
419
- logger.warn("execution_lane_home_undeclared", { provider: config.remoteExec.provider, note: homeNote });
421
+ logger.warn(LANE_HOME_UNDECLARED_EVENT, { provider: config.remoteExec.provider, note: homeNote });
420
422
  if (executionLaneOf(config.remoteExec.provider) === "host")
421
423
  logger.info("task_inherit_env_honored", { honored: taskInheritEnvRefusal(config) === undefined });
422
424
  }
@@ -1,13 +1,23 @@
1
1
  import { loadRemoteExec } from "@sema-agent/settings-schema/node";
2
+ import { assertLocalConfigDirTrusted } from "../config-dir-trust.js";
2
3
  import { crossInvariant } from "../config-invariants.js";
3
4
  import { executionLaneOf, laneIsolated } from "../execution-lane-caps.js";
5
+ import { buildReadFacePostureNotice, settleDerivedReadFace } from "../read-face-posture.js";
4
6
  import { settleHostShellAtBoot } from "../plugins/host-platform.js";
5
7
  export const FILE_SOURCED_LANES = ["host", "local-docker"];
6
8
  export async function composeExecutionLane(config, ctx) {
7
9
  if (ctx.configSource === "local")
8
10
  await applyRemoteExecFile(config, ctx);
11
+ settleReadFaceForFinalLane(config, ctx.logger);
9
12
  assertExecutionLaneInvariants(config);
10
13
  }
14
+ function settleReadFaceForFinalLane(config, logger) {
15
+ if (!settleDerivedReadFace(config, config.requirePrincipal !== true))
16
+ return;
17
+ const notice = buildReadFacePostureNotice(config);
18
+ if (notice !== undefined)
19
+ logger.info(notice.event, notice.fields);
20
+ }
11
21
  export async function settleHostLaneShell(config, logger) {
12
22
  if (config.remoteExec?.provider !== "host")
13
23
  return;
@@ -34,6 +44,7 @@ export function assertExecutionLaneInvariants(config) {
34
44
  }
35
45
  async function applyRemoteExecFile(config, ctx) {
36
46
  const { localRoot, logger } = ctx;
47
+ await assertLocalConfigDirTrusted({ root: localRoot, declaredOwnerUid: config.configLocalOwnerUid });
37
48
  let fileRx;
38
49
  try {
39
50
  fileRx = await loadRemoteExec(localRoot);
@@ -1,4 +1,5 @@
1
1
  import { createLeaderEndpoint } from "../leader/endpoint.js";
2
+ import { createLeaderRunVisibility } from "../http/owner-access.js";
2
3
  import { createLeaderRunner } from "../leader/wire.js";
3
4
  import { buildDeploymentPostureSeats } from "./runner-deps.js";
4
5
  import { hasApprovalListIntent } from "../approval.js";
@@ -86,6 +87,7 @@ export function createLeaderFace(ctx) {
86
87
  logger,
87
88
  requiredFields: ["objective", "durableRemote", "testCmd", "seedCmd", "baseSha"],
88
89
  ...(leaderRunStore ? { store: leaderRunStore } : {}),
90
+ ownerVisible: createLeaderRunVisibility(config),
89
91
  })
90
92
  : undefined;
91
93
  if (leaderEndpoint)
@@ -1,5 +1,5 @@
1
1
  import { resolve } from "node:path";
2
- import { executionLaneCaps, executionLaneOf } from "../execution-lane-caps.js";
2
+ import { executionLaneCaps, executionLaneOf, laneWiresExecutionEnv } from "../execution-lane-caps.js";
3
3
  export function effectiveMemoryPersistenceCapable(config) {
4
4
  if (config.memoryPersistenceCapable !== undefined)
5
5
  return config.memoryPersistenceCapable;
@@ -11,7 +11,7 @@ export function buildMemoryBoundaryLaneFacts(config, processCwd) {
11
11
  return {
12
12
  lane,
13
13
  hostSemanticsLane: caps.hostFilePlane === "supported",
14
- coreRemoteExecutionEnv: caps.coreRemoteExecutionEnv === "supported",
14
+ coreRemoteExecutionEnv: laneWiresExecutionEnv(lane),
15
15
  containmentRoots: lane === "in-process" ? [processCwd] : [],
16
16
  };
17
17
  }
@@ -298,9 +298,9 @@ export declare function judgeConsolidationValve(input: ConsolidationValveInput):
298
298
  *
299
299
  * consolidation 要后端自带引擎控制面归属 ⇒ 今天只有 file 记忆后端满足 ⇒ 本仓只在**单用户**形
300
300
  * (`REQUIRE_PRINCIPAL !== true`)上装配记忆引擎 —— 而那种部署的 `OPERATOR_PRINCIPALS` 通常是**空的**。
301
- * 空名单下 `explicitOperatorOk` 对任何身份恒假(那是它与 `isOperator` 刻意分家的地方:空名单绝不等于
302
- * 「人人都是 operator」),于是:阀门开着、启动成功、两口挂着、**每一次调用 403**,能力位诚实地报
303
- * `false` —— 唯独运维不知道为什么,而他刚刚显式拧了一根写着 "on" 的旋钮。
301
+ * 没有运维名册(名单空且没有单用户声明 `OPERATOR_SINGLE_USER`)时 `explicitOperatorOk` 对任何身份恒假(「谁是 operator」的唯一读法:空名单绝不等于
302
+ * 「人人都是 operator」),于是:阀门开着、启动成功、两口挂着、**每一次调用 501 `capability.operator_principals_required`**(运维面同一只拒发口;403 只留给名单非空而你不在名单上),
303
+ * 能力位诚实地报 `false` —— 唯独运维不知道为什么,而他刚刚显式拧了一根写着 "on" 的旋钮。
304
304
  *
305
305
  * ## 为什么是 warn 而不是拒启(与 D1 的三条拒启臂**刻意不同档**)
306
306
  *
@@ -322,7 +322,8 @@ export declare function judgeConsolidationValve(input: ConsolidationValveInput):
322
322
  export declare function buildConsolidationValveAudit(input: {
323
323
  /** 阀门判决({@link resolveConsolidationValve} 的 `enabled` + `source`)。 */
324
324
  valve: Pick<ConsolidationValve, "enabled" | "source">;
325
- operatorPrincipals: readonly string[];
325
+ /** 这台部署有没有运维名册(`operatorRosterPresent`:名单非空 ∨ 单用户声明)—— 判据不在本函数里另写一份。 */
326
+ operatorRosterPresent: boolean;
326
327
  /** 这台部署配了任何一把 service 凭证吗(`config.authToken` 或 `config.authTokens` 非空)。 */
327
328
  hasServiceAuth: boolean;
328
329
  /** 本地开发的显式逃生口(`ALLOW_UNAUTHED_WRITES=true`)。 */
@@ -1,5 +1,6 @@
1
1
  import { redactSecrets } from "../trace/redact.js";
2
2
  import { recordFailOpen } from "../observability/fail-open.js";
3
+ import { buildOperatorRosterWayOut } from "../http/principal-gate.js";
3
4
  import { memoryMountRootOf } from "../memory-scope.js";
4
5
  import { executionLaneHomeDir } from "../execution-lane-caps.js";
5
6
  import { DEFAULT_MODEL_REF, resolveMainModel } from "../model-select.js";
@@ -266,15 +267,15 @@ export function buildConsolidationValveAudit(input) {
266
267
  if (!input.valve.enabled || input.valve.source !== "explicit")
267
268
  return { warnings: [] };
268
269
  const warnings = [];
269
- if (input.operatorPrincipals.length === 0) {
270
+ if (!input.operatorRosterPresent) {
270
271
  warnings.push({
271
272
  tag: "memory_consolidation_valve_unreachable",
272
273
  detail: "MEMORY_CONSOLIDATION_DRIVER=on armed the consolidation valve and both admin endpoints are mounted, but " +
273
- "OPERATOR_PRINCIPALS is EMPTY — an empty operator list means NO ONE is an operator (it deliberately does " +
274
- "not mean 'everyone'), so POST /v1/admin/memory/consolidation/run and GET /v1/admin/memory/consolidation " +
275
- "answer 403 auth.operator_only to every caller and capabilities.memoryConsolidationDriver reports false. " +
276
- "Set OPERATOR_PRINCIPALS to the principal(s) allowed to drive consolidation, and send that principal in " +
277
- "the configured principal header. (Not a startup refusal: OPERATOR_PRINCIPALS is shared by every operator " +
274
+ "this worker has no operator: OPERATOR_PRINCIPALS is EMPTY and OPERATOR_SINGLE_USER is not set — an empty operator list means NO ONE " +
275
+ "is an operator (it deliberately does not mean 'everyone'), so POST /v1/admin/memory/consolidation/run and GET /v1/admin/memory/consolidation " +
276
+ "answer 501 capability.operator_principals_required to every caller and capabilities.memoryConsolidationDriver reports false. " +
277
+ `To fix: ${buildOperatorRosterWayOut()}. With OPERATOR_PRINCIPALS, callers must send a listed principal in the configured principal header; a single-user declaration needs no principal. ` +
278
+ "(Not a startup refusal: the operator roster is shared by every operator " +
278
279
  "endpoint on this worker, so one valve must not decide whether the whole worker starts.)",
279
280
  });
280
281
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * [ref] §10.2 —— 跨主体投递门的**装配点**(门本体与规则在 `src/org-delivery-gate.ts`)。
3
+ *
4
+ * 挂载规则(一条):**部署声明了 principal 收件箱的消费方 ⟺ 门在座**。声明 = `RunnerDeps.principalInboxConsumer`
5
+ * (由 `PRINCIPAL_INBOX_ASSISTANT` 铸,`boot/runner-deps.ts`);门要的四件 —— 消费方、耐久 mailbox、org 成员目录、配额店 ——
6
+ * 是这条声明的**前提**,不是可选项:声明在而任一件缺 ⇒ **拒启**,拒句点名缺哪件。不存在「声明了但门没挂」的静默半态:
7
+ * 那一形下收件箱有消费方却没有任何合法的写入方,运维以为跨主体投递开着,wire 上它恒 501。
8
+ *
9
+ * 消费方取自**同一个** `RunnerDeps` 对象(`principalInboxConsumerOf(runnerDeps)`),不从 config 再读一遍(core 契约原句:
10
+ * 「over the same RunnerDeps the deployment runs its legs with」)。
11
+ */
12
+ import { type MailboxStore, type OrgDeliveryGate, type RunnerDeps } from "@sema-agent/core";
13
+ import type { OrgMemoryDirectory } from "../org-memory-admission.js";
14
+ import type { StoreBackend } from "../plugins/store-backend.js";
15
+ import type { Logger } from "../observability/logger.js";
16
+ export interface OrgDeliveryMountInput {
17
+ /** 主 Runner 的那一份 `RunnerDeps`(消费方声明从它读)。 */
18
+ readonly runnerDeps: Pick<RunnerDeps, "principalInboxConsumer">;
19
+ /** 记忆准入 / memory-policy / 共享记忆读面共用的那一个目录实例(`boot/org-memory.ts`)。 */
20
+ readonly directory: OrgMemoryDirectory | undefined;
21
+ /** 与引擎 `RunnerDeps.mailboxStore` 同一只店。 */
22
+ readonly mailboxStore: MailboxStore | undefined;
23
+ readonly backend: Pick<StoreBackend, "orgDeliveryQuota"> | undefined;
24
+ readonly logger: Pick<Logger, "info">;
25
+ }
26
+ /** 门在座 ⇒ 门;部署没声明消费方 ⇒ `undefined`;声明了而前提缺 ⇒ 抛(拒启)。 */
27
+ export declare function mountOrgDeliveryGate(input: OrgDeliveryMountInput): OrgDeliveryGate | undefined;
28
+ //# sourceMappingURL=org-delivery.d.ts.map
@@ -0,0 +1,20 @@
1
+ import { principalInboxConsumerOf } from "@sema-agent/core";
2
+ import { createOrgDeliveryGate } from "../org-delivery-gate.js";
3
+ export function mountOrgDeliveryGate(input) {
4
+ const consumer = principalInboxConsumerOf(input.runnerDeps);
5
+ if (consumer.kind === "none")
6
+ return undefined;
7
+ const { mailboxStore, directory, backend } = input;
8
+ if (mailboxStore === undefined || directory === undefined || backend === undefined) {
9
+ const missing = [
10
+ ...(mailboxStore === undefined ? ["a durable mailbox store (DB_BACKEND=mysql|pg|local)"] : []),
11
+ ...(directory === undefined ? ["an organization membership directory (a web-admin center, or MEMORY_ORG_DIRECTORY_JSON)"] : []),
12
+ ...(backend === undefined ? ["a store backend for the delivery quota (DB_BACKEND=mysql|pg|local)"] : []),
13
+ ];
14
+ throw new Error(`PRINCIPAL_INBOX_ASSISTANT declares a principal-inbox consumer, so this deployment must mount the organization delivery gate — but it lacks ${missing.join("; ")}. ` +
15
+ `Refusing to boot rather than run with a declared inbox that nothing may legitimately write to; provide the missing pieces or unset PRINCIPAL_INBOX_ASSISTANT.`);
16
+ }
17
+ input.logger.info("org_delivery_gate_mounted", { consumer: consumer.kind });
18
+ return createOrgDeliveryGate({ directory, mailbox: mailboxStore, quota: backend.orgDeliveryQuota(), consumer });
19
+ }
20
+ //# sourceMappingURL=org-delivery.js.map
@@ -25,6 +25,7 @@ import type { FileHistoryErasureFace } from "../file-history-capture.js";
25
25
  import type { ApprovalNonceStore, CheckpointStoreFull, CostQuotaStore, ImageBake, RateLimiterStore, ServiceWorkflowJournalStore, StoreBackend, ToolResultStoreFull } from "../plugins/store-backend.js";
26
26
  import type { ToolApprovalCoordinator } from "../tool-approval.js";
27
27
  import type { ParkCommitWatch } from "../plugins/park-commit-watch.js";
28
+ import { type AuditRotationPort } from "../approval-ask-retention.js";
28
29
  /** [ref] / [ref]§五(sema-comms `audits/failopen-governance-176.md` §7 "Z 类 1 条"):default consecutive-failure
29
30
  * count before a reaper leg's swallowed error gets a `warn` line. The ~15 `.catch(() => undefined)` sites
30
31
  * below are correct in DIRECTION (a hiccuping periodic sweep must never crash the whole tick loop — one bad
@@ -108,6 +109,8 @@ export interface ReapersCtx {
108
109
  * 受理的最后一刻),所以存量是「到达率 × TTL」而不是历史总量,清扫无需分批。无 backend 的 env-only
109
110
  * 部署 ⇒ undefined ⇒ 本腿零调用(那种部署也没有 durable 审批门)。 */
110
111
  approvalNonceStore: ApprovalNonceStore | undefined;
112
+ /** local 车道的审批审计账(装配三合取见 `boot/coordinators.ts`;SQL 车道 / 审批关着 ⇒ undefined)—— 本 tick 只用它的**留存轮转**一手。 */
113
+ approvalAskAudit: AuditRotationPort | undefined;
111
114
  /** 晚绑(server 造出来才有)——见文件头「位置即契约」①。 */
112
115
  getRunDenySweep: () => ((now: number) => Promise<void>) | undefined;
113
116
  }
@@ -4,6 +4,7 @@ import { CostQuota } from "../observability/cost-quota.js";
4
4
  import { isAdoptionQuiescing, trackMaintenanceLeg } from "../adoption/quiesce.js";
5
5
  import { createApprovalReconciler } from "../approval-reconciler.js";
6
6
  import { createE2bOrphanSandboxProvider, reclaimOrphanE2bSandboxes, E2B_ORPHAN_GRACE_MS } from "../plugins/e2b-orphan-reclaim.js";
7
+ import { APPROVAL_ASK_RETENTION_PASS_MS, runApprovalAskRetentionPass } from "../approval-ask-retention.js";
7
8
  export const REAPER_FAILURE_WARN_THRESHOLD = 5;
8
9
  export function createThrottledReaperCatch(name, logger, threshold = REAPER_FAILURE_WARN_THRESHOLD) {
9
10
  let streak = 0;
@@ -56,7 +57,7 @@ export function createPlacementAwareReapSessions(deps) {
56
57
  };
57
58
  }
58
59
  export function startReapers(ctx) {
59
- const { config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, parkCommits, rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap, workflowNotifyGate, workflowRecoverOpts, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore, backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore, getRunDenySweep, userInputLedger, } = ctx;
60
+ const { config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, parkCommits, rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap, workflowNotifyGate, workflowRecoverOpts, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore, backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore, getRunDenySweep, userInputLedger, approvalAskAudit, } = ctx;
60
61
  const leg = (p) => {
61
62
  if (p !== undefined)
62
63
  trackMaintenanceLeg(p);
@@ -101,6 +102,17 @@ export function startReapers(ctx) {
101
102
  const leaderRunStaleGuard = createThrottledReaperCatch("leader_run_reap_stale", logger);
102
103
  const leaderRunStore = config.leaderEnabled ? backend?.leaderRun?.() : undefined;
103
104
  const scratchpadSweepStaleGuard = createThrottledReaperCatch("scratchpad_sweep_stale", logger);
105
+ const approvalAskRetentionMs = config.approvalAskRetentionMs;
106
+ const approvalAskRetentionGuard = createThrottledReaperCatch("approval_ask_retention", logger);
107
+ let approvalAskRetentionLastRunMs = Number.NEGATIVE_INFINITY;
108
+ let approvalAskRetentionInFlight = false;
109
+ logger.info("approval_ask_retention", {
110
+ windowMs: approvalAskRetentionMs,
111
+ ledgers: { asks: backend !== undefined, audit: approvalAskAudit !== undefined },
112
+ note: approvalAskRetentionMs > 0
113
+ ? "settled approval asks quiet for longer than windowMs are deleted whole from the approval ledgers on the maintenance tick (at most once an hour); unsettled asks, and every ask hanging off something that can still move (a running / parked run or delegated child, by run id or session), are never aged out. APPROVAL_ASK_RETENTION_MS=0 keeps everything."
114
+ : "APPROVAL_ASK_RETENTION_MS=0 — the approval ledgers are kept forever (nothing is aged out).",
115
+ });
104
116
  const approvalReconcileGuard = createThrottledReaperCatch("approval_reconcile", logger);
105
117
  const approvalSuspendedPollGuard = createThrottledReaperCatch("approval_suspended_poll", logger);
106
118
  let approvalSuspendedPollInFlight = false;
@@ -325,6 +337,14 @@ export function startReapers(ctx) {
325
337
  if (permissionRuleStores?.reapExpired === undefined)
326
338
  permissionRuleReapInFlight = false;
327
339
  }
340
+ if (approvalAskRetentionMs > 0 && runStore !== undefined && !approvalAskRetentionInFlight && Date.now() - approvalAskRetentionLastRunMs >= APPROVAL_ASK_RETENTION_PASS_MS && (backend !== undefined || approvalAskAudit !== undefined)) {
341
+ approvalAskRetentionInFlight = true;
342
+ approvalAskRetentionLastRunMs = Date.now();
343
+ leg(Promise.resolve()
344
+ .then(() => runApprovalAskRetentionPass({ askStore: backend?.approvalAsk(), audit: approvalAskAudit, runs: runStore, backgroundAgents: backgroundAgentStore, checkpoints: backend?.checkpointReadView(), cutoffMs: Date.now() - approvalAskRetentionMs, logger, metrics }))
345
+ .then(() => approvalAskRetentionGuard.onSuccess(), approvalAskRetentionGuard.onError)
346
+ .finally(() => (approvalAskRetentionInFlight = false)));
347
+ }
328
348
  if (config.scratchpadSweepTtlMs > 0) {
329
349
  leg(sweepStaleScratchpads(config.localDataRoot ?? localRoot, { olderThanMs: config.scratchpadSweepTtlMs })
330
350
  .then((removed) => {
@@ -16,6 +16,7 @@ import type { StoreBackend } from "../plugins/store-backend.js";
16
16
  import { type TaskAttachmentStore } from "../plugins/task-attachment-store.js";
17
17
  import { type createPrincipalEntitlementsClient } from "../runtime-caps-resolver.js";
18
18
  import { type OwnerAwareSessionStore } from "../security.js";
19
+ import type { MemorySyncRunner } from "../memory-sync-client.js";
19
20
  import type { RunnerDepsOnAsk } from "./runner-deps.js";
20
21
  type PrincipalCaps = ReturnType<typeof createPrincipalEntitlementsClient>;
21
22
  /** `resolveSpec` 原先从 `main()` 闭包里拿到的全部 boot 局部量。 */
@@ -56,6 +57,8 @@ export interface ResolveSpecCtx {
56
57
  backend: MemoryBackend;
57
58
  root: string;
58
59
  } | undefined;
60
+ /** S-640:记忆同步腿(开 `MEMORY_SYNC_*` 且记忆引擎接线时在场)—— 项目层准备一步把本任务的项目层交给它跟踪(`memory-project-layer.ts`)。 */
61
+ memorySyncRunner: MemorySyncRunner | undefined;
59
62
  durableEnabled: boolean;
60
63
  /** [ref] ([ref] 案二):活体 AskUserQuestion 面(QuestionCoordinator 的判决探针切面)。在场(=
61
64
  * ASK_QUESTION_ENABLED)时 durable question 门按活流上下文分腿、spec 不再 stamp QUESTION_AWAITS_RESUME