@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,5 +1,6 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { ServiceConfig } from "../config-types.js";
3
+ import { type DurableOwnerKey, type Principal, type SessionCaller, type SessionOwnerCell } from "../security.js";
3
4
  /** Coerce a possibly-repeated request header to a single string (or undefined). */
4
5
  export declare function headerStr(v: string | string[] | undefined): string | undefined;
5
6
  export declare function safeEqual(a: string, b: string): boolean;
@@ -11,6 +12,9 @@ export declare function systemFor(req: IncomingMessage, config: ServiceConfig):
11
12
  /** "presented credentials must verify":Authorization 带 Bearer/token scheme 且三路全验不过 → true。
12
13
  * 其他 scheme(Basic 等,非我方凭证空间)不管——由原有门语义处置,避免误伤未知代理注头。 */
13
14
  export declare function bearerPresentedButUnverified(req: IncomingMessage, config: ServiceConfig): boolean;
15
+ /** 「这次请求出示了这台部署的只读 trace 凭据(`TRACE_TOKEN`)」—— 一句,三处读:凭据验不过判({@link bearerPresentedButUnverified})、门前读路谓词
16
+ * (`dispatch.ts` 的 `readCredentialOk`)、fleet 读档的只读臂({@link fleetViewOf})。没配 ⇒ 恒 false。 */
17
+ export declare function traceTokenPresented(req: IncomingMessage, config: ServiceConfig): boolean;
14
18
  /** loopback 三形(IPv4 / IPv6 / IPv4-mapped)—— 一处定义,diagnostics 门与任何「本机自用」判据同吃。缺席 ⇒ false(fail-closed)。 */
15
19
  export declare function isLoopbackAddress(addr: string | undefined): boolean;
16
20
  /**
@@ -27,7 +31,7 @@ export type IdentitySource = (typeof IDENTITY_SOURCES)[number];
27
31
  * 有可验身份时才是身份,零凭据下它只是谁都能写的字符串;而 JWT 身份不依赖静态 token 的在场。
28
32
  */
29
33
  export declare function verifiedIdentitySource(req: IncomingMessage, config: ServiceConfig): IdentitySource | undefined;
30
- export declare function gatedPrincipal(req: IncomingMessage, config: ServiceConfig): string | undefined;
34
+ export declare function gatedPrincipal(req: IncomingMessage, config: ServiceConfig): Principal | undefined;
31
35
  /**
32
36
  * 「**出示了凭证但验不过** ≠ **没出示**」在 **direct-door principal JWT** 面上的形 —— 本仓
33
37
  * {@link bearerPresentedButUnverified} 早就是同一条律在 Bearer 面的形,这里只是把它推到另一面。
@@ -61,8 +65,8 @@ export declare function sendPrincipalRefusal(res: ServerResponse, req: IncomingM
61
65
  * 每面一句模块级常量(冻结门按常量解引用逐字钉)。三句都**不含任何值**(令牌 / 头名 / 路径实参一概不回显),且**不区分**
62
66
  * 「没带」与「带错」—— 同一道门上两者逐字同体,区分就是探测面。
63
67
  * · `credential` —— 全局凭据门(`dispatch.ts`):部署配了 service token,请求没带或带的不认(registry 登录令牌验不过同属此面);
64
- * · `operator` —— 只给运维凭据开的口(`/metrics*` 与 `GET /v1/tasks/source-summary`):service token 开得了,指标口另认只读的
65
- * `METRICS_TOKEN`(它在全局门之前判);
68
+ * · `operator` —— 只给运维凭据开的口(`/metrics*` 与 `GET /v1/tasks/source-summary`):不带主体头的 service token 开得了(带主体头的是那位主体,
69
+ * {@link actsForDeployment}),指标口另认只读的 `METRICS_TOKEN`、`source-summary` 另认只读的 `TRACE_TOKEN`(都在全局门之前判);
66
70
  * · `identity` —— 过了凭据门(或这台部署没配 service token)、但这一口要一个**验过的调用方身份**:属主寻址的读 / 写面、规则面、
67
71
  * 记忆面。在配了 service token 的部署上,「带 service token 却没身份」只会落在只认身份的口(规则 / 记忆 / 会话策略)上 ——
68
72
  * 这时再叫调用方「去带 service token」是假出路,所以这一面的句子只讲身份。
@@ -70,7 +74,7 @@ export declare function sendPrincipalRefusal(res: ServerResponse, req: IncomingM
70
74
  */
71
75
  export type UnauthorizedFace = "credential" | "operator" | "identity";
72
76
  export declare const UNAUTHORIZED_CREDENTIAL = "unauthorized \u2014 the request carries no credential this deployment accepts: send the deployment's service token as a Bearer token in the Authorization header (its operator set it as SERVICE_AUTH_TOKEN or SERVICE_AUTH_TOKENS; a sema-up deployment keeps SERVICE_AUTH_TOKEN in ~/.sema-up/<project>/.env on the machine that ran sema-up)";
73
- export declare const UNAUTHORIZED_OPERATOR = "unauthorized \u2014 this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header (the metrics endpoints also accept the read-only METRICS_TOKEN)";
77
+ export declare const UNAUTHORIZED_OPERATOR = "unauthorized \u2014 this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header (a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
74
78
  export declare const UNAUTHORIZED_IDENTITY = "unauthorized \u2014 this endpoint acts for a named caller and the request carries no caller identity this deployment verifies: identify the caller the way this deployment does (a registry sign-in token as the Bearer token, a signed principal token on a direct-door deployment, or the principal header set by a trusted front end)";
75
79
  export declare function sendUnauthorized(res: ServerResponse, face: UnauthorizedFace): void;
76
80
  /**
@@ -91,7 +95,7 @@ export declare function sendUnauthorized(res: ServerResponse, face: Unauthorized
91
95
  * 放宽它是一次独立裁定。需要 operator 臂的读面在**自己的调用点**显式并上 {@link explicitOperatorOk} ——
92
96
  * 那样「谁多给了 operator 一条路」在代码上看得见,而不是被偷偷塞进共享谓词里。
93
97
  */
94
- export declare function runOwnerReadable(principal: string | undefined, owner: string | null, config: ServiceConfig): boolean;
98
+ export declare function runOwnerReadable(principal: Principal | undefined, owner: DurableOwnerKey | null, config: Pick<ServiceConfig, "requirePrincipal">): boolean;
95
99
  /** 「这台部署配了任何一把 service 凭证吗」—— fail-closed 写门族的真值源,也是身份来源 `service_token` 接没接线的那一句。**单一属主**:`handle()` 的
96
100
  * 凭证门、[ref] 的 parked 赎回席、[ref] 的 consolidation 阀门启动期告警、以及下面 {@link wiredIdentitySources} 读同一句(手抄迟早只改一处,而这条判据
97
101
  * 决定的是「无凭证部署上写口开不开」)。住在本叶(与 {@link systemFor} 同处)而不是 `dispatch.ts`:身份原语只依赖本叶。 */
@@ -112,36 +116,83 @@ export declare function wiredIdentitySources(w: IdentityWiring): readonly Identi
112
116
  * 没配 service token、没装鉴权桥、没开直连门)、**也没声明**只读 trace token 或 `REQUIRE_PRINCIPAL`:请求里没有任何东西替主体头作保,头是谁都能自报的
113
117
  * **标签**(过滤 / 展示用),不是身份。装了鉴权桥的部署(SSO 单开)带登录令牌的调用方是验过的身份 ⇒ 不是 dev-open(修前只看 token / `REQUIRE_PRINCIPAL`,
114
118
  * 这一形被读成 dev-open,任何人 fleet-wide 读全部会话)。
115
- * 四处读它、不各写一份:会话列表的 fleet-wide 第一臂(`isFleetWide`)、会话写面的 fleet-wide 第一臂(`sessionOwnerScopeForWrite`)、
119
+ * 三处读它、不各写一份:fleet 调用方的第一臂({@link sessionCallerOf} —— fleet 面的 {@link fleetViewOf} 与会话行属主门都经它)、
116
120
  * 会话面的属主谓词({@link sessionOwnerReadable})、`/metrics` 族的免凭据臂(`dispatch.ts`)—— 于是「调用方是谁」在列表、单会话面与指标面上只有一只读法。
117
121
  */
118
122
  export declare function devOpenDeployment(w: IdentityWiring): boolean;
123
+ /**
124
+ * service 凭据**代部署本身**说话:出示了这台部署的 service 凭据({@link systemFor}),且不代任何验过的主体。带主体头的 service 凭据请求是前端(BFF)
125
+ * 代那位主体发的 —— 它读那位主体,不读全舰队;部署姿态(单用户 / 多租)不改这一句(单用户形上的主体头同样是「这次请求为谁」)。
126
+ * 两处读它:fleet 调用方的凭据臂({@link sessionCallerOf})与 `/metrics` 族的 service 臂(`dispatch.ts`)。先判凭据、后取主体:`principal` 只在出示了
127
+ * service 凭据时才求值(调用点那一次 {@link gatedPrincipal}),没带凭据的请求不因主体头的形而改答。
128
+ */
129
+ export declare function actsForDeployment(req: IncomingMessage, config: ServiceConfig, principal: () => Principal | undefined): boolean;
130
+ /**
131
+ * 🔴 **「这个调用方是不是 fleet 调用方(看得到所有租户)」的唯一铸点**({@link SessionCaller}):验过的主体 + 是不是 fleet —— {@link devOpenDeployment} 上的任何
132
+ * 调用方,或 {@link actsForDeployment}(出示 service 凭据、不报主体)。带主体头的是那位主体,不是 fleet;只读 trace token 不是 service 凭据;operator 不在这里
133
+ * (运维口各自读 {@link explicitOperatorOk})。读者:会话行属主门(无主 placed 行的放行臂)与 fleet 面的 {@link fleetViewOf} —— 同一问一只读法。
134
+ */
135
+ export declare function sessionCallerOf(req: IncomingMessage, w: IdentityWiring): SessionCaller;
136
+ /** fleet 面的两档(闭集):`read` = 只读面,只读 trace 凭据在这一档也是 fleet;`write` = 写面,只认 {@link sessionCallerOf}(读凭据不能变成跨租户写权)。 */
137
+ export type FleetFace = "read" | "write";
138
+ /** 一次 fleet 面判定的读数:`fleetWide` = 看全舰队(不钉人);否则 `gateOwner` = 钉住的那位验过的主体,`null` = 没有可用身份(调用点答 401 identity)。 */
139
+ export interface FleetView {
140
+ readonly fleetWide: boolean;
141
+ readonly gateOwner: Principal | null;
142
+ }
143
+ /**
144
+ * 🔴 **fleet 面「看全舰队,还是钉住一位主体」的唯一读法**。fleet 判据只有一个来源 —— {@link sessionCallerOf};本函数只把它投成 fleet 面要的两格,
145
+ * 并按档并上只读 trace 凭据(读档)。读者 —— 读档:舰队流、会话列表、发件链接列表、后台名册、trace 五口、用量三口、`/v1/tasks/source-summary`;
146
+ * 写档:删除、fork、同步族(拉取与推送同门)。
147
+ */
148
+ export declare function fleetViewOf(req: IncomingMessage, w: IdentityWiring, face: FleetFace): FleetView;
119
149
  /**
120
150
  * **「这个调用方能不能动这只会话」的唯一谓词**(会话面:视图 / head / 事件流 / 记忆状态与自助抹除 / 改名置顶 / 后台任务 / MCP 重连 /
121
- * 面板的上一腿 MCP 投影)。= {@link devOpenDeployment} ∨ {@link runOwnerReadable}:没有身份边界的部署上不钉任何人(与会话列表同读,
122
- * 列表把这只会话列给谁,谁就读得到它);有身份边界的部署上就是 run 面那一条谓词,一字不变。
151
+ * 面板的上一腿 MCP 投影)。没有身份边界的部署({@link devOpenDeployment})上不钉任何人(与会话列表同读,列表把这只会话列给谁,谁就读得到它);
152
+ * 有身份边界的部署上:
153
+ * · **无主的行**经无主臂的唯一判据 `ownerlessRowOpen`(`security.ts`):普通会话照旧对任何调用方开放;委派子代的 placed 行只对 fleet 调用方
154
+ * ({@link sessionCallerOf})开放 —— 任何具名主体、没有 service 凭据的无身份调用方都与别人的行同体(调用点答 404)(S-1770)。
155
+ * 代价如实:属主还没定下的子代行连它将来的属主也暂时读不到(由一次性迁移 M23 / 那一行的下一次停驻定下);
156
+ * · 有主的行就是 run 面那一条谓词({@link runOwnerReadable}),一字不变。
123
157
  * run 面(poll / events / cancel …)不读本谓词 —— 那是 run 资源的门,另一只。
124
158
  */
125
- export declare function sessionOwnerReadable(principal: string | undefined, owner: string | null, w: IdentityWiring): boolean;
126
- /** The EXPLICIT operator gate (IMAGE-API-DESIGN.md §P2.4a MUST-FIX) — NOT the bare `isOperator` (whose empty-list
127
- * "true-for-all" is an unrestricted-write exec door the instant OPERATOR_PRINCIPALS is empty). Requires a non-empty
128
- * operator set AND a present principal IN it. The same form the preempt/resume endpoints already use.
129
- * 🔴 SINGLE mint point (E1): a byte-identical twin `explicitOperator` used to live below (image-visibility lane)
130
- * and two more hand-inlined copies sat in approvals-assistant — a future hardening of this judgment would have
131
- * missed them. All call sites now consume THIS function; do not re-introduce a sibling. */
132
- export declare function explicitOperatorOk(principal: string | undefined, operatorPrincipals: readonly string[]): boolean;
159
+ export declare function sessionOwnerReadable(caller: SessionCaller, cell: SessionOwnerCell, w: IdentityWiring): boolean;
160
+ /**
161
+ * 运维名册 —— 「谁是 operator」读的两格(都住在部署配置里):具名名单 `OPERATOR_PRINCIPALS` 与单用户形的显式声明 `OPERATOR_SINGLE_USER`。
162
+ * 两者互斥(声明只在单用户形、名单为空时成立;否则拒启 —— 一个事实一个来源,`config-invariants.ts` 的 `operator-single-user`)。
163
+ */
164
+ export type OperatorRoster = Pick<ServiceConfig, "operatorPrincipals" | "operatorSingleUser">;
165
+ /**
166
+ * 🔴 **「谁是 operator」的唯一读法**(S-1050,[ref] ① 裁 A;IMAGE-API-DESIGN.md §P2.4a MUST-FIX 的那一只门)。
167
+ * · 名单为空 ⇒ **没人是**(没有任何形把「空名单」读成「人人是」—— 那条读法 `isOperator` 已删);
168
+ * · 名单非空 ⇒ 验过的主体在名单里才是;
169
+ * · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**都是(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
170
+ * 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形成立(起服不变量)。
171
+ * `principal` 必须是验过的身份(`gatedPrincipal`),绝不是自述头。全部运维面(审批队列、steer.trusted、记忆运维口、bake 门……)读这一只;
172
+ * 🔴 SINGLE mint point (E1):不要再造兄弟。
173
+ */
174
+ export declare function explicitOperatorOk(principal: string | undefined, roster: OperatorRoster): boolean;
175
+ /** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane`、整理阀门的可达性告警、起服提示同读这一只。 */
176
+ export declare function operatorRosterPresent(roster: OperatorRoster): boolean;
177
+ /**
178
+ * 起服提示(S-1050):单用户形(`REQUIRE_PRINCIPAL` 未开)+ 没有运维名册 + 这台部署有审批底座 ⇒ 一行 warn。这一形在「空名单 = 人人是」那条读法退役之后
179
+ * 丢的东西就是审批队列的运维视图(跨 scope 列表 / `?owner=` / 无主体调用方的整个队列),补回它只要一行配置 —— 不拒启:升级那一拍打掉一台今天跑得好好的
180
+ * 单用户机器比一条提示重。多租形不提示(它另有拒启不变量);没有审批底座的形什么都没少。
181
+ */
182
+ export declare function buildOperatorUndeclaredNotice(config: OperatorRoster & Pick<ServiceConfig, "requirePrincipal">, approvalFaceWired: boolean): {
183
+ event: "operator_undeclared_single_user";
184
+ fields: {
185
+ detail: string;
186
+ };
187
+ } | undefined;
133
188
  /** operator 面族在「名单为空」这一形上的**唯一**拒发口:事实 `operatorLane`(`capability-facts.ts`)为假 ⇒ 这一面对任何
134
189
  * 身份都打不通 = 这台部署上不可用 ⇒ 501,不是鉴权拒(403 只留给「名单非空而你不在名单上」)。能力位读的是同一只事实。 */
135
190
  export declare function sendOperatorPrincipalsRequired(res: ServerResponse): void;
136
- /** May `principal` act as an OPERATOR on the F4 approval queue? Empty `operatorPrincipals` = legacy
137
- * behavior (the shared service token IS the operator boundary → everyone authenticated is an operator).
138
- * Otherwise only listed principals are operators. */
139
- export declare function isOperator(principal: string | undefined, operatorPrincipals: readonly string[]): boolean;
140
- /** Operator check WITHOUT the empty-list "everyone is an operator" legacy fallback — an EMPTY `operatorPrincipals`
141
- * yields `false` (no one is an operator). Use this where empty-operators-means-all would be a SECURITY hole rather
142
- * than a back-compat convenience: image VISIBILITY scoping (a tenant-scoped image must not leak to every caller
143
- * just because OPERATOR_PRINCIPALS is unset). Adversarial-review HIGH: `isOperator([], p)=true` made
144
- * `latestPublished(..., {operator:true})` bypass tenant visibility for any caller on an operator-less deployment.
145
- * (The byte-identical `explicitOperator` twin that used to live here was folded into `explicitOperatorOk` above —
146
- * one judgment, one mint point.) */
191
+ /**
192
+ * 「这台部署没有运维名册」时**唯一**的出路句 —— 与 {@link operatorRosterPresent} 同一对旋钮,所以句子不比事实少说一条出路:
193
+ * 名单 `OPERATOR_PRINCIPALS`(具名运维;多租形只有这一条),或单用户形的显式声明 `OPERATOR_SINGLE_USER=true`(只在 `REQUIRE_PRINCIPAL` 未开且名单为空时成立,
194
+ * 否则起服拒 —— 句子把它限定在单用户部署上)。拒发口 {@link sendOperatorPrincipalsRequired}、能力事实闭集 `operator_principals_empty` 的义、记忆整理阀门的起服告警
195
+ * 都说这一句,别处不再各写一份。
196
+ */
197
+ export declare function buildOperatorRosterWayOut(): string;
147
198
  //# sourceMappingURL=principal-gate.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { timingSafeEqual } from "node:crypto";
2
- import { PRINCIPAL_TOKEN_HEADER, verifiedPrincipal, ssoVerifiedPrincipal } from "../security.js";
2
+ import { PRINCIPAL_TOKEN_HEADER, verifiedPrincipal, ssoVerifiedPrincipal, ownerlessRowOpen, mintPrincipal } from "../security.js";
3
3
  import { sendError } from "./send.js";
4
4
  export function headerStr(v) {
5
5
  return Array.isArray(v) ? v[0] : v;
@@ -30,10 +30,13 @@ export function bearerPresentedButUnverified(req, config) {
30
30
  return false;
31
31
  if (systemFor(req, config) !== undefined)
32
32
  return false;
33
- if (config.traceToken && authorized(req, config.traceToken))
33
+ if (traceTokenPresented(req, config))
34
34
  return false;
35
35
  return true;
36
36
  }
37
+ export function traceTokenPresented(req, config) {
38
+ return !!config.traceToken && authorized(req, config.traceToken);
39
+ }
37
40
  export function isLoopbackAddress(addr) {
38
41
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
39
42
  }
@@ -50,7 +53,8 @@ export function verifiedIdentitySource(req, config) {
50
53
  export function gatedPrincipal(req, config) {
51
54
  if (bearerPresentedButUnverified(req, config))
52
55
  return undefined;
53
- return verifiedPrincipal(req, config);
56
+ const verified = verifiedPrincipal(req, config);
57
+ return verified === undefined ? undefined : mintPrincipal(verified);
54
58
  }
55
59
  export function principalTokenPresentedButUnverified(req, config) {
56
60
  if (!config.directDoorActive)
@@ -67,7 +71,7 @@ export function sendPrincipalRefusal(res, req, config) {
67
71
  sendError(res, 401, "auth.principal_required", `missing principal header '${config.principalHeader}'`);
68
72
  }
69
73
  export const UNAUTHORIZED_CREDENTIAL = "unauthorized — the request carries no credential this deployment accepts: send the deployment's service token as a Bearer token in the Authorization header (its operator set it as SERVICE_AUTH_TOKEN or SERVICE_AUTH_TOKENS; a sema-up deployment keeps SERVICE_AUTH_TOKEN in ~/.sema-up/<project>/.env on the machine that ran sema-up)";
70
- export const UNAUTHORIZED_OPERATOR = "unauthorized — this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header (the metrics endpoints also accept the read-only METRICS_TOKEN)";
74
+ export const UNAUTHORIZED_OPERATOR = "unauthorized — this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header (a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
71
75
  export const UNAUTHORIZED_IDENTITY = "unauthorized — this endpoint acts for a named caller and the request carries no caller identity this deployment verifies: identify the caller the way this deployment does (a registry sign-in token as the Bearer token, a signed principal token on a direct-door deployment, or the principal header set by a trusted front end)";
72
76
  export function sendUnauthorized(res, face) {
73
77
  switch (face) {
@@ -86,10 +90,13 @@ export function sendUnauthorized(res, face) {
86
90
  }
87
91
  }
88
92
  }
93
+ function sameIdentity(principal, owner) {
94
+ return principal === owner;
95
+ }
89
96
  export function runOwnerReadable(principal, owner, config) {
90
97
  if (owner === null)
91
98
  return true;
92
- if (principal === owner)
99
+ if (principal !== undefined && sameIdentity(principal, owner))
93
100
  return true;
94
101
  return !config.requirePrincipal && owner === "anon:shell-live" && principal === undefined;
95
102
  }
@@ -116,18 +123,61 @@ export function wiredIdentitySources(w) {
116
123
  export function devOpenDeployment(w) {
117
124
  return wiredIdentitySources(w).length === 0 && !w.config.traceToken && !w.config.requirePrincipal;
118
125
  }
119
- export function sessionOwnerReadable(principal, owner, w) {
120
- return devOpenDeployment(w) || runOwnerReadable(principal, owner, w.config);
126
+ export function actsForDeployment(req, config, principal) {
127
+ return systemFor(req, config) !== undefined && principal() === undefined;
121
128
  }
122
- export function explicitOperatorOk(principal, operatorPrincipals) {
123
- return operatorPrincipals.length > 0 && principal !== undefined && operatorPrincipals.includes(principal);
129
+ export function sessionCallerOf(req, w) {
130
+ const principal = gatedPrincipal(req, w.config);
131
+ return { principal, fleet: devOpenDeployment(w) || actsForDeployment(req, w.config, () => principal) };
124
132
  }
125
- export function sendOperatorPrincipalsRequired(res) {
126
- sendError(res, 501, "capability.operator_principals_required", "this endpoint is operator-only and OPERATOR_PRINCIPALS is empty, so no caller can be an operator on this deployment; configure OPERATOR_PRINCIPALS to enable it");
133
+ export function fleetViewOf(req, w, face) {
134
+ const caller = sessionCallerOf(req, w);
135
+ const fleetWide = caller.fleet || readOnlyFleetCredential(req, w.config, face);
136
+ return { fleetWide, gateOwner: fleetWide ? null : caller.principal || null };
137
+ }
138
+ function readOnlyFleetCredential(req, config, face) {
139
+ switch (face) {
140
+ case "read":
141
+ return traceTokenPresented(req, config);
142
+ case "write":
143
+ return false;
144
+ default: {
145
+ const unknownFace = face;
146
+ throw new Error(`fleetViewOf: unknown fleet face ${String(unknownFace)}`);
147
+ }
148
+ }
127
149
  }
128
- export function isOperator(principal, operatorPrincipals) {
129
- if (operatorPrincipals.length === 0)
150
+ export function sessionOwnerReadable(caller, cell, w) {
151
+ if (devOpenDeployment(w))
130
152
  return true;
131
- return principal !== undefined && operatorPrincipals.includes(principal);
153
+ if (cell.owner === null)
154
+ return ownerlessRowOpen(cell, caller);
155
+ return runOwnerReadable(caller.principal, cell.owner, w.config);
156
+ }
157
+ export function explicitOperatorOk(principal, roster) {
158
+ if (roster.operatorSingleUser === true)
159
+ return true;
160
+ return roster.operatorPrincipals.length > 0 && principal !== undefined && roster.operatorPrincipals.includes(principal);
161
+ }
162
+ export function operatorRosterPresent(roster) {
163
+ return roster.operatorSingleUser === true || roster.operatorPrincipals.length > 0;
164
+ }
165
+ export function buildOperatorUndeclaredNotice(config, approvalFaceWired) {
166
+ if (config.requirePrincipal === true || operatorRosterPresent(config) || !approvalFaceWired)
167
+ return undefined;
168
+ return {
169
+ event: "operator_undeclared_single_user",
170
+ fields: {
171
+ detail: "this single-user deployment declares no operator: OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not set, so no caller is an operator — " +
172
+ "GET /v1/approvals, its stream, /v1/assistant/inbox and /v1/assistant/tasks show each caller only its own pending approvals (a caller that sends no principal sees only the anonymous ones - the cards and tasks that were submitted without a principal - never a named principal's) and ignore ?owner=. " +
173
+ "To act as this deployment's operator, add one line: OPERATOR_SINGLE_USER=true",
174
+ },
175
+ };
176
+ }
177
+ export function sendOperatorPrincipalsRequired(res) {
178
+ sendError(res, 501, "capability.operator_principals_required", `this endpoint is operator-only and this deployment has no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can be an operator; ${buildOperatorRosterWayOut()}`);
179
+ }
180
+ export function buildOperatorRosterWayOut() {
181
+ return "configure OPERATOR_PRINCIPALS with the named operator principals, or — on a single-user deployment (REQUIRE_PRINCIPAL off) — declare OPERATOR_SINGLE_USER=true";
132
182
  }
133
183
  //# sourceMappingURL=principal-gate.js.map
@@ -23,6 +23,7 @@
23
23
  */
24
24
  import type { ServerResponse } from "node:http";
25
25
  import type { ServingLeaseView } from "../fleet/engine-signal.js";
26
+ import { type RefusalBody } from "./refusal-body.js";
26
27
  /**
27
28
  * 就绪原因闭集,**数组序 = 优先序**:`/health.readyReason` 取首条的句、计费门取首条的拒绝码。
28
29
  * draining 在前 —— 一台正在下线的副本「去找替补」(Retry-After 15)比「稍后重试本机」(5)更对。
@@ -86,11 +87,8 @@ export declare function admissionRefusalOf(verdict: ReadinessVerdict, lease: Ser
86
87
  * `{status, body}` 的赎回席只取体(它的路由刻意不带头,见 `approval-sweeps.ts` 该臂注)。 */
87
88
  export interface BillableRefusal {
88
89
  readonly status: 503;
89
- readonly body: {
90
- readonly error: string;
91
- readonly errorCode: string;
92
- readonly message: string;
93
- };
90
+ /** `error` 是冻结的词(`draining` / `model_roster_pending` / `lease_expired`),`message` 是给人读的句子(机读事实里的一键)。 */
91
+ readonly body: RefusalBody;
94
92
  readonly retryAfterSec: 15 | 5 | 60;
95
93
  }
96
94
  /**
@@ -100,6 +98,14 @@ export interface BillableRefusal {
100
98
  * 停机因由声明口一起退役(排空口的体改成契约 `DrainRequest`,没有因由字段);`lease_expired` 一臂新增。
101
99
  */
102
100
  export declare function billableRefusalOf(reason: AdmissionRefusal): BillableRefusal;
101
+ /**
102
+ * 订阅面终帧要的 `{ errorCode, message }` —— 与提交面 503 体**同一只铸点**的产物:`errorCode` 是体的码,`message` 是体里 `message` 键的那句话(`error` 是冻结的词,
103
+ * 句子在 `message`)。从体里读,不另抄一份;体里没有那句话是铸点坏了 ⇒ 响亮抛(不静默发一帧没有句子的终帧)。
104
+ */
105
+ export declare function billableRefusalFrame(refusal: BillableRefusal): {
106
+ readonly errorCode: string;
107
+ readonly message: string;
108
+ };
103
109
  /** 发送形:`Retry-After` + 体(`dispatch.ts` 的 billable 门与 a2a `message/send` 同调)。走 `sendError` —— errorCode
104
110
  * 是它的必填位置参(对抗复审 #3:修前这里是 `sendJson(res, r.status, r.body)`,与 leader 口的豁免行逐字同文,
105
111
  * 在 error-code-key-gate 上借了别人的豁免过门);体键序与修前逐字同(`error, errorCode, message, reason?`)。 */
@@ -1,4 +1,5 @@
1
1
  import { sendJson, sendError } from "./send.js";
2
+ import { refusalBody } from "./refusal-body.js";
2
3
  export const READINESS_REASONS = ["draining", "model_roster_pending"];
3
4
  export function readinessOf(deps) {
4
5
  const [first, ...rest] = READINESS_REASONS.filter((r) => holds(r, deps));
@@ -60,17 +61,23 @@ export function admissionRefusalOf(verdict, lease, kind) {
60
61
  export function billableRefusalOf(reason) {
61
62
  switch (reason) {
62
63
  case "draining":
63
- return { status: 503, body: { error: "draining", errorCode: "draining", message: "this instance is draining for shutdown/upgrade — retry against the replacement instance" }, retryAfterSec: 15 };
64
+ return { status: 503, body: refusalBody({ errorCode: "draining", message: "draining", facts: { message: "this instance is draining for shutdown/upgrade — retry against the replacement instance" } }), retryAfterSec: 15 };
64
65
  case "model_roster_pending":
65
- return { status: 503, body: { error: "model_roster_pending", errorCode: "state.model_roster_pending", message: "this worker has no model yet (waiting for the first effective-config pull to land the roster) — retry shortly" }, retryAfterSec: 5 };
66
+ return { status: 503, body: refusalBody({ errorCode: "state.model_roster_pending", message: "model_roster_pending", facts: { message: "this worker has no model yet (waiting for the first effective-config pull to land the roster) — retry shortly" } }), retryAfterSec: 5 };
66
67
  case "lease_expired":
67
- return { status: 503, body: { error: "lease_expired", errorCode: "state.lease_expired", message: "this instance has not renewed its serving lease with the fleet center for longer than its outage limit — it takes no new work; cancel, approvals, resume and reads stay open here — retry new work against another instance" }, retryAfterSec: 60 };
68
+ return { status: 503, body: refusalBody({ errorCode: "state.lease_expired", message: "lease_expired", facts: { message: "this instance has not renewed its serving lease with the fleet center for longer than its outage limit — it takes no new work; cancel, approvals, resume and reads stay open here — retry new work against another instance" } }), retryAfterSec: 60 };
68
69
  default: {
69
70
  const unhandled = reason;
70
71
  throw new Error(`admission refusal without a billable refusal: ${String(unhandled)}`);
71
72
  }
72
73
  }
73
74
  }
75
+ export function billableRefusalFrame(refusal) {
76
+ const message = refusal.body["message"];
77
+ if (typeof message !== "string")
78
+ throw new Error(`billable refusal body without its message sentence: ${refusal.body.errorCode}`);
79
+ return { errorCode: refusal.body.errorCode, message };
80
+ }
74
81
  export function sendBillableRefusal(res, refusal) {
75
82
  const { error, errorCode, ...extra } = refusal.body;
76
83
  res.setHeader("retry-after", String(refusal.retryAfterSec));
@@ -18,4 +18,16 @@ export type RefusalBody = {
18
18
  } & Record<string, unknown>;
19
19
  /** 拒体:`{ error, errorCode, ...facts }`。 */
20
20
  export declare function refusalBody(r: Refusal): RefusalBody;
21
+ /**
22
+ * 引擎拒一次续跑时的**三个机读判别位** → 拒体的同名事实键(唯一读法;续跑家族的每一只拒答都读它):
23
+ * `detail.code` ⇒ `blockedBy`(挡住它的准入码)· `detail.field` ⇒ `field`(哪一侧 / 哪一格)· `detail.reason` ⇒ `reason`(同码多臂时哪一臂)。
24
+ * 一员在场 ⇔ 它是非空串;其余(缺席、非串、空串)一律不铸键 —— 引擎没说就是没说,本层不编值,也不把一个非串原样推上 wire。
25
+ * 载体有两种,读法同一只:同步腿的 `CheckpointError.detail`(`http/resume-legs.ts` `checkpointRefusalAnswer`),与后台停驻子代赎回回执的
26
+ * `details.detail`(`parked-decide.ts` 的 422 `parked_resume.startup_failed`;引擎 7.54.0 起它把认领前那只失败的同三位交到回执上)。
27
+ */
28
+ export declare function resumeRefusalFacts(detail: unknown): {
29
+ blockedBy?: string;
30
+ field?: string;
31
+ reason?: string;
32
+ };
21
33
  //# sourceMappingURL=refusal-body.d.ts.map
@@ -1,4 +1,15 @@
1
1
  export function refusalBody(r) {
2
2
  return { error: r.message, errorCode: r.errorCode, ...r.facts };
3
3
  }
4
+ export function resumeRefusalFacts(detail) {
5
+ if (typeof detail !== "object" || detail === null)
6
+ return {};
7
+ const d = detail;
8
+ const word = (v) => typeof v === "string" && v !== "";
9
+ return {
10
+ ...(word(d.code) ? { blockedBy: d.code } : {}),
11
+ ...(word(d.field) ? { field: d.field } : {}),
12
+ ...(word(d.reason) ? { reason: d.reason } : {}),
13
+ };
14
+ }
4
15
  //# sourceMappingURL=refusal-body.js.map
@@ -4,6 +4,8 @@
4
4
  * ctx 字段 1 只(`deps`):本族对外围的耦合就这一格,它也是这一族的可测性读数。
5
5
  */
6
6
  import type { IncomingMessage, ServerResponse } from "node:http";
7
+ import { type SessionOwnerCell } from "../security.js";
8
+ import { type RefusalBody } from "./refusal-body.js";
7
9
  import type { FlatServiceDeps } from "./server.js";
8
10
  import type { LeaseRefusalAdmission } from "../fleet-lease.js";
9
11
  import { type QuotaDecision } from "../observability/cost-quota.js";
@@ -18,6 +20,13 @@ import { type SqlWallSource, type SqlWallsReading } from "../plugins/sql-driver.
18
20
  * 两腿的折算与 SQL 快照 blob 的缺省帽读同一份(`plugins/sql-driver.ts`,余量各只在那里定义一次)。两腿都拒时报行墙那条(行墙句逐字沿用)。
19
21
  * 入参是**已判好的墙**(`sql-driver.ts` `sqlWallsOf` —— 事实缺席时的落点只在那里定义,与 blob 帽同一只判官、同一个方向);本函数不读事实、不判缺席,
20
22
  * 墙从哪来(`sources` 里**被拒的那一堵**的出处)原样带进判决(`wallSource`),拒句按它分两形:库报的墙点名库的上限与旋钮,假定的墙(事实还没建立,或事实在场但这一堵读失败、退了文档缺省)只说「库的这个上限没读到、按最保守的墙拒」。
23
+ *
24
+ * 🔴 **包墙腿是同一只规则的提前一跑,不是第二套规则**(S-1746 主会话裁定):包墙是物理连接的事实(会话值,连接建立时从全局拷一份、此后不变),
25
+ * 终判在将要执行写入的那条连接上 —— 那是库自己(续跑输入那一笔被拒 ⇒ 店的带码拒 ⇒ 同一个 413;会话日志那一笔走它既有的失败面);SQL 快照 blob 则由
26
+ * `blob-backend.ts` 经 `connectJudged` 在写入连接上判。受理时手里没有那条连接,判官 `sqlWallsOf` 读的 `facts` 是池里**最近一次初始化**的那条连接的读数
27
+ * (`SqlDriver.facts`:池见过的最新读数,只在有连接初始化时才更新),同一个折算 `packetWallStatementBytes`:拒 ⇒ 413 在任何副作用之前;收 ⇒ 写入那条连接上的判决仍是终判。
28
+ * 这个读数是**缓存**,DBA 调了全局值之后、下一条连接初始化之前,它与库此刻的值两个方向都可能不一致:调大 ⇒ 受理口仍按旧的小值拒(新墙本装得下的体也 413,
29
+ * 直到有连接按新值初始化 —— 快照 blob 的旧连接自换就会带来一条);调小 ⇒ 受理口按旧的大值放行,写入那条连接上的库再拒(续跑输入那一笔 = 同一个 413)。
21
30
  * 两堵墙都不存在(PG / 没有 SQL 后端)⇒ `null`。一堵墙「够不着」(行墙门限 ≥ 请求体上限;包墙门限 ≥ 请求体上限的 2×,即转义上界也到不了)时那一腿不量,
22
31
  * 两腿都够不着就连 `JSON.stringify` 都不调 —— 默认的 PG / MySQL 8(包墙 64 MiB)/ 无 SQL 后端部署零额外开销。
23
32
  * 受理口(`admission.ts` `prepareSpec`)按它答 413 `request.payload_too_large`,句子按 `by` × `wallSource` 点名真正拒绝的那堵墙;两位都是闭集,加一臂 = 编译红。
@@ -36,16 +45,11 @@ export interface SubmitBodyRefusal {
36
45
  export declare function refuseSubmitBody(walls: SqlWallsReading, body: unknown): SubmitBodyRefusal | null;
37
46
  /**
38
47
  * S-866 ③ —— 租约拒绝的应答形({@link leaseRefusalOf} 的产物;`{status, body}` 交回形 + 镜像头用的 `retryAfterSec`)。
39
- * 体键序固定 `error, errorCode, …`(冻结门 `FROZEN_RESULT_BODY` 按这个字面形锚)。
48
+ * 体经唯一组句器铸(键序 `error, errorCode, …机读位`;冻结门 `FROZEN_RESULT_BODY` 读 `refusalBody({ errorCode, message, … })` 这一形)。
40
49
  */
41
50
  export interface LeaseRefusal {
42
51
  readonly status: 429 | 503;
43
- readonly body: {
44
- readonly error: string;
45
- readonly errorCode: string;
46
- readonly retryAfterSec: number;
47
- readonly [extra: string]: unknown;
48
- };
52
+ readonly body: RefusalBody;
49
53
  readonly retryAfterSec: number;
50
54
  }
51
55
  /**
@@ -60,20 +64,13 @@ export interface LeaseRefusal {
60
64
  export declare function leaseRefusalOf(adm: LeaseRefusalAdmission): LeaseRefusal;
61
65
  /**
62
66
  * 成本配额越顶 → 429 `limit.cost_quota_exceeded` 的**唯一**体铸点(三只门同调:路由门 `quotaExceeded`、属主门
63
- * `ownerCostQuotaDenied`、赎回席 `approval-sweeps.ts`;修前三份手抄)。体键序 `error, errorCode, …`(冻结门
64
- * `FROZEN_RESULT_BODY` 按这个字面形锚)。`retryAfterSec` 与 `windowResetsAt` 同源于决策的 `windowEndsAtMs`
67
+ * `ownerCostQuotaDenied`、赎回席 `approval-sweeps.ts`;修前三份手抄)。体经唯一组句器铸(键序 `error, errorCode, …机读位`;冻结门
68
+ * `FROZEN_RESULT_BODY` 读 `refusalBody({ errorCode, message, … })` 这一形)。`retryAfterSec` 与 `windowResetsAt` 同源于决策的 `windowEndsAtMs`
65
69
  * (同一次读钟),`Retry-After` 头由各发送点从体里的 `retryAfterSec` 镜像。
66
70
  */
67
71
  export declare function costQuotaRefusalOf(d: QuotaDecision): {
68
72
  status: 429;
69
- body: {
70
- error: string;
71
- errorCode: string;
72
- usedMicroUsd: number;
73
- limitMicroUsd: number;
74
- retryAfterSec: number;
75
- windowResetsAt: string;
76
- };
73
+ body: RefusalBody;
77
74
  };
78
75
  export declare function createRequestGuards(ctx: {
79
76
  deps: FlatServiceDeps;
@@ -92,27 +89,14 @@ export declare function createRequestGuards(ctx: {
92
89
  leaseDenied: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
93
90
  usageWindowDenialFor: (key: string) => Promise<{
94
91
  status: number;
95
- body: {
96
- error: string;
97
- errorCode: string;
98
- retryAfterSec: number;
99
- };
92
+ body: RefusalBody;
100
93
  retryAfterSec: number;
101
94
  } | undefined>;
102
95
  usageWindowDenied: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
103
96
  rateLimited: (req: IncomingMessage, res: ServerResponse) => boolean;
104
97
  safeDecode: (seg: string) => string | null;
105
- isFleetWide: (req: IncomingMessage) => boolean;
106
- sessionOwnerScope: (req: IncomingMessage) => {
107
- fleetWide: boolean;
108
- gateOwner: string | null;
109
- };
110
- sessionOwnerScopeForWrite: (req: IncomingMessage) => {
111
- fleetWide: boolean;
112
- gateOwner: string | null;
113
- };
114
98
  runOwnerOk: (req: IncomingMessage, res: ServerResponse, owner: string | null) => boolean;
115
- sessionOwnerOk: (req: IncomingMessage, res: ServerResponse, owner: string | null) => boolean;
99
+ sessionOwnerOk: (req: IncomingMessage, res: ServerResponse, cell: SessionOwnerCell) => boolean;
116
100
  runSessionAcceptOk: (req: IncomingMessage, res: ServerResponse, run: {
117
101
  sessionId: string | null;
118
102
  }, face: string, notFoundError?: string) => boolean;