@sema-agent/server 7.132.0 → 7.134.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 (473) hide show
  1. package/MIGRATION.md +353 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +301 -64
  5. package/deploy/sema-up/README.md +35 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
  11. package/deploy/sema-up/chart/templates/server.yaml +19 -2
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/deploy/sema-up/stack/compose.yaml +3 -0
  15. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  16. package/dist/adoption/plan.d.ts +3 -2
  17. package/dist/adoption/plan.js +7 -5
  18. package/dist/adoption/runner.js +3 -10
  19. package/dist/adoption/sql.d.ts +3 -2
  20. package/dist/adoption/sql.js +3 -5
  21. package/dist/adoption/wire.d.ts +4 -1
  22. package/dist/adoption/wire.js +1 -0
  23. package/dist/approval-ask-audit-store.d.ts +32 -14
  24. package/dist/approval-ask-audit-store.js +272 -74
  25. package/dist/approval-ask-machine.d.ts +15 -0
  26. package/dist/approval-ask-machine.js +6 -0
  27. package/dist/approval-ask-retention.d.ts +136 -0
  28. package/dist/approval-ask-retention.js +102 -0
  29. package/dist/approval-card.d.ts +83 -23
  30. package/dist/approval-card.js +45 -15
  31. package/dist/approval-content-kind.d.ts +5 -2
  32. package/dist/approval-content-kind.js +16 -3
  33. package/dist/approval-deny-reasons.d.ts +1 -1
  34. package/dist/approval-gate-currency.d.ts +72 -0
  35. package/dist/approval-gate-currency.js +94 -0
  36. package/dist/approval.d.ts +15 -0
  37. package/dist/approval.js +55 -17
  38. package/dist/audit.d.ts +27 -10
  39. package/dist/audit.js +12 -16
  40. package/dist/bake-runner/main.js +3 -2
  41. package/dist/boot/coordinators.d.ts +6 -1
  42. package/dist/boot/coordinators.js +6 -3
  43. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  44. package/dist/boot/execution-env.js +9 -7
  45. package/dist/boot/execution-lane.js +11 -0
  46. package/dist/boot/leader.d.ts +2 -0
  47. package/dist/boot/leader.js +4 -1
  48. package/dist/boot/memory-boundary.js +2 -2
  49. package/dist/boot/memory-consolidation.d.ts +5 -4
  50. package/dist/boot/memory-consolidation.js +7 -6
  51. package/dist/boot/org-delivery.d.ts +28 -0
  52. package/dist/boot/org-delivery.js +20 -0
  53. package/dist/boot/read-deny-anchor-audit.js +2 -2
  54. package/dist/boot/reapers.d.ts +3 -0
  55. package/dist/boot/reapers.js +21 -1
  56. package/dist/boot/resolve-spec.d.ts +3 -0
  57. package/dist/boot/resolve-spec.js +60 -81
  58. package/dist/boot/runner-deps.d.ts +18 -5
  59. package/dist/boot/runner-deps.js +10 -0
  60. package/dist/boot/session-faces.d.ts +1 -0
  61. package/dist/boot/session-faces.js +4 -2
  62. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  63. package/dist/boot/stage-06-runners.d.ts +6 -3
  64. package/dist/boot/stage-06-runners.js +20 -4
  65. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  66. package/dist/boot/stage-07-capability-layer.js +24 -3
  67. package/dist/boot/stage-08-reapers.d.ts +4 -1
  68. package/dist/boot/stage-08-reapers.js +2 -2
  69. package/dist/boot/stage-09-leader.d.ts +5 -1
  70. package/dist/boot/stage-09-leader.js +2 -2
  71. package/dist/boot/stage-10-http-server.d.ts +5 -1
  72. package/dist/boot/stage-10-http-server.js +6 -6
  73. package/dist/boot/stores.d.ts +8 -0
  74. package/dist/boot/stores.js +10 -14
  75. package/dist/boot/web-admin.d.ts +10 -0
  76. package/dist/boot/web-admin.js +162 -65
  77. package/dist/boot/workflow-orchestration.d.ts +2 -0
  78. package/dist/boot/workflow-orchestration.js +2 -1
  79. package/dist/brain.js +8 -3
  80. package/dist/breaker-key.d.ts +6 -0
  81. package/dist/breaker-key.js +29 -0
  82. package/dist/budget.js +5 -1
  83. package/dist/caller-text-echo.d.ts +11 -6
  84. package/dist/caller-text-echo.js +10 -12
  85. package/dist/canonical-json.d.ts +2 -41
  86. package/dist/canonical-json.js +2 -13
  87. package/dist/capabilities/center-plugins.d.ts +7 -0
  88. package/dist/capabilities/center-plugins.js +1 -1
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +21 -0
  93. package/dist/capabilities/hands-lane.js +10 -0
  94. package/dist/capabilities/mcp-probe.d.ts +36 -4
  95. package/dist/capabilities/mcp-probe.js +29 -6
  96. package/dist/capabilities/scenarios.d.ts +63 -7
  97. package/dist/capabilities/scenarios.js +39 -7
  98. package/dist/capability-facts.d.ts +36 -4
  99. package/dist/capability-facts.js +30 -4
  100. package/dist/center-config-tier.d.ts +69 -0
  101. package/dist/center-config-tier.js +42 -0
  102. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  103. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  104. package/dist/checkpoint-identity.d.ts +16 -0
  105. package/dist/checkpoint-identity.js +19 -0
  106. package/dist/config-catalog.d.ts +17 -10
  107. package/dist/config-catalog.js +43 -28
  108. package/dist/config-d-migration.d.ts +3 -1
  109. package/dist/config-d-migration.js +2 -2
  110. package/dist/config-dir-trust.d.ts +114 -0
  111. package/dist/config-dir-trust.js +388 -0
  112. package/dist/config-invariants.d.ts +18 -5
  113. package/dist/config-invariants.js +35 -3
  114. package/dist/config-provider.d.ts +6 -1
  115. package/dist/config-provider.js +6 -2
  116. package/dist/config-types.d.ts +71 -14
  117. package/dist/config-types.js +8 -0
  118. package/dist/config.d.ts +13 -0
  119. package/dist/config.js +121 -59
  120. package/dist/delegated-session-owner.d.ts +185 -0
  121. package/dist/delegated-session-owner.js +119 -0
  122. package/dist/device-protocol.d.ts +5 -3
  123. package/dist/device-protocol.js +1 -1
  124. package/dist/device-ws-hub.js +21 -2
  125. package/dist/device-ws-protocol.d.ts +70 -6
  126. package/dist/device-ws-protocol.js +50 -23
  127. package/dist/elicitation.js +3 -2
  128. package/dist/entry-problems.d.ts +34 -0
  129. package/dist/entry-problems.js +14 -0
  130. package/dist/execution-lane-caps.d.ts +49 -10
  131. package/dist/execution-lane-caps.js +43 -4
  132. package/dist/field-conflict.d.ts +44 -0
  133. package/dist/field-conflict.js +21 -0
  134. package/dist/file-history-disclosure.d.ts +34 -5
  135. package/dist/file-history-disclosure.js +2 -2
  136. package/dist/fleet/fleet-bus.d.ts +84 -6
  137. package/dist/fleet/fleet-bus.js +42 -9
  138. package/dist/hooks/classic-stations.d.ts +10 -5
  139. package/dist/hooks/classic-stations.js +4 -4
  140. package/dist/hooks/command-spawn.d.ts +57 -0
  141. package/dist/hooks/command-spawn.js +139 -0
  142. package/dist/hooks/hook-llm.js +2 -2
  143. package/dist/hooks/hook-runner.d.ts +127 -25
  144. package/dist/hooks/hook-runner.js +668 -287
  145. package/dist/hooks/hook-source.d.ts +44 -0
  146. package/dist/hooks/hook-source.js +40 -0
  147. package/dist/http/active-run-conflict.d.ts +5 -13
  148. package/dist/http/active-run-conflict.js +17 -27
  149. package/dist/http/admission.js +111 -60
  150. package/dist/http/approval-sweeps.js +58 -19
  151. package/dist/http/caller-trust.d.ts +77 -0
  152. package/dist/http/caller-trust.js +143 -0
  153. package/dist/http/checkpoint-ctx.d.ts +173 -18
  154. package/dist/http/checkpoint-ctx.js +171 -12
  155. package/dist/http/claimed-run.d.ts +4 -3
  156. package/dist/http/device-placement.d.ts +2 -4
  157. package/dist/http/device-placement.js +2 -1
  158. package/dist/http/dispatch.js +13 -7
  159. package/dist/http/durable-run-leg.d.ts +4 -32
  160. package/dist/http/durable-run-leg.js +37 -12
  161. package/dist/http/idempotency.d.ts +2 -2
  162. package/dist/http/idempotency.js +2 -2
  163. package/dist/http/owner-access.d.ts +56 -0
  164. package/dist/http/owner-access.js +42 -0
  165. package/dist/http/principal-gate.d.ts +78 -27
  166. package/dist/http/principal-gate.js +64 -14
  167. package/dist/http/readiness.d.ts +11 -5
  168. package/dist/http/readiness.js +10 -3
  169. package/dist/http/refusal-body.d.ts +12 -0
  170. package/dist/http/refusal-body.js +11 -0
  171. package/dist/http/request-guards.d.ts +16 -32
  172. package/dist/http/request-guards.js +31 -30
  173. package/dist/http/resume-ctx-read.d.ts +50 -6
  174. package/dist/http/resume-ctx-read.js +33 -7
  175. package/dist/http/resume-legs.d.ts +5 -5
  176. package/dist/http/resume-legs.js +163 -91
  177. package/dist/http/retired-service-deps.d.ts +43 -0
  178. package/dist/http/retired-service-deps.js +18 -0
  179. package/dist/http/route-ctx.d.ts +44 -37
  180. package/dist/http/route-ctx.js +4 -0
  181. package/dist/http/route-table.js +2 -0
  182. package/dist/http/routes/a2a-serve.js +3 -4
  183. package/dist/http/routes/admin-config-refresh.js +1 -1
  184. package/dist/http/routes/admin-drain.js +1 -1
  185. package/dist/http/routes/admin-memory-optout.js +5 -1
  186. package/dist/http/routes/adoption.js +2 -9
  187. package/dist/http/routes/agents-roster.js +2 -3
  188. package/dist/http/routes/approvals-assistant.js +91 -56
  189. package/dist/http/routes/background.js +3 -2
  190. package/dist/http/routes/capabilities.js +20 -4
  191. package/dist/http/routes/config-catalog.d.ts +3 -3
  192. package/dist/http/routes/config-catalog.js +1 -1
  193. package/dist/http/routes/devices.js +3 -17
  194. package/dist/http/routes/diagnostics.d.ts +3 -3
  195. package/dist/http/routes/diagnostics.js +6 -2
  196. package/dist/http/routes/fleet.js +4 -4
  197. package/dist/http/routes/images.js +6 -7
  198. package/dist/http/routes/leader.js +1 -8
  199. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  200. package/dist/http/routes/mcp-reconnect.js +3 -2
  201. package/dist/http/routes/memory-bundle.js +1 -1
  202. package/dist/http/routes/memory-compliance.js +1 -1
  203. package/dist/http/routes/memory-consolidation.js +1 -1
  204. package/dist/http/routes/memory-origin.d.ts +1 -1
  205. package/dist/http/routes/memory-origin.js +1 -1
  206. package/dist/http/routes/memory-policy.d.ts +1 -1
  207. package/dist/http/routes/memory-policy.js +3 -2
  208. package/dist/http/routes/notify-wake.js +8 -21
  209. package/dist/http/routes/observability.js +2 -2
  210. package/dist/http/routes/principal-inbox.d.ts +39 -0
  211. package/dist/http/routes/principal-inbox.js +76 -0
  212. package/dist/http/routes/retention-ops.js +2 -9
  213. package/dist/http/routes/rules.js +9 -22
  214. package/dist/http/routes/runs.d.ts +5 -0
  215. package/dist/http/routes/runs.js +63 -115
  216. package/dist/http/routes/session-sync.d.ts +3 -2
  217. package/dist/http/routes/session-sync.js +53 -48
  218. package/dist/http/routes/sessions-list.d.ts +1 -1
  219. package/dist/http/routes/sessions-list.js +3 -4
  220. package/dist/http/routes/sessions.js +33 -43
  221. package/dist/http/routes/side-query.js +6 -4
  222. package/dist/http/routes/tasks.js +71 -30
  223. package/dist/http/routes/trace-usage.js +7 -9
  224. package/dist/http/routes/workflows.d.ts +351 -0
  225. package/dist/http/routes/workflows.js +153 -119
  226. package/dist/http/run-declared-families.d.ts +16 -0
  227. package/dist/http/run-declared-families.js +12 -0
  228. package/dist/http/send.d.ts +24 -3
  229. package/dist/http/send.js +14 -2
  230. package/dist/http/server.d.ts +23 -18
  231. package/dist/http/server.js +20 -15
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +4 -3
  234. package/dist/http/submit-ctx.js +23 -6
  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 +17 -10
  238. package/dist/index.d.ts +3 -1
  239. package/dist/index.js +1 -1
  240. package/dist/lane-home-probe.d.ts +78 -9
  241. package/dist/lane-home-probe.js +78 -12
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/leader/wire.d.ts +4 -0
  245. package/dist/leader/wire.js +8 -7
  246. package/dist/limit-refusal.d.ts +17 -5
  247. package/dist/limit-refusal.js +4 -1
  248. package/dist/main.js +1 -1
  249. package/dist/mcp-assertion-header.d.ts +31 -10
  250. package/dist/mcp-assertion-header.js +10 -3
  251. package/dist/memory-origin-fence.js +2 -2
  252. package/dist/memory-project-layer.d.ts +37 -0
  253. package/dist/memory-project-layer.js +46 -0
  254. package/dist/memory-scope.d.ts +23 -16
  255. package/dist/memory-scope.js +24 -8
  256. package/dist/memory-sync-client.d.ts +27 -13
  257. package/dist/memory-sync-client.js +107 -18
  258. package/dist/model-compat.d.ts +1 -1
  259. package/dist/model-entry-refusal.d.ts +9 -1
  260. package/dist/model-entry-refusal.js +6 -1
  261. package/dist/model-plane-face.d.ts +51 -0
  262. package/dist/model-plane-face.js +24 -0
  263. package/dist/model-provider.d.ts +5 -0
  264. package/dist/model-provider.js +4 -2
  265. package/dist/model-route-endpoint.d.ts +8 -11
  266. package/dist/model-route-endpoint.js +4 -7
  267. package/dist/model-route-env.d.ts +22 -0
  268. package/dist/model-route-env.js +2 -0
  269. package/dist/model-route-gap.d.ts +60 -30
  270. package/dist/model-route-gap.js +21 -15
  271. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  272. package/dist/observability/corrupt-read-seat.js +9 -0
  273. package/dist/observability/err-text.d.ts +6 -0
  274. package/dist/observability/err-text.js +18 -4
  275. package/dist/observability/fail-open.d.ts +35 -9
  276. package/dist/observability/fail-open.js +35 -9
  277. package/dist/observability/metrics.js +1 -0
  278. package/dist/observability/prompt-manifest.d.ts +22 -25
  279. package/dist/observability/prompt-manifest.js +54 -50
  280. package/dist/observability/tool-trace.js +9 -10
  281. package/dist/operator-ask.d.ts +10 -0
  282. package/dist/operator-ask.js +3 -0
  283. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  284. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  285. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  286. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  287. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  288. package/dist/orchestration/workflow-notify-journal.js +27 -34
  289. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  290. package/dist/orchestration/workflow-park-decision.js +119 -0
  291. package/dist/org-delivery-gate.d.ts +81 -0
  292. package/dist/org-delivery-gate.js +59 -0
  293. package/dist/panel-tool-names.d.ts +23 -0
  294. package/dist/panel-tool-names.js +8 -0
  295. package/dist/parked-decide.d.ts +43 -11
  296. package/dist/parked-decide.js +100 -51
  297. package/dist/parked-revive-surface.d.ts +9 -2
  298. package/dist/parked-revive-surface.js +11 -8
  299. package/dist/permission-rule-list.d.ts +1 -1
  300. package/dist/permission-rule-list.js +2 -2
  301. package/dist/permission-rule-vocab.d.ts +1 -23
  302. package/dist/permission-rule-vocab.js +0 -13
  303. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  304. package/dist/plugins/approval-ask-store-file.js +21 -0
  305. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  306. package/dist/plugins/approval-ask-store-memory.js +34 -2
  307. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  308. package/dist/plugins/approval-ask-store-sql.js +37 -1
  309. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  310. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  311. package/dist/plugins/blob-backend.d.ts +38 -25
  312. package/dist/plugins/blob-backend.js +29 -19
  313. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  314. package/dist/plugins/breaker-state-sql.js +4 -4
  315. package/dist/plugins/caching-session-store.d.ts +4 -1
  316. package/dist/plugins/caching-session-store.js +7 -3
  317. package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
  318. package/dist/plugins/checkpoint-store-sql.js +65 -3
  319. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  320. package/dist/plugins/file-history-store-sql.js +3 -1
  321. package/dist/plugins/file-run-store.d.ts +5 -13
  322. package/dist/plugins/file-run-store.js +9 -0
  323. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  324. package/dist/plugins/fork-routing-session-store.js +12 -1
  325. package/dist/plugins/host-platform.d.ts +2 -0
  326. package/dist/plugins/host-platform.js +2 -1
  327. package/dist/plugins/local-checkpoint-store.d.ts +15 -2
  328. package/dist/plugins/local-checkpoint-store.js +32 -1
  329. package/dist/plugins/local-session-store.d.ts +13 -10
  330. package/dist/plugins/local-session-store.js +23 -14
  331. package/dist/plugins/local-session-window.d.ts +45 -0
  332. package/dist/plugins/local-session-window.js +38 -0
  333. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  334. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  335. package/dist/plugins/mailbox-store-sql.js +77 -52
  336. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  337. package/dist/plugins/memory-run-store.d.ts +5 -13
  338. package/dist/plugins/memory-run-store.js +8 -0
  339. package/dist/plugins/one-time-migrations.d.ts +121 -5
  340. package/dist/plugins/one-time-migrations.js +332 -8
  341. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  342. package/dist/plugins/org-delivery-quota-store.js +228 -0
  343. package/dist/plugins/permission-rule-store-file.js +10 -6
  344. package/dist/plugins/permission-rule-store-sql.js +8 -8
  345. package/dist/plugins/pg-pool.js +39 -7
  346. package/dist/plugins/pg-session-storage.d.ts +18 -5
  347. package/dist/plugins/pg-session-storage.js +68 -23
  348. package/dist/plugins/remote-env-adb.d.ts +6 -12
  349. package/dist/plugins/remote-env-adb.js +12 -2
  350. package/dist/plugins/remote-env-device.d.ts +14 -7
  351. package/dist/plugins/remote-env-device.js +23 -15
  352. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  353. package/dist/plugins/remote-env-k8s.js +23 -5
  354. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  355. package/dist/plugins/remote-env-local-docker.js +12 -9
  356. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  357. package/dist/plugins/remote-env-ssh.js +17 -11
  358. package/dist/plugins/run-store-sql.d.ts +16 -14
  359. package/dist/plugins/run-store-sql.js +22 -2
  360. package/dist/plugins/schema-indexes.js +2 -0
  361. package/dist/plugins/send-user-file.js +2 -2
  362. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  363. package/dist/plugins/session-epoch-anchor.js +2 -3
  364. package/dist/plugins/session-ownership.d.ts +11 -0
  365. package/dist/plugins/session-ownership.js +11 -0
  366. package/dist/plugins/session-placement.d.ts +12 -14
  367. package/dist/plugins/session-placement.js +2 -15
  368. package/dist/plugins/session-store.d.ts +18 -8
  369. package/dist/plugins/session-store.js +15 -4
  370. package/dist/plugins/sql-driver.d.ts +74 -11
  371. package/dist/plugins/sql-driver.js +210 -12
  372. package/dist/plugins/sql-errors.d.ts +23 -0
  373. package/dist/plugins/sql-errors.js +21 -0
  374. package/dist/plugins/store-backend.d.ts +36 -1
  375. package/dist/plugins/store-backend.js +40 -14
  376. package/dist/plugins/store-contracts.d.ts +42 -0
  377. package/dist/plugins/store-contracts.js +1 -0
  378. package/dist/plugins/tidb-pool.d.ts +6 -1
  379. package/dist/plugins/tidb-pool.js +44 -10
  380. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  381. package/dist/plugins/tidb-session-storage.js +2 -2
  382. package/dist/plugins/tidb-session-store.d.ts +25 -5
  383. package/dist/plugins/tidb-session-store.js +67 -21
  384. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  385. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  386. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  387. package/dist/plugins/workflow-run-store-sql.js +50 -9
  388. package/dist/posture-source.d.ts +18 -10
  389. package/dist/posture-source.js +4 -1
  390. package/dist/project-identity.d.ts +45 -6
  391. package/dist/project-identity.js +162 -8
  392. package/dist/project-layer-key.d.ts +28 -0
  393. package/dist/project-layer-key.js +29 -0
  394. package/dist/question.js +3 -2
  395. package/dist/read-deny-entry.d.ts +25 -0
  396. package/dist/read-deny-entry.js +12 -0
  397. package/dist/read-face-posture.d.ts +37 -11
  398. package/dist/read-face-posture.js +32 -3
  399. package/dist/request-key-closure.d.ts +7 -0
  400. package/dist/request-key-closure.js +9 -1
  401. package/dist/request-tool-axes.d.ts +12 -0
  402. package/dist/request-tool-axes.js +20 -0
  403. package/dist/request-value-closure.d.ts +5 -0
  404. package/dist/request-value-closure.js +11 -3
  405. package/dist/rule-entry-list.d.ts +26 -2
  406. package/dist/rule-entry-list.js +72 -12
  407. package/dist/rules-consent.js +3 -4
  408. package/dist/run-acceptance.d.ts +19 -3
  409. package/dist/run-acceptance.js +13 -1
  410. package/dist/run-local.js +37 -6
  411. package/dist/runs.d.ts +12 -10
  412. package/dist/runs.js +25 -6
  413. package/dist/runtime-caps-resolver.d.ts +16 -6
  414. package/dist/runtime-caps-resolver.js +18 -5
  415. package/dist/sandbox-pkg-source.d.ts +19 -1
  416. package/dist/sandbox-pkg-source.js +29 -7
  417. package/dist/sealed-key.d.ts +32 -0
  418. package/dist/sealed-key.js +55 -1
  419. package/dist/security.d.ts +95 -15
  420. package/dist/security.js +52 -9
  421. package/dist/session-error-wire.d.ts +31 -7
  422. package/dist/session-error-wire.js +9 -2
  423. package/dist/session-sync-kernel.d.ts +37 -10
  424. package/dist/session-sync-kernel.js +10 -0
  425. package/dist/session-titled-frame.d.ts +33 -0
  426. package/dist/session-titled-frame.js +4 -0
  427. package/dist/session-titler.d.ts +9 -1
  428. package/dist/session-titler.js +15 -4
  429. package/dist/spec-fields.js +21 -2
  430. package/dist/sql-engine-posture.d.ts +3 -1
  431. package/dist/task-a2a.js +4 -3
  432. package/dist/task-cwd.d.ts +1 -1
  433. package/dist/task-mcp.d.ts +5 -5
  434. package/dist/task-mcp.js +27 -74
  435. package/dist/task-settings.d.ts +93 -88
  436. package/dist/task-settings.js +71 -63
  437. package/dist/text-bidi.d.ts +0 -4
  438. package/dist/text-bidi.js +1 -3
  439. package/dist/tighten-only-seats.d.ts +150 -0
  440. package/dist/tighten-only-seats.js +196 -0
  441. package/dist/tool-approval.d.ts +451 -136
  442. package/dist/tool-approval.js +733 -256
  443. package/dist/tool-rule-names.d.ts +6 -0
  444. package/dist/trace/core-keyset-guard.d.ts +108 -25
  445. package/dist/trace/exit-seat.d.ts +40 -0
  446. package/dist/trace/exit-seat.js +130 -0
  447. package/dist/trace/ledger-events.d.ts +6 -3
  448. package/dist/trace/project.d.ts +98 -13
  449. package/dist/trace/project.js +57 -32
  450. package/dist/trace/projection-table.d.ts +100 -0
  451. package/dist/trace/projection-table.js +130 -0
  452. package/dist/trace/redact.d.ts +57 -0
  453. package/dist/trace/redact.js +962 -168
  454. package/dist/trace/self-minted-wire.d.ts +349 -1
  455. package/dist/trace/self-minted-wire.js +118 -1
  456. package/dist/trace/wire-projection-faces.d.ts +304 -2
  457. package/dist/trace/wire-projection-faces.js +160 -13
  458. package/dist/url-refusal.js +2 -0
  459. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  460. package/dist/web-admin-client/apply-effective.js +56 -5
  461. package/dist/web-admin-client/facade.d.ts +1 -1
  462. package/dist/web-admin-client/facade.js +1 -1
  463. package/dist/web-admin-client/read-face.js +5 -9
  464. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  465. package/dist/web-admin-client/skills-mcp.js +6 -8
  466. package/dist/web-admin-client/types.d.ts +1 -1
  467. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  468. package/package.json +8 -4
  469. package/scripts/drain-check-local.mjs +34 -2
  470. package/scripts/drain-check.mysql.sql +20 -2
  471. package/scripts/drain-check.pg.sql +20 -2
  472. package/dist/mcp-tool-faces.d.ts +0 -69
  473. package/dist/mcp-tool-faces.js +0 -106
@@ -1,16 +1,23 @@
1
- import { WEB_FETCH_TOOL_NAME, assembleCodeTools, defaultTaskRegistry } from "@sema-agent/core";
1
+ import { USER_ATTACHMENT_SEAT, WEB_FETCH_TOOL_NAME, assembleCodeTools, defaultTaskRegistry } from "@sema-agent/core";
2
2
  import { HttpError, createCodedHttpError } from "../security.js";
3
3
  import { createSubagentExtraTools, extraToolsErrorFields, nowTool } from "./builtin-tools.js";
4
4
  import { parseRepo, repoToolsFor } from "./repo-tools.js";
5
5
  import { NOW_TOOL_NAME, REPO_PULL_DIFF_TOOL_NAME, REPO_READ_FILE_TOOL_NAME, REPO_TREE_TOOL_NAME } from "./host-tool-names.js";
6
6
  import { createWebSearchBackend, judgeRequestWebSearch } from "../plugins/web-search.js";
7
7
  import { skillsForScenario } from "./skills.js";
8
+ import { OFFICE_EXCLUDED_TOOL_NAMES, runHasWorkspace } from "./hands-lane.js";
8
9
  import { BRAND_IDENTITY_SCENARIOS } from "./brand-identity.js";
9
10
  export function buildPromptSeats(scenarioName, prompt, callerSystemPrompt) {
10
11
  const parts = [prompt?.roleText, callerSystemPrompt].filter((t) => typeof t === "string" && t.length > 0);
11
12
  const systemPrompt = parts.length > 0 ? parts.join("\n\n") : callerSystemPrompt;
12
13
  return { promptBinding: scenarioName, ...(prompt?.role !== undefined ? { promptRole: prompt.role } : {}), ...(systemPrompt !== undefined ? { systemPrompt } : {}) };
13
14
  }
15
+ export function buildExcludeToolsSeat(scenarioExcludes, callerExcludes) {
16
+ if (scenarioExcludes === undefined || scenarioExcludes.length === 0)
17
+ return callerExcludes !== undefined ? { excludeTools: [...callerExcludes] } : {};
18
+ const own = new Set(scenarioExcludes);
19
+ return { excludeTools: [...scenarioExcludes, ...(callerExcludes ?? []).filter((n) => !own.has(n))] };
20
+ }
14
21
  export { SEMA_IDENTITY } from "./prompts/identity.js";
15
22
  function requestWebSearchBackend(verdict, deployment, logger) {
16
23
  switch (verdict.kind) {
@@ -31,6 +38,8 @@ export function buildScenarios(deps) {
31
38
  const webSearch = requestWebSearchBackend(deps.requirePrincipal !== true
32
39
  ? judgeRequestWebSearch(req?.settings?.webSearch)
33
40
  : { kind: "absent" }, deps.webSearch, deps.logger);
41
+ const ensureChildSessionDurable = deps.ensureChildSessionDurable;
42
+ const delegationRoot = ctx?.delegationRoot;
34
43
  return {
35
44
  tools: [
36
45
  nowTool(),
@@ -49,7 +58,7 @@ export function buildScenarios(deps) {
49
58
  scope: "default",
50
59
  ...(deps.backgroundAgentStore ? { agentStore: deps.backgroundAgentStore } : {}),
51
60
  ...(deps.checkpointStore ? { checkpointStore: deps.checkpointStore } : {}),
52
- ...(deps.ensureChildSessionDurable ? { ensureChildSessionDurable: deps.ensureChildSessionDurable } : {}),
61
+ ...(ensureChildSessionDurable !== undefined ? { ensureChildSessionDurable: (childSessionId) => ensureChildSessionDurable(childSessionId, delegationRoot) } : {}),
53
62
  },
54
63
  ...createSubagentExtraTools(deps.subagentExtraTools),
55
64
  ...(deps.logger
@@ -59,7 +68,7 @@ export function buildScenarios(deps) {
59
68
  ...(webSearch ? { webSearch } : {}),
60
69
  }).filter((t) => t.name !== WEB_FETCH_TOOL_NAME || deps.requirePrincipal !== true),
61
70
  ],
62
- hands: "full",
71
+ hands: BUILTIN_SCENARIO_HANDS.default,
63
72
  skills: skillsForScenario(deps.skills, "default"),
64
73
  };
65
74
  };
@@ -67,6 +76,7 @@ export function buildScenarios(deps) {
67
76
  default: defaultScenario,
68
77
  code: (req, principal, ctx) => ({
69
78
  ...defaultScenario(req, principal, ctx),
79
+ hands: BUILTIN_SCENARIO_HANDS.code,
70
80
  prompt: { role: "code" },
71
81
  }),
72
82
  "code-review": (req) => codeReview(deps, req),
@@ -77,10 +87,17 @@ export function buildScenarios(deps) {
77
87
  }
78
88
  return {
79
89
  tools: [...repoToolsFor(repoClient, parseRepo(req.repo)), nowTool()],
80
- hands: "none",
90
+ hands: BUILTIN_SCENARIO_HANDS.scan,
81
91
  skills: skillsForScenario(deps.skills, "scan"),
82
92
  };
83
93
  },
94
+ cowork: (req, principal, ctx) => ({
95
+ ...defaultScenario(req, principal, ctx),
96
+ hands: BUILTIN_SCENARIO_HANDS.cowork,
97
+ skills: skillsForScenario(deps.skills, "cowork"),
98
+ excludeTools: OFFICE_EXCLUDED_TOOL_NAMES,
99
+ prompt: { role: "cowork" },
100
+ }),
84
101
  };
85
102
  }
86
103
  export function selectScenario(scenarios, name) {
@@ -91,11 +108,22 @@ export function selectScenario(scenarios, name) {
91
108
  throw new Error(`scenario "${name}" is not registered — resolve a request's scenario through gateScenarioRequest, which only returns registered names`);
92
109
  return picked;
93
110
  }
111
+ export function attachmentSuppliesFor(hands, handsLane) {
112
+ const workspace = runHasWorkspace(hands, handsLane);
113
+ return USER_ATTACHMENT_SEAT.supplies.filter((supply) => workspace || supply !== "path");
114
+ }
94
115
  function availabilityFields(deps, toolset) {
95
116
  const verdict = scenarioAvailability(deps, toolset);
96
117
  return verdict.available ? { available: true } : { available: false, unavailableReason: verdict.reason };
97
118
  }
98
- export const BUILTIN_SCENARIO_NAMES = ["code", "default", "code-review", "scan"];
119
+ export const BUILTIN_SCENARIO_NAMES = ["code", "default", "code-review", "scan", "cowork"];
120
+ export const BUILTIN_SCENARIO_HANDS = {
121
+ code: "full",
122
+ default: "full",
123
+ "code-review": "none",
124
+ scan: "none",
125
+ cowork: "full",
126
+ };
99
127
  export function builtinScenarioDetails(scenarios, deps, branded) {
100
128
  const probe = (name, req, principal, fallback) => {
101
129
  try {
@@ -109,6 +137,7 @@ export function builtinScenarioDetails(scenarios, deps, branded) {
109
137
  const mk = (name, summary, toolset, tools, promptSummary) => ({
110
138
  name, source: "builtin", builtin: true, summary, toolset, tools, promptSummary, enabled: true,
111
139
  ...availabilityFields(deps, toolset),
140
+ attachmentSupplies: attachmentSuppliesFor(BUILTIN_SCENARIO_HANDS[name], deps.handsLane === true),
112
141
  });
113
142
  const brandedScenario = (name) => branded && BRAND_IDENTITY_SCENARIOS.includes(name);
114
143
  const details = {
@@ -116,6 +145,7 @@ export function builtinScenarioDetails(scenarios, deps, branded) {
116
145
  default: mk("default", "通用/助理场景(域中性 persona,CC agent loop 全量工具面;[891] 起非出厂缺省,显式可选)", "full-body", probe("default", {}, undefined, [NOW_TOOL_NAME]), brandedScenario("default") ? "Sema 产品身份 + core 默认宪法(结构层由引擎合成)" : "core 默认宪法(中性,无场景附加 persona)"),
117
146
  "code-review": mk("code-review", "代码评审(clone-free 只读仓库工具)", "repo-readonly", probe("code-review", { repo: "probe/probe" }, undefined, REPO_TOOLS), "评审员提示词(产出契约)"),
118
147
  scan: mk("scan", "中性只读仓库扫描(输出契约由 objective+skills 决定)", "repo-readonly", probe("scan", { repo: "probe/probe" }, undefined, REPO_TOOLS), "无场景附加提示词(objective+center skills 拥有输出契约)"),
148
+ cowork: mk("cowork", "办公向场景(default 的工具面去编码类工具:文件读 / 浏览 / 连接器挂载;Cowork 角色基底)", "office", probe("cowork", {}, undefined, [NOW_TOOL_NAME]), "core Cowork 角色基底(promptRole: cowork;办公向,不带编码 persona)"),
119
149
  };
120
150
  return details;
121
151
  }
@@ -126,7 +156,8 @@ export function centerScenarioDetails(specs, builtinNames, deps) {
126
156
  continue;
127
157
  if (typeof spec.name !== "string" || !SCENARIO_NAME_RE.test(spec.name))
128
158
  continue;
129
- if (!Object.hasOwn(TOOLSETS, spec.toolset) || !TOOLSETS[spec.toolset])
159
+ const toolset = Object.hasOwn(TOOLSETS, spec.toolset) ? TOOLSETS[spec.toolset] : undefined;
160
+ if (!toolset)
130
161
  continue;
131
162
  out[spec.name] = {
132
163
  name: spec.name,
@@ -138,6 +169,7 @@ export function centerScenarioDetails(specs, builtinNames, deps) {
138
169
  promptSummary: "",
139
170
  enabled: true,
140
171
  ...availabilityFields(deps, spec.toolset),
172
+ attachmentSupplies: attachmentSuppliesFor(toolset.hands, deps.handsLane === true),
141
173
  };
142
174
  }
143
175
  return out;
@@ -213,7 +245,7 @@ function codeReview(deps, req) {
213
245
  const coords = parseRepo(req.repo);
214
246
  const repoTools = repoToolsFor(repoClient, coords);
215
247
  const skills = skillsForScenario(deps.skills, "code-review");
216
- const hands = "none";
248
+ const hands = BUILTIN_SCENARIO_HANDS["code-review"];
217
249
  return { tools: [...repoTools, nowTool()], hands, skills, prompt: { roleText: REVIEWER_ROLE_TEXT } };
218
250
  }
219
251
  const REVIEWER_ROLE_TEXT = "You are a senior code reviewer. Call repo_tree to map the repository, then repo_read_file to read " +
@@ -22,7 +22,7 @@ import type { FlatServiceDeps } from "./http/server.js";
22
22
  import type { ServiceConfig } from "./config.js";
23
23
  import type { OwnerAwareSessionStore } from "./security.js";
24
24
  import type { ServiceFileHistoryStore } from "./plugins/store-backend.js";
25
- import { resolveStreamApprovalGate } from "./tool-approval.js";
25
+ import { resolveStreamApprovalGate, type ApprovalFrameFamily } from "./tool-approval.js";
26
26
  import { type WorkspaceSyncCapability } from "./workspace-space.js";
27
27
  import type { WorkspaceCacheCapability } from "./workspace-cache.js";
28
28
  /** why 闭集:词 → 给运维看的一句义(诊断 / 测试读它;wire 上的拒句由各门自写)。 */
@@ -56,7 +56,8 @@ export declare const CAPABILITY_FACT_WHY: {
56
56
  readonly image_index_absent: "no image index is wired (SQL backends only)";
57
57
  readonly shared_memory_store_absent: "no shared memory store provider is wired";
58
58
  readonly org_memory_directory_absent: "no org memory directory (membership fold) is wired";
59
- readonly operator_principals_empty: "OPERATOR_PRINCIPALS is empty, so no caller can ever be an operator";
59
+ readonly org_delivery_gate_absent: "no organization delivery gate is mounted (PRINCIPAL_INBOX_ASSISTANT is unset: the deployment declares no principal-inbox consumer)";
60
+ readonly operator_principals_empty: `no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can ever be an operator; ${string}`;
60
61
  readonly adoption_store_absent: "no adoption log store is wired (SQL backends only)";
61
62
  readonly memory_bundle_faces_absent: "the memory engine's governance bundle faces are not wired";
62
63
  readonly memory_compliance_faces_absent: "the memory engine's provenance/erasure faces are not wired";
@@ -73,6 +74,7 @@ export declare const CAPABILITY_FACT_WHY: {
73
74
  readonly ask_question_disabled: "AskUserQuestion live HITL is off (ASK_QUESTION_ENABLED)";
74
75
  readonly tool_approval_disabled: "live tool approval is off (TOOL_APPROVAL_ENABLED)";
75
76
  readonly stream_approval_disabled: "the stream approval protocol is off (STREAM_APPROVAL_ENABLED)";
77
+ readonly read_root_grant_posture_refused: "this is not a single-user host-lane deployment (REMOTE_EXEC=host without REQUIRE_PRINCIPAL), the only posture that honors a read-directory grant";
76
78
  readonly background_agent_store_absent: "no background-agent store is wired";
77
79
  readonly sendfile_ledger_absent: "no SendUserFile ledger is wired";
78
80
  readonly workflow_engine_absent: "the workflow engine is not available on this worker";
@@ -199,6 +201,29 @@ type ActiveStreamApproval = Extract<ReturnType<typeof resolveStreamApprovalGate>
199
201
  export declare function streamApproval(d: Pick<Deps, "toolApproval" | "config" | "backend" | "checkpointStore">): Fact<StreamApprovalWhy, {
200
202
  askStore: ActiveStreamApproval["askStore"];
201
203
  }>;
204
+ /**
205
+ * 读根授权(「Yes, and add directory」)这台部署**受理不受理** —— `GET /v1/capabilities` 的 `approvalReadRootGrant` 位,与
206
+ * `POST /v1/tool-approvals/:id/respond` 对应答体 `readRootGrant` 的受理门**读同一只**(位说不受理而口照收,就是「位说 X、行为不是 X」)。
207
+ *
208
+ * 判据 = 单用户 host 车道姿态 {@link cwdHonored}(与调用方 `cwd` / 附加目录同一条信任边界):授权把一个**宿主目录**加进本 run 的读目录,
209
+ * 只有「这台机器一个可信主人」的姿态才有这个授权的语义;多租户与云上 / 容器车道的读面另有归宿(沙箱内的读面档位见 `READ_FACE`)。
210
+ * 消费方的选项可见条件是**合取**:卡上有 `readRootCandidate`(逐卡位,引擎铸)∧ 本位为真。位缺席 = 老 server(不受理)。
211
+ * 没有别的端点按本位判可用与否 —— 它只管应答体里的这一键。
212
+ */
213
+ export declare function readRootGrant(d: Pick<Deps, "config">): Fact<"read_root_grant_posture_refused">;
214
+ /**
215
+ * 审批开卡帧的族 —— `GET /v1/capabilities` 的 `approvalFrameFamilies` 位。**值族投影**(出形是闭集词数组,不是 `{ available }`;同
216
+ * `engineCapabilityBits` 一类),入参是 {@link streamApproval} **已求出的那一份事实**而不是 deps:一次请求里 `streamApproval` 位与本位读同一次判据求值
217
+ * (判据读活配置与 backend,两次求值在开关热改的窗口里会撕出 `streamApproval:true` 配旧族的应答;也多取一次 ask 店)。
218
+ * · 流内审批在场(呈卡协议上场)⇒ `["approval_request"]`;
219
+ * · 活卡协调器在、协议没上场(开关关 / 无 store backend / 无 park 设施)⇒ `["tool_approval"]`;
220
+ * · 活卡协调器缺席 ⇒ `[]`(没有审批卡可呈)。
221
+ * 对 why 闭集穷举:`streamApproval` 的拒因多一个 ⇒ 这里编译红,逼着给新拒因定族。三条执行腿选族读的是同一只判据的 `active`,
222
+ * 与本映射的「在场 ⇒ 呈卡族」是同一条规则(真腿对拍钉在 `test/stream-approval-on-e2e.test.ts`)。没有端点按它拒:它是消费方分派帧族的读点,`streamApproval` 的词义不变。
223
+ * S-1914:它也是壳**声明**的依据 —— 一条 run 只在 `settings.approvalFrameFamilies` 含本位那一个族时有活审批通道(三条腿判的是同一只映射
224
+ * `presentedApprovalFrameFamily`);不含 ⇒ 这条腿不呈卡,问当场交无人值守政策口。本位的值不因声明而变。
225
+ */
226
+ export declare function approvalFrameFamilies(stream: ReturnType<typeof streamApproval>): readonly ApprovalFrameFamily[];
202
227
  export declare function deviceLane(d: Pick<Deps, "deviceHub">): Fact<"device_hub_absent", {
203
228
  hub: Store<"deviceHub">;
204
229
  }>;
@@ -232,12 +257,19 @@ export declare function sharedMemoryRead(d: Pick<Deps, "sharedMemoryStore" | "or
232
257
  provider: Store<"sharedMemoryStore">;
233
258
  directory: Store<"orgMemoryDirectory">;
234
259
  }>;
235
- /** operator 名单非空。空名单下 `explicitOperatorOk` 对任何身份恒假 ⇒ 这一族的口对谁都打不通 = 部署不可用(不是鉴权拒)。
260
+ /** 跨主体投递门在座(`POST /v1/principal-inbox/messages` 的可用性门与能力位 `principalInboxDelivery` 同读这一只)。门的装配本身是
261
+ * 一道合取(收件箱消费方声明 ∧ 耐久 mailbox ∧ org 成员目录 ∧ 配额店,缺一拒启 —— `boot/stage-06-runners.ts`),
262
+ * 所以这里只判「门在不在」:在 ⟺ 那四件都在。 */
263
+ export declare function principalInboxDelivery(d: Pick<Deps, "orgDeliveryGate">): Fact<"org_delivery_gate_absent", {
264
+ gate: Store<"orgDeliveryGate">;
265
+ }>;
266
+ /** 这台部署有运维名册(名单非空 ∨ 单用户声明 `OPERATOR_SINGLE_USER`;唯一读法 `operatorRosterPresent`)。没有时 `explicitOperatorOk` 对任何身份恒假
267
+ * ⇒ 这一族的口对谁都打不通 = 部署不可用(不是鉴权拒)。
236
268
  *
237
269
  * operator 族的复合事实**先判名单、再判设施**:门序是「身份 → 名单空(501)→ 授权(403)→ 设施缺席(501)」——
238
270
  * 名单空时没有人过得了授权,不先判它,这一形就永远答成 403;设施缺席则留在授权之后答(不对非 operator 透露部署形态)。 */
239
271
  export declare function operatorLane(d: {
240
- readonly config: Pick<ServiceConfig, "operatorPrincipals">;
272
+ readonly config: Pick<ServiceConfig, "operatorPrincipals" | "operatorSingleUser">;
241
273
  }): Fact<"operator_principals_empty">;
242
274
  type AdoptionCapableBackend = Store<"backend"> & {
243
275
  adoptionLog(): ReturnType<NonNullable<Store<"backend">["adoptionLog"]>>;
@@ -1,5 +1,7 @@
1
+ import { buildOperatorRosterWayOut, operatorRosterPresent } from "./http/principal-gate.js";
1
2
  import { mcpInjectionHonored } from "./task-mcp.js";
2
- import { resolveStreamApprovalGate } from "./tool-approval.js";
3
+ import { cwdHonored } from "./task-cwd.js";
4
+ import { presentedApprovalFrameFamily, resolveStreamApprovalGate } from "./tool-approval.js";
3
5
  import { selfOrchestrationDenial } from "./task-workflow.js";
4
6
  import { centerEntitlementSourceWired } from "./runtime-caps-resolver.js";
5
7
  import { overwriteWipeIncapable } from "./session-sync.js";
@@ -34,7 +36,8 @@ export const CAPABILITY_FACT_WHY = {
34
36
  image_index_absent: "no image index is wired (SQL backends only)",
35
37
  shared_memory_store_absent: "no shared memory store provider is wired",
36
38
  org_memory_directory_absent: "no org memory directory (membership fold) is wired",
37
- operator_principals_empty: "OPERATOR_PRINCIPALS is empty, so no caller can ever be an operator",
39
+ org_delivery_gate_absent: "no organization delivery gate is mounted (PRINCIPAL_INBOX_ASSISTANT is unset: the deployment declares no principal-inbox consumer)",
40
+ operator_principals_empty: `no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can ever be an operator; ${buildOperatorRosterWayOut()}`,
38
41
  adoption_store_absent: "no adoption log store is wired (SQL backends only)",
39
42
  memory_bundle_faces_absent: "the memory engine's governance bundle faces are not wired",
40
43
  memory_compliance_faces_absent: "the memory engine's provenance/erasure faces are not wired",
@@ -51,6 +54,7 @@ export const CAPABILITY_FACT_WHY = {
51
54
  ask_question_disabled: "AskUserQuestion live HITL is off (ASK_QUESTION_ENABLED)",
52
55
  tool_approval_disabled: "live tool approval is off (TOOL_APPROVAL_ENABLED)",
53
56
  stream_approval_disabled: "the stream approval protocol is off (STREAM_APPROVAL_ENABLED)",
57
+ read_root_grant_posture_refused: "this is not a single-user host-lane deployment (REMOTE_EXEC=host without REQUIRE_PRINCIPAL), the only posture that honors a read-directory grant",
54
58
  background_agent_store_absent: "no background-agent store is wired",
55
59
  sendfile_ledger_absent: "no SendUserFile ledger is wired",
56
60
  workflow_engine_absent: "the workflow engine is not available on this worker",
@@ -192,7 +196,7 @@ export function streamApproval(d) {
192
196
  toolApprovalEnabled: d.toolApproval !== undefined,
193
197
  streamApprovalEnabled: d.config.streamApproval?.enabled === true,
194
198
  backend: d.backend,
195
- parkFacility: d.checkpointStore !== undefined,
199
+ checkpointStore: d.checkpointStore,
196
200
  });
197
201
  if (gate.active)
198
202
  return yes({ askStore: gate.askStore });
@@ -211,6 +215,25 @@ export function streamApproval(d) {
211
215
  }
212
216
  }
213
217
  }
218
+ export function readRootGrant(d) {
219
+ return cwdHonored(d.config) ? YES : no("read_root_grant_posture_refused");
220
+ }
221
+ export function approvalFrameFamilies(stream) {
222
+ if (stream.available)
223
+ return [presentedApprovalFrameFamily(true)];
224
+ switch (stream.why) {
225
+ case "tool_approval_disabled":
226
+ return [];
227
+ case "stream_approval_disabled":
228
+ case "store_backend_absent":
229
+ case "checkpoint_store_absent":
230
+ return [presentedApprovalFrameFamily(false)];
231
+ default: {
232
+ const unhandled = stream.why;
233
+ throw new Error(`unhandled stream-approval why: ${JSON.stringify(unhandled)}`);
234
+ }
235
+ }
236
+ }
214
237
  export function deviceLane(d) {
215
238
  return d.deviceHub !== undefined ? yes({ hub: d.deviceHub }) : no("device_hub_absent");
216
239
  }
@@ -252,8 +275,11 @@ export function sharedMemoryRead(d) {
252
275
  return no("org_memory_directory_absent");
253
276
  return yes({ provider: d.sharedMemoryStore, directory: d.orgMemoryDirectory });
254
277
  }
278
+ export function principalInboxDelivery(d) {
279
+ return d.orgDeliveryGate !== undefined ? yes({ gate: d.orgDeliveryGate }) : no("org_delivery_gate_absent");
280
+ }
255
281
  export function operatorLane(d) {
256
- return d.config.operatorPrincipals.length > 0 ? YES : no("operator_principals_empty");
282
+ return operatorRosterPresent(d.config) ? YES : no("operator_principals_empty");
257
283
  }
258
284
  export function adoption(d) {
259
285
  const lane = operatorLane(d);
@@ -0,0 +1,69 @@
1
+ /**
2
+ * S-667 —— **中心配置档位的唯一属主**:「在用的中心配置是谁的」+「换人之后降到了无中心配置档没有」+ 两态通告。
3
+ *
4
+ * ## 律
5
+ * 凭证身份(凭据文件里的主体,`center-credential.ts` 的 `identity`)变化的那一刻,server 自己:
6
+ * 1. 把在用的中心配置降到「无中心配置」档 —— 每个中心下发的热面回 env 底、中心提示词层撤下、Runner 的模型表换回 env 表;
7
+ * 2. 当场发起一次拉取(不等下一个 60s 拍);
8
+ * 3. 通告 {@link CenterIdentityNoticeCode} `center_identity_demoted`;新身份的候选落地 ⇒ 通告 `center_identity_landed`。
9
+ * 拉取成功之前**不回退**到上一个人的任何东西(盘上 LKG 是按身份分箱的,新身份的箱里没有上一个人的;内存里的在用候选在降档时已清)。
10
+ * 不采「壳重启引擎」:读凭据文件的那一刻引擎自己就判得出,壳只能猜;本机引擎多会话共享,重启会打断别的会话正在跑的 run。
11
+ *
12
+ * ## 本模块只管状态与词,不管动作
13
+ * 降档的动作(换活配置、换 Runner 席、撤提示词层、拉取)在 `boot/web-admin.ts`,那里是活配置与单飞拍的属主;本模块是纯状态机:
14
+ * · `committed(identity)` —— 一份中心候选(或「无中心配置」候选自己,身份缺席)提交了:记下在用配置的身份;降档态下第一份带身份的提交 = 换上了;
15
+ * · `drifted(identity)` —— 此刻凭证的身份与参照身份(在用配置的,或已降档时在等的)不一致吗(只有存在参照且「凭证身份读得出」才可能为真);
16
+ * · `demote(awaiting)` / `retarget(awaiting)` —— 记下降档、改在等的身份;
17
+ * · `notice()` —— 最近一条通告(`/health.centerIdentityNotice` 的取值口读它)。
18
+ *
19
+ * ## 通告的面
20
+ * 通告是**最近一条**,不是事件日志:`/health.centerIdentityNotice = { code, message, at, retained? }`(无鉴权面 —— 只有闭集码、冻结句、时刻,
21
+ * 不带身份、不带令牌、不带路径);从未换过人 ⇒ 键缺席。消费端按 `at` 判断「这一条我转述过没有」。日志轴另有同名事件
22
+ * (`center_identity_demoted` warn / `center_identity_landed` info)。
23
+ * 这两只码**不在** core 的 `EngineNotice` 码册里(那是 core 的闭集,受众与归属键由 core 定;进该册要 core 加行)—— 它们是本服务自铸的 `/health` 值,
24
+ * 登记在 `trace/self-minted-wire.ts` 的 `centerIdentityNotice`,契约 §0.4 成文。
25
+ */
26
+ import type { ConfigApplyGroup } from "./web-admin-client/apply-ledger.js";
27
+ /** 两态通告码(闭集)。新增一个 = `CENTER_IDENTITY_NOTICE_MESSAGE` 与 `SELF_MINTED_WIRE.centerIdentityNotice` 当场编译红。 */
28
+ export declare const CENTER_IDENTITY_NOTICE_CODES: readonly ["center_identity_demoted", "center_identity_landed"];
29
+ export type CenterIdentityNoticeCode = (typeof CENTER_IDENTITY_NOTICE_CODES)[number];
30
+ /**
31
+ * 每个码的**冻结句**(wire 可见 —— `test/api-notice-text-freeze.test.ts` §8 逐字冻;改一个字节要同步契约与消费端)。
32
+ * 句子是定句:不带身份、不带版本号、不带路径,免鉴权面上读到它不泄露任何东西。映射型逐码穷举。
33
+ */
34
+ export declare const CENTER_IDENTITY_NOTICE_MESSAGE: {
35
+ readonly center_identity_demoted: "The center credential now belongs to another account: this engine dropped the previous account's center configuration and runs on its base configuration (no center layer) until the new account's configuration is pulled.";
36
+ readonly center_identity_landed: "The new account's center configuration was pulled and is now in force.";
37
+ };
38
+ /** 一条通告(wire 形:`/health.centerIdentityNotice` 就是这个对象)。 */
39
+ export interface CenterIdentityNotice {
40
+ readonly code: CenterIdentityNoticeCode;
41
+ readonly message: string;
42
+ /** 铸这条通告的时刻(ms epoch)。 */
43
+ readonly at: number;
44
+ /**
45
+ * 只在 `center_identity_demoted` 上、且非空时在场:降档**没能降到底**的组 —— 该组被整拒(例:env 的审批名单在这台部署上无处可服务),活值仍是上一个人下发的。
46
+ * 冻结句说「回了基础配置」,这一键让它对这几组如实:成员是世代账的组闭集(`ConfigApplyGroup`)。缺席 = 每个热面都已回 env 底。
47
+ */
48
+ readonly retained?: readonly ConfigApplyGroup[];
49
+ }
50
+ export interface CenterConfigTier {
51
+ /** 一份候选提交了(含部分应用)。`identity` = 拉到它的凭证身份;缺席 = 本地腿候选 / 「无中心配置」候选自己(没有中心配置在服务)。
52
+ * 降档态下第一份带身份的提交 ⇒ 铸并返回 `center_identity_landed`;其余返回 undefined。 */
53
+ committed(identity: string | undefined): CenterIdentityNotice | undefined;
54
+ /**
55
+ * 此刻凭证的身份与「参照身份」不一致吗 —— 参照 = 在用中心配置的身份;已降档则是降档在等的那个身份。没有参照(没有中心配置在服务、也没降过档)/
56
+ * 凭证身份读不出(`undefined`)⇒ 恒假:降无可降,读不出不是换了人。
57
+ */
58
+ drifted(identity: string | undefined): boolean;
59
+ /** 记下降档(此后没有中心配置在服务,在等 `awaiting` 这个身份的候选)并铸 `center_identity_demoted`;`retained` = 没能降到底的组(空 / 缺席 = 全降到底)。 */
60
+ demote(awaiting: string, retained?: readonly ConfigApplyGroup[]): CenterIdentityNotice;
61
+ /** 已降档态下凭证又换了人:只改「在等谁」,不再铸通告(还是同一次降档 —— 新身份的候选没落地)。 */
62
+ retarget(awaiting: string): void;
63
+ /** 最近一条通告;从未铸过 ⇒ undefined。 */
64
+ notice(): CenterIdentityNotice | undefined;
65
+ /** 是否在降档态(降过、新身份的候选还没落地)。 */
66
+ isDemoted(): boolean;
67
+ }
68
+ export declare function createCenterConfigTier(now?: () => number): CenterConfigTier;
69
+ //# sourceMappingURL=center-config-tier.d.ts.map
@@ -0,0 +1,42 @@
1
+ export const CENTER_IDENTITY_NOTICE_CODES = ["center_identity_demoted", "center_identity_landed"];
2
+ export const CENTER_IDENTITY_NOTICE_MESSAGE = {
3
+ center_identity_demoted: "The center credential now belongs to another account: this engine dropped the previous account's center configuration and runs on its base configuration (no center layer) until the new account's configuration is pulled.",
4
+ center_identity_landed: "The new account's center configuration was pulled and is now in force.",
5
+ };
6
+ export function createCenterConfigTier(now = Date.now) {
7
+ let inForce;
8
+ let awaiting;
9
+ let demoted = false;
10
+ let last;
11
+ const mint = (code, retained = []) => {
12
+ last = { code, message: CENTER_IDENTITY_NOTICE_MESSAGE[code], at: now(), ...(retained.length > 0 ? { retained: [...retained] } : {}) };
13
+ return last;
14
+ };
15
+ return {
16
+ committed(identity) {
17
+ inForce = identity;
18
+ if (!demoted || identity === undefined)
19
+ return undefined;
20
+ demoted = false;
21
+ awaiting = undefined;
22
+ return mint("center_identity_landed");
23
+ },
24
+ drifted(identity) {
25
+ const reference = demoted ? awaiting : inForce;
26
+ return reference !== undefined && identity !== undefined && identity !== reference;
27
+ },
28
+ demote(next, retained) {
29
+ inForce = undefined;
30
+ awaiting = next;
31
+ demoted = true;
32
+ return mint("center_identity_demoted", retained);
33
+ },
34
+ retarget(next) {
35
+ if (demoted)
36
+ awaiting = next;
37
+ },
38
+ notice: () => last,
39
+ isDemoted: () => demoted,
40
+ };
41
+ }
42
+ //# sourceMappingURL=center-config-tier.js.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 一次性迁移 M28 —— 升级之前写下的停驻行(`checkpoint_ctx`)里,请求面凭据位上的明文起服**原地封好**。
3
+ * 🔴 M28 · 窗口见 `plugins/one-time-migrations.ts` 的 ONE_TIME_MIGRATIONS 登记表(窗、删法、删后由谁接住只写在那一行)。
4
+ *
5
+ * ## 为什么要它(持久数据面)
6
+ * 7.134.0 起凭据位上的值在 ctx 里只以封签存在(规则属主 `http/checkpoint-ctx.ts` 末段「凭据位密封」),续跑上下文读口对凭据位上的明文答
7
+ * 409 `conflict.checkpoint_ctx_unsealable`(`reason:"plaintext"`)。升级前停驻的行是明文 —— 持久数据面不能「翻红」,所以起服扫一遍、用**同一只**封口
8
+ * (`sealStoredCheckpointCtxM28`,与写侧 `sealCheckpointCtx` 同一只走法)封好、原地回写;不删行、不动续跑时钟、已封的与不带凭据的行零写。
9
+ *
10
+ * ## 为什么不在 `one-time-migrations.ts` 的迁移段里
11
+ * 封要保管店派生的封签器,而那一段跑在店层(起服第 3 段,`openStores`),比建店的 web-admin 运行时能把封签器交下去的地方早、也不该反向依赖它;
12
+ * 本条在起服第 6 段 checkpoint 店建成、封签器的装配判(`CHECKPOINT_CTX_SEALING_REQUIRED`)过了之后调一次,早于任何路由装配(与 M10 / M19 / M25
13
+ * 同为在迁移段之外跑的条目)。读数一行 info `checkpoint_ctx_credentials_sealed`,不进 `OneTimeMigrationReport`(登记行 `reportKeys` 空)。
14
+ */
15
+ import { type CheckpointCtxSealer, type SealedCheckpointCtx } from "./http/checkpoint-ctx.js";
16
+ import { type OneTimeMigrationWindow } from "./plugins/one-time-migrations.js";
17
+ import type { CtxRowsRewriteM28 } from "./plugins/checkpoint-store-sql.js";
18
+ /** 两孪生的店腿(`SqlCheckpointStore` / `LocalCheckpointStore` 的 `rewriteCtxRowsM28`)。 */
19
+ export interface CheckpointCtxRowsRewriterM28 {
20
+ rewriteCtxRowsM28(rewrite: (sessionId: string, ctx: object) => {
21
+ readonly ctx: SealedCheckpointCtx;
22
+ readonly values: number;
23
+ } | undefined): Promise<CtxRowsRewriteM28>;
24
+ }
25
+ /** M28 一次起服的读数(起服 info 行逐键打出;测试按它断言)。`window: "closed"` ⇒ 一行都没读(其余全 0)。 */
26
+ export interface CheckpointCtxSealM28Report {
27
+ readonly window: "open" | "closed";
28
+ readonly rowsScanned: number;
29
+ readonly rowsSealed: number;
30
+ readonly valuesSealed: number;
31
+ readonly rowsUnreadable: number;
32
+ readonly rowsTooLarge: number;
33
+ }
34
+ /**
35
+ * 跑一次 M28(`today` = UTC 日历日 YYYY-MM-DD;`window` 缺省 = 登记表 M28 那一行 —— 只有测试递别的窗)。窗关 ⇒ 不扫。
36
+ * 店腿的每一行:`sealStoredCheckpointCtxM28` 交回新体(凭据位上的明文封好)⇒ 回写;交回 `undefined`(没有明文)⇒ 不写。
37
+ */
38
+ export declare function sealCheckpointCtxCredentialsM28(store: CheckpointCtxRowsRewriterM28, sealer: CheckpointCtxSealer, opts: {
39
+ readonly today: string;
40
+ readonly window?: Pick<OneTimeMigrationWindow, "removableAfter">;
41
+ }): Promise<CheckpointCtxSealM28Report>;
42
+ //# sourceMappingURL=checkpoint-ctx-seal-m28.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { sealStoredCheckpointCtxM28 } from "./http/checkpoint-ctx.js";
2
+ import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
3
+ function m28Window() {
4
+ const row = ONE_TIME_MIGRATIONS.find((w) => w.id === "M28");
5
+ if (row === undefined)
6
+ throw new Error("checkpoint-ctx-seal-m28: the one-time migration registry has no M28 row — this migration outlived its registry row; delete it with that row");
7
+ return row;
8
+ }
9
+ export async function sealCheckpointCtxCredentialsM28(store, sealer, opts) {
10
+ if (!migrationWindowOpen(opts.window ?? m28Window(), opts.today)) {
11
+ return { window: "closed", rowsScanned: 0, rowsSealed: 0, valuesSealed: 0, rowsUnreadable: 0, rowsTooLarge: 0 };
12
+ }
13
+ const r = await store.rewriteCtxRowsM28((sessionId, ctx) => {
14
+ const out = sealStoredCheckpointCtxM28(ctx, sealer, sessionId);
15
+ return out === undefined ? undefined : { ctx: out.ctx, values: out.valuesSealed };
16
+ });
17
+ return { window: "open", rowsScanned: r.scanned, rowsSealed: r.rewritten, valuesSealed: r.valuesRewritten, rowsUnreadable: r.unreadable, rowsTooLarge: r.tooLarge };
18
+ }
19
+ //# sourceMappingURL=checkpoint-ctx-seal-m28.js.map
@@ -0,0 +1,16 @@
1
+ /** `checkpointId` 的长度上界(见本文件头注第 2 条)。 */
2
+ export declare const MAX_CHECKPOINT_ID_CHARS = 128;
3
+ /** 持久层读出的 `checkpointId` 过信任边界:是串、非空、不超长、不含 token(大小写不敏感)⇒ 原值;否则 `undefined`。判据全文见本文件头注。 */
4
+ export declare function trustedCheckpointId(raw: unknown, token: unknown): string | undefined;
5
+ /** 带 `checkpointId` 当 join 键的两类 durable 读面(计数 detail 的 `face`)。 */
6
+ export type DurableCheckpointFace = "approvals-queue" | "assistant-inbox";
7
+ /**
8
+ * durable 读面的一行 → 它的身份片段,**由调用方原样展开进行投影**(`...durableRowIdentity(face, raw, token)`):读得出可信值 ⇒ `{ checkpointId }`;
9
+ * 读不出 ⇒ `{}`(这一行**照列**,键缺席)+ 计一次(见本文件头注「durable 面的 join 键」)。
10
+ * `raw === undefined` = 行上没有这一格(`why=absent`,老行);在场却没过信任边界(非串 / 空串 / 超长 / 含 token / 读不出)= `why=untrusted`。
11
+ * 三处读面(两只店的 `listPending` + 收件 handler)只经这一只 —— 读法、计数、缺席形各只有一份。
12
+ */
13
+ export declare function durableRowIdentity(face: DurableCheckpointFace, raw: unknown, token: unknown): {
14
+ readonly checkpointId?: string;
15
+ };
16
+ //# sourceMappingURL=checkpoint-identity.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { recordFailOpen } from "./observability/fail-open.js";
2
+ export const MAX_CHECKPOINT_ID_CHARS = 128;
3
+ export function trustedCheckpointId(raw, token) {
4
+ if (typeof raw !== "string" || raw === "" || raw.length > MAX_CHECKPOINT_ID_CHARS)
5
+ return undefined;
6
+ const secret = token === undefined || token === null ? "" : String(token).toLowerCase();
7
+ if (secret !== "" && raw.toLowerCase().includes(secret))
8
+ return undefined;
9
+ return raw;
10
+ }
11
+ export function durableRowIdentity(face, raw, token) {
12
+ const id = trustedCheckpointId(raw, token);
13
+ if (id === undefined) {
14
+ recordFailOpen("server.approvals.durable-row-checkpoint-id-missing", `face=${face} why=${raw === undefined ? "absent" : "untrusted"}`);
15
+ return {};
16
+ }
17
+ return { checkpointId: id };
18
+ }
19
+ //# sourceMappingURL=checkpoint-identity.js.map
@@ -93,7 +93,23 @@ export interface ConfigCatalogRowCenter {
93
93
  /** center 写**现在真的在生效**(在管 ∧ 未被 env 占位压住;env-wins 族 env 占位 ⇒ false = ⚪ 成因 a)。 */
94
94
  readonly effectiveNow: boolean;
95
95
  }
96
- export interface ConfigCatalogRow {
96
+ /**
97
+ * 行上**对 `effectiveValue` 的判词位**(闭集;S-527 收成一族)—— 每一位**只在为真时铸 `true`、恒不铸 `false`**,缺席 = 这一格没有这件事
98
+ * (不是「不知道」)。净化器({@link sanitizeValue})一次读出值与判词,行投影原样铺平 —— 判词位只有这一种形,第三个判词位加进本闭集即受同一条约束。
99
+ * · `effectiveValueInvalid`(S-100,additive)—— 本行的实算值**落在它自己宣告的回显闭集之外**(`echoWords ?? enumValues`,S-201①),
100
+ * 或它的实算腿回了一个本行没有声明映射的布尔。在场时 `effectiveValue` 恒 `null`:回显一个集外值等于目录在教消费方写一个写回去就非法的词,
101
+ * 而**静默丢**会让「配错了」与「真的没设」在 wire 上同形([ref] 响亮臂)。只服务闭集族(`type:"enum"`)。
102
+ * · `effectiveValueWithheld`(S-527,additive)—— `type:"url"` 行:展示铸点对这一格(单值)或其中任一项(列表)判了扣下(`failedClosed`:
103
+ * 位置律本会显示的一段 —— 整段 query / 一个路径段 —— 因为里面有一条凭据形而不出门)。判决的属主是铸点,目录不另判;
104
+ * 标准位置律(userinfo 落地、query 每个值成记号)对每一行同样成立,不是扣下;值整只成占位 = 这一行的展示律显示不了这个值
105
+ * (通用 url 行:不是层级式 URL;两只出网代理行的展示律更窄 —— 只显示 `scheme://host[:port]`,形不干净整只占位,`outbound-dispatcher.ts` `displayProxyUrl`),也不是本位。
106
+ */
107
+ export type CatalogValueVerdict = "effectiveValueInvalid" | "effectiveValueWithheld";
108
+ /** 判词位的行内形({@link CatalogValueVerdict} 每一员都是只取 `true` 的可选键)。 */
109
+ export type CatalogValueVerdicts = {
110
+ readonly [K in CatalogValueVerdict]?: true;
111
+ };
112
+ export interface ConfigCatalogRow extends CatalogValueVerdicts {
97
113
  readonly name: string;
98
114
  readonly domain: CatalogDomain;
99
115
  readonly type: CatalogValueType;
@@ -105,15 +121,6 @@ export interface ConfigCatalogRow {
105
121
  readonly staticDefault?: string;
106
122
  readonly derivedDefaultNote?: string;
107
123
  readonly effectiveValue: CatalogValue;
108
- /**
109
- * S-100(additive;**只在真非法时铸,恒不铸 `false`**)—— 本行的实算值**落在它自己宣告的
110
- * 回显闭集之外**(`echoWords ?? enumValues`,S-201①),或它的实算腿回了一个本行没有声明映射的布尔。
111
- *
112
- * 在场时 `effectiveValue` 恒 `null`:回显一个集外值等于目录在教消费方写一个写回去就非法的词,
113
- * 而**静默丢**会让「配错了」与「真的没设」在 wire 上同形([ref] 响亮臂)。
114
- * 缺席 = 这一格没问题(不是「不知道」)。
115
- */
116
- readonly effectiveValueInvalid?: true;
117
124
  readonly valueClass: "plain" | "secret" | "opaque";
118
125
  readonly danger: readonly CatalogDangerAxis[];
119
126
  readonly center?: ConfigCatalogRowCenter;