@sema-agent/server 7.131.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 (509) hide show
  1. package/MIGRATION.md +575 -0
  2. package/README.md +12 -9
  3. package/README.zh-CN.md +9 -6
  4. package/USAGE.md +326 -98
  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 +82 -20
  24. package/dist/approval-card.js +46 -16
  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 +33 -19
  29. package/dist/audit.js +12 -16
  30. package/dist/auth-bridge.d.ts +4 -0
  31. package/dist/auth-bridge.js +10 -11
  32. package/dist/bake-runner/main.js +3 -2
  33. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  34. package/dist/boot/deployment-mods.d.ts +31 -0
  35. package/dist/boot/deployment-mods.js +26 -0
  36. package/dist/boot/execution-env.d.ts +1 -1
  37. package/dist/boot/execution-env.js +27 -12
  38. package/dist/boot/execution-lane.js +11 -0
  39. package/dist/boot/leader.js +2 -0
  40. package/dist/boot/memory-boundary.d.ts +2 -2
  41. package/dist/boot/memory-boundary.js +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +5 -4
  43. package/dist/boot/memory-consolidation.js +7 -6
  44. package/dist/boot/org-delivery.d.ts +28 -0
  45. package/dist/boot/org-delivery.js +20 -0
  46. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  47. package/dist/boot/read-deny-anchor-audit.js +36 -0
  48. package/dist/boot/reapers.d.ts +3 -0
  49. package/dist/boot/reapers.js +21 -1
  50. package/dist/boot/resolve-spec.d.ts +4 -5
  51. package/dist/boot/resolve-spec.js +74 -123
  52. package/dist/boot/runner-deps.d.ts +19 -8
  53. package/dist/boot/runner-deps.js +15 -2
  54. package/dist/boot/session-faces.d.ts +2 -7
  55. package/dist/boot/session-faces.js +4 -2
  56. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  57. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  58. package/dist/boot/stage-03-store-backend.js +2 -2
  59. package/dist/boot/stage-04-stores.d.ts +1 -1
  60. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  61. package/dist/boot/stage-05-execution-env.js +7 -10
  62. package/dist/boot/stage-06-runners.d.ts +4 -2
  63. package/dist/boot/stage-06-runners.js +11 -7
  64. package/dist/boot/stage-07-capability-layer.d.ts +4 -2
  65. package/dist/boot/stage-07-capability-layer.js +27 -6
  66. package/dist/boot/stage-08-reapers.d.ts +4 -2
  67. package/dist/boot/stage-08-reapers.js +2 -2
  68. package/dist/boot/stage-09-leader.d.ts +6 -9
  69. package/dist/boot/stage-10-http-server.d.ts +6 -9
  70. package/dist/boot/stage-10-http-server.js +7 -9
  71. package/dist/boot/stores.d.ts +1 -1
  72. package/dist/boot/stores.js +7 -8
  73. package/dist/boot/web-admin.d.ts +4 -3
  74. package/dist/boot/web-admin.js +186 -98
  75. package/dist/boot/workflow-orchestration.d.ts +2 -0
  76. package/dist/boot/workflow-orchestration.js +2 -1
  77. package/dist/brain.js +25 -25
  78. package/dist/breaker-key.d.ts +6 -0
  79. package/dist/breaker-key.js +29 -0
  80. package/dist/budget.js +5 -4
  81. package/dist/caller-text-echo.d.ts +23 -0
  82. package/dist/caller-text-echo.js +21 -0
  83. package/dist/capabilities/brand-identity.d.ts +26 -0
  84. package/dist/capabilities/brand-identity.js +27 -0
  85. package/dist/capabilities/center-plugins.d.ts +7 -0
  86. package/dist/capabilities/center-plugins.js +1 -1
  87. package/dist/capabilities/center-prompts.d.ts +32 -59
  88. package/dist/capabilities/center-prompts.js +18 -32
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/engine-capabilities.js +2 -1
  92. package/dist/capabilities/execution-lane.js +2 -2
  93. package/dist/capabilities/hands-lane.d.ts +30 -6
  94. package/dist/capabilities/hands-lane.js +11 -1
  95. package/dist/capabilities/mcp-probe.d.ts +48 -3
  96. package/dist/capabilities/mcp-probe.js +47 -135
  97. package/dist/capabilities/scenarios.d.ts +95 -45
  98. package/dist/capabilities/scenarios.js +53 -38
  99. package/dist/capabilities/skills.d.ts +19 -4
  100. package/dist/capabilities/skills.js +30 -10
  101. package/dist/capability-facts.d.ts +34 -4
  102. package/dist/capability-facts.js +28 -2
  103. package/dist/center-config-tier.d.ts +69 -0
  104. package/dist/center-config-tier.js +42 -0
  105. package/dist/checkpoint-identity.d.ts +16 -0
  106. package/dist/checkpoint-identity.js +19 -0
  107. package/dist/config-catalog.d.ts +17 -10
  108. package/dist/config-catalog.js +47 -32
  109. package/dist/config-d-migration.d.ts +3 -1
  110. package/dist/config-d-migration.js +2 -2
  111. package/dist/config-dir-trust.d.ts +114 -0
  112. package/dist/config-dir-trust.js +388 -0
  113. package/dist/config-invariants.d.ts +18 -5
  114. package/dist/config-invariants.js +35 -3
  115. package/dist/config-lkg.d.ts +9 -9
  116. package/dist/config-lkg.js +20 -4
  117. package/dist/config-provider.d.ts +9 -2
  118. package/dist/config-provider.js +18 -6
  119. package/dist/config-types.d.ts +75 -20
  120. package/dist/config-types.js +8 -0
  121. package/dist/config.d.ts +13 -0
  122. package/dist/config.js +137 -62
  123. package/dist/delegated-session-owner.d.ts +185 -0
  124. package/dist/delegated-session-owner.js +119 -0
  125. package/dist/device-protocol.d.ts +5 -3
  126. package/dist/device-protocol.js +1 -1
  127. package/dist/device-ws-hub.js +21 -2
  128. package/dist/device-ws-protocol.d.ts +70 -6
  129. package/dist/device-ws-protocol.js +50 -22
  130. package/dist/elicitation.js +3 -2
  131. package/dist/entry-problems.d.ts +34 -0
  132. package/dist/entry-problems.js +14 -0
  133. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  134. package/dist/env-name-allowlist-knobs.js +5 -4
  135. package/dist/exec-bounds.d.ts +15 -3
  136. package/dist/exec-bounds.js +4 -0
  137. package/dist/execution-lane-caps.d.ts +56 -10
  138. package/dist/execution-lane-caps.js +50 -0
  139. package/dist/field-conflict.d.ts +43 -0
  140. package/dist/field-conflict.js +20 -0
  141. package/dist/fleet/fleet-bus.d.ts +80 -6
  142. package/dist/fleet/fleet-bus.js +41 -9
  143. package/dist/hooks/classic-stations.d.ts +91 -0
  144. package/dist/hooks/classic-stations.js +27 -0
  145. package/dist/hooks/command-spawn.d.ts +57 -0
  146. package/dist/hooks/command-spawn.js +139 -0
  147. package/dist/hooks/hook-llm.d.ts +8 -5
  148. package/dist/hooks/hook-llm.js +79 -36
  149. package/dist/hooks/hook-runner.d.ts +349 -95
  150. package/dist/hooks/hook-runner.js +855 -568
  151. package/dist/hooks/hook-source.d.ts +44 -0
  152. package/dist/hooks/hook-source.js +40 -0
  153. package/dist/http/active-run-conflict.d.ts +5 -13
  154. package/dist/http/active-run-conflict.js +17 -27
  155. package/dist/http/admission.d.ts +8 -2
  156. package/dist/http/admission.js +188 -101
  157. package/dist/http/approval-sweeps.js +99 -21
  158. package/dist/http/caller-trust.d.ts +77 -0
  159. package/dist/http/caller-trust.js +143 -0
  160. package/dist/http/checkpoint-ctx.d.ts +41 -24
  161. package/dist/http/checkpoint-ctx.js +23 -16
  162. package/dist/http/claimed-run.d.ts +14 -0
  163. package/dist/http/claimed-run.js +15 -0
  164. package/dist/http/device-placement.d.ts +2 -4
  165. package/dist/http/device-placement.js +7 -11
  166. package/dist/http/dispatch.d.ts +0 -4
  167. package/dist/http/dispatch.js +15 -13
  168. package/dist/http/durable-run-leg.d.ts +6 -33
  169. package/dist/http/durable-run-leg.js +36 -10
  170. package/dist/http/health-self-report.d.ts +7 -5
  171. package/dist/http/health-self-report.js +4 -18
  172. package/dist/http/owner-access.d.ts +56 -0
  173. package/dist/http/owner-access.js +42 -0
  174. package/dist/http/principal-gate.d.ts +70 -28
  175. package/dist/http/principal-gate.js +61 -15
  176. package/dist/http/readiness.d.ts +11 -5
  177. package/dist/http/readiness.js +10 -3
  178. package/dist/http/refusal-body.d.ts +21 -0
  179. package/dist/http/refusal-body.js +4 -0
  180. package/dist/http/request-guards.d.ts +43 -23
  181. package/dist/http/request-guards.js +53 -17
  182. package/dist/http/resume-ctx-read.d.ts +2 -5
  183. package/dist/http/resume-ctx-read.js +7 -4
  184. package/dist/http/resume-legs.d.ts +28 -4
  185. package/dist/http/resume-legs.js +169 -91
  186. package/dist/http/retired-service-deps.d.ts +43 -0
  187. package/dist/http/retired-service-deps.js +18 -0
  188. package/dist/http/route-ctx.d.ts +44 -28
  189. package/dist/http/route-ctx.js +4 -0
  190. package/dist/http/route-table.js +2 -0
  191. package/dist/http/routes/a2a-serve.js +3 -4
  192. package/dist/http/routes/admin-config-refresh.js +1 -1
  193. package/dist/http/routes/admin-drain.js +1 -1
  194. package/dist/http/routes/admin-memory-optout.js +5 -1
  195. package/dist/http/routes/adoption.js +2 -9
  196. package/dist/http/routes/approvals-assistant.js +49 -48
  197. package/dist/http/routes/background.js +3 -2
  198. package/dist/http/routes/capabilities.js +21 -5
  199. package/dist/http/routes/config-catalog.d.ts +3 -3
  200. package/dist/http/routes/config-catalog.js +1 -1
  201. package/dist/http/routes/devices.js +3 -17
  202. package/dist/http/routes/diagnostics.js +6 -2
  203. package/dist/http/routes/images.js +6 -7
  204. package/dist/http/routes/leader.js +1 -8
  205. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  206. package/dist/http/routes/mcp-reconnect.js +3 -2
  207. package/dist/http/routes/memory-bundle.js +1 -1
  208. package/dist/http/routes/memory-compliance.js +1 -1
  209. package/dist/http/routes/memory-consolidation.js +1 -1
  210. package/dist/http/routes/memory-origin.js +1 -1
  211. package/dist/http/routes/memory-policy.d.ts +1 -1
  212. package/dist/http/routes/memory-policy.js +3 -2
  213. package/dist/http/routes/notify-wake.js +8 -21
  214. package/dist/http/routes/observability.js +2 -2
  215. package/dist/http/routes/principal-inbox.d.ts +39 -0
  216. package/dist/http/routes/principal-inbox.js +76 -0
  217. package/dist/http/routes/retention-ops.js +2 -9
  218. package/dist/http/routes/rules.js +5 -18
  219. package/dist/http/routes/runs.d.ts +5 -0
  220. package/dist/http/routes/runs.js +34 -107
  221. package/dist/http/routes/session-sync.js +15 -26
  222. package/dist/http/routes/sessions.js +30 -40
  223. package/dist/http/routes/shared-memory.js +2 -13
  224. package/dist/http/routes/side-query.js +8 -7
  225. package/dist/http/routes/tasks.js +67 -21
  226. package/dist/http/routes/workflows.d.ts +351 -0
  227. package/dist/http/routes/workflows.js +153 -119
  228. package/dist/http/send.d.ts +33 -10
  229. package/dist/http/send.js +21 -4
  230. package/dist/http/server.d.ts +27 -18
  231. package/dist/http/server.js +34 -6
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +25 -0
  234. package/dist/http/submit-ctx.js +40 -0
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +11 -8
  238. package/dist/index.d.ts +2 -2
  239. package/dist/index.js +1 -2
  240. package/dist/lane-home-probe.d.ts +112 -0
  241. package/dist/lane-home-probe.js +101 -0
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/limit-refusal.d.ts +59 -0
  245. package/dist/limit-refusal.js +15 -0
  246. package/dist/main.js +1 -1
  247. package/dist/mcp-assertion-header.d.ts +32 -19
  248. package/dist/mcp-assertion-header.js +10 -9
  249. package/dist/mcp-tool-faces.d.ts +5 -0
  250. package/dist/mcp-tool-faces.js +6 -4
  251. package/dist/memory-project-layer.d.ts +37 -0
  252. package/dist/memory-project-layer.js +46 -0
  253. package/dist/memory-scope.d.ts +24 -17
  254. package/dist/memory-scope.js +24 -8
  255. package/dist/memory-sync-client.d.ts +27 -13
  256. package/dist/memory-sync-client.js +107 -18
  257. package/dist/model-entry-refusal.d.ts +9 -1
  258. package/dist/model-entry-refusal.js +6 -1
  259. package/dist/model-plane-face.d.ts +51 -0
  260. package/dist/model-plane-face.js +24 -0
  261. package/dist/model-provider.d.ts +44 -12
  262. package/dist/model-provider.js +21 -2
  263. package/dist/model-route-endpoint.d.ts +9 -12
  264. package/dist/model-route-endpoint.js +8 -11
  265. package/dist/model-route-env.d.ts +22 -0
  266. package/dist/model-route-env.js +2 -0
  267. package/dist/model-route-gap.d.ts +60 -30
  268. package/dist/model-route-gap.js +21 -15
  269. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  270. package/dist/observability/corrupt-read-seat.js +9 -0
  271. package/dist/observability/cost-taxonomy.d.ts +7 -7
  272. package/dist/observability/err-text.d.ts +6 -0
  273. package/dist/observability/err-text.js +18 -4
  274. package/dist/observability/fail-open.d.ts +76 -14
  275. package/dist/observability/fail-open.js +76 -14
  276. package/dist/observability/metrics.js +4 -1
  277. package/dist/observability/prompt-manifest.d.ts +33 -82
  278. package/dist/observability/prompt-manifest.js +122 -17
  279. package/dist/observability/run-terminal.js +14 -6
  280. package/dist/observability/secret-env-scrub.d.ts +13 -1
  281. package/dist/observability/secret-env-scrub.js +13 -1
  282. package/dist/observability/tool-trace.d.ts +16 -21
  283. package/dist/observability/tool-trace.js +58 -49
  284. package/dist/operator-ask.d.ts +10 -0
  285. package/dist/operator-ask.js +3 -0
  286. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  287. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  288. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  289. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  290. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  291. package/dist/orchestration/workflow-notify-journal.js +27 -34
  292. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  293. package/dist/orchestration/workflow-park-decision.js +118 -0
  294. package/dist/org-delivery-gate.d.ts +81 -0
  295. package/dist/org-delivery-gate.js +59 -0
  296. package/dist/panel-tool-names.d.ts +23 -0
  297. package/dist/panel-tool-names.js +8 -0
  298. package/dist/parked-decide.d.ts +39 -6
  299. package/dist/parked-decide.js +98 -51
  300. package/dist/parked-revive-surface.d.ts +9 -2
  301. package/dist/parked-revive-surface.js +11 -8
  302. package/dist/per-task-image.d.ts +7 -1
  303. package/dist/per-task-image.js +3 -3
  304. package/dist/permission-rule-list.d.ts +1 -1
  305. package/dist/permission-rule-list.js +2 -2
  306. package/dist/plain-string-record.d.ts +25 -0
  307. package/dist/plain-string-record.js +32 -0
  308. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  309. package/dist/plugins/approval-ask-store-file.js +21 -0
  310. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  311. package/dist/plugins/approval-ask-store-memory.js +34 -2
  312. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  313. package/dist/plugins/approval-ask-store-sql.js +37 -1
  314. package/dist/plugins/blob-backend.d.ts +83 -15
  315. package/dist/plugins/blob-backend.js +68 -15
  316. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  317. package/dist/plugins/breaker-state-sql.js +4 -4
  318. package/dist/plugins/caching-session-store.d.ts +3 -0
  319. package/dist/plugins/caching-session-store.js +3 -0
  320. package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
  321. package/dist/plugins/checkpoint-store-sql.js +59 -28
  322. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  323. package/dist/plugins/file-history-store-sql.js +3 -1
  324. package/dist/plugins/file-run-store.d.ts +5 -13
  325. package/dist/plugins/file-run-store.js +9 -0
  326. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  327. package/dist/plugins/fork-routing-session-store.js +12 -1
  328. package/dist/plugins/host-platform.d.ts +2 -0
  329. package/dist/plugins/host-platform.js +2 -1
  330. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  331. package/dist/plugins/k8s-bg-scripts.js +22 -0
  332. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  333. package/dist/plugins/local-checkpoint-store.js +11 -3
  334. package/dist/plugins/local-session-store.d.ts +1 -1
  335. package/dist/plugins/local-session-store.js +1 -1
  336. package/dist/plugins/local-session-window.d.ts +39 -0
  337. package/dist/plugins/local-session-window.js +54 -0
  338. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  340. package/dist/plugins/mailbox-store-sql.js +77 -52
  341. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  342. package/dist/plugins/memory-run-store.d.ts +5 -13
  343. package/dist/plugins/memory-run-store.js +8 -0
  344. package/dist/plugins/one-time-migrations.d.ts +245 -93
  345. package/dist/plugins/one-time-migrations.js +668 -207
  346. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  347. package/dist/plugins/org-delivery-quota-store.js +228 -0
  348. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  349. package/dist/plugins/permission-rule-store-sql.js +4 -18
  350. package/dist/plugins/pg-pool.js +39 -7
  351. package/dist/plugins/pg-session-storage.d.ts +20 -8
  352. package/dist/plugins/pg-session-storage.js +34 -21
  353. package/dist/plugins/remote-env-adb.d.ts +12 -12
  354. package/dist/plugins/remote-env-adb.js +21 -6
  355. package/dist/plugins/remote-env-device.js +3 -0
  356. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  357. package/dist/plugins/remote-env-e2b.js +21 -9
  358. package/dist/plugins/remote-env-host.d.ts +9 -9
  359. package/dist/plugins/remote-env-host.js +10 -32
  360. package/dist/plugins/remote-env-k8s.d.ts +103 -38
  361. package/dist/plugins/remote-env-k8s.js +288 -95
  362. package/dist/plugins/remote-env-local-docker.d.ts +27 -13
  363. package/dist/plugins/remote-env-local-docker.js +82 -11
  364. package/dist/plugins/remote-env-ssh.d.ts +21 -12
  365. package/dist/plugins/remote-env-ssh.js +117 -5
  366. package/dist/plugins/remote-shell.d.ts +0 -1
  367. package/dist/plugins/remote-shell.js +1 -2
  368. package/dist/plugins/retention-store-sql.js +6 -2
  369. package/dist/plugins/run-store-sql.d.ts +16 -14
  370. package/dist/plugins/run-store-sql.js +22 -2
  371. package/dist/plugins/schema-consistency.d.ts +54 -0
  372. package/dist/plugins/schema-consistency.js +52 -0
  373. package/dist/plugins/schema-indexes.js +2 -0
  374. package/dist/plugins/send-user-file.js +2 -2
  375. package/dist/plugins/session-epoch-anchor.d.ts +39 -0
  376. package/dist/plugins/session-epoch-anchor.js +22 -0
  377. package/dist/plugins/session-store.d.ts +18 -8
  378. package/dist/plugins/session-store.js +15 -4
  379. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  380. package/dist/plugins/shared-memory-store-sql.js +5 -16
  381. package/dist/plugins/sql-driver.d.ts +205 -1
  382. package/dist/plugins/sql-driver.js +325 -13
  383. package/dist/plugins/sql-errors.d.ts +64 -0
  384. package/dist/plugins/sql-errors.js +57 -0
  385. package/dist/plugins/store-backend.d.ts +36 -1
  386. package/dist/plugins/store-backend.js +42 -15
  387. package/dist/plugins/store-contracts.d.ts +42 -0
  388. package/dist/plugins/store-contracts.js +1 -0
  389. package/dist/plugins/tidb-pool.d.ts +6 -1
  390. package/dist/plugins/tidb-pool.js +44 -10
  391. package/dist/plugins/tidb-session-storage.d.ts +8 -11
  392. package/dist/plugins/tidb-session-storage.js +6 -16
  393. package/dist/plugins/tidb-session-store.d.ts +24 -4
  394. package/dist/plugins/tidb-session-store.js +29 -5
  395. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  396. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  397. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  398. package/dist/plugins/workflow-run-store-sql.js +50 -9
  399. package/dist/posture-source.d.ts +18 -10
  400. package/dist/posture-source.js +4 -1
  401. package/dist/project-identity.d.ts +45 -6
  402. package/dist/project-identity.js +162 -8
  403. package/dist/project-layer-key.d.ts +28 -0
  404. package/dist/project-layer-key.js +29 -0
  405. package/dist/prompts-domain-validate.d.ts +17 -61
  406. package/dist/prompts-domain-validate.js +9 -119
  407. package/dist/question.js +3 -2
  408. package/dist/read-deny-entry.d.ts +25 -0
  409. package/dist/read-deny-entry.js +12 -0
  410. package/dist/read-face-posture.d.ts +37 -11
  411. package/dist/read-face-posture.js +32 -3
  412. package/dist/request-key-closure.d.ts +9 -2
  413. package/dist/request-key-closure.js +11 -5
  414. package/dist/request-value-closure.d.ts +5 -0
  415. package/dist/request-value-closure.js +11 -3
  416. package/dist/rule-entry-list.d.ts +38 -11
  417. package/dist/rule-entry-list.js +106 -30
  418. package/dist/rules-consent.js +3 -4
  419. package/dist/run-acceptance.d.ts +19 -3
  420. package/dist/run-acceptance.js +13 -1
  421. package/dist/run-local.js +54 -24
  422. package/dist/runs.d.ts +15 -8
  423. package/dist/runs.js +35 -1
  424. package/dist/runtime-caps-resolver.d.ts +16 -6
  425. package/dist/runtime-caps-resolver.js +18 -5
  426. package/dist/sandbox-pkg-source.d.ts +19 -1
  427. package/dist/sandbox-pkg-source.js +29 -7
  428. package/dist/security.d.ts +87 -9
  429. package/dist/security.js +52 -9
  430. package/dist/server-secret-env.d.ts +44 -18
  431. package/dist/server-secret-env.js +49 -8
  432. package/dist/session-error-wire.d.ts +19 -2
  433. package/dist/session-error-wire.js +5 -1
  434. package/dist/session-incarnation.d.ts +15 -5
  435. package/dist/session-incarnation.js +16 -9
  436. package/dist/session-titled-frame.d.ts +33 -0
  437. package/dist/session-titled-frame.js +4 -0
  438. package/dist/session-titler.d.ts +9 -1
  439. package/dist/session-titler.js +27 -6
  440. package/dist/spec-fields.d.ts +28 -16
  441. package/dist/spec-fields.js +66 -54
  442. package/dist/sql-engine-posture.d.ts +31 -4
  443. package/dist/sql-engine-posture.js +36 -1
  444. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  445. package/dist/stored-request-tool-axes-m19.js +30 -2
  446. package/dist/task-a2a.d.ts +9 -1
  447. package/dist/task-a2a.js +73 -47
  448. package/dist/task-cwd.d.ts +1 -1
  449. package/dist/task-mcp.d.ts +46 -58
  450. package/dist/task-mcp.js +82 -107
  451. package/dist/task-settings.d.ts +95 -108
  452. package/dist/task-settings.js +77 -98
  453. package/dist/text-bidi.d.ts +1 -48
  454. package/dist/text-bidi.js +3 -5
  455. package/dist/tighten-only-seats.d.ts +150 -0
  456. package/dist/tighten-only-seats.js +196 -0
  457. package/dist/tool-approval.d.ts +304 -88
  458. package/dist/tool-approval.js +623 -239
  459. package/dist/trace/core-keyset-guard.d.ts +122 -20
  460. package/dist/trace/engine-notice-wire.d.ts +11 -3
  461. package/dist/trace/engine-notice-wire.js +8 -1
  462. package/dist/trace/exit-seat.d.ts +28 -0
  463. package/dist/trace/exit-seat.js +76 -0
  464. package/dist/trace/ledger-events.d.ts +6 -3
  465. package/dist/trace/ledger-sink.js +4 -1
  466. package/dist/trace/model-segment.js +1 -1
  467. package/dist/trace/project.d.ts +98 -17
  468. package/dist/trace/project.js +98 -50
  469. package/dist/trace/projection-table.d.ts +100 -0
  470. package/dist/trace/projection-table.js +130 -0
  471. package/dist/trace/redact.d.ts +54 -0
  472. package/dist/trace/redact.js +778 -152
  473. package/dist/trace/self-minted-wire.d.ts +345 -1
  474. package/dist/trace/self-minted-wire.js +117 -1
  475. package/dist/trace/wire-projection-faces.d.ts +377 -3
  476. package/dist/trace/wire-projection-faces.js +164 -1
  477. package/dist/url-refusal.js +2 -0
  478. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  479. package/dist/web-admin-client/apply-effective.js +56 -5
  480. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  481. package/dist/web-admin-client/candidate-gate.js +3 -3
  482. package/dist/web-admin-client/facade.d.ts +1 -1
  483. package/dist/web-admin-client/facade.js +1 -1
  484. package/dist/web-admin-client/http-client.js +0 -6
  485. package/dist/web-admin-client/read-face.js +5 -9
  486. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  487. package/dist/web-admin-client/read-warnings.js +10 -0
  488. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  489. package/dist/web-admin-client/skills-mcp.js +11 -9
  490. package/dist/web-admin-client/types.d.ts +2 -3
  491. package/dist/workspace-cache.d.ts +35 -0
  492. package/dist/workspace-cache.js +36 -0
  493. package/dist/workspace-space.d.ts +3 -2
  494. package/dist/workspace-space.js +2 -0
  495. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
  496. package/package.json +8 -4
  497. package/scripts/drain-check-local.mjs +34 -1
  498. package/scripts/drain-check.mysql.sql +30 -2
  499. package/scripts/drain-check.pg.sql +29 -2
  500. package/dist/capabilities/memory-notice.d.ts +0 -138
  501. package/dist/capabilities/memory-notice.js +0 -64
  502. package/dist/capabilities/prompt.d.ts +0 -17
  503. package/dist/capabilities/prompt.js +0 -6
  504. package/dist/mcp-content-origin.d.ts +0 -34
  505. package/dist/mcp-content-origin.js +0 -10
  506. package/dist/tool-axis-words.d.ts +0 -27
  507. package/dist/tool-axis-words.js +0 -9
  508. package/dist/wire-name-bound.d.ts +0 -14
  509. package/dist/wire-name-bound.js +0 -13
package/dist/config.js CHANGED
@@ -3,48 +3,55 @@ import { DEFAULT_AT_MENTION, DEFAULT_MODEL_REF, mintCapabilityKeys } from "./mod
3
3
  import { homedir } from "node:os";
4
4
  import { join, posix as posixPath } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { compileAllowList, BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, CROSS_SESSION_INBOUND_SETTINGS, CROSS_SESSION_DIALOG_EXPIRY_VALUES, compileReadDeny, resolveReadDenyBuiltins, CODE_AGENT_PROMPT, isModelPriced, PROTOCOL_TABLE, RECOMMENDED_SENSITIVE_PATTERNS, judgeRuleToolName, resolveFileHistoryRetention, resolveLockedKeys, validatePermissionRules, WRITE_PROTECTED_DEFAULT_TABLE, resolveWriteProtectedTable } from "@sema-agent/core";
7
- import { ROSTER_PRIMARY_ROLES, ROSTER_CHEAP_ROLES, WEB_ADMIN_ENV, retiredEnvRefusal } from "@sema-agent/settings-schema";
6
+ import { compileAllowList, inheritEnvPolicyProblem, BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, CROSS_SESSION_INBOUND_SETTINGS, CROSS_SESSION_DIALOG_EXPIRY_VALUES, compileReadDeny, resolveReadDenyBuiltins, CODE_AGENT_PROMPT, isModelPriced, PROTOCOL_TABLE, RECOMMENDED_SENSITIVE_PATTERNS, judgeRuleToolName, resolveFileHistoryRetention, resolveLockedKeys, validatePermissionRules, WRITE_PROTECTED_DEFAULT_TABLE, resolveWriteProtectedTable, principalInboxConsumerOf } from "@sema-agent/core";
7
+ import { ROSTER_PRIMARY_ROLES, ROSTER_CHEAP_ROLES, WEB_ADMIN_ENV, retiredEnvRefusal, stripControlAndBidi } from "@sema-agent/settings-schema";
8
8
  import { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
9
9
  import { DEFAULT_ELICITATION_THROTTLE } from "./elicitation.js";
10
- import { isV2ScopeKey, memoryReplicationCoverage, replicationCovers } from "./memory-scope.js";
10
+ import { isV2ScopeKey, memoryReplicationCoverage, replicatesProjectLayersOf } from "./memory-scope.js";
11
+ import { assertProjectLayerOwnable } from "./project-identity.js";
12
+ import { projectLayerOwnerOf } from "./project-layer-key.js";
11
13
  import { DEFAULT_QUESTION_THROTTLE } from "./question.js";
12
14
  import { GIT_API_KINDS, isGitApiKind } from "./git-api-kind.js";
13
- import { CONFIG_PROVIDER_WORDS, RETENTION_MODES, MEMORY_CONSOLIDATION_MIN_INTERVAL_SEC, RESILIENCE_DEFAULTS, TASK_WRITE_FACE_ESCALATIONS, MAX_TIMER_DELAY_MS, AUTO_MODE_CLASSIFIER_TIMEOUT_BOUNDS, DRAIN_GRACE_FLOOR_MS, DRAIN_SECOND_SIGNAL_MIN_GAP_BOUNDS, DRAIN_SECOND_SIGNAL_MIN_GAP_DEFAULT_MS, FIRST_BYTE_TIMEOUT_BOUNDS, FLEET_LEASE_OUTAGE_MAX_DEFAULT_MS, fleetScopeOf } from "./config-types.js";
15
+ import { CONFIG_PROVIDER_WORDS, RETENTION_MODES, MEMORY_CONSOLIDATION_MIN_INTERVAL_SEC, RESILIENCE_DEFAULTS, TASK_WRITE_FACE_ESCALATIONS, MAX_TIMER_DELAY_MS, AUTO_MODE_CLASSIFIER_TIMEOUT_BOUNDS, DRAIN_GRACE_FLOOR_MS, DRAIN_SECOND_SIGNAL_MIN_GAP_BOUNDS, DRAIN_SECOND_SIGNAL_MIN_GAP_DEFAULT_MS, FIRST_BYTE_TIMEOUT_BOUNDS, FLEET_LEASE_OUTAGE_MAX_DEFAULT_MS, fleetScopeOf, DEVICE_DELIVERY_TIMEOUT_BOUNDS, DEVICE_EXEC_TIMEOUT_BOUNDS, inWholeNumberBounds, wholeNumberBoundsRule } from "./config-types.js";
16
+ import { DEVICE_HELLO_ACK_BOUNDS } from "./device-ws-protocol.js";
14
17
  import { FLEET_GENERATION_ENV, FLEET_SCOPE_ENV, SERVING_LEASE_TTL_FLOOR_MS, isCanonicalGeneration } from "@sema-agent/settings-schema/fleet";
15
18
  import { ScopeId } from "@sema-agent/settings-schema/api/scopes";
16
19
  import { centerLaneConfigured, pathBaseUrlRefusal } from "./web-admin-client/center-request.js";
17
20
  import { resolveLocalDataRoot } from "./local-data-root.js";
18
21
  import { buildWriteProtectionPosture } from "./write-protection.js";
19
22
  import { normalizeSshFingerprint } from "./ssh-host-key.js";
20
- import { buildReadFacePostureNotice, readFaceForPosture } from "./read-face-posture.js";
23
+ import { buildReadFacePostureNotice, settleDerivedReadFace } from "./read-face-posture.js";
21
24
  import { THINKING_LEVELS, THINKING_FORMATS, buildModelCompat, isThinkingFormat, isThinkingTier } from "./model-compat.js";
22
25
  import {} from "./posture-source.js";
23
26
  import { COST_QUOTA_WINDOW_SEC_RANGE, costQuotaWindowSecInRange } from "./observability/cost-quota.js";
24
- import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
25
27
  import { TOOL_NAME_ROSTER, describeUnmatchableRuleName, ruleEntryToolName, unmatchableRuleNameOf } from "./namespaced-rule-name.js";
26
- import { bakeOperatorPrincipalsRefusal, bakeRunnerCredentialRefusal, centerIdentityRefusal, halfOpenDirectDoorRefusal, leaderDurableStoreRefusal, operatorPrincipalsRequiredRefusal } from "./config-invariants.js";
28
+ import { bakeOperatorPrincipalsRefusal, bakeRunnerCredentialRefusal, centerIdentityRefusal, halfOpenDirectDoorRefusal, leaderDurableStoreRefusal, operatorPrincipalsRequiredRefusal, operatorSingleUserRefusal, workflowParkDecisionDomainRefusal } from "./config-invariants.js";
27
29
  import { declaredSemaConfigDir } from "./sema-config-dir.js";
28
30
  import { lkgPathOverrideOf } from "./config-lkg.js";
29
31
  import { K8S_WORKSPACE_MOUNT_DEFAULT, WORKSPACE_PERSIST_DEFAULT, WORKSPACE_PERSIST_WORDS, WORKSPACE_SNAPSHOT_KEEP_DEFAULT, WORKSPACE_SNAPSHOT_KEEP_RANGE, WORKSPACE_SNAPSHOT_TIMEOUT_MS_DEFAULT, WORKSPACE_SNAPSHOT_TIMEOUT_MS_RANGE, parseWorkspaceSnapshotExclude } from "./workspace-space.js";
30
32
  import { laneLivenessOf } from "./exec-bounds.js";
31
33
  import { SANDBOX_IPV6_DEFAULT, SANDBOX_IPV6_WORDS } from "./sandbox-egress-policy.js";
32
- import { WORKSPACE_CACHE_DEFAULT, WORKSPACE_CACHE_MOUNT_DEFAULT, WORKSPACE_CACHE_SIZE_DEFAULT, WORKSPACE_CACHE_WORDS, isK8sQuantity, mountsOverlap } from "./workspace-cache.js";
34
+ import { WORKSPACE_CACHE_DEFAULT, WORKSPACE_CACHE_MOUNT_DEFAULT, WORKSPACE_CACHE_MOUNT_RESERVED, WORKSPACE_CACHE_SIZE_DEFAULT, WORKSPACE_CACHE_WORDS, isK8sQuantity, mountsOverlap, reservedMountCollision } from "./workspace-cache.js";
33
35
  import { REMOTE_EXEC_PROVIDER_WORDS, executionLaneOf, executionLaneRequiredRefusal, isSingleMachineDefaultLane, laneRequiredEnv } from "./execution-lane-caps.js";
34
36
  import { MEMORY_ENGINE_BACKENDS, SESSION_BACKENDS, STORE_BACKENDS } from "@sema-agent/settings-schema/execution-lanes";
35
37
  import { AUTONOMY_MODES } from "./runtime-governance.js";
36
38
  import { MAX_NAMED_INERT_ENTRIES, allowLayerEntryCountIssue, describeInertRuleEntries, inertRuleEntriesOf, inertRuleEntryGuidance, ruleEntryListShapeOk } from "./rule-entry-list.js";
39
+ import { readReadDenyEntry } from "./read-deny-entry.js";
37
40
  import { createCenterCredentialSource, readCenterCredentialDeclaration } from "./center-credential.js";
38
41
  import { parseCenterCredentialRenewLeadMs } from "./center-credential-renewer.js";
39
42
  import { modelProviderRefusal } from "./model-provider.js";
40
43
  import { modelRouteUrlRefusal } from "./model-route-url.js";
41
44
  import { httpUrlFlaws } from "@sema-agent/settings-schema";
42
45
  import { buildHttpUrlRefusal } from "./url-refusal.js";
46
+ import { customPkgSourceFromEnv } from "./sandbox-pkg-source.js";
43
47
  import { csvOf, envLaneTable, mintedCheapId, readModelRouteEnv } from "./model-route-gap.js";
44
48
  import { displayListEntry } from "./list-entry-display.js";
49
+ import { echoCallerText } from "./caller-text-echo.js";
45
50
  import { buildDisplaySafeUrl, redactSecrets } from "./trace/redact.js";
51
+ import { parseConfigLocalOwnerUid } from "./config-dir-trust.js";
46
52
  import { allowlistedEnv } from "./server-secret-env.js";
47
53
  import { ENV_NAME_ALLOWLIST_KNOBS, ENV_NAME_ALLOWLIST_KNOB_NAMES, describeAllowlistPostures } from "./env-name-allowlist-knobs.js";
54
+ import { APPROVAL_ASK_RETENTION_DEFAULT_MS, APPROVAL_ASK_RETENTION_FLOOR_MS } from "./approval-ask-retention.js";
48
55
  export { RETENTION_MODES, MEMORY_CONSOLIDATION_MIN_INTERVAL_SEC } from "./config-types.js";
49
56
  function csv(name) {
50
57
  return csvOf(process.env[name]);
@@ -183,13 +190,14 @@ function buildExecLaneNotice(remoteExec) {
183
190
  source: lane === "in-process" ? "default-unset" : isSingleMachineDefaultLane(remoteExec) ? "default-local-provider" : "explicit-env",
184
191
  };
185
192
  }
193
+ const ENV_VALUE_ECHO_CHARS = 120;
186
194
  function parseConfigProvider() {
187
195
  const raw = process.env.CONFIG_PROVIDER;
188
196
  if (raw === undefined || raw === "")
189
197
  return undefined;
190
198
  const word = CONFIG_PROVIDER_WORDS.find((w) => w === raw);
191
199
  if (word === undefined) {
192
- throw new Error(`env CONFIG_PROVIDER="${raw.slice(0, 120)}" must be one of: ${CONFIG_PROVIDER_WORDS.join(", ")} — or leave it unset (then ${WEB_ADMIN_ENV.url}, if set, selects the center as the config source; otherwise this worker is env-only). ` +
200
+ throw new Error(`env CONFIG_PROVIDER="${echoCallerText(raw, { maxChars: ENV_VALUE_ECHO_CHARS })}" must be one of: ${CONFIG_PROVIDER_WORDS.join(", ")} — or leave it unset (then ${WEB_ADMIN_ENV.url}, if set, selects the center as the config source; otherwise this worker is env-only). ` +
193
201
  `The word is matched exactly (no trimming, no case folding). Refusing to boot rather than guessing: the config source, the execution-lane default and the local config root all key on this one word.`);
194
202
  }
195
203
  return word;
@@ -338,6 +346,17 @@ function livenessMsEnv(name) {
338
346
  const n = optNumEnvStrict(name);
339
347
  return n === undefined ? undefined : laneLivenessOf(n, name).ms;
340
348
  }
349
+ function parseDeviceBoundedIntEnv(name, raw, bounds) {
350
+ if (raw === undefined || raw === "")
351
+ return undefined;
352
+ const n = /^(0|[1-9]\d*)$/.test(raw) ? Number(raw) : Number.NaN;
353
+ if (!inWholeNumberBounds(bounds, n)) {
354
+ const shown = raw.length > 40 ? `${raw.slice(0, 40)}…(${raw.length} chars)` : raw;
355
+ throw new Error(`env ${name}=${JSON.stringify(shown)} must be ${wholeNumberBoundsRule(bounds)} (canonical decimal digits only — no sign, leading zero, fraction, exponent, hex, whitespace or unit; unset = the device lane's own default). ` +
356
+ `Refusing to boot rather than sending an out-of-range value to every executor, or running the default while the operator believes their value is in force.`);
357
+ }
358
+ return n;
359
+ }
341
360
  function parseDeviceEnrollTokenTtlEnv() {
342
361
  const raw = process.env.DEVICE_ENROLL_TOKEN_TTL_SEC;
343
362
  if (raw === undefined || raw === "")
@@ -440,15 +459,10 @@ function parseReadDenyPatternsEnv(raw) {
440
459
  if (!Array.isArray(arr))
441
460
  throw new Error('READ_DENY_PATTERNS must be a JSON array of "pattern" strings or {pattern, caseSensitive?} objects');
442
461
  const entries = arr.map((it, i) => {
443
- if (typeof it === "string")
444
- return { pattern: it, caseSensitive: false };
445
- if (typeof it !== "object" || it === null || typeof it.pattern !== "string") {
446
- throw new Error(`READ_DENY_PATTERNS[${i}] must be a string or an object with a string 'pattern'`);
447
- }
448
- const cs = it.caseSensitive;
449
- if (cs !== undefined && typeof cs !== "boolean")
450
- throw new Error(`READ_DENY_PATTERNS[${i}].caseSensitive must be boolean when present`);
451
- return { pattern: it.pattern, caseSensitive: cs === true };
462
+ const read = readReadDenyEntry(it);
463
+ if (!read.ok)
464
+ throw new Error(`READ_DENY_PATTERNS[${i}]${read.after}`);
465
+ return read.entry;
452
466
  });
453
467
  compileReadDeny(entries);
454
468
  return entries;
@@ -467,6 +481,12 @@ function parseNameListEnv(name, raw, opts) {
467
481
  }
468
482
  const ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
469
483
  const ENV_NAME_ALLOWLIST_WITHHELD = "<withheld: entries are not echoed — a value pasted in place of a name can pass the name check>";
484
+ function ownCredentialPutBackProblem(name) {
485
+ const engine = inheritEnvPolicyProblem([name]);
486
+ return engine === undefined
487
+ ? undefined
488
+ : `this deployment's own credential — a put-back list hands the named variable back, as written, to the child the engine withheld it from (the engine refuses it on any allow list: ${engine})`;
489
+ }
470
490
  export function parseEnvNameAllowlist(knob, singleUserTurnkey) {
471
491
  const raw = process.env[knob];
472
492
  if (raw === undefined || raw === "")
@@ -480,7 +500,9 @@ export function parseEnvNameAllowlist(knob, singleUserTurnkey) {
480
500
  ? 'not an environment-variable name (letters, digits and "_", not starting with a digit)'
481
501
  : ENV_NAME_ALLOWLIST_KNOB_NAMES.has(seg.toUpperCase())
482
502
  ? `the name of a name-list knob (${[...ENV_NAME_ALLOWLIST_KNOB_NAMES].join(" / ")}: their raw text is withheld from every child process and sandbox; naming one would put that text back)`
483
- : undefined;
503
+ : spec.channel === "host-put-back"
504
+ ? ownCredentialPutBackProblem(seg)
505
+ : undefined;
484
506
  if (problem === undefined)
485
507
  return;
486
508
  throw new Error(`env ${knob}: entry #${i + 1} of ${segments.length} is ${problem}` +
@@ -637,11 +659,22 @@ function optionalEnumKey(key, envName, raw, allowed) {
637
659
  if (raw === undefined || raw === "")
638
660
  return {};
639
661
  if (!allowed.includes(raw)) {
640
- throw new Error(`env ${envName}="${raw.slice(0, 120)}" must be one of: ${allowed.join(", ")} — or leave it UNSET to say nothing on this layer. ` +
662
+ throw new Error(`env ${envName}="${echoCallerText(raw, { maxChars: ENV_VALUE_ECHO_CHARS })}" must be one of: ${allowed.join(", ")} — or leave it UNSET to say nothing on this layer. ` +
641
663
  `Refusing to boot rather than reading a misspelled value as "unset": that runs the deployment with NO policy on this axis while the operator believes one is configured`);
642
664
  }
643
665
  return { [key]: raw };
644
666
  }
667
+ function principalInboxAssistantKey(raw) {
668
+ if (raw === undefined || raw === "")
669
+ return {};
670
+ try {
671
+ principalInboxConsumerOf({ principalInboxConsumer: { assistant: raw } });
672
+ }
673
+ catch (err) {
674
+ throw new Error(`env PRINCIPAL_INBOX_ASSISTANT must name the agent handle that consumes the principal inbox (or stay UNSET for no cross-principal delivery): ${err instanceof Error ? err.message : String(err)}`);
675
+ }
676
+ return { principalInboxAssistant: raw };
677
+ }
645
678
  function parseAutoModeClassifierTimeoutMs(raw) {
646
679
  if (raw === undefined || raw === "")
647
680
  return {};
@@ -684,7 +717,7 @@ function parseHooksTimeoutEnv() {
684
717
  return undefined;
685
718
  const n = parseNumOrFail("HOOKS_TIMEOUT_MS", raw);
686
719
  if (!Number.isInteger(n) || n < 0 || n > 2147483647) {
687
- throw new Error(`env HOOKS_TIMEOUT_MS="${raw}" must be an integer in [0, 2147483647] ms (0 = every hook seat expires immediately; unset = core's own default)`);
720
+ throw new Error(`env HOOKS_TIMEOUT_MS="${raw}" must be an integer in [0, 2147483647] ms (0 = a zero budget for every request-hook handler; unset = 600000)`);
688
721
  }
689
722
  return n;
690
723
  }
@@ -1026,7 +1059,7 @@ function parseModelDomain() {
1026
1059
  noticeAutoCompactAboveWindow("cheap", "MODEL_CHEAP_AUTO_COMPACT_TOKENS", cheapModel);
1027
1060
  }
1028
1061
  const models = envLaneTable(modelId, model, cheapModel);
1029
- const gatewayApiKey = process.env.MODEL_API_KEY;
1062
+ const gatewayApiKey = route.gatewayApiKey;
1030
1063
  if (gatewayBaseUrl === undefined && gatewayApiKey !== undefined && gatewayApiKey !== "") {
1031
1064
  CONFIG_NOTICES.push({
1032
1065
  level: "warn",
@@ -1159,7 +1192,7 @@ function uncompilableRuleGuidance(name, behavior, pathBases) {
1159
1192
  const issue = issues[0];
1160
1193
  if (issue === undefined)
1161
1194
  return undefined;
1162
- return `${issue.code} — core's rule grammar cannot compile this entry: ${issue.message}`;
1195
+ return { code: issue.code, guidance: `${issue.code} — core's rule grammar cannot compile this entry: ${issue.message}` };
1163
1196
  }
1164
1197
  function findUnmatchableToolNames(names, opts) {
1165
1198
  const out = [];
@@ -1167,42 +1200,46 @@ function findUnmatchableToolNames(names, opts) {
1167
1200
  if (opts.consumer === "tool-name-table") {
1168
1201
  const ccGuidance = ccRuleFormGuidance(name);
1169
1202
  if (ccGuidance !== undefined) {
1170
- out.push({ name, guidance: ccGuidance });
1203
+ out.push({ name, guidance: ccGuidance, reason: "cc_rule_form" });
1171
1204
  continue;
1172
1205
  }
1173
1206
  }
1174
1207
  const subject = opts.consumer === "tool-name-table" ? name : ruleEntryToolName(name);
1175
1208
  const verdict = unmatchableRuleNameOf(subject);
1176
1209
  if (verdict?.kind === "retired") {
1177
- out.push({ name, guidance: describeUnmatchableRuleName(verdict, subject) });
1210
+ out.push({ name, guidance: describeUnmatchableRuleName(verdict, subject), reason: verdict.kind });
1178
1211
  continue;
1179
1212
  }
1180
1213
  const uncompilable = uncompilableRuleGuidance(name, opts.behavior, opts.pathBases);
1181
1214
  if (uncompilable !== undefined) {
1182
- out.push({ name, guidance: uncompilable });
1215
+ out.push({ name, guidance: uncompilable.guidance, reason: uncompilable.code });
1183
1216
  continue;
1184
1217
  }
1185
1218
  if (verdict !== undefined) {
1186
- out.push({ name, guidance: describeUnmatchableRuleName(verdict, subject) });
1219
+ out.push({ name, guidance: describeUnmatchableRuleName(verdict, subject), reason: verdict.kind });
1187
1220
  continue;
1188
1221
  }
1189
1222
  const nearMiss = compileAllowList([subject], "deny", TOOL_NAME_ROSTER).inert.find((i) => i.reason === "near_miss");
1190
1223
  if (nearMiss?.currentName !== undefined) {
1191
1224
  const rest = name.startsWith(subject) ? name.slice(subject.length) : "";
1192
- out.push({ name, guidance: inertRuleEntryGuidance({ ...nearMiss, currentName: `${nearMiss.currentName}${rest}` }) });
1225
+ out.push({ name, guidance: inertRuleEntryGuidance({ ...nearMiss, currentName: `${nearMiss.currentName}${rest}` }), reason: nearMiss.reason });
1193
1226
  }
1194
1227
  }
1195
1228
  return out;
1196
1229
  }
1197
1230
  export function unmatchableToolNamesRefusal(source, names, judgment) {
1231
+ const judged = judgeUnmatchableToolNames(source, names, judgment);
1232
+ return judged === undefined ? undefined : { message: judged.message, names: judged.bad.map((b) => b.name) };
1233
+ }
1234
+ export function judgeUnmatchableToolNames(source, names, judgment) {
1198
1235
  const bad = findUnmatchableToolNames(names, judgment);
1199
1236
  if (bad.length === 0)
1200
1237
  return undefined;
1201
1238
  const named = bad.slice(0, MAX_NAMED_INERT_ENTRIES).map((b) => `${displayListEntry(b.name)} → ${b.guidance}`).join("; ");
1202
- const message = (`${source} has ${bad.length === 1 ? "an entry" : "entries"} that can never take effect — ${bad.length === 1 ? "it" : "each"} would never match a live tool or cannot be compiled into a rule ` +
1239
+ const message = stripControlAndBidi(`${source} has ${bad.length === 1 ? "an entry" : "entries"} that can never take effect — ${bad.length === 1 ? "it" : "each"} would never match a live tool or cannot be compiled into a rule ` +
1203
1240
  `(names are read exactly as written: no alias folding, no protocol prefix added): ` +
1204
- (bad.length > MAX_NAMED_INERT_ENTRIES ? `${named}; and ${bad.length - MAX_NAMED_INERT_ENTRIES} more` : named)).replace(CONTROL_AND_BIDI_STRIP_RE, "");
1205
- return { message, names: bad.map((b) => b.name) };
1241
+ (bad.length > MAX_NAMED_INERT_ENTRIES ? `${named}; and ${bad.length - MAX_NAMED_INERT_ENTRIES} more` : named));
1242
+ return { message, bad };
1206
1243
  }
1207
1244
  const APPROVAL_GRANT_ENV = "APPROVAL_GRANT";
1208
1245
  export function approvalGrantRefusal(names) {
@@ -1257,7 +1294,7 @@ function unattendedApprovalPolicyEnv() {
1257
1294
  return "park";
1258
1295
  if (raw === "park" || raw === "deny")
1259
1296
  return raw;
1260
- throw new Error(`env UNATTENDED_APPROVAL_POLICY="${raw.slice(0, 120)}" is not a recognized value — use "park" (default: an ask nobody can answer becomes a durable park, the run suspends and waits for a human) ` +
1297
+ throw new Error(`env UNATTENDED_APPROVAL_POLICY="${echoCallerText(raw, { maxChars: ENV_VALUE_ECHO_CHARS })}" is not a recognized value — use "park" (default: an ask nobody can answer becomes a durable park, the run suspends and waits for a human) ` +
1261
1298
  `or "deny" (an unattended/headless deployment declaring that NOBODY will ever answer: such asks are denied on the spot instead of piling up parked runs). ` +
1262
1299
  `The words are matched EXACTLY (lowercase, surrounding whitespace trimmed) and there is no "off" — both values are real postures, and unset simply means the documented default "park". ` +
1263
1300
  `Refusing to boot rather than treating a misspelled value as "unset": that runs the deployment on a policy the operator did not choose, with no trace anywhere`);
@@ -1339,7 +1376,7 @@ function parseApprovalDomain(ctx) {
1339
1376
  `Use "always" to keep EVERY shell call behind an approval under every mode (bypassPermissions included), or unset it / "off" to rely on the engine's mode arbitration. ` +
1340
1377
  `Refusing to boot rather than accepting it as a no-op: that would silently drop the half the operator configured it for`);
1341
1378
  }
1342
- throw new Error(`env MANUAL_MODE_SHELL_GATE="${trimmed.slice(0, 120)}" is not a recognized value — use "always" (every shell call is gated) or "off"/unset (this knob contributes nothing). ` +
1379
+ throw new Error(`env MANUAL_MODE_SHELL_GATE="${echoCallerText(trimmed, { maxChars: ENV_VALUE_ECHO_CHARS })}" is not a recognized value — use "always" (every shell call is gated) or "off"/unset (this knob contributes nothing). ` +
1343
1380
  `The words are matched EXACTLY (lowercase, surrounding whitespace trimmed): "OFF"/"Always" land here too, deliberately — a closed word table with no case-folding is what keeps "it looked accepted" from meaning "it did nothing". ` +
1344
1381
  `Refusing to boot rather than treating a misspelled value as "unset": that silently ran the deployment with NO shell gate while the operator believed one was configured`);
1345
1382
  })(process.env.MANUAL_MODE_SHELL_GATE),
@@ -1348,6 +1385,7 @@ function parseApprovalDomain(ctx) {
1348
1385
  ...parseAutoModeClassifierTimeoutMs(process.env.AUTO_MODE_CLASSIFIER_TIMEOUT_MS),
1349
1386
  ...optionalEnumKey("crossSessionInbound", "CROSS_SESSION_INBOUND", process.env.CROSS_SESSION_INBOUND, CROSS_SESSION_INBOUND_SETTINGS),
1350
1387
  ...optionalEnumKey("crossSessionDialogExpiry", "CROSS_SESSION_DIALOG_EXPIRY", process.env.CROSS_SESSION_DIALOG_EXPIRY, CROSS_SESSION_DIALOG_EXPIRY_VALUES),
1388
+ ...principalInboxAssistantKey(process.env.PRINCIPAL_INBOX_ASSISTANT),
1351
1389
  mcpElicitation: {
1352
1390
  enabled: boolEnv("MCP_ELICITATION_ENABLED", false),
1353
1391
  throttle: {
@@ -1372,8 +1410,20 @@ function parseApprovalDomain(ctx) {
1372
1410
  durableApprovalSource: postureSourceOfKnob("DURABLE_APPROVAL"),
1373
1411
  unattendedApprovalPolicy: unattendedPolicy,
1374
1412
  approvalTimeoutSec: numEnv("APPROVAL_TIMEOUT_SEC", "0"),
1413
+ approvalAskRetentionMs: approvalAskRetentionEnv(),
1375
1414
  };
1376
1415
  }
1416
+ function approvalAskRetentionEnv() {
1417
+ const n = numEnv("APPROVAL_ASK_RETENTION_MS", String(APPROVAL_ASK_RETENTION_DEFAULT_MS));
1418
+ const raw = env("APPROVAL_ASK_RETENTION_MS", "");
1419
+ if (n < 0 || !Number.isSafeInteger(n)) {
1420
+ throw new Error(`env APPROVAL_ASK_RETENTION_MS="${raw}" must be 0 (keep the approval ledgers forever) or a whole number of milliseconds (the retention window)`);
1421
+ }
1422
+ if (n === 0 || n >= APPROVAL_ASK_RETENTION_FLOOR_MS)
1423
+ return n;
1424
+ CONFIG_WARNINGS.push({ env: "APPROVAL_ASK_RETENTION_MS", raw, used: String(APPROVAL_ASK_RETENTION_FLOOR_MS), kind: "clamped" });
1425
+ return APPROVAL_ASK_RETENTION_FLOOR_MS;
1426
+ }
1377
1427
  const MEMORY_ENGINE_ON_WORDS = ["on", "true", "1", "yes", "enabled"];
1378
1428
  const MEMORY_ENGINE_OFF_WORDS = ["off", "false", "0", "no", "disabled"];
1379
1429
  function parseMemoryEngineWord(word) {
@@ -1423,6 +1473,13 @@ function pkgSourceEnv() {
1423
1473
  }
1424
1474
  return v;
1425
1475
  }
1476
+ function pkgSourceFields() {
1477
+ if (process.env.SANDBOX_PKG_SOURCE === "none")
1478
+ return {};
1479
+ const sandboxPkgSource = pkgSourceEnv();
1480
+ const custom = sandboxPkgSource === "custom" ? customPkgSourceFromEnv() : {};
1481
+ return { sandboxPkgSource, ...(Object.keys(custom).length > 0 ? { sandboxPkgSourceCustom: custom } : {}) };
1482
+ }
1426
1483
  function syncEntryCap(name, field) {
1427
1484
  const raw = process.env[name];
1428
1485
  if (raw === undefined || raw === "")
@@ -1585,6 +1642,8 @@ function parseMemoryDomain(ctx) {
1585
1642
  const memoryEngineEnabled = parseMemoryEngineWord(env("MEMORY_ENGINE", "on"));
1586
1643
  const memoryEngineBackend = enumEnv("MEMORY_ENGINE_BACKEND", "file", MEMORY_ENGINE_BACKENDS);
1587
1644
  const memoryScope = process.env.MEMORY_SCOPE ?? (memoryEngineEnabled && !requirePrincipal ? "local" : undefined);
1645
+ if (memoryScope !== undefined && memoryEngineEnabled && !requirePrincipal)
1646
+ assertProjectLayerOwnable(memoryScope, "MEMORY_SCOPE");
1588
1647
  const memorySyncUrl = process.env.MEMORY_SYNC_URL || undefined;
1589
1648
  const memorySyncToken = process.env.MEMORY_SYNC_TOKEN || undefined;
1590
1649
  const memorySyncScopeRaw = process.env.MEMORY_SYNC_SCOPE || undefined;
@@ -1610,6 +1669,7 @@ function parseMemoryDomain(ctx) {
1610
1669
  if (scope === undefined) {
1611
1670
  throw new Error("MEMORY_SYNC_URL is set but no sync scope is derivable (memory engine off or multi-tenant without an explicit scope) — set MEMORY_SYNC_SCOPE, or run the single-user file memory engine with a typed MEMORY_SCOPE (e.g. user:<tenant>) so it provides one");
1612
1671
  }
1672
+ assertProjectLayerOwnable(scope, memorySyncScopeRaw !== undefined ? "MEMORY_SYNC_SCOPE" : "MEMORY_SCOPE");
1613
1673
  memorySync = {
1614
1674
  url: memorySyncUrl,
1615
1675
  token: memorySyncToken,
@@ -1619,23 +1679,17 @@ function parseMemoryDomain(ctx) {
1619
1679
  };
1620
1680
  }
1621
1681
  const replication = memoryReplicationCoverage(memorySync !== undefined ? { memorySync } : {});
1622
- if (replication.kind === "scopes" && memoryEngineEnabled && !requirePrincipal && memoryScope !== undefined) {
1623
- const YIELD_HINT = {
1624
- in: "memory sync (MEMORY_SYNC_*) replicates only the scope(s) listed in replicatedScopes — the per-project memory layer (S-512, repo:<key>) is not replicated, " +
1625
- "so sessions do NOT write project-keyed memory here: new memory lands in the global layer (writeScope = MEMORY_SCOPE), which IS replicated, and every " +
1626
- "project reads it. Project-layer replication is a separate change; unset MEMORY_SYNC_URL to get per-project memory without sync.",
1627
- out: "memory sync (MEMORY_SYNC_*) replicates only the scope(s) listed in replicatedScopes — the per-project memory layer (S-512, repo:<key>) is not replicated, " +
1628
- "so sessions do NOT write project-keyed memory here: new memory lands in the global layer (writeScope = MEMORY_SCOPE), every project reads it, " +
1629
- "and that write scope is not among the replicated scopes either — NONE of the memory this deployment writes is synced. " +
1630
- "Point MEMORY_SYNC_SCOPE at the write scope (sync replicates one scope), or unset MEMORY_SYNC_URL to stop expecting sync.",
1631
- };
1682
+ if (replication.kind === "layers" && memoryEngineEnabled && !requirePrincipal && memoryScope !== undefined && !replicatesProjectLayersOf(replication, projectLayerOwnerOf(memoryScope))) {
1632
1683
  CONFIG_NOTICES.push({
1633
1684
  level: "warn",
1634
1685
  event: "memory_project_scope_yields_to_sync",
1635
1686
  fields: {
1636
- replicatedScopes: replication.scopes.join(","),
1687
+ replicatedScopes: replication.layers.join(","),
1637
1688
  writeScope: memoryScope,
1638
- hint: YIELD_HINT[replicationCovers(replication, memoryScope) ? "in" : "out"],
1689
+ hint: "memory sync (MEMORY_SYNC_*) replicates the scope(s) listed in replicatedScopes and the per-project memory layers of the same owner; " +
1690
+ "this deployment's project layers belong to MEMORY_SCOPE, which has a different owner, so sessions do NOT write project-keyed memory here: " +
1691
+ "new memory lands in the global layer (writeScope = MEMORY_SCOPE), every project reads it, and NONE of the memory this deployment writes is synced. " +
1692
+ "Set MEMORY_SCOPE to the replicated user key (the same value as MEMORY_SYNC_SCOPE) to sync the global and per-project layers, or unset MEMORY_SYNC_URL to stop expecting sync.",
1639
1693
  },
1640
1694
  });
1641
1695
  }
@@ -1768,6 +1822,7 @@ function parseAuthDomain(ctx) {
1768
1822
  autonomy: parseAutonomy(process.env.AUTONOMY),
1769
1823
  ...parseGovernanceDeclarations(),
1770
1824
  operatorPrincipals: csv("OPERATOR_PRINCIPALS"),
1825
+ operatorSingleUser: boolEnv("OPERATOR_SINGLE_USER", false),
1771
1826
  configCatalogEnabled: boolEnv("CONFIG_CATALOG_ENABLED", true),
1772
1827
  principalJwtPubkeys,
1773
1828
  principalJwtIss,
@@ -1812,10 +1867,7 @@ function parseOrchestrationDomain(ctx) {
1812
1867
  }
1813
1868
  const readFaceFacts = process.env.READ_FACE !== undefined
1814
1869
  ? { readFace: enumEnv("READ_FACE", "roots", ["open", "roots"]), readFaceSource: "env" }
1815
- : readFaceForPosture(singleUserTurnkey);
1816
- const readFaceNotice = buildReadFacePostureNotice(readFaceFacts);
1817
- if (readFaceNotice !== undefined)
1818
- CONFIG_NOTICES.push({ level: "info", ...readFaceNotice });
1870
+ : { readFaceSource: "engine-default" };
1819
1871
  return {
1820
1872
  requireExecutionLane: boolEnv("REQUIRE_EXECUTION_LANE", false),
1821
1873
  ...readFaceFacts,
@@ -1923,10 +1975,10 @@ function parseOrchestrationDomain(ctx) {
1923
1975
  process.env.REMOTE_EXEC === "device"
1924
1976
  ? {
1925
1977
  provider: "device",
1926
- ...((n) => (n !== undefined ? { deliveryTimeoutMs: n } : {}))(optNumEnvStrict("DEVICE_DELIVERY_TIMEOUT_MS")),
1927
- ...((n) => (n !== undefined ? { reconnectGraceMs: n } : {}))(optNumEnvStrict("DEVICE_RECONNECT_GRACE_MS")),
1928
- ...((n) => (n !== undefined ? { execTimeoutMs: n } : {}))(optNumEnvStrict("DEVICE_EXEC_TIMEOUT_MS")),
1929
- ...((n) => (n !== undefined ? { maxInflightPerDevice: n } : {}))(optNumEnvStrict("DEVICE_MAX_INFLIGHT_PER_DEVICE")),
1978
+ ...((n) => (n !== undefined ? { deliveryTimeoutMs: n } : {}))(parseDeviceBoundedIntEnv("DEVICE_DELIVERY_TIMEOUT_MS", process.env.DEVICE_DELIVERY_TIMEOUT_MS, DEVICE_DELIVERY_TIMEOUT_BOUNDS)),
1979
+ ...((n) => (n !== undefined ? { reconnectGraceMs: n } : {}))(parseDeviceBoundedIntEnv("DEVICE_RECONNECT_GRACE_MS", process.env.DEVICE_RECONNECT_GRACE_MS, DEVICE_HELLO_ACK_BOUNDS.reconnectGraceMs)),
1980
+ ...((n) => (n !== undefined ? { execTimeoutMs: n } : {}))(parseDeviceBoundedIntEnv("DEVICE_EXEC_TIMEOUT_MS", process.env.DEVICE_EXEC_TIMEOUT_MS, DEVICE_EXEC_TIMEOUT_BOUNDS)),
1981
+ ...((n) => (n !== undefined ? { maxInflightPerDevice: n } : {}))(parseDeviceBoundedIntEnv("DEVICE_MAX_INFLIGHT_PER_DEVICE", process.env.DEVICE_MAX_INFLIGHT_PER_DEVICE, DEVICE_HELLO_ACK_BOUNDS.maxInflight)),
1930
1982
  ...((n) => (n !== undefined ? { maxPreAuthPerRemote: n } : {}))(parseDevicePreAuthPerRemoteEnv()),
1931
1983
  ...((n) => (n !== undefined ? { enrollTokenTtlSec: n } : {}))(parseDeviceEnrollTokenTtlEnv()),
1932
1984
  ...(process.env.DEVICE_SUPERSEDE ? { supersede: enumEnv("DEVICE_SUPERSEDE", "stale_only", ["stale_only", "deny"]) } : {}),
@@ -1978,9 +2030,7 @@ function parseOrchestrationDomain(ctx) {
1978
2030
  }
1979
2031
  return n;
1980
2032
  })(numEnv("SCRATCHPAD_SWEEP_TTL_MS", String(7 * 24 * 60 * 60 * 1000)), env("SCRATCHPAD_SWEEP_TTL_MS", String(7 * 24 * 60 * 60 * 1000))),
1981
- ...(process.env.SANDBOX_PKG_SOURCE !== "none"
1982
- ? { sandboxPkgSource: pkgSourceEnv() }
1983
- : {}),
2033
+ ...pkgSourceFields(),
1984
2034
  sessionAutoTitle: boolEnv("SESSION_AUTO_TITLE", true),
1985
2035
  sessionAutoTitleSource: postureSourceOfKnob("SESSION_AUTO_TITLE"),
1986
2036
  selectEnvironmentTool: boolEnv("SELECT_ENVIRONMENT_TOOL", true),
@@ -2117,6 +2167,7 @@ function parseGitApiKind(raw, baseUrl) {
2117
2167
  }
2118
2168
  function parseIntegrationsDomain(ctx) {
2119
2169
  const { requirePrincipal, configProvider } = ctx;
2170
+ const configLocalOwnerUid = parseConfigLocalOwnerUid(process.env.CONFIG_LOCAL_OWNER_UID);
2120
2171
  const baseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.url, process.env[WEB_ADMIN_ENV.url], `It is the center base every config pull, fleet and lease request is sent to; setting it selects the center as the config source.`);
2121
2172
  const liveBaseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.liveUrl, process.env[WEB_ADMIN_ENV.liveUrl], `It is the center base the fleet liveness endpoints (heartbeat, serving lease) are sent to; unset it to send them to ${WEB_ADMIN_ENV.url}.`);
2122
2173
  const webBaseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.webUrl, process.env[WEB_ADMIN_ENV.webUrl], `It is the center's web console base this engine reports on GET /health (center.webBaseUrl); unset it if the center has no web console to link to.`);
@@ -2141,6 +2192,7 @@ function parseIntegrationsDomain(ctx) {
2141
2192
  fleetLeaseOutageMaxMs: parseFleetLeaseOutageMaxMs(process.env.FLEET_LEASE_OUTAGE_MAX_MS),
2142
2193
  ...(configProvider !== undefined ? { configProvider } : {}),
2143
2194
  configLocalDir: process.env.CONFIG_LOCAL_DIR || undefined,
2195
+ ...(configLocalOwnerUid !== undefined ? { configLocalOwnerUid } : {}),
2144
2196
  a2aServe: parseA2aServe(),
2145
2197
  };
2146
2198
  }
@@ -2326,10 +2378,10 @@ const MODEL_PLANE_GROUP_KEYS = [
2326
2378
  "modelApiKeyEnv", "modelApiKeys", "modelRefusals", "droppedCatalogEntries", "modelQuotaWeights", "tiers", "projects", "roles", "atMention", "cascadeLadder", "degrade",
2327
2379
  ];
2328
2380
  const APPROVAL_GROUP_KEYS = [
2329
- "approvalRequire", "approvalDeny", "approvalTimeoutSec", "approvalAutoBudget", "approvalNeverAuto", "approvalGrant",
2381
+ "approvalRequire", "approvalDeny", "approvalTimeoutSec", "approvalAskRetentionMs", "approvalAutoBudget", "approvalNeverAuto", "approvalGrant",
2330
2382
  "approvalHmacKeys", "durableApproval", "durableApprovalSource", "streamAskWindowMsSource", "directApprovalDoor", "directDoorActive", "resourceSuspend",
2331
2383
  "resourceSuspendTtlSec", "resourceSuspendTotalTokens", "resourceSuspendTotalBudgetUsd", "resourceSuspendMaxSlices", "askQuestionEnabled", "questionThrottle", "toolApprovalEnabled", "permissionRulesEnabled", "permissionRulesEnabledExplicit", "streamAskWindowMarginMs", "streamApproval", "unattendedApprovalPolicy", "mcpElicitation",
2332
- "sensitiveWritePatterns", "writeProtectedPaths", "manualModeShellGate", "permissionsDisableAutoMode", "autoModeClassifierFallback", "autoModeClassifierTimeoutMs", "crossSessionInbound", "crossSessionDialogExpiry",
2384
+ "sensitiveWritePatterns", "writeProtectedPaths", "manualModeShellGate", "permissionsDisableAutoMode", "autoModeClassifierFallback", "autoModeClassifierTimeoutMs", "crossSessionInbound", "crossSessionDialogExpiry", "principalInboxAssistant",
2333
2385
  ];
2334
2386
  const MEMORY_GROUP_KEYS = [
2335
2387
  "memoryEngineEnabled", "memoryEngineDir", "memoryEngineRemoteLaneAllowed", "memoryEngineBackend", "memoryScope",
@@ -2339,7 +2391,7 @@ const MEMORY_GROUP_KEYS = [
2339
2391
  const AUTH_GROUP_KEYS = [
2340
2392
  "authToken", "authTokens", "allowUnauthedWrites", "corsOrigins", "principalHeader", "requirePrincipal", "autonomy",
2341
2393
  "commandPolicy", "compliancePosture", "lockedConfigKeys", "retentionPolicy", "retentionSweep",
2342
- "operatorPrincipals", "configCatalogEnabled", "principalJwtPubkeys", "principalJwtIss", "principalJwtAud",
2394
+ "operatorPrincipals", "operatorSingleUser", "configCatalogEnabled", "principalJwtPubkeys", "principalJwtIss", "principalJwtAud",
2343
2395
  "principalJwtMaxTtlSec", "authBridgeIssuer", "bindHost", "bindHostSource",
2344
2396
  ];
2345
2397
  const ORCHESTRATION_GROUP_KEYS = [
@@ -2348,7 +2400,7 @@ const ORCHESTRATION_GROUP_KEYS = [
2348
2400
  "schedulerEnabled", "schedulerSessionWakeup", "schedulerSessionLifetime", "schedulerStorePath", "planModeEnabled", "hooksTimeoutMs", "workflowRunStoreBackend",
2349
2401
  "workflowOrphanGraceMs", "workflowJournalRetentionMs", "workflowRunRetentionMs", "usageWindows", "workflowAgentsReadOnly",
2350
2402
  "workflowSizeGuideline", "backgroundAgentRetentionMs", "backgroundAgentStaleRunningMs",
2351
- "backgroundAgentParkClaimStaleMs", "delegationEntryCaps", "rosterRetentionMs", "leaderRunStaleMs", "scratchpadSweepTtlMs", "sandboxPkgSource",
2403
+ "backgroundAgentParkClaimStaleMs", "delegationEntryCaps", "rosterRetentionMs", "leaderRunStaleMs", "scratchpadSweepTtlMs", "sandboxPkgSource", "sandboxPkgSourceCustom",
2352
2404
  "sessionAutoTitle", "sessionAutoTitleSource", "selectEnvironmentTool", "envFactsEnabled", "toolDeferLongtail", "lspEnabled", "lspHostEnabled", "lspEnvAllow",
2353
2405
  "imageBakes", "readFace", "readFaceSource", "taskWriteFaceEscalation", "readDenyPatterns", "readDenyBuiltinTiers", "readDenyBuiltinExclude",
2354
2406
  "agentConfigDir", "configLkgPath", "configLkgEnabled",
@@ -2363,7 +2415,7 @@ const LIMITS_HTTP_GROUP_KEYS = [
2363
2415
  const OBSERVABILITY_GROUP_KEYS = ["metricsToken", "traceToken", "toolTrace", "traceThinking", "logLevel", "otel"];
2364
2416
  const INTEGRATIONS_GROUP_KEYS = [
2365
2417
  "pluginsAllowHosts", "mcpServers", "a2aPeers", "a2aServe", "configBootFetchBudgetMs", "gitApiBaseUrl", "gitApiToken", "gitApiKind", "defaultScenario",
2366
- "skillsDir", "centerCredentialRenewLeadMs", "webAdmin", "fleetLeaseFailClosed", "fleetGeneration", "fleetScope", "fleetAdvertiseAddress", "fleetLeaseOutageMaxMs", "configProvider", "configLocalDir",
2418
+ "skillsDir", "centerCredentialRenewLeadMs", "webAdmin", "fleetLeaseFailClosed", "fleetGeneration", "fleetScope", "fleetAdvertiseAddress", "fleetLeaseOutageMaxMs", "configProvider", "configLocalDir", "configLocalOwnerUid",
2367
2419
  ];
2368
2420
  export const CONFIG_GROUP_KEYS = {
2369
2421
  store: STORE_GROUP_KEYS,
@@ -2461,6 +2513,11 @@ function k8sWorkspaceCache() {
2461
2513
  throw new Error(`env WORKSPACE_CACHE_MOUNT=${mount} overlaps the workspace mount ${workspace} (K8S_MOUNT_PATH) — the cache volume must sit OUTSIDE the workspace ` +
2462
2514
  "(the workspace is snapshotted between runs, the cache is not); pick a separate absolute path such as /cache");
2463
2515
  }
2516
+ const reserved = reservedMountCollision(mount);
2517
+ if (reserved !== undefined) {
2518
+ throw new Error(`env WORKSPACE_CACHE_MOUNT=${mount} collides with the reserved image directory ${reserved} (a volume at, under or above it hides what the sandbox image keeps there) — ` +
2519
+ `pick a separate absolute path such as /cache; reserved: ${WORKSPACE_CACHE_MOUNT_RESERVED.join(" ")}`);
2520
+ }
2464
2521
  return { mount, size };
2465
2522
  }
2466
2523
  export function loadConfig() {
@@ -2485,6 +2542,10 @@ export function loadConfig() {
2485
2542
  const memory = parseMemoryDomain({ requirePrincipal });
2486
2543
  const auth = parseAuthDomain({ requirePrincipal });
2487
2544
  const orchestration = parseOrchestrationDomain({ postureOn, singleUserTurnkey, configProvider });
2545
+ settleDerivedReadFace(orchestration, singleUserTurnkey);
2546
+ const readFaceNotice = buildReadFacePostureNotice(orchestration);
2547
+ if (readFaceNotice !== undefined)
2548
+ CONFIG_NOTICES.push({ level: "info", ...readFaceNotice });
2488
2549
  const limitsHttp = parseLimitsHttpDomain();
2489
2550
  const observability = parseObservabilityDomain();
2490
2551
  const integrations = parseIntegrationsDomain({ requirePrincipal, configProvider });
@@ -2493,7 +2554,7 @@ export function loadConfig() {
2493
2554
  throw new Error(centerIdentity);
2494
2555
  }
2495
2556
  const { directApprovalDoor, durableApproval: dgDurable, approvalHmacKeys: dgHmacKeys } = approval;
2496
- const { principalJwtPubkeys, principalJwtIss, principalJwtAud, operatorPrincipals: dgOperators, authTokens } = auth;
2557
+ const { principalJwtPubkeys, principalJwtIss, principalJwtAud, operatorPrincipals: dgOperators, operatorSingleUser, authTokens } = auth;
2497
2558
  const directDoorActive = directApprovalDoor && dgDurable && dgHmacKeys.length > 0 && principalJwtPubkeys.length > 0 && !!principalJwtIss && !!principalJwtAud;
2498
2559
  const doorRefusal = halfOpenDirectDoorRefusal({
2499
2560
  directApprovalDoor,
@@ -2512,6 +2573,10 @@ export function loadConfig() {
2512
2573
  if (operatorsRefusal !== undefined) {
2513
2574
  throw new Error(operatorsRefusal);
2514
2575
  }
2576
+ const singleUserOperatorRefusal = operatorSingleUserRefusal({ operatorSingleUser, requirePrincipal, operatorPrincipals: dgOperators });
2577
+ if (singleUserOperatorRefusal !== undefined) {
2578
+ throw new Error(singleUserOperatorRefusal);
2579
+ }
2515
2580
  const bakeOperatorsRefusal = bakeOperatorPrincipalsRefusal({ imageBakes: orchestration.imageBakes, operatorPrincipals: dgOperators });
2516
2581
  if (bakeOperatorsRefusal !== undefined) {
2517
2582
  throw new Error(bakeOperatorsRefusal);
@@ -2524,6 +2589,16 @@ export function loadConfig() {
2524
2589
  if (leaderStoreRefusal !== undefined) {
2525
2590
  throw new Error(leaderStoreRefusal);
2526
2591
  }
2592
+ const parkDecisionDomainRefusal = workflowParkDecisionDomainRefusal({
2593
+ selfOrchestrationEnabled: orchestration.selfOrchestrationEnabled,
2594
+ workflowRunStoreBackend: orchestration.workflowRunStoreBackend,
2595
+ dbBackend: store.dbBackend,
2596
+ tidb: store.tidb,
2597
+ pg: store.pg,
2598
+ });
2599
+ if (parkDecisionDomainRefusal !== undefined) {
2600
+ throw new Error(parkDecisionDomainRefusal);
2601
+ }
2527
2602
  const laneRequiredRefusal = executionLaneRequiredRefusal(orchestration);
2528
2603
  if (laneRequiredRefusal !== undefined) {
2529
2604
  throw new Error(laneRequiredRefusal);