@sema-agent/server 7.145.0 → 7.147.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 (526) hide show
  1. package/MIGRATION.md +876 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +374 -99
  5. package/deploy/facts/CHANGES.json +25 -0
  6. package/deploy/facts/README.md +57 -0
  7. package/deploy/facts/lanes.json +61 -0
  8. package/deploy/facts/lanes.schema.json +57 -0
  9. package/deploy/facts/sandbox-rbac.json +113 -0
  10. package/deploy/facts/sandbox-rbac.schema.json +74 -0
  11. package/deploy/facts/sealed-key.json +9 -0
  12. package/deploy/facts/sealed-key.schema.json +52 -0
  13. package/deploy/sema-up/README.md +2 -2
  14. package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
  15. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
  16. package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
  17. package/deploy/sema-up/chart/templates/server.yaml +9 -4
  18. package/deploy/sema-up/chart/values.yaml +8 -1
  19. package/deploy/sema-up/cluster-up.sh +2 -1
  20. package/deploy/sema-up/lib/flagshape.sh +4 -0
  21. package/deploy/sema-up/lib/lanes.json +2 -5
  22. package/deploy/sema-up/sema-up.sh +12 -9
  23. package/deploy/sema-up/stack/compose.yaml +5 -4
  24. package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
  25. package/dist/adoption/import-limits.d.ts +6 -0
  26. package/dist/adoption/import-limits.js +7 -0
  27. package/dist/adoption/import.d.ts +62 -0
  28. package/dist/adoption/import.js +107 -0
  29. package/dist/adoption/wire.d.ts +52 -0
  30. package/dist/adoption/wire.js +9 -0
  31. package/dist/approval-ask-machine.d.ts +2 -2
  32. package/dist/approval-card.d.ts +7 -16
  33. package/dist/approval-card.js +0 -4
  34. package/dist/approval-gate-currency.d.ts +1 -1
  35. package/dist/approval-gate-currency.js +1 -1
  36. package/dist/approval-reconciler.d.ts +1 -1
  37. package/dist/approval.d.ts +3 -3
  38. package/dist/audit.js +2 -2
  39. package/dist/bench/s1/live-deps.js +3 -1
  40. package/dist/boot/crash-last.js +2 -1
  41. package/dist/boot/deployment-mods.d.ts +11 -1
  42. package/dist/boot/deployment-mods.js +15 -2
  43. package/dist/boot/device-lane.js +7 -5
  44. package/dist/boot/engine-lease.d.ts +195 -22
  45. package/dist/boot/engine-lease.js +146 -20
  46. package/dist/boot/execution-env.d.ts +5 -0
  47. package/dist/boot/execution-env.js +57 -33
  48. package/dist/boot/execution-lane.d.ts +37 -9
  49. package/dist/boot/execution-lane.js +74 -20
  50. package/dist/boot/exit-boundary.d.ts +50 -0
  51. package/dist/boot/exit-boundary.js +32 -0
  52. package/dist/boot/exit-last.d.ts +20 -4
  53. package/dist/boot/exit-last.js +23 -5
  54. package/dist/boot/governance-seams.d.ts +2 -2
  55. package/dist/boot/governance-seams.js +1 -0
  56. package/dist/boot/leader.js +1 -1
  57. package/dist/boot/memory-boundary.d.ts +11 -11
  58. package/dist/boot/memory-boundary.js +3 -3
  59. package/dist/boot/memory-consolidation.d.ts +42 -41
  60. package/dist/boot/memory-consolidation.js +26 -28
  61. package/dist/boot/org-memory.js +3 -2
  62. package/dist/boot/parked-revive-gate.d.ts +1 -1
  63. package/dist/boot/parked-revive-gate.js +1 -1
  64. package/dist/boot/reapers.d.ts +12 -4
  65. package/dist/boot/reapers.js +40 -16
  66. package/dist/boot/resolve-spec.d.ts +2 -0
  67. package/dist/boot/resolve-spec.js +126 -123
  68. package/dist/boot/retention-lane.d.ts +4 -42
  69. package/dist/boot/runner-deps.js +1 -1
  70. package/dist/boot/session-faces.d.ts +1 -0
  71. package/dist/boot/session-faces.js +11 -3
  72. package/dist/boot/shutdown.js +27 -9
  73. package/dist/boot/stage-01-config.d.ts +1 -1
  74. package/dist/boot/stage-01-config.js +7 -3
  75. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
  76. package/dist/boot/stage-02-web-admin-pull.js +10 -8
  77. package/dist/boot/stage-03-store-backend.d.ts +2 -1
  78. package/dist/boot/stage-03-store-backend.js +2 -2
  79. package/dist/boot/stage-04-stores.d.ts +2 -1
  80. package/dist/boot/stage-05-execution-env.d.ts +4 -1
  81. package/dist/boot/stage-05-execution-env.js +6 -6
  82. package/dist/boot/stage-06-runners.d.ts +5 -2
  83. package/dist/boot/stage-06-runners.js +12 -13
  84. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  85. package/dist/boot/stage-07-capability-layer.js +7 -7
  86. package/dist/boot/stage-08-reapers.d.ts +5 -2
  87. package/dist/boot/stage-08-reapers.js +3 -3
  88. package/dist/boot/stage-09-leader.d.ts +6 -2
  89. package/dist/boot/stage-10-http-server.d.ts +6 -2
  90. package/dist/boot/stage-10-http-server.js +5 -3
  91. package/dist/boot/stores.d.ts +10 -0
  92. package/dist/boot/stores.js +53 -26
  93. package/dist/boot/web-admin.js +3 -3
  94. package/dist/boot/workflow-orchestration.d.ts +1 -1
  95. package/dist/boot/workflow-orchestration.js +2 -1
  96. package/dist/capabilities/center-plugins.d.ts +2 -0
  97. package/dist/capabilities/center-plugins.js +6 -2
  98. package/dist/capabilities/composite-members.d.ts +4 -1
  99. package/dist/capabilities/composite-members.js +4 -1
  100. package/dist/capabilities/execution-lane.d.ts +7 -7
  101. package/dist/capabilities/execution-lane.js +2 -2
  102. package/dist/capabilities/hands-lane.d.ts +1 -1
  103. package/dist/capabilities/scenarios.d.ts +34 -20
  104. package/dist/capabilities/scenarios.js +13 -9
  105. package/dist/capabilities/settings-contract.d.ts +29 -0
  106. package/dist/capabilities/settings-contract.js +14 -0
  107. package/dist/capabilities/skills.d.ts +5 -5
  108. package/dist/capability-facts.d.ts +56 -1
  109. package/dist/capability-facts.js +59 -8
  110. package/dist/center-credential-renewer.js +3 -2
  111. package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
  112. package/dist/config-catalog.js +19 -9
  113. package/dist/config-invariants.d.ts +18 -3
  114. package/dist/config-invariants.js +36 -19
  115. package/dist/config-lkg.d.ts +1 -1
  116. package/dist/config-lkg.js +5 -6
  117. package/dist/config-provider.d.ts +2 -2
  118. package/dist/config-provider.js +2 -0
  119. package/dist/config-types.d.ts +228 -185
  120. package/dist/config.d.ts +74 -6
  121. package/dist/config.js +146 -64
  122. package/dist/degenerate-instrument.js +1 -1
  123. package/dist/deleted-session-ids.d.ts +19 -0
  124. package/dist/deleted-session-ids.js +26 -0
  125. package/dist/deploy-facts.d.ts +155 -0
  126. package/dist/deploy-facts.js +95 -0
  127. package/dist/deployment-shape.d.ts +21 -12
  128. package/dist/deployment-shape.js +24 -6
  129. package/dist/device-ws-hub.d.ts +48 -3
  130. package/dist/device-ws-hub.js +48 -2
  131. package/dist/env-facts.d.ts +7 -5
  132. package/dist/env-facts.js +10 -6
  133. package/dist/error-code-family.d.ts +35 -0
  134. package/dist/error-code-family.js +26 -0
  135. package/dist/execution-config-root.d.ts +5 -5
  136. package/dist/execution-config-root.js +5 -5
  137. package/dist/execution-env-purpose.d.ts +14 -0
  138. package/dist/execution-env-purpose.js +29 -0
  139. package/dist/execution-lane-caps.d.ts +49 -86
  140. package/dist/execution-lane-caps.js +52 -62
  141. package/dist/execution-placement.d.ts +18 -2
  142. package/dist/execution-placement.js +19 -0
  143. package/dist/file-history-disclosure.d.ts +2 -2
  144. package/dist/fleet/drain-entry.d.ts +46 -3
  145. package/dist/fleet/drain-entry.js +6 -0
  146. package/dist/fleet/fleet-bus.d.ts +2 -1
  147. package/dist/fleet/serving-lease.js +3 -4
  148. package/dist/history-anchor.d.ts +22 -0
  149. package/dist/history-anchor.js +14 -0
  150. package/dist/hooks/branch-transcript.d.ts +1 -1
  151. package/dist/hooks/branch-transcript.js +1 -0
  152. package/dist/hooks/classic-stations.d.ts +25 -8
  153. package/dist/hooks/classic-stations.js +29 -3
  154. package/dist/hooks/command-spawn.d.ts +1 -4
  155. package/dist/hooks/command-spawn.js +0 -11
  156. package/dist/hooks/hook-runner.d.ts +85 -24
  157. package/dist/hooks/hook-runner.js +326 -109
  158. package/dist/hooks/hook-source.d.ts +14 -2
  159. package/dist/hooks/hook-source.js +8 -0
  160. package/dist/http/active-run-conflict.d.ts +1 -1
  161. package/dist/http/active-run-conflict.js +1 -1
  162. package/dist/http/admission.js +11 -1
  163. package/dist/http/approval-sweeps.d.ts +2 -5
  164. package/dist/http/approval-sweeps.js +3 -2
  165. package/dist/http/checkpoint-ctx.d.ts +76 -71
  166. package/dist/http/checkpoint-ctx.js +40 -40
  167. package/dist/http/claim-latency.d.ts +10 -0
  168. package/dist/http/claim-latency.js +12 -0
  169. package/dist/http/dispatch.js +19 -3
  170. package/dist/http/durable-run-leg.d.ts +5 -0
  171. package/dist/http/durable-run-leg.js +3 -1
  172. package/dist/http/execution-context.d.ts +7 -1
  173. package/dist/http/execution-context.js +13 -0
  174. package/dist/http/health-self-report.d.ts +6 -2
  175. package/dist/http/health-self-report.js +3 -2
  176. package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
  177. package/dist/http/memory-compliance-failure-reply.js +5 -15
  178. package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
  179. package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
  180. package/dist/http/memory-store-refusal-reply.d.ts +3 -3
  181. package/dist/http/memory-store-refusal-reply.js +3 -0
  182. package/dist/http/owner-access.d.ts +11 -0
  183. package/dist/http/owner-access.js +7 -4
  184. package/dist/http/principal-gate.d.ts +28 -16
  185. package/dist/http/principal-gate.js +10 -19
  186. package/dist/http/request-guards.d.ts +2 -2
  187. package/dist/http/request-guards.js +5 -5
  188. package/dist/http/resume-legs.d.ts +29 -10
  189. package/dist/http/resume-legs.js +94 -56
  190. package/dist/http/rewind-files-reply.d.ts +34 -0
  191. package/dist/http/rewind-files-reply.js +36 -0
  192. package/dist/http/route-ctx.d.ts +43 -26
  193. package/dist/http/route-table.js +4 -0
  194. package/dist/http/routes/adoption.d.ts +11 -0
  195. package/dist/http/routes/adoption.js +80 -6
  196. package/dist/http/routes/agents-roster.js +1 -0
  197. package/dist/http/routes/approvals-assistant.js +7 -26
  198. package/dist/http/routes/background.js +1 -0
  199. package/dist/http/routes/capabilities.js +12 -3
  200. package/dist/http/routes/devices.js +1 -1
  201. package/dist/http/routes/diagnostics.d.ts +9 -14
  202. package/dist/http/routes/diagnostics.js +10 -20
  203. package/dist/http/routes/engine.d.ts +31 -0
  204. package/dist/http/routes/engine.js +81 -0
  205. package/dist/http/routes/memory-bundle.js +3 -0
  206. package/dist/http/routes/memory-consolidation.js +3 -5
  207. package/dist/http/routes/memory-origin.d.ts +2 -2
  208. package/dist/http/routes/memory-origin.js +2 -4
  209. package/dist/http/routes/memory-policy.js +5 -1
  210. package/dist/http/routes/notify-wake.js +2 -1
  211. package/dist/http/routes/observability.js +3 -6
  212. package/dist/http/routes/projects.d.ts +70 -0
  213. package/dist/http/routes/projects.js +86 -0
  214. package/dist/http/routes/rules.js +30 -2
  215. package/dist/http/routes/runs.js +15 -11
  216. package/dist/http/routes/session-sync.js +39 -35
  217. package/dist/http/routes/sessions-list.d.ts +1 -1
  218. package/dist/http/routes/sessions.d.ts +7 -1
  219. package/dist/http/routes/sessions.js +108 -2
  220. package/dist/http/routes/tasks.js +32 -8
  221. package/dist/http/routes/trace-usage.js +1 -1
  222. package/dist/http/run-concurrency-cap.d.ts +86 -0
  223. package/dist/http/run-concurrency-cap.js +54 -0
  224. package/dist/http/server.d.ts +31 -14
  225. package/dist/http/server.js +29 -3
  226. package/dist/http/stored-body-replay.d.ts +12 -7
  227. package/dist/http/stored-body-replay.js +28 -5
  228. package/dist/http/wire-types.d.ts +27 -13
  229. package/dist/index.d.ts +2 -2
  230. package/dist/index.js +1 -1
  231. package/dist/instruction-source-notice.d.ts +1 -1
  232. package/dist/json-body-limit.d.ts +8 -0
  233. package/dist/json-body-limit.js +2 -0
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/local-data-root.d.ts +2 -2
  236. package/dist/memory-embedder-reembed.d.ts +38 -0
  237. package/dist/memory-embedder-reembed.js +20 -0
  238. package/dist/memory-incident-sink.d.ts +0 -28
  239. package/dist/memory-incident-sink.js +5 -0
  240. package/dist/memory-operator-faces.d.ts +9 -4
  241. package/dist/memory-scope-stores.d.ts +9 -7
  242. package/dist/memory-scope-stores.js +3 -14
  243. package/dist/memory-scope.d.ts +38 -2
  244. package/dist/memory-scope.js +33 -2
  245. package/dist/memory-store-refusal.d.ts +17 -4
  246. package/dist/memory-store-refusal.js +1 -1
  247. package/dist/memory-sync-client.d.ts +2 -0
  248. package/dist/memory-sync-client.js +13 -11
  249. package/dist/memory-sync.js +1 -1
  250. package/dist/model-compat.d.ts +35 -21
  251. package/dist/model-compat.js +49 -21
  252. package/dist/model-entry-refusal.d.ts +11 -1
  253. package/dist/model-entry-refusal.js +7 -0
  254. package/dist/namespaced-rule-name.d.ts +18 -1
  255. package/dist/namespaced-rule-name.js +12 -0
  256. package/dist/net-address.d.ts +53 -0
  257. package/dist/net-address.js +111 -0
  258. package/dist/observability/fail-open.d.ts +29 -17
  259. package/dist/observability/fail-open.js +29 -17
  260. package/dist/observability/metrics.d.ts +2 -0
  261. package/dist/observability/metrics.js +2 -0
  262. package/dist/observability/secret-env-scrub.d.ts +30 -4
  263. package/dist/observability/secret-env-scrub.js +15 -3
  264. package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
  265. package/dist/orchestration/workflow-agent-session-index.js +1 -6
  266. package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
  267. package/dist/orchestration/workflow-completion-inbox.js +63 -45
  268. package/dist/orchestration/workflow-notify-journal.js +2 -3
  269. package/dist/org-delivery-gate.js +1 -1
  270. package/dist/org-memory-admission.d.ts +5 -2
  271. package/dist/org-memory-admission.js +25 -10
  272. package/dist/parked-decide.d.ts +33 -26
  273. package/dist/parked-decide.js +36 -44
  274. package/dist/peer-directory.d.ts +6 -12
  275. package/dist/peer-directory.js +5 -1
  276. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  277. package/dist/plugins/approval-ask-store-file.js +37 -4
  278. package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
  279. package/dist/plugins/approval-ask-store-memory.js +11 -2
  280. package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
  281. package/dist/plugins/approval-ask-store-sql.js +3 -1
  282. package/dist/plugins/blob-backend.d.ts +38 -195
  283. package/dist/plugins/blob-backend.js +33 -229
  284. package/dist/plugins/caching-session-store.d.ts +12 -5
  285. package/dist/plugins/caching-session-store.js +3 -0
  286. package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
  287. package/dist/plugins/checkpoint-index-columns.js +3 -2
  288. package/dist/plugins/checkpoint-store-face.d.ts +426 -0
  289. package/dist/plugins/checkpoint-store-face.js +152 -0
  290. package/dist/plugins/device-store-sql.d.ts +2 -2
  291. package/dist/plugins/device-store-sql.js +5 -10
  292. package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
  293. package/dist/plugins/execution-lane-rename-m40.js +10 -0
  294. package/dist/plugins/execution-placement-sql.d.ts +63 -88
  295. package/dist/plugins/execution-placement-sql.js +94 -54
  296. package/dist/plugins/file-run-store.d.ts +26 -18
  297. package/dist/plugins/file-run-store.js +64 -75
  298. package/dist/plugins/fork-routing-session-store.d.ts +6 -2
  299. package/dist/plugins/fork-routing-session-store.js +2 -2
  300. package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
  301. package/dist/plugins/imported-layer-root-retirement.js +4 -8
  302. package/dist/plugins/inbox-payload-column.d.ts +14 -0
  303. package/dist/plugins/inbox-payload-column.js +13 -0
  304. package/dist/plugins/local-checkpoint-store.d.ts +7 -2
  305. package/dist/plugins/local-checkpoint-store.js +13 -8
  306. package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
  307. package/dist/plugins/local-data-dir-modes-m39.js +182 -0
  308. package/dist/plugins/local-engine-high-water.d.ts +11 -0
  309. package/dist/plugins/local-engine-high-water.js +59 -0
  310. package/dist/plugins/local-session-store.d.ts +119 -30
  311. package/dist/plugins/local-session-store.js +156 -53
  312. package/dist/plugins/local-task-attachment-store.d.ts +2 -0
  313. package/dist/plugins/local-task-attachment-store.js +10 -11
  314. package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
  315. package/dist/plugins/memory-embedder-fingerprint.js +52 -12
  316. package/dist/plugins/memory-embedder.d.ts +1 -1
  317. package/dist/plugins/memory-embedder.js +2 -2
  318. package/dist/plugins/memory-engine-pg.d.ts +30 -6
  319. package/dist/plugins/memory-engine-pg.js +96 -214
  320. package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
  321. package/dist/plugins/memory-engine-sql-apply.js +358 -0
  322. package/dist/plugins/memory-engine-tidb.d.ts +38 -9
  323. package/dist/plugins/memory-engine-tidb.js +99 -230
  324. package/dist/plugins/memory-key-guards.d.ts +1 -1
  325. package/dist/plugins/memory-origin-law.d.ts +3 -3
  326. package/dist/plugins/one-time-migrations.d.ts +169 -83
  327. package/dist/plugins/one-time-migrations.js +295 -235
  328. package/dist/plugins/owner-only-file-mode.d.ts +29 -0
  329. package/dist/plugins/owner-only-file-mode.js +141 -0
  330. package/dist/plugins/permission-rule-store-file.d.ts +17 -3
  331. package/dist/plugins/permission-rule-store-file.js +20 -1
  332. package/dist/plugins/pg-pool.d.ts +2 -1
  333. package/dist/plugins/pg-pool.js +12 -5
  334. package/dist/plugins/release-version.d.ts +20 -0
  335. package/dist/plugins/release-version.js +28 -0
  336. package/dist/plugins/remote-env-adb.d.ts +20 -4
  337. package/dist/plugins/remote-env-adb.js +39 -11
  338. package/dist/plugins/remote-env-e2b.d.ts +12 -3
  339. package/dist/plugins/remote-env-e2b.js +6 -4
  340. package/dist/plugins/remote-env-host.d.ts +9 -1
  341. package/dist/plugins/remote-env-host.js +6 -5
  342. package/dist/plugins/remote-env-k8s.d.ts +5 -2
  343. package/dist/plugins/remote-env-k8s.js +15 -4
  344. package/dist/plugins/remote-env-local-docker.d.ts +4 -1
  345. package/dist/plugins/remote-env-local-docker.js +3 -3
  346. package/dist/plugins/remote-env-ssh.d.ts +8 -2
  347. package/dist/plugins/remote-env-ssh.js +26 -24
  348. package/dist/plugins/remote-shell.d.ts +59 -30
  349. package/dist/plugins/remote-shell.js +175 -62
  350. package/dist/plugins/retention-declaration.d.ts +37 -0
  351. package/dist/plugins/retention-declaration.js +9 -0
  352. package/dist/plugins/retention-deployment.d.ts +126 -0
  353. package/dist/plugins/retention-deployment.js +88 -0
  354. package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
  355. package/dist/plugins/retention-lane-store-sql.js +103 -1
  356. package/dist/plugins/retention-sql.d.ts +29 -0
  357. package/dist/plugins/retention-sql.js +8 -0
  358. package/dist/plugins/run-store-sql.js +2 -2
  359. package/dist/plugins/schema-consistency.d.ts +0 -6
  360. package/dist/plugins/schema-consistency.js +1 -2
  361. package/dist/plugins/schema-ensure-legs.d.ts +1 -1
  362. package/dist/plugins/schema-ensure-legs.js +13 -3
  363. package/dist/plugins/session-ext-table.d.ts +74 -0
  364. package/dist/plugins/session-ext-table.js +121 -0
  365. package/dist/plugins/session-fork.d.ts +31 -9
  366. package/dist/plugins/session-fork.js +3 -2
  367. package/dist/plugins/session-placement.d.ts +4 -2
  368. package/dist/plugins/session-row-sql.d.ts +8 -7
  369. package/dist/plugins/session-row-sql.js +15 -7
  370. package/dist/plugins/session-store-sql.d.ts +131 -0
  371. package/dist/plugins/session-store-sql.js +298 -0
  372. package/dist/plugins/session-workspace-cell.d.ts +2 -2
  373. package/dist/plugins/session-workspace-cell.js +2 -2
  374. package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
  375. package/dist/plugins/shared-memory-store-sql.js +13 -13
  376. package/dist/plugins/snapshot-bucket-presence.js +1 -1
  377. package/dist/plugins/sql-driver.d.ts +23 -7
  378. package/dist/plugins/sql-driver.js +41 -8
  379. package/dist/plugins/sql-errors.d.ts +5 -2
  380. package/dist/plugins/sql-errors.js +4 -0
  381. package/dist/plugins/sql-json-column.d.ts +5 -1
  382. package/dist/plugins/store-backend.d.ts +46 -16
  383. package/dist/plugins/store-backend.js +192 -69
  384. package/dist/plugins/store-contracts.d.ts +10 -13
  385. package/dist/plugins/store-contracts.js +1 -9
  386. package/dist/plugins/store-sweep.d.ts +63 -0
  387. package/dist/plugins/store-sweep.js +48 -0
  388. package/dist/plugins/task-attachment-store.d.ts +6 -8
  389. package/dist/plugins/task-attachment-store.js +15 -10
  390. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  391. package/dist/plugins/text-column-capacity.d.ts +21 -0
  392. package/dist/plugins/text-column-capacity.js +5 -0
  393. package/dist/plugins/tidb-pool.d.ts +3 -2
  394. package/dist/plugins/tidb-pool.js +20 -32
  395. package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
  396. package/dist/prompt-screen.d.ts +6 -9
  397. package/dist/prompt-screen.js +2 -5
  398. package/dist/read-face-posture.d.ts +6 -6
  399. package/dist/read-face-posture.js +2 -2
  400. package/dist/request-value-closure.d.ts +5 -5
  401. package/dist/request-value-closure.js +1 -1
  402. package/dist/rules-consent.d.ts +48 -27
  403. package/dist/rules-consent.js +147 -23
  404. package/dist/run-cancel-context.d.ts +4 -1
  405. package/dist/run-cancel-context.js +2 -1
  406. package/dist/run-local.js +17 -13
  407. package/dist/runs.d.ts +48 -30
  408. package/dist/runs.js +27 -17
  409. package/dist/runtime-caps-resolver.d.ts +15 -8
  410. package/dist/runtime-caps-resolver.js +14 -10
  411. package/dist/sandbox-egress-policy.js +6 -11
  412. package/dist/sandbox-rbac-rules.d.ts +88 -0
  413. package/dist/sandbox-rbac-rules.js +80 -0
  414. package/dist/sealed-key-layout.d.ts +16 -0
  415. package/dist/sealed-key-layout.js +3 -0
  416. package/dist/sealed-key.js +8 -6
  417. package/dist/security.d.ts +43 -9
  418. package/dist/security.js +9 -2
  419. package/dist/sema-config-dir.js +2 -2
  420. package/dist/server-secret-env.d.ts +2 -0
  421. package/dist/service-version.d.ts +2 -1
  422. package/dist/service-version.js +2 -2
  423. package/dist/session-error-wire.d.ts +1 -1
  424. package/dist/session-incarnation.d.ts +8 -5
  425. package/dist/session-notify-door.d.ts +5 -3
  426. package/dist/session-resident-background.d.ts +110 -0
  427. package/dist/session-resident-background.js +88 -0
  428. package/dist/session-row.d.ts +1 -1
  429. package/dist/session-sync-kernel.d.ts +53 -14
  430. package/dist/session-sync-kernel.js +70 -1
  431. package/dist/session-sync.d.ts +5 -3
  432. package/dist/session-workspace.d.ts +12 -2
  433. package/dist/session-workspace.js +6 -0
  434. package/dist/sighup-idle.d.ts +9 -7
  435. package/dist/sighup-idle.js +4 -5
  436. package/dist/spec-fields.d.ts +16 -0
  437. package/dist/spec-fields.js +7 -0
  438. package/dist/store-posture.d.ts +2 -1
  439. package/dist/stored-request-env-credentials-m38.d.ts +3 -0
  440. package/dist/stored-request-env-credentials-m38.js +8 -0
  441. package/dist/stored-request-hooks-m20.d.ts +3 -2
  442. package/dist/stored-request-hooks-m20.js +19 -14
  443. package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
  444. package/dist/stores-sql/blob-index-sql.d.ts +148 -0
  445. package/dist/stores-sql/blob-index-sql.js +154 -0
  446. package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
  447. package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
  448. package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
  449. package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
  450. package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
  451. package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
  452. package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
  453. package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
  454. package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
  455. package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
  456. package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
  457. package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
  458. package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
  459. package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
  460. package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
  461. package/dist/stores-sql/session-write-hooks.d.ts +59 -0
  462. package/dist/stores-sql/session-write-hooks.js +2 -0
  463. package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
  464. package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
  465. package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
  466. package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
  467. package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
  468. package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
  469. package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
  470. package/dist/stores-sql/windowed-session-storage.js +61 -0
  471. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
  472. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
  473. package/dist/task-a2a.d.ts +7 -1
  474. package/dist/task-a2a.js +15 -14
  475. package/dist/task-cwd.d.ts +11 -3
  476. package/dist/task-cwd.js +17 -1
  477. package/dist/task-mcp.d.ts +10 -2
  478. package/dist/task-mcp.js +13 -16
  479. package/dist/task-settings.d.ts +68 -8
  480. package/dist/task-settings.js +63 -6
  481. package/dist/tool-approval.d.ts +23 -10
  482. package/dist/tool-approval.js +10 -6
  483. package/dist/trace/core-keyset-guard.d.ts +17 -10
  484. package/dist/trace/engine-notice-wire.d.ts +1 -1
  485. package/dist/trace/engine-notice-wire.js +4 -0
  486. package/dist/trace/exit-seat.d.ts +29 -1
  487. package/dist/trace/exit-seat.js +4 -0
  488. package/dist/trace/project.d.ts +33 -16
  489. package/dist/trace/project.js +21 -9
  490. package/dist/trace/redact.d.ts +13 -2
  491. package/dist/trace/redact.js +347 -78
  492. package/dist/trace/self-minted-wire.d.ts +587 -16
  493. package/dist/trace/self-minted-wire.js +215 -9
  494. package/dist/trace/sema-provenance.d.ts +45 -41
  495. package/dist/trace/sema-provenance.js +81 -10
  496. package/dist/trace/task-notification-facets.d.ts +70 -2
  497. package/dist/trace/task-notification-facets.js +71 -1
  498. package/dist/trace/wire-projection-faces.d.ts +39 -3
  499. package/dist/trace/wire-projection-faces.js +27 -2
  500. package/dist/unread-request-members.d.ts +66 -0
  501. package/dist/unread-request-members.js +41 -0
  502. package/dist/usage-analytics.d.ts +4 -0
  503. package/dist/user-input-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/apply-effective.js +22 -26
  505. package/dist/web-admin-client/candidate-gate.d.ts +35 -3
  506. package/dist/web-admin-client/candidate-gate.js +53 -5
  507. package/dist/web-admin-client/center-request.d.ts +4 -1
  508. package/dist/web-admin-client/center-request.js +2 -1
  509. package/dist/web-admin-client/effective-keys.js +0 -1
  510. package/dist/web-admin-client/facade.d.ts +1 -1
  511. package/dist/web-admin-client/http-client.d.ts +1 -0
  512. package/dist/web-admin-client/http-client.js +17 -9
  513. package/dist/web-admin-client/restart-signal.js +5 -2
  514. package/dist/web-admin-client/skills-mcp.d.ts +20 -6
  515. package/dist/web-admin-client/skills-mcp.js +26 -21
  516. package/dist/web-admin-client/types.d.ts +34 -49
  517. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
  518. package/package.json +22 -13
  519. package/scripts/drain-check-local.mjs +8 -55
  520. package/scripts/drain-check.mysql.sql +3 -40
  521. package/scripts/drain-check.pg.sql +3 -40
  522. package/skills/update-config.md +1 -1
  523. package/wire-changes/server@7.146.0.json +3221 -0
  524. package/wire-changes/server@7.147.0.json +813 -0
  525. package/dist/approval-batch-census.d.ts +0 -27
  526. package/dist/approval-batch-census.js +0 -27
@@ -1,10 +1,9 @@
1
1
  import { once } from "node:events";
2
- import { randomBytes } from "node:crypto";
3
- import { sessionLogDigest, sessionLogDigestsComparable, StreamingImportValidator, validateFileHistoryExport } from "@sema-agent/core";
2
+ import { sessionLogDigest, sessionLogDigestsComparable, validateFileHistoryExport } from "@sema-agent/core";
4
3
  import { StringDecoder } from "node:string_decoder";
5
4
  import { FileHistoryUnreadableError, blobGetterOf, exportSessionManifest, exportedFileHistory, fileHistoryImportFace, replayFileHistory, replayPolicyRecords, wipeSessionAttendants } from "../../session-sync.js";
6
5
  import * as facts from "../../capability-facts.js";
7
- import { classifySyncRelationshipByIds, readImportAnchors, SyncConflictError } from "../../session-sync-kernel.js";
6
+ import { classifySyncRelationshipByIds, createStagedLogFeed, MalformedImportEntryError, newStagingToken, readImportAnchors, SyncConflictError } from "../../session-sync-kernel.js";
8
7
  import { isUuidShape, legacyUnownedSessionOk, sessionOwnerCellOf } from "../../security.js";
9
8
  import { sendJson, sendError, sendSessionError, sendSessionPolicyError, logRequestError, msg } from "../send.js";
10
9
  import { StampedSessionArchiveError } from "../../session-error-wire.js";
@@ -14,7 +13,6 @@ import { storeFaultClassOf } from "../../plugins/store-fault.js";
14
13
  import { fleetViewOf, gatedPrincipal, explicitOperatorOk, sendUnauthorized, sessionCallerOf } from "../principal-gate.js";
15
14
  const SYNC_BLOB_MAX_BYTES = 64 * 1024 * 1024;
16
15
  const SYNC_NDJSON_LINE_MAX_BYTES = 8 * 1024 * 1024;
17
- const SYNC_IMPORT_BATCH = 500;
18
16
  import { SHA256_HEX_RE } from "../../digest-form.js";
19
17
  import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
20
18
  import { readSessionRulesRecords, describeSessionRulesRecordProblem } from "../../session-policy-wire.js";
@@ -40,6 +38,21 @@ export function createSessionSyncLocal() {
40
38
  };
41
39
  return { pendingStagings, importLeases, touchImportLease, cleanupStaging };
42
40
  }
41
+ async function firstPhaseRefusal(sessionStorage, sessionId, relation, consented) {
42
+ if (consented || (relation !== "fork" && relation !== "stale"))
43
+ return undefined;
44
+ if (sessionStorage.assertArchiveAnonymous !== undefined && (await readSessionAgent(sessionStorage, sessionId)) === undefined) {
45
+ try {
46
+ await sessionStorage.assertArchiveAnonymous(sessionId);
47
+ }
48
+ catch (e) {
49
+ if (e instanceof StampedSessionArchiveError)
50
+ return { kind: "stamped", error: e };
51
+ throw e;
52
+ }
53
+ }
54
+ return { kind: "needs_consent" };
55
+ }
43
56
  export async function handleSessionSync(req, res, match, ctx) {
44
57
  const { deps } = ctx;
45
58
  const { readJson, readRawBody, safeDecode, rateLimited } = ctx.helpers;
@@ -360,16 +373,12 @@ export async function handleSessionSync(req, res, match, ctx) {
360
373
  const anchors = anchorsRead.anchors;
361
374
  const dstIds = (await sessionStorage.listEntryIds?.(sessionId)) ?? null;
362
375
  const relA = classifySyncRelationshipByIds(entryIds, dstIds);
363
- if ((relA.relation === "fork" || relA.relation === "stale") && resolution !== "overwrite-dst") {
364
- if (sessionStorage.assertArchiveAnonymous !== undefined && (await readSessionAgent(sessionStorage, sessionId)) === undefined) {
365
- try {
366
- await sessionStorage.assertArchiveAnonymous(sessionId);
367
- }
368
- catch (e) {
369
- if (e instanceof StampedSessionArchiveError && sendSessionError(res, e, "import"))
370
- return;
371
- throw e;
372
- }
376
+ const refusalA = await firstPhaseRefusal(sessionStorage, sessionId, relA.relation, resolution === "overwrite-dst");
377
+ if (refusalA !== undefined) {
378
+ if (refusalA.kind === "stamped") {
379
+ if (sendSessionError(res, refusalA.error, "import"))
380
+ return;
381
+ throw refusalA.error;
373
382
  }
374
383
  sendError(res, 409, "conflict", "sync conflict", { relation: relA });
375
384
  return;
@@ -501,7 +510,7 @@ export async function handleSessionSync(req, res, match, ctx) {
501
510
  }
502
511
  const importingPrincipal = scope.fleetWide ? (owner ?? null) : scope.gateOwner;
503
512
  const operatorOk = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config);
504
- const token = randomBytes(8).toString("hex");
513
+ const token = newStagingToken();
505
514
  const handle = sessionStorage.beginImportStaging(sessionId, token);
506
515
  const stagingId = handle.stagingId;
507
516
  importLeases.set(sessionId, { at: Date.now(), stagingId });
@@ -527,13 +536,8 @@ export async function handleSessionSync(req, res, match, ctx) {
527
536
  sendError(res, 404, "not_found.staging", "staging not found");
528
537
  return;
529
538
  }
530
- const validator = new StreamingImportValidator();
539
+ const feed = createStagedLogFeed(pending.handle);
531
540
  let lineBuf = "";
532
- let pendingBatch = [];
533
- const flush = async () => { if (pendingBatch.length) {
534
- await pending.handle.appendBatch(pendingBatch);
535
- pendingBatch = [];
536
- } };
537
541
  class PrecheckError extends Error {
538
542
  status;
539
543
  constructor(status, msg) {
@@ -542,12 +546,7 @@ export async function handleSessionSync(req, res, match, ctx) {
542
546
  }
543
547
  }
544
548
  const streamedIds = new Set();
545
- const onEntry = (e) => {
546
- if (!e || typeof e !== "object" || typeof e.id !== "string")
547
- throw new PrecheckError(422, "malformed entry (missing id)");
548
- streamedIds.add(e.id);
549
- validator.step(e);
550
- };
549
+ const onEntry = async (e) => { streamedIds.add(await feed.push(e)); };
551
550
  const utf8 = new StringDecoder("utf8");
552
551
  try {
553
552
  for await (const chunk of req) {
@@ -568,10 +567,7 @@ export async function handleSessionSync(req, res, match, ctx) {
568
567
  catch {
569
568
  throw new PrecheckError(400, "malformed NDJSON line");
570
569
  }
571
- onEntry(e);
572
- pendingBatch.push(e);
573
- if (pendingBatch.length >= SYNC_IMPORT_BATCH)
574
- await flush();
570
+ await onEntry(e);
575
571
  }
576
572
  }
577
573
  lineBuf += utf8.end();
@@ -584,11 +580,9 @@ export async function handleSessionSync(req, res, match, ctx) {
584
580
  catch {
585
581
  throw new PrecheckError(400, "malformed NDJSON line");
586
582
  }
587
- onEntry(e);
588
- pendingBatch.push(e);
583
+ await onEntry(e);
589
584
  }
590
- await flush();
591
- validator.finish();
585
+ await feed.finish();
592
586
  if (streamedIds.size !== pending.declaredEntryIds.length || !pending.declaredEntryIds.every((id) => streamedIds.has(id))) {
593
587
  throw new PrecheckError(422, "streamed entries do not match the Phase-A declared entryIds");
594
588
  }
@@ -600,6 +594,10 @@ export async function handleSessionSync(req, res, match, ctx) {
600
594
  sendError(res, e.status, "invalid_entries", e.message);
601
595
  return;
602
596
  }
597
+ if (e instanceof MalformedImportEntryError) {
598
+ sendError(res, 422, "invalid_entries", e.message);
599
+ return;
600
+ }
603
601
  if (sendSessionError(res, e, "import"))
604
602
  return;
605
603
  throw e;
@@ -696,6 +694,12 @@ export async function handleSessionSync(req, res, match, ctx) {
696
694
  }
697
695
  const dst = await sessionStorage.exportEntries(sessionId);
698
696
  const relation = classifySyncRelationshipByIds(body.entryIds, dst ? dst.map((e) => e.id) : null);
697
+ const refusal = await firstPhaseRefusal(sessionStorage, sessionId, relation.relation, false);
698
+ if (refusal?.kind === "stamped") {
699
+ if (sendSessionError(res, refusal.error, "import"))
700
+ return;
701
+ throw refusal.error;
702
+ }
699
703
  sendJson(res, 200, relation);
700
704
  return;
701
705
  }
@@ -2,7 +2,7 @@
2
2
  * [ref] A9 域模块 —— 会话列表 / 发件链接列表。
3
3
  *
4
4
  * 路由:`GET /v1/sessions`(CC /resume picker,keyset 分页)、`GET /v1/sendfile-links`。
5
- * owner-scope 与 trace 列表同一权威模型(`fleetViewOf` 读档:service 凭据不报主体 / 只读 trace 凭据 / dev-open = fleet-wide;带验过的主体 = 钉住那位主体)。本域零可变状态。
5
+ * owner-scope 与 trace 列表同一权威模型(`fleetViewOf` 读档:service 凭据不报主体〔部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` 时不算〕/ 只读 trace 凭据 / dev-open = fleet-wide;带验过的主体 = 钉住那位主体)。本域零可变状态。
6
6
  */
7
7
  import type { IncomingMessage, ServerResponse } from "node:http";
8
8
  import { type SessionListItem } from "../../security.js";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * [ref] A9 域模块 —— 单会话面。
3
3
  *
4
- * 路由:`/v1/sessions/:id` 的 init / settings / mcp / head / events(SSE)/ fork / PATCH(会话行可写位)/ DELETE / policy / workspace,
4
+ * 路由:`/v1/sessions/:id` 的 init / settings / mcp / head / events(SSE)/ fork / rewind-files(run 外只恢复代码)/ PATCH(会话行可写位)/ DELETE / policy / workspace,
5
5
  * 外加同段的 `deps.sessionAudit` 只读审计面。
6
6
  *
7
7
  * 单域独占状态(lens1 §C2 的 12 条里的 5 条)全部收进 `SessionsLocal`,每个 server 实例一份:
@@ -121,6 +121,12 @@ export declare const SESSIONS_ROUTES: readonly [{
121
121
  readonly pattern: RegExp;
122
122
  readonly label: "/v1/sessions/:id";
123
123
  readonly methods: readonly ["GET"];
124
+ }, {
125
+ readonly id: "session-rewind-files";
126
+ readonly pattern: RegExp;
127
+ readonly label: "/v1/sessions/:id/rewind-files";
128
+ readonly credentialGated: readonly ["POST"];
129
+ readonly methods: readonly ["POST"];
124
130
  }, {
125
131
  readonly id: "session-patch";
126
132
  readonly pattern: RegExp;
@@ -8,23 +8,29 @@ import { recordFailOpen } from "../../observability/fail-open.js";
8
8
  import { MCP_DIAL_DEADLINE_MS, raceDeadline } from "../mcp-dial-deadline.js";
9
9
  import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
10
10
  import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
11
+ import { DEPLOYMENT_SHAPE_PREDICATES } from "../../deployment-shape.js";
11
12
  import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS } from "../../task-settings.js";
12
13
  import { readWritableSessionPermissionRules } from "../../session-policy-wire.js";
13
14
  import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
14
15
  import { fleetViewOf, gatedPrincipal, explicitOperatorOk, sessionCallerOf, sessionOwnerReadable, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
15
16
  import { headReadOf, leafOfAdmittedHead, sessionFaceOfHead } from "../../session-incarnation.js";
16
- import { foldOwnerUnreadable, runRowReadableOnSessionFace } from "../owner-access.js";
17
+ import { foldOwnerUnreadable, readOwnedSessionHead, runRowReadableOnSessionFace } from "../owner-access.js";
17
18
  import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
18
19
  import * as facts from "../../capability-facts.js";
19
20
  import { rosterAgentId } from "./agents-roster.js";
20
21
  import { projectSessionListRow } from "./sessions-list.js";
21
22
  import { readSessionRowPatch } from "../../session-row.js";
22
- import { forkPathOf } from "../execution-context.js";
23
+ import { forkPathOf, resolveExecutionContext } from "../execution-context.js";
23
24
  import { executionPlacementView } from "../../execution-placement.js";
25
+ import { resolveHistoryAnchor } from "../../history-anchor.js";
26
+ import { engineRefusalAnswerOf } from "../engine-refusal.js";
27
+ import { buildRewindFilesReply } from "../rewind-files-reply.js";
24
28
  import { ForkTargetUnsettledError, forkKeyOf } from "../../plugins/session-fork.js";
25
29
  import { fieldConflictFacts } from "../../field-conflict.js";
26
30
  import { buildBoundedToolNames } from "../../panel-tool-names.js";
27
31
  import { projectMcpAuthorization } from "../../mcp-authorization-face.js";
32
+ import { presentHostWorkspaceOf } from "../../task-cwd.js";
33
+ import { rewindFilesUnderPurpose } from "../../execution-env-purpose.js";
28
34
  const MCP_STATUS_TTL_MS = 5_000;
29
35
  const A2A_STATUS_TTL_MS = 5_000;
30
36
  const A2A_MATERIALIZE_TIMEOUT_MS = 10_000;
@@ -615,6 +621,7 @@ export async function handleSessions(req, res, match, ctx) {
615
621
  memoryStatusCache.delete(cacheKey); });
616
622
  }
617
623
  const s = await pending;
624
+ const workerPathsDisclosed = DEPLOYMENT_SHAPE_PREDICATES.callerOwnsWorkerDisk.holds(deps.config);
618
625
  sendJson(res, 200, {
619
626
  sessionId,
620
627
  autoConsolidationArmed: deps.memoryAutoConsolidationArmed,
@@ -624,6 +631,8 @@ export async function handleSessions(req, res, match, ctx) {
624
631
  ...(s.foldedCount !== undefined ? { foldedCount: s.foldedCount } : {}),
625
632
  ...(s.optOutSource !== undefined ? { optOutSource: s.optOutSource } : {}),
626
633
  ...(s.lastCaptureAt !== undefined ? { lastCaptureAt: s.lastCaptureAt } : {}),
634
+ ...(s.writeHome !== undefined && workerPathsDisclosed ? { writeHome: s.writeHome } : {}),
635
+ ...(s.planes !== undefined && workerPathsDisclosed ? { planes: s.planes.map((row) => ({ plane: row.plane, ...(row.status.writeHome !== undefined ? { writeHome: row.status.writeHome } : {}) })) } : {}),
627
636
  });
628
637
  }
629
638
  catch (err) {
@@ -739,6 +748,82 @@ export async function handleSessions(req, res, match, ctx) {
739
748
  }
740
749
  }
741
750
  }
751
+ if (match.decl.id === "session-rewind-files") {
752
+ if (ctx.helpers.rateLimited(req, res))
753
+ return;
754
+ const rewind = facts.sessionRewindFiles(deps);
755
+ if (!rewind.available) {
756
+ switch (rewind.why) {
757
+ case "file_history_store_absent":
758
+ sendError(res, 501, "capability.snapshot_store_required", "rewinding a session's files is not available on this deployment: no file-history store is wired, so no file history was ever recorded");
759
+ return;
760
+ case "session_head_face_absent":
761
+ sendError(res, 501, "capability.session_store_required", "rewinding a session's files requires a durable session store (DB_BACKEND=mysql|pg|local)");
762
+ return;
763
+ case "resume_anchor_store_absent":
764
+ sendError(res, 501, "capability.session_store_required", "rewinding a session's files is not available on this deployment: no session-store backend holds the rewind anchor map");
765
+ return;
766
+ case "execution_lane_handless":
767
+ sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment: it mounts no execution environment (REMOTE_EXEC=none), so a session has no working tree to rewind");
768
+ return;
769
+ case "workspace_rebuilt_per_task":
770
+ sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment: each task's workspace is rebuilt when the task starts (fresh, or restored from a saved copy that a rewind cannot yet write into), so a rewind would not reach the files the next task works on");
771
+ return;
772
+ case "session_store_shared":
773
+ sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment yet: its session store is shared by several server instances (DB_BACKEND=mysql|pg), and a rewind cannot yet keep runs started on another instance off the session while it restores");
774
+ return;
775
+ default:
776
+ return assertNever(rewind.why);
777
+ }
778
+ }
779
+ const { anchors, sessionStorage } = rewind;
780
+ const sessionId = safeDecode(match.params.sessionId);
781
+ if (sessionId === null || !isUuidShape(sessionId)) {
782
+ sendError(res, 400, "request.id_invalid", "invalid session id (must be a canonical uuid)");
783
+ return;
784
+ }
785
+ const caller = sessionCallerOf(req, deps);
786
+ if (DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(deps.config) && caller.principal === undefined) {
787
+ sendPrincipalRefusal(res, req, deps.config);
788
+ return;
789
+ }
790
+ const owned = await readOwnedSessionHead(deps, sessionStorage, caller, sessionId, "owner_or_operator");
791
+ if (owned === undefined) {
792
+ sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
793
+ return;
794
+ }
795
+ const sessionOwner = owned.head.owner;
796
+ leafOfAdmittedHead(owned.head);
797
+ const read = readRewindFilesBody(await readJson(req));
798
+ if (read.kind === "refused") {
799
+ sendError(res, 400, read.errorCode, read.message);
800
+ return;
801
+ }
802
+ const execution = await resolveExecutionContext(deps, { kind: "continuation", root: sessionId, principal: sessionOwner ?? undefined });
803
+ if (execution.lane === "host" && (await presentHostWorkspaceOf(deps.perSessionCwd?.get(sessionId))) === undefined) {
804
+ sendError(res, 409, "conflict.session_workspace_unknown", "this server process does not know a working directory for this session that it can rewind into (no prompt carrying its cwd has been submitted since the server started, or the directory that prompt named no longer exists), so nothing was rewound; submit a prompt with its cwd first, then rewind");
805
+ return;
806
+ }
807
+ const entryId = await resolveHistoryAnchor("rewindFilesTo", anchors, sessionId, read.to, sessionOwner, "to");
808
+ const activeTaskId = await deps.runStore?.getActiveTaskId(sessionId);
809
+ if (activeTaskId) {
810
+ sendError(res, 409, "conflict.session_active_run", `session has an active run (${activeTaskId}); its files cannot be rewound under it — wait for that run to end (or cancel it), then rewind`, { activeTaskId });
811
+ return;
812
+ }
813
+ let result;
814
+ try {
815
+ result = await rewindFilesUnderPurpose(deps.runner, { sessionId, to: entryId, dryRun: read.dryRun });
816
+ }
817
+ catch (e) {
818
+ const answer = engineRefusalAnswerOf(e);
819
+ if (answer === undefined)
820
+ throw e;
821
+ sendError(res, answer.status, answer.refusal.errorCode, answer.refusal.message);
822
+ return;
823
+ }
824
+ sendJson(res, 200, buildRewindFilesReply(result));
825
+ return;
826
+ }
742
827
  {
743
828
  if (match.decl.id === "session-fork") {
744
829
  const forkFact = facts.sessionFork(deps);
@@ -963,6 +1048,7 @@ export const SESSIONS_ROUTES = [
963
1048
  { id: "session-memory-status", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/memory-status$/, label: "/v1/sessions/:id/memory-status", methods: ["GET"] },
964
1049
  { id: "session-workspace", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/workspace(?:\/(?<key>[^/]+)(?:\/(?<sub>tree|file|archive))?)?$/, label: "/v1/sessions/:id/workspace", methods: ["GET"] },
965
1050
  { id: "session-detail", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["GET"] },
1051
+ { id: "session-rewind-files", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/rewind-files$/, label: "/v1/sessions/:id/rewind-files", credentialGated: ["POST"], methods: ["POST"] },
966
1052
  { id: "session-patch", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["PATCH"] },
967
1053
  { id: "session-delete", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["DELETE"] },
968
1054
  ];
@@ -985,4 +1071,24 @@ function readForkTarget(raw, sourceId) {
985
1071
  return { kind: "keyed", forkId, forkNonce };
986
1072
  }
987
1073
  const FORK_NONCE_MAX_CHARS = 255;
1074
+ const REWIND_TO_MAX_CHARS = 255;
1075
+ function readRewindFilesBody(raw) {
1076
+ const shape = {
1077
+ kind: "refused",
1078
+ errorCode: "request.body_shape",
1079
+ message: 'the rewind-files body must be an object { to: string, dryRun?: boolean } — acceptPartialRestore is not accepted: the engine\'s out-of-run rewind has no partial-restore policy, so a partial restore answers 200 with restore.outcome "partial" and every refused or failed file on its ledger',
1080
+ };
1081
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
1082
+ return shape;
1083
+ const keys = Object.keys(raw);
1084
+ if (!keys.includes("to") || keys.some((k) => k !== "to" && k !== "dryRun"))
1085
+ return shape;
1086
+ const { to, dryRun } = raw;
1087
+ if (typeof to !== "string" || to.length === 0 || to.length > REWIND_TO_MAX_CHARS) {
1088
+ return { kind: "refused", errorCode: "request.field_invalid", message: `to must be a non-empty string of at most ${REWIND_TO_MAX_CHARS} characters: the handle of a prompt in this session (the handle rewindFilesTo takes)` };
1089
+ }
1090
+ if (dryRun !== undefined && typeof dryRun !== "boolean")
1091
+ return { kind: "refused", errorCode: "request.field_invalid", message: "dryRun must be a boolean when given" };
1092
+ return { kind: "read", to, dryRun: dryRun === true };
1093
+ }
988
1094
  //# sourceMappingURL=sessions.js.map
@@ -16,7 +16,7 @@ import { buildCancelledLedgerRow, createRunAbort, mintCancelledResult } from "..
16
16
  import { recordResourceWindow } from "../../resource-window.js";
17
17
  import { redactSecrets } from "../../trace/redact.js";
18
18
  import { writeLiveFrame, writeLiveHeartbeat } from "../live-frame.js";
19
- import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, liveIdentityFields } from "../../trace/project.js";
19
+ import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat, liveIdentityFields } from "../../trace/project.js";
20
20
  import { cascadeConfig, fillRunPreviewOnDelivery, runMeta } from "../run-meta.js";
21
21
  import { idemCallerOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
22
22
  import { replayOfExistingRun } from "../submit-replay.js";
@@ -27,6 +27,7 @@ import { approvalPreambleReplays, createApprovalCardEmitter, declaredApprovalFra
27
27
  import { buildActiveRunConflict, isActiveRunConflictBody, toDoneFrameResult } from "../active-run-conflict.js";
28
28
  import { commitExecutionContext } from "../execution-context.js";
29
29
  import { rootSessionAbsentAnswer } from "../execution-context.js";
30
+ import { timeClaim } from "../claim-latency.js";
30
31
  import { commitSessionInheritEnv } from "../session-inherit-env.js";
31
32
  import { headerStr, gatedPrincipal, explicitOperatorOk, runIdentityOf } from "../principal-gate.js";
32
33
  import { failOpenTagForDroppedFrame, recordFailOpen } from "../../observability/fail-open.js";
@@ -76,7 +77,7 @@ const MULTI_ATTEMPT_NO_EVENT_CHANNEL_NOTICE = "verify / cascade ran with their n
76
77
  export async function handleTasks(req, res, match, ctx) {
77
78
  const { deps } = ctx;
78
79
  const { idemCache, inflightRuns, steerableRuns, counters } = ctx.registry;
79
- const { readJson, rateLimited, quotaExceeded, leaseDenied, usageWindowDenied } = ctx.helpers;
80
+ const { readJson, rateLimited, quotaExceeded, leaseDenied, usageWindowDenied, admitRun } = ctx.helpers;
80
81
  const { prepareSpec, finalizeTaskResult } = ctx.legs;
81
82
  const reqState = ctx.req;
82
83
  const source = ctx.req.source;
@@ -144,10 +145,14 @@ export async function handleTasks(req, res, match, ctx) {
144
145
  }
145
146
  if (rateLimited(req, res) || quotaExceeded(req, res) || (await leaseDenied(req, res)) || (await usageWindowDenied(req, res)))
146
147
  return;
148
+ let runSlot = undefined;
147
149
  const prepared = await prepareSpec(req, res, keyedBody, undefined, { liveStream });
148
150
  if (!prepared)
149
151
  return;
150
152
  try {
153
+ runSlot = admitRun(req, res);
154
+ if (runSlot === undefined)
155
+ return;
151
156
  const declaredFamilies = declaredApprovalFrameFamilies(prepared.body.settings);
152
157
  const approvalLegInput = (streamApprovalOn) => {
153
158
  const legWalltimeMs = typeof prepared.spec.limits?.maxWalltimeMs === "number" ? prepared.spec.limits.maxWalltimeMs : undefined;
@@ -180,11 +185,12 @@ export async function handleTasks(req, res, match, ctx) {
180
185
  }
181
186
  reqState.streamTaskId = earlyDurableTid;
182
187
  let usageKey;
188
+ let manifestSeat;
183
189
  reqState.streamDetached = detachOnDisconnect;
184
190
  sseHeaders(res, earlyDurableTid ? { "x-task-id": earlyDurableTid } : undefined);
185
191
  if (earlyDurableTid)
186
192
  writeMetaFrame(res, earlyDurableTid, prepared.spec.sessionId, prepared.warnings);
187
- const ac = createRunAbort();
193
+ const ac = createRunAbort(prepared.auth?.principal ?? null);
188
194
  let closed = false;
189
195
  let detachLogged = false;
190
196
  let disconnectParkGrace;
@@ -298,7 +304,7 @@ export async function handleTasks(req, res, match, ctx) {
298
304
  };
299
305
  if (deps.runStore) {
300
306
  const tid = earlyDurableTid ?? uuidv7();
301
- const created = await deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null });
307
+ const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null }));
302
308
  if (created.ok)
303
309
  clearTurnActivity(tid);
304
310
  if (created.ok)
@@ -344,6 +350,7 @@ export async function handleTasks(req, res, match, ctx) {
344
350
  ledgerSink = createLedgerSink({ appendEvent: (seq, type, data) => rs.appendEvent(tid, seq, type, data), persistThinking: deps.config.traceThinking, onActivity: (kind, statusData) => recordTurnActivity(tid, kind, statusData), legSections: legWiringSections, usage: { modelUsage: deps.modelUsage, taskId: tid } });
345
351
  usageKey = tid;
346
352
  deps.modelUsage?.register(tid);
353
+ manifestSeat = createPromptManifestSeat(deps.promptManifests, tid);
347
354
  const owner = principal ?? null;
348
355
  const abortFromVerb = () => ac.abort("cancel_verb");
349
356
  durableHeartbeat = setInterval(() => {
@@ -355,6 +362,7 @@ export async function handleTasks(req, res, match, ctx) {
355
362
  }, HEARTBEAT_MS);
356
363
  durableHeartbeat.unref?.();
357
364
  inflightRuns.set(tid, ac);
365
+ runSlot?.release();
358
366
  void Promise.resolve(rs.isCancelRequested?.(tid, owner)).then((c) => { if (c && !ac.signal.aborted)
359
367
  abortFromVerb(); }).catch(() => undefined);
360
368
  }
@@ -503,6 +511,8 @@ export async function handleTasks(req, res, match, ctx) {
503
511
  await deps.userInputLedger?.observeLegEvent(liveStream, ev);
504
512
  await prepared.acceptance.observe(ev);
505
513
  await liveWorkspace.observe(ev);
514
+ if (ledgerSink)
515
+ await manifestSeat?.drain(ledgerSink.append);
506
516
  if (ev.type === "done") {
507
517
  finalResult = await mintSubmitExitResult(ev.result, deps.checkpointStore);
508
518
  if (durableTaskId && finalResult)
@@ -849,7 +859,10 @@ export async function handleTasks(req, res, match, ctx) {
849
859
  };
850
860
  counters.uncountedBillableInflight++;
851
861
  try {
852
- resp = await idemCache.run(inflightKey, async () => withRunReceipt(await runStreamSubmitLeg()));
862
+ const settling = idemCache.run(inflightKey, async () => withRunReceipt(await runStreamSubmitLeg()));
863
+ if (!ranLive)
864
+ runSlot?.release();
865
+ resp = await settling;
853
866
  }
854
867
  catch (e) {
855
868
  deps.logger?.error("stream_error", { closed, err: redactHead(e instanceof Error ? e.message : String(e), 2000) });
@@ -861,6 +874,7 @@ export async function handleTasks(req, res, match, ctx) {
861
874
  clearInterval(hb);
862
875
  if (usageKey)
863
876
  deps.modelUsage?.clear(usageKey);
877
+ manifestSeat?.release();
864
878
  }
865
879
  if (!ranLive && resp && !res.writableEnded) {
866
880
  writeLiveFrame(res, { type: "done", result: doneResultOfOutcome(resp), replay: true });
@@ -881,7 +895,7 @@ export async function handleTasks(req, res, match, ctx) {
881
895
  let durableHeartbeat;
882
896
  if (deps.runStore) {
883
897
  const tid = uuidv7();
884
- const created = await deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null });
898
+ const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null }));
885
899
  if (created.ok)
886
900
  clearTurnActivity(tid);
887
901
  if (created.ok)
@@ -904,7 +918,7 @@ export async function handleTasks(req, res, match, ctx) {
904
918
  return ctxRefusal;
905
919
  }
906
920
  commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
907
- const syncCancelCtrl = createRunAbort();
921
+ const syncCancelCtrl = createRunAbort(principal ?? null);
908
922
  markChildrenStoppedByUserOnAbort(syncCancelCtrl.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.principal);
909
923
  if (durableTaskId && deps.runStore) {
910
924
  const rs = deps.runStore;
@@ -920,11 +934,13 @@ export async function handleTasks(req, res, match, ctx) {
920
934
  }, HEARTBEAT_MS);
921
935
  durableHeartbeat.unref?.();
922
936
  inflightRuns.set(tid, syncCancelCtrl);
937
+ runSlot?.release();
923
938
  void Promise.resolve(rs.isCancelRequested?.(tid, owner)).then((c) => { if (c && !syncCancelCtrl.signal.aborted)
924
939
  abortFromVerb(); }).catch(() => undefined);
925
940
  }
926
941
  else if (durableTaskId) {
927
942
  inflightRuns.set(durableTaskId, syncCancelCtrl);
943
+ runSlot?.release();
928
944
  }
929
945
  const specWithSignal = { ...prepared.spec, signal: syncCancelCtrl.signal, ...(durableTaskId ? { taskId: durableTaskId } : {}) };
930
946
  const observeSyncLegEvent = (ev) => {
@@ -1001,12 +1017,20 @@ export async function handleTasks(req, res, match, ctx) {
1001
1017
  noteRunOutcome(result);
1002
1018
  return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult)) };
1003
1019
  };
1004
- const resp = await idemCache.run(inflightKey, async () => withRunReceipt(await runSyncSubmitLeg()));
1020
+ let ranSyncLeg = false;
1021
+ const settling = idemCache.run(inflightKey, async () => {
1022
+ ranSyncLeg = true;
1023
+ return withRunReceipt(await runSyncSubmitLeg());
1024
+ });
1025
+ if (!ranSyncLeg)
1026
+ runSlot?.release();
1027
+ const resp = await settling;
1005
1028
  sendSubmitResult(res, resp);
1006
1029
  }
1007
1030
  return;
1008
1031
  }
1009
1032
  finally {
1033
+ runSlot?.release();
1010
1034
  prepared.peerLease.release();
1011
1035
  }
1012
1036
  }
@@ -102,7 +102,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
102
102
  };
103
103
  const now = Date.now();
104
104
  const from = parseT(q.get("from"), now - 7 * 86_400_000);
105
- const to = parseT(q.get("to"), now);
105
+ const to = parseT(q.get("to"), now + 1);
106
106
  if (Number.isNaN(from) || Number.isNaN(to) || from >= to) {
107
107
  sendError(res, 400, "request.query_invalid", "invalid from/to (ISO-8601 or epoch-ms; from < to)");
108
108
  return;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 在飞 run 并发帽 —— `RUN_MAX_CONCURRENT`(本副本全局)/ `RUN_MAX_CONCURRENT_PER_PRINCIPAL`(同一已验提交主体),缺省 0 = 关。
3
+ *
4
+ * ## 为什么有这一只
5
+ * 共享一台 GPU / 一只小模型网关的部署,调用方自己限并发不可靠(多个调用方、重试风暴、脚本一把梭)。`RATE_LIMIT_RPM` 是速率桶(每分钟几条),
6
+ * 不是「此刻有几条在跑」;一条 run 可以跑几十分钟,速率桶放行的新提交会在同一台机器上叠起来。本帽数的就是后一个量。
7
+ *
8
+ * ## 数什么
9
+ * **同一份**在飞集:`inflightRuns ∪ steerableRuns`({@link liveRunIdsOf} —— `drainState.inflight` 读的也是它;`isRunLiveOnThisReplica`(`http/server.ts`)是同一并集的逐 id 判,
10
+ * 另写成两只 `has` 的析取,不经本函数;计数只有这一处写法,不另造第二份)。按主体数时读 `inflightRuns` 值上的 `owner`({@link RunAbort.owner} —— 句柄与腿同寿,不另起旁表);
11
+ * 只在 `steerableRuns` 里的键没有属主可读,只计入全局(今天每条可 steer 的腿都同时登记在 `inflightRuns`,这是形式上的保守)。
12
+ * 数的是**本副本**:副本之间不共享,多副本部署的整体并发 = 各副本的帽之和。
13
+ *
14
+ * ## 判点(哪几扇门判、哪几扇不判)
15
+ * 判 = **新提交要起一条 run** 的三个提交门(`routes/runs.ts` 的 `createDurableRun` —— `POST /v1/runs` 与 A2A `message/send` 共用的建行腿、
16
+ * `routes/tasks.ts` 的 `POST /v1/tasks` 与 `POST /v1/tasks/stream`),且排在**幂等重放之后**(同键 / 自带 taskId 的重试拿回自己的回执,不吃新 429)。
17
+ * 不判 = 已有 run 的延续与作答:续跑、唤醒、审批 / 问答作答、`/decide` —— 它们不是新提交,在飞时照样占一格(被数;没有 run 行的老形续跑不登记进在飞集,不被数),
18
+ * 但拒它们会把一张已经在等人的卡卡死。所以帽闸的是**新提交**,不是在飞总数的硬上限:一条停驻的 run 续跑回来时,在飞数可以越过帽。
19
+ * leader 口的后台 run 不在 `inflightRuns` 里(drain 靠 `uncountedBillableInflight` 看见它),本帽不数它也不判它。
20
+ * 位置的两个如实:三个口的帽都排在受理漏斗(`prepareSpec`,可能为新会话做登记)**之后**、建行与 SSE 头之前 —— `POST /v1/runs` 与 A2A 口因自带 `taskId` 的重放在漏斗之后才答、帽必须排在它后面
21
+ * (与 lease / 治理窗的 429 同位),`POST /v1/tasks` 两口与它们同位;拒时漏斗已做的会话登记不撤。同键的并发重复提交若赶在首发还在受理(尚未落行、尚未进在飞合流)的窗里到达,按新提交判,
22
+ * 帽满时与其它准入门(速率 / 配额)同形可能拿到一次 429 + `Retry-After`,按它重投即拿回首发的回执。
23
+ *
24
+ * ## 席位(为什么放行不是「读一下数就完了」)
25
+ * 判完帽到这条 run 登记进 `inflightRuns` 之间隔着若干次 await(建行、执行放置、续跑输入落库 …)。并发一阵提交若都只「读数」,会全部在登记之前读到同一个数、
26
+ * 一起放行 —— 越帽。所以放行即**占一枚席位**({@link RunSlot}),在飞数 = 在飞集 + 未放的席位。席位在这条 run 登记进在飞集的那一拍放掉:
27
+ * 三个提交门同形:建行腿 `mintAndDriveDurableRun` 在 `runInBackground`(返回前同步登记)返回后就地放(`runSlot` 入参),`POST /v1/tasks` / `/v1/tasks/stream` 两腿在各自的
28
+ * `inflightRuns.set` 之后就地放;提交门的 `finally` 总再放一次兜底(早退、被别的门拒、抛 —— `release` 幂等)。登记到放席位之间没有 await,别的提交读不到
29
+ * 「既在集里又占着席位」的中间态,所以不重复计。
30
+ * 两个尾巴:合流进别人在飞建行的重复提交(同键赛过 `peek`)自己不建行 —— `POST /v1/tasks` 一族席位当场放回;`POST /v1/runs`(与 A2A 提交)的席位到这一次提交的整段结清(`.finally`)才放,
31
+ * 合流的那一次要等共享铸件结清,帽边上可多答一次 429;没有 run store 的部署上同步 / 流式腿根本不登记进在飞集
32
+ * (drain 靠 `uncountedBillableInflight` 数它们),它们的席位就活到请求结束 —— 帽照样数得到它们。
33
+ *
34
+ * ## 拒的形
35
+ * 429 `limit.rate_exceeded`(沿用现有限流码,不新铸一枚:消费端的分支同「稍后再来」)+ 体里机读 `reason`(闭集 {@link RATE_EXCEEDED_REASONS},今天一词)
36
+ * + `retryAfterSec`(固定 {@link RUN_CONCURRENCY_RETRY_AFTER_SEC});头 `Retry-After` 与体里同值,同其它限流 / 配额门的发送形(`res.setHeader("retry-after")` + `sendError`)。
37
+ * 拒在建行、认领会话与 SSE 头之前(受理漏斗已做的会话登记见上面「位置的两个如实」)。
38
+ *
39
+ * ## 谁需要 / 谁受伤 / 补偿
40
+ * 需要:共享一台 GPU 或一只小模型网关的家用 / 小团队部署。受伤:超帽者拿 429(新行为,缺省关)。补偿:缺省 0 = 关(升级零变化)+ `Retry-After` 给退避。
41
+ * 无主体请求(无头 service 凭据、`REQUIRE_PRINCIPAL=false` 的单用户部署)只受全局帽 —— 按主体帽对它不判(没有主体可分账)。
42
+ */
43
+ import type { IncomingMessage, ServerResponse } from "node:http";
44
+ import type { RunAbort } from "../run-cancel-context.js";
45
+ import { type RefusalBody } from "./refusal-body.js";
46
+ import type { FlatServiceDeps } from "./server.js";
47
+ /**
48
+ * 本副本在飞 run 的 id 集 —— `inflightRuns`(durable 腿)∪ `steerableRuns`(活流)的**唯一**并集写法:
49
+ * `drainState.inflight`(排空等多久)、`isRunLiveOnThisReplica`(这条 run 是不是在本副本跑)与并发帽读的是同一份。
50
+ * 参数取 `ReadonlyMap`:读法不改登记簿。
51
+ */
52
+ export declare function liveRunIdsOf(inflightRuns: ReadonlyMap<string, unknown>, steerableRuns: ReadonlyMap<string, unknown>): Set<string>;
53
+ /** 并发帽拒的机读 `reason` 词。 */
54
+ export declare const RUN_CONCURRENCY_CAP_REASON: "run_concurrency_cap";
55
+ /**
56
+ * 429 `limit.rate_exceeded` 体上机读 `reason` 的**闭集**(穷举读它;加一种拒因 ⇒ 这里加一词,`switch` 的消费端编译红)。
57
+ * 其余 `limit.rate_exceeded` 的产地(速率桶、赎回准入、MCP 探活、烘焙提交)不带 `reason` —— 读法是「有 `reason` 才分」。
58
+ */
59
+ export declare const RATE_EXCEEDED_REASONS: readonly ["run_concurrency_cap"];
60
+ export type RateExceededReason = (typeof RATE_EXCEEDED_REASONS)[number];
61
+ /** 退避提示:固定 5 秒(是提示不是承诺 —— 在飞的 run 可能再跑很久;帽满只说「稍后再来」)。 */
62
+ export declare const RUN_CONCURRENCY_RETRY_AFTER_SEC = 5;
63
+ /** 一枚席位:放行与登记进在飞集之间占着的那一格。`release` 幂等(登记点放一次,提交门的 `finally` 再放一次兜底)。 */
64
+ export interface RunSlot {
65
+ release(): void;
66
+ }
67
+ /** 并发帽拒的 `{status, body, retryAfterSec}`(体经全仓唯一组句器;状态与退避供发送口用)。 */
68
+ export declare function runConcurrencyRefusalOf(): {
69
+ readonly status: 429;
70
+ readonly body: RefusalBody;
71
+ readonly retryAfterSec: number;
72
+ };
73
+ export interface RunConcurrencyGate {
74
+ /**
75
+ * 提交门的并发帽准入:放行 ⇒ 交回席位(调用点登记那一拍 / `finally` 放);超帽 ⇒ 已应答 429(+ `Retry-After`),交回 `undefined`,调用点 `return`。
76
+ * 位序:在幂等重放、`rateLimited` / `quotaExceeded` / `leaseDenied` / `usageWindowDenied` 之后,任何建行 / 认领 / SSE 头之前。
77
+ */
78
+ admitRun(req: IncomingMessage, res: ServerResponse): RunSlot | undefined;
79
+ }
80
+ /** 装配口:`deps` 只读 `config`(两旋钮,每次判时现读)与 `logger`;在飞集由 server 装配层交来(两张登记簿本身,不拷)。 */
81
+ export declare function createRunConcurrencyGate(ctx: {
82
+ deps: Pick<FlatServiceDeps, "config" | "logger">;
83
+ inflightRuns: ReadonlyMap<string, RunAbort>;
84
+ steerableRuns: ReadonlyMap<string, unknown>;
85
+ }): RunConcurrencyGate;
86
+ //# sourceMappingURL=run-concurrency-cap.d.ts.map