@sema-agent/server 7.150.0 → 7.151.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 (341) hide show
  1. package/MIGRATION.md +185 -0
  2. package/USAGE.md +53 -25
  3. package/deploy/sema-up/README.md +7 -1
  4. package/deploy/sema-up/chart/Chart.yaml +1 -1
  5. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  6. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  7. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  8. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  9. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  10. package/deploy/sema-up/chart/values.yaml +8 -1
  11. package/deploy/sema-up/cluster-up.sh +1 -0
  12. package/deploy/sema-up/kube-up.sh +1 -1
  13. package/deploy/sema-up/lib/flagshape.sh +1 -1
  14. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  16. package/dist/adoption/import.js +3 -3
  17. package/dist/approval-ask-machine.d.ts +1 -1
  18. package/dist/approval-card.d.ts +2 -2
  19. package/dist/approval-gate-currency.d.ts +1 -1
  20. package/dist/auth-bridge.d.ts +20 -0
  21. package/dist/auth-bridge.js +9 -0
  22. package/dist/background-session-reap.d.ts +1 -1
  23. package/dist/bake-runner/main.d.ts +4 -2
  24. package/dist/bind-host.d.ts +2 -3
  25. package/dist/bind-host.js +2 -4
  26. package/dist/boot/budget-tracing.js +1 -1
  27. package/dist/boot/engine-lease.d.ts +5 -0
  28. package/dist/boot/engine-lease.js +1 -0
  29. package/dist/boot/execution-env.d.ts +8 -14
  30. package/dist/boot/execution-env.js +54 -17
  31. package/dist/boot/execution-lane.js +32 -5
  32. package/dist/boot/late-binds.d.ts +8 -4
  33. package/dist/boot/late-binds.js +7 -1
  34. package/dist/boot/memory-consolidation.d.ts +3 -2
  35. package/dist/boot/memory-consolidation.js +6 -6
  36. package/dist/boot/reapers.d.ts +5 -0
  37. package/dist/boot/reapers.js +12 -1
  38. package/dist/boot/resolve-spec.d.ts +3 -3
  39. package/dist/boot/resolve-spec.js +31 -22
  40. package/dist/boot/runner-deps.d.ts +9 -2
  41. package/dist/boot/runner-deps.js +3 -3
  42. package/dist/boot/session-age-out.d.ts +36 -0
  43. package/dist/boot/session-age-out.js +101 -0
  44. package/dist/boot/session-faces.d.ts +5 -14
  45. package/dist/boot/session-faces.js +9 -5
  46. package/dist/boot/stage-01-config.js +2 -0
  47. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  48. package/dist/boot/stage-05-execution-env.js +2 -2
  49. package/dist/boot/stage-06-runners.d.ts +7 -4
  50. package/dist/boot/stage-06-runners.js +15 -6
  51. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  52. package/dist/boot/stage-07-capability-layer.js +2 -1
  53. package/dist/boot/stage-08-reapers.d.ts +7 -4
  54. package/dist/boot/stage-08-reapers.js +4 -2
  55. package/dist/boot/stage-09-leader.d.ts +11 -5
  56. package/dist/boot/stage-09-leader.js +12 -3
  57. package/dist/boot/stage-10-http-server.d.ts +11 -5
  58. package/dist/boot/stage-10-http-server.js +3 -6
  59. package/dist/boot/web-admin.js +3 -1
  60. package/dist/boot/workflow-orchestration.d.ts +7 -2
  61. package/dist/boot/workflow-orchestration.js +24 -7
  62. package/dist/bounded-rotation.d.ts +29 -0
  63. package/dist/bounded-rotation.js +24 -0
  64. package/dist/capability-facts.d.ts +22 -13
  65. package/dist/capability-facts.js +28 -18
  66. package/dist/center-credential.d.ts +25 -6
  67. package/dist/center-credential.js +25 -5
  68. package/dist/config-catalog.d.ts +26 -7
  69. package/dist/config-catalog.js +14 -11
  70. package/dist/config-invariants.d.ts +2 -1
  71. package/dist/config-invariants.js +4 -4
  72. package/dist/config-types.d.ts +10 -4
  73. package/dist/config.d.ts +51 -2
  74. package/dist/config.js +35 -24
  75. package/dist/deployment-shape.d.ts +9 -1
  76. package/dist/deployment-shape.js +2 -1
  77. package/dist/device-protocol.d.ts +5 -4
  78. package/dist/device-protocol.js +1 -1
  79. package/dist/device-ws-hub.js +3 -2
  80. package/dist/device-ws-protocol.d.ts +63 -10
  81. package/dist/device-ws-protocol.js +56 -25
  82. package/dist/engine-identity.d.ts +19 -7
  83. package/dist/engine-identity.js +10 -2
  84. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  85. package/dist/execution-env-refusal.d.ts +23 -0
  86. package/dist/execution-env-refusal.js +5 -0
  87. package/dist/execution-lane-caps.d.ts +3 -1
  88. package/dist/field-conflict.d.ts +1 -1
  89. package/dist/file-history-capture.d.ts +11 -4
  90. package/dist/file-history-capture.js +9 -6
  91. package/dist/file-history-disclosure.d.ts +7 -5
  92. package/dist/file-history-disclosure.js +7 -5
  93. package/dist/fleet/drain-entry.d.ts +4 -0
  94. package/dist/hooks/hook-runner.js +2 -2
  95. package/dist/host-lsp-manager.d.ts +2 -2
  96. package/dist/http/admission.js +17 -2
  97. package/dist/http/approval-sweeps.js +5 -5
  98. package/dist/http/checkpoint-ctx.d.ts +2 -0
  99. package/dist/http/checkpoint-ctx.js +1 -0
  100. package/dist/http/dispatch.d.ts +2 -1
  101. package/dist/http/dispatch.js +34 -27
  102. package/dist/http/durable-run-leg.js +16 -16
  103. package/dist/http/health-self-report.d.ts +9 -1
  104. package/dist/http/health-self-report.js +2 -0
  105. package/dist/http/owner-access.d.ts +31 -11
  106. package/dist/http/owner-access.js +37 -6
  107. package/dist/http/resume-ctx-read.js +25 -3
  108. package/dist/http/resume-legs.d.ts +2 -1
  109. package/dist/http/resume-legs.js +259 -79
  110. package/dist/http/route-ctx.d.ts +18 -8
  111. package/dist/http/route-table.d.ts +1 -1
  112. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  113. package/dist/http/routes/agents-roster.js +2 -3
  114. package/dist/http/routes/approvals-assistant.js +4 -3
  115. package/dist/http/routes/background.d.ts +3 -3
  116. package/dist/http/routes/capabilities.js +8 -5
  117. package/dist/http/routes/fleet.js +10 -8
  118. package/dist/http/routes/projects.d.ts +3 -2
  119. package/dist/http/routes/projects.js +4 -5
  120. package/dist/http/routes/runs.js +102 -36
  121. package/dist/http/routes/session-sync.d.ts +4 -3
  122. package/dist/http/routes/session-sync.js +172 -77
  123. package/dist/http/routes/sessions-list.js +13 -7
  124. package/dist/http/routes/sessions.js +10 -6
  125. package/dist/http/routes/tasks.js +30 -16
  126. package/dist/http/routes/trace-usage.js +2 -2
  127. package/dist/http/server.d.ts +21 -27
  128. package/dist/http/server.js +2 -2
  129. package/dist/http/submit-ctx.js +5 -4
  130. package/dist/http/wire-types.d.ts +14 -4
  131. package/dist/identity-source.d.ts +20 -3
  132. package/dist/identity-source.js +14 -0
  133. package/dist/index.d.ts +4 -0
  134. package/dist/lane-home-probe.d.ts +3 -7
  135. package/dist/lane-home-probe.js +0 -1
  136. package/dist/leader/leader.d.ts +2 -1
  137. package/dist/leg-facts.d.ts +13 -5
  138. package/dist/leg-facts.js +2 -1
  139. package/dist/memory-scope.d.ts +5 -4
  140. package/dist/memory-scope.js +4 -4
  141. package/dist/memory-sync-client.d.ts +30 -2
  142. package/dist/memory-sync-client.js +16 -9
  143. package/dist/observability/err-text.d.ts +7 -0
  144. package/dist/observability/err-text.js +5 -0
  145. package/dist/observability/fail-open.d.ts +7 -3
  146. package/dist/observability/fail-open.js +7 -3
  147. package/dist/observability/metrics.js +1 -0
  148. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  149. package/dist/orchestration/workflow-notify-journal.js +12 -1
  150. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  151. package/dist/orchestration/workflow-park-decision.js +49 -10
  152. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  153. package/dist/orchestration/workflow-park-holder.js +98 -0
  154. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  155. package/dist/orchestration/workflow-record-fence.js +42 -0
  156. package/dist/owner-faces.d.ts +1 -1
  157. package/dist/parked-decide.d.ts +104 -53
  158. package/dist/parked-decide.js +153 -117
  159. package/dist/peer-directory.d.ts +2 -2
  160. package/dist/peer-inbound-face.d.ts +2 -6
  161. package/dist/peer-inbound-face.js +0 -3
  162. package/dist/permission-mode-admission.d.ts +41 -5
  163. package/dist/permission-mode-admission.js +29 -3
  164. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  165. package/dist/plugins/adoption-log-sql.js +7 -1
  166. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  167. package/dist/plugins/approval-ask-store-file.js +8 -0
  168. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  169. package/dist/plugins/approval-ask-store-memory.js +28 -9
  170. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  171. package/dist/plugins/approval-ask-store-sql.js +34 -5
  172. package/dist/plugins/approval-exemption-store.js +3 -0
  173. package/dist/plugins/approval-nonce-store.js +2 -0
  174. package/dist/plugins/breaker-state-sql.js +2 -0
  175. package/dist/plugins/caching-session-store.d.ts +9 -15
  176. package/dist/plugins/caching-session-store.js +6 -0
  177. package/dist/plugins/device-store-sql.js +6 -0
  178. package/dist/plugins/error-origin.d.ts +18 -0
  179. package/dist/plugins/error-origin.js +10 -0
  180. package/dist/plugins/execution-placement-sql.js +6 -6
  181. package/dist/plugins/image-bake-store-sql.js +6 -0
  182. package/dist/plugins/image-index-sql.js +4 -0
  183. package/dist/plugins/landed-attendants.d.ts +212 -0
  184. package/dist/plugins/landed-attendants.js +161 -0
  185. package/dist/plugins/leader-run-store-sql.js +4 -0
  186. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  187. package/dist/plugins/local-session-live-reference.js +39 -0
  188. package/dist/plugins/local-session-store.d.ts +71 -33
  189. package/dist/plugins/local-session-store.js +129 -27
  190. package/dist/plugins/memory-engine-pg.js +4 -0
  191. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  192. package/dist/plugins/memory-engine-tidb.js +4 -0
  193. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  194. package/dist/plugins/memory-sync-store-pg.js +5 -0
  195. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  196. package/dist/plugins/one-time-migrations.d.ts +57 -63
  197. package/dist/plugins/one-time-migrations.js +162 -90
  198. package/dist/plugins/org-delivery-quota-store.js +4 -1
  199. package/dist/plugins/outcome-ledger-sql.js +2 -0
  200. package/dist/plugins/permission-rule-store-sql.js +11 -4
  201. package/dist/plugins/pg-cost-quota.js +4 -0
  202. package/dist/plugins/pg-pool.js +24 -1
  203. package/dist/plugins/pg-rate-limiter.js +2 -0
  204. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  205. package/dist/plugins/posix-shell-fs.js +4 -1
  206. package/dist/plugins/remote-env-adb.d.ts +19 -15
  207. package/dist/plugins/remote-env-adb.js +41 -15
  208. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  209. package/dist/plugins/remote-env-connect-seat.js +72 -0
  210. package/dist/plugins/remote-env-device.d.ts +22 -5
  211. package/dist/plugins/remote-env-device.js +106 -8
  212. package/dist/plugins/remote-env-e2b.d.ts +15 -6
  213. package/dist/plugins/remote-env-e2b.js +42 -32
  214. package/dist/plugins/remote-env-file-error.js +6 -2
  215. package/dist/plugins/remote-env-host.d.ts +17 -0
  216. package/dist/plugins/remote-env-host.js +30 -38
  217. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  218. package/dist/plugins/remote-env-k8s.js +53 -30
  219. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  220. package/dist/plugins/remote-env-local-docker.js +34 -41
  221. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  222. package/dist/plugins/remote-env-ssh.js +60 -59
  223. package/dist/plugins/remote-shell.d.ts +98 -1
  224. package/dist/plugins/remote-shell.js +218 -0
  225. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  226. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  227. package/dist/plugins/retention-lane-store-sql.js +4 -0
  228. package/dist/plugins/retention-sql.d.ts +20 -2
  229. package/dist/plugins/retention-sql.js +11 -0
  230. package/dist/plugins/run-store-sql.d.ts +21 -2
  231. package/dist/plugins/run-store-sql.js +31 -7
  232. package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
  233. package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
  234. package/dist/plugins/schema-consistency.d.ts +4 -2
  235. package/dist/plugins/schema-consistency.js +19 -2
  236. package/dist/plugins/send-file-ledger.js +3 -0
  237. package/dist/plugins/serving-requirement.d.ts +26 -7
  238. package/dist/plugins/serving-requirement.js +11 -4
  239. package/dist/plugins/session-birth.d.ts +6 -2
  240. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  241. package/dist/plugins/session-ext-table.d.ts +14 -1
  242. package/dist/plugins/session-ext-table.js +5 -1
  243. package/dist/plugins/session-row-sql.d.ts +49 -2
  244. package/dist/plugins/session-row-sql.js +56 -13
  245. package/dist/plugins/session-store-sql.d.ts +34 -18
  246. package/dist/plugins/session-store-sql.js +98 -17
  247. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  248. package/dist/plugins/shared-memory-store-sql.js +6 -2
  249. package/dist/plugins/sql-driver.d.ts +2 -1
  250. package/dist/plugins/sql-driver.js +18 -3
  251. package/dist/plugins/sql-errors.d.ts +11 -6
  252. package/dist/plugins/sql-errors.js +5 -6
  253. package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
  254. package/dist/plugins/stop-then-start-sentence.js +14 -10
  255. package/dist/plugins/stop-then-start.d.ts +109 -0
  256. package/dist/plugins/stop-then-start.js +104 -0
  257. package/dist/plugins/store-backend.d.ts +40 -13
  258. package/dist/plugins/store-backend.js +169 -27
  259. package/dist/plugins/store-boundary.d.ts +57 -0
  260. package/dist/plugins/store-boundary.js +139 -0
  261. package/dist/plugins/store-contracts.d.ts +17 -0
  262. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  263. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  264. package/dist/plugins/store-fault.d.ts +26 -7
  265. package/dist/plugins/store-fault.js +18 -2
  266. package/dist/plugins/task-attachment-store.js +9 -0
  267. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  268. package/dist/plugins/task-list-store-sql.js +10 -8
  269. package/dist/plugins/tidb-cost-quota.js +4 -0
  270. package/dist/plugins/tidb-pool.js +2 -1
  271. package/dist/plugins/tidb-rate-limiter.js +4 -0
  272. package/dist/plugins/user-input-ledger-sql.js +4 -0
  273. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  274. package/dist/plugins/workflow-run-store-sql.js +64 -4
  275. package/dist/plugins/workspace-fill.d.ts +4 -7
  276. package/dist/plugins/workspace-fill.js +2 -1
  277. package/dist/plugins/write-behind-counter.js +5 -0
  278. package/dist/project-context.d.ts +0 -2
  279. package/dist/project-context.js +4 -8
  280. package/dist/project-registry.d.ts +46 -0
  281. package/dist/project-registry.js +44 -0
  282. package/dist/request-key-closure.js +1 -1
  283. package/dist/request-value-closure.d.ts +4 -0
  284. package/dist/request-value-closure.js +10 -0
  285. package/dist/run-acceptance.d.ts +3 -2
  286. package/dist/run-acceptance.js +4 -6
  287. package/dist/run-local.js +1 -0
  288. package/dist/runs.d.ts +37 -8
  289. package/dist/runs.js +53 -12
  290. package/dist/runtime-governance.d.ts +5 -4
  291. package/dist/security.d.ts +30 -32
  292. package/dist/security.js +41 -7
  293. package/dist/server-secret-env.d.ts +12 -10
  294. package/dist/server-secret-env.js +24 -15
  295. package/dist/session-bindings.d.ts +82 -0
  296. package/dist/session-bindings.js +18 -0
  297. package/dist/session-children-retire.d.ts +2 -2
  298. package/dist/session-children-retire.js +2 -6
  299. package/dist/session-deletion.d.ts +16 -1
  300. package/dist/session-error-wire.d.ts +3 -3
  301. package/dist/session-error-wire.js +3 -3
  302. package/dist/session-incarnation.d.ts +10 -0
  303. package/dist/session-incarnation.js +10 -1
  304. package/dist/session-kind.d.ts +57 -0
  305. package/dist/session-kind.js +22 -0
  306. package/dist/session-row.d.ts +21 -1
  307. package/dist/session-row.js +7 -1
  308. package/dist/session-sync-kernel.d.ts +24 -14
  309. package/dist/session-sync-kernel.js +3 -6
  310. package/dist/session-sync.d.ts +4 -98
  311. package/dist/session-sync.js +1 -71
  312. package/dist/session-titler.d.ts +10 -3
  313. package/dist/session-titler.js +19 -6
  314. package/dist/ssh-host-key.d.ts +5 -0
  315. package/dist/ssh-host-key.js +3 -0
  316. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  317. package/dist/stores-sql/file-history-store-sql.js +108 -70
  318. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  319. package/dist/stores-sql/pg-session-storage.js +37 -13
  320. package/dist/stores-sql/retention-store-sql.d.ts +1 -9
  321. package/dist/stores-sql/retention-store-sql.js +2 -10
  322. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  323. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  324. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  325. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  326. package/dist/stores-sql/tidb-session-store.js +37 -13
  327. package/dist/submission-exit.d.ts +3 -2
  328. package/dist/submission-exit.js +9 -1
  329. package/dist/task-cwd.d.ts +2 -2
  330. package/dist/task-settings.d.ts +6 -5
  331. package/dist/terminal.d.ts +33 -2
  332. package/dist/terminal.js +139 -9
  333. package/dist/tool-approval.d.ts +140 -6
  334. package/dist/tool-approval.js +165 -72
  335. package/dist/trace/self-minted-wire.d.ts +290 -27
  336. package/dist/trace/self-minted-wire.js +101 -13
  337. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +78 -27
  338. package/package.json +2 -2
  339. package/wire-changes/server@7.151.0.json +762 -0
  340. package/dist/http/session-inherit-env.d.ts +0 -36
  341. package/dist/http/session-inherit-env.js +0 -6
@@ -3,11 +3,12 @@ import { Runner, InMemoryToolResultStore, TtlSessionStore, uuidv7, createAllowDe
3
3
  import { createEngineSessionRulesSeat } from "../session-rules-seat.js";
4
4
  import { outwardPlane } from "../terminal.js";
5
5
  import { createSessionTitler } from "../session-titler.js";
6
+ import { sessionOccupantReadOf } from "../http/owner-access.js";
6
7
  import { cardRuleScopeRoot } from "../task-cwd.js";
7
8
  import { ForkRoutingSessionStore } from "../plugins/fork-routing-session-store.js";
8
9
  import { withoutHands } from "../capabilities/hands-lane.js";
9
10
  import { isBrandedDeployment } from "../capabilities/brand-identity.js";
10
- import { hasServiceAuth } from "../identity-source.js";
11
+ import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
11
12
  import { workflowModelAllowlistFor } from "../task-workflow.js";
12
13
  import { createHookLlm, buildHookFailureText } from "../hooks/hook-llm.js";
13
14
  import { assertRetentionLaneWirable } from "./retention-lane.js";
@@ -26,16 +27,21 @@ import { createOrgMemoryAdmissionWiring } from "./org-memory.js";
26
27
  import { createGovernanceSeams } from "./governance-seams.js";
27
28
  import { createSharedMemoryScopeAuthorizer } from "../shared-memory-scope-authorizer.js";
28
29
  import { mountOrgDeliveryGate } from "./org-delivery.js";
29
- import { parkedAskRedeem, runStore } from "./late-binds.js";
30
+ import { parkedAskRedeem, runEndedHandoff, runStore } from "./late-binds.js";
31
+ import { createWorkflowParkHolderPull } from "../orchestration/workflow-park-holder.js";
30
32
  import { withInternalRunEnvs } from "../internal-run-env.js";
31
33
  import { retentionSweepRuns } from "../plugins/retention-declaration.js";
32
34
  import { createOperatorFaceIncidentSink } from "../memory-incident-sink.js";
33
35
  export async function runStage06(ctx) {
34
36
  const { backend, backgroundAgentStore, brain, engineDataRoot, peerDesk, config, webAdmin, consolidationValve, deploymentMods, executionEnvFactory, fileHistoryStore, localRoot, logger, lspManager, mailboxRecipientLifecycle, mailboxStore, memoryEngine, memorySyncRunner, metrics, perSessionCwd, permissionRuleProvider, pricing, rosterStore, ruleConsent, sendUserFileTaskEnvs, sessionCaptureRecords, sessionPolicyStore, sessionStore, spaceReclaimer, taskAttachmentStore, taskListLane, toolResultStore, tracer, usageWindowStore } = ctx;
35
- const { sqlWorkflowRunStore, workflowNotifyJournal, workflowCompletionInbox, deliverWorkflowCompletion, workflowNotifyGate, fleetBus, workflowRunStore, workflowJournalStore, outcomeSink, workflowRecoverOpts, workflowAgentRegistry, subagentSteerRegistry, workflowAgentSessionIndex, workflowParkDecisions, } = createWorkflowOrchestration({ config, logger, metrics, localRoot, backend, getRunStore: () => runStore });
37
+ const { sqlWorkflowRunStore, workflowNotifyJournal, workflowCompletionInbox, deliverWorkflowCompletion, workflowNotifyGate, fleetBus, workflowRunStore, workflowJournalStore, outcomeSink, workflowRecoverOpts, workflowAgentRegistry, subagentSteerRegistry, workflowAgentSessionIndex, workflowParkDecisions, heldParksHere, } = createWorkflowOrchestration({ config, logger, metrics, localRoot, backend, getRunStore: () => runStore, getRunEndedHandoff: () => runEndedHandoff });
38
+ backend?.bindWorkflowRunReader?.(workflowRunStore ?? "none");
36
39
  const parkCommitted = backend?.checkpoint && config.durableApproval ? createParkCommitWatch(backend.checkpoint(logger)) : undefined;
37
40
  const checkpointStore = parkCommitted?.store;
38
41
  const parkCommits = parkCommitted?.watch;
42
+ const workflowParkHolderPull = heldParksHere !== undefined && workflowParkDecisions !== undefined && workflowAgentSessionIndex !== undefined && workflowRunStore !== undefined && checkpointStore !== undefined
43
+ ? createWorkflowParkHolderPull({ held: heldParksHere, decisions: workflowParkDecisions, checkpointStore, workflowAgentSessionIndex, workflowRunStore, warn: (event, fields) => logger.warn(event, fields) })
44
+ : undefined;
39
45
  const checkpointCtxSealing = webAdmin.checkpointCtxSealing;
40
46
  if (checkpointStore !== undefined) {
41
47
  if (checkpointCtxSealing === undefined)
@@ -115,7 +121,7 @@ export async function runStage06(ctx) {
115
121
  : undefined;
116
122
  for (const w of buildConsolidationValveAudit({
117
123
  valve: consolidationValve,
118
- hasServiceAuth: hasServiceAuth(config),
124
+ credentialGateSource: DEPLOYMENT_SHAPE_PREDICATES.credentialGateSource.holds(config),
119
125
  allowUnauthedWrites: config.allowUnauthedWrites ?? false,
120
126
  }).warnings) {
121
127
  logger.warn(w.tag, { detail: w.detail });
@@ -186,9 +192,11 @@ export async function runStage06(ctx) {
186
192
  };
187
193
  const clipHookErr = (s) => (s ?? "").slice(0, 300);
188
194
  const titleCapable = sessionStore;
189
- const sessionTitler = config.sessionAutoTitle && titleCapable.setTitleIfNull && titleCapable.probeTitle
195
+ const titleOccupantOf = sessionOccupantReadOf(sessionStore);
196
+ const sessionTitler = config.sessionAutoTitle && titleCapable.setTitleIfNull && titleCapable.probeTitle && titleOccupantOf
190
197
  ? createSessionTitler({
191
198
  setTitleIfNull: titleCapable.setTitleIfNull.bind(sessionStore),
199
+ occupantOf: titleOccupantOf,
192
200
  probeTitle: titleCapable.probeTitle.bind(sessionStore),
193
201
  llm: hookLlm,
194
202
  logger,
@@ -226,6 +234,7 @@ export async function runStage06(ctx) {
226
234
  sharedMemoryStores: sharedMemoryStore ? sharedMemoryStore : undefined,
227
235
  engineDataRoot,
228
236
  peerDesk,
237
+ runtimeCapsResolver,
229
238
  }),
230
239
  sessionStore: subRunnerSessions,
231
240
  onBackgroundChildEvent: runnerDeps.onBackgroundChildEvent ? runnerDeps.onBackgroundChildEvent : undefined,
@@ -235,6 +244,6 @@ export async function runStage06(ctx) {
235
244
  };
236
245
  const subRunner = new Runner(subRunnerDeps);
237
246
  const settleErasedSessions = createSessionEraseSettler({ attachments: taskAttachmentStore, spaceReclaimer, logger });
238
- return { ...ctx, sessionEraser, settleErasedSessions, approvalAskAudit, approvalExemptionStore, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, durableEnabled, elicitation, fleetBus, governanceSeams, handslessRunner, hookAgent, hookAgentRunner, hookLlm, mcpRevocations, memoryConsolidationFaces, memoryOptOutGrantStore, orgMemoryAdmission, outcomeSink, principalCaps, question, retentionExecutor, retentionLaneStore, runner, runnerDeps, runtimeCapsPeekReading, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionTitler, sharedMemoryStore, sqlWorkflowRunStore, streamApprovalGate, subRunner, subagentSteerRegistry, toolApproval, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowParkDecisions, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate };
247
+ return { ...ctx, sessionEraser, settleErasedSessions, approvalAskAudit, approvalExemptionStore, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, durableEnabled, elicitation, fleetBus, governanceSeams, handslessRunner, hookAgent, hookAgentRunner, hookLlm, mcpRevocations, memoryConsolidationFaces, memoryOptOutGrantStore, orgMemoryAdmission, outcomeSink, principalCaps, question, retentionExecutor, retentionLaneStore, runner, runnerDeps, runtimeCapsPeekReading, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionTitler, sharedMemoryStore, sqlWorkflowRunStore, streamApprovalGate, subRunner, subagentSteerRegistry, toolApproval, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowParkDecisions, workflowParkHolderPull, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate };
239
248
  }
240
249
  //# sourceMappingURL=stage-06-runners.js.map
@@ -56,7 +56,7 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
56
56
  sendUserFileToolSpec: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
57
57
  sessionTitler: import("../session-titler.js").SessionTitler | undefined;
58
58
  sharedMemoryStore: import("../plugins/shared-memory-store-sql.js").SqlSharedMemoryStore | undefined;
59
- sqlWorkflowRunStore: import("@sema-agent/core").WorkflowRunStore | undefined;
59
+ sqlWorkflowRunStore: import("../plugins/workflow-run-store-sql.js").SqlWorkflowRunStore | undefined;
60
60
  streamApprovalGate: import("../tool-approval.js").StreamApprovalGate<import("../approval-gate-currency.js").GateCurrencyStore>;
61
61
  subRunner: import("@sema-agent/core").Runner;
62
62
  subagentSteerRegistry: import("../orchestration/subagent-steer.js").SubagentSteerRegistry;
@@ -67,6 +67,7 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
67
67
  workflowJournalStore: import("../plugins/store-backend.js").ServiceWorkflowJournalStore | undefined;
68
68
  workflowModelAllowlistSnapshot: readonly string[];
69
69
  workflowParkDecisions: import("../orchestration/workflow-park-decision.js").WorkflowParkDecisionStore | undefined;
70
+ workflowParkHolderPull: (() => Promise<import("../orchestration/workflow-park-holder.js").HolderPullTally>) | undefined;
70
71
  workflowNotifyGate: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyGate | undefined;
71
72
  workflowNotifyJournal: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyJournalStore | undefined;
72
73
  workflowRecoverOpts: {
@@ -95,10 +96,12 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
95
96
  perSessionCwd: Map<string, string>;
96
97
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
97
98
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
99
+ sessionBindings: {
100
+ commitSessionBindings: (sessionId: string, bindings: import("../session-bindings.js").SessionBindings) => import("../session-bindings.js").SessionBindingReceipt;
101
+ withdrawSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
102
+ settleSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
103
+ };
98
104
  sessionEnvSelection: import("../capabilities/select-environment-tool.js").SessionEnvironmentSelection;
99
- setSessionCwd: (sid: string, cwd: string) => void;
100
- setSessionInheritEnv: (sid: string, policy: import("../request-value-closure.js").TaskInheritEnv | undefined) => void;
101
- setSessionShellEnv: (sid: string, env: Record<string, string>) => void;
102
105
  worktreeReap: (() => Promise<void>) | undefined;
103
106
  brain: import("@sema-agent/core").Brain;
104
107
  consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
@@ -33,6 +33,7 @@ import { buildDisplaySafeUrl } from "../trace/redact.js";
33
33
  import * as facts from "../capability-facts.js";
34
34
  import { WEB_ADMIN_ENV } from "@sema-agent/settings-schema";
35
35
  import { seatText } from "../trace/exit-seat.js";
36
+ import { hasServiceAuth } from "../identity-source.js";
36
37
  export async function runStage07(ctx) {
37
38
  const { approvalAskAudit, approvalExemptionStore, backend, backgroundAgentStore, brain, checkpointStore, config, webAdmin, counterDegradeHook, peerDesk, durableEnabled, instanceId, localRoot, logger, question, runner, runnerDeps, sendUserFileToolSpec, sessionEnvSelection, sessionStore, subRunner, taskListLane, toolApproval } = ctx;
38
39
  const authorize = createAuthorizer(config, sessionStore, logger);
@@ -149,7 +150,7 @@ export async function runStage07(ctx) {
149
150
  if (inert)
150
151
  logger.warn(inert.event, inert.fields);
151
152
  }
152
- if (config.requirePrincipal && !config.authToken && Object.keys(config.authTokens ?? {}).length === 0 && !config.traceToken)
153
+ if (config.requirePrincipal && !hasServiceAuth(config) && !config.traceToken)
153
154
  logger.warn("multi_tenant_no_service_token", { detail: "REQUIRE_PRINCIPAL is on but no SERVICE_AUTH_TOKEN/authTokens/TRACE_TOKEN — fleet/trace/session-list are owner-gated only (never fleet-wide, tenant-isolation safe). Set a token for cross-tenant ops visibility." });
154
155
  const rateLimiter = backend?.rateLimiter
155
156
  ? backend.rateLimiter(config.rateLimitPerMin, counterDegradeHook).startRefresh()
@@ -69,7 +69,7 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
69
69
  sendUserFileToolSpec: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
70
70
  sessionTitler: import("../session-titler.js").SessionTitler | undefined;
71
71
  sharedMemoryStore: import("../plugins/shared-memory-store-sql.js").SqlSharedMemoryStore | undefined;
72
- sqlWorkflowRunStore: import("@sema-agent/core").WorkflowRunStore | undefined;
72
+ sqlWorkflowRunStore: import("../plugins/workflow-run-store-sql.js").SqlWorkflowRunStore | undefined;
73
73
  streamApprovalGate: import("../tool-approval.js").StreamApprovalGate<import("../approval-gate-currency.js").GateCurrencyStore>;
74
74
  subRunner: Runner;
75
75
  subagentSteerRegistry: import("../orchestration/subagent-steer.js").SubagentSteerRegistry;
@@ -80,6 +80,7 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
80
80
  workflowJournalStore: import("../plugins/store-backend.js").ServiceWorkflowJournalStore | undefined;
81
81
  workflowModelAllowlistSnapshot: readonly string[];
82
82
  workflowParkDecisions: import("../orchestration/workflow-park-decision.js").WorkflowParkDecisionStore | undefined;
83
+ workflowParkHolderPull: (() => Promise<import("../orchestration/workflow-park-holder.js").HolderPullTally>) | undefined;
83
84
  workflowNotifyGate: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyGate | undefined;
84
85
  workflowNotifyJournal: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyJournalStore | undefined;
85
86
  workflowRecoverOpts: {
@@ -108,10 +109,12 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
108
109
  perSessionCwd: Map<string, string>;
109
110
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
110
111
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
112
+ sessionBindings: {
113
+ commitSessionBindings: (sessionId: string, bindings: import("../session-bindings.js").SessionBindings) => import("../session-bindings.js").SessionBindingReceipt;
114
+ withdrawSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
115
+ settleSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
116
+ };
111
117
  sessionEnvSelection: import("../capabilities/select-environment-tool.js").SessionEnvironmentSelection;
112
- setSessionCwd: (sid: string, cwd: string) => void;
113
- setSessionInheritEnv: (sid: string, policy: import("../request-value-closure.js").TaskInheritEnv | undefined) => void;
114
- setSessionShellEnv: (sid: string, env: Record<string, string>) => void;
115
118
  worktreeReap: (() => Promise<void>) | undefined;
116
119
  brain: import("@sema-agent/core").Brain;
117
120
  consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
@@ -3,10 +3,10 @@ import { startOtlpExporter } from "../observability/otel-exporter.js";
3
3
  import { startReapers } from "./reapers.js";
4
4
  import { startRetentionLane, RETENTION_LEASE_TTL_FACTOR } from "./retention-lane.js";
5
5
  import { createLimitSync } from "./limit-sync.js";
6
- import { runDenySweep } from "./late-binds.js";
6
+ import { runDenySweep, sessionAgeOut } from "./late-binds.js";
7
7
  import { seatText } from "../trace/exit-seat.js";
8
8
  export function runStage08(ctx) {
9
- const { approvalAskAudit, approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, parkCommits, config, webAdmin, consolidationSeatWatch, costQuota, degradeRouteWatch, fileHistoryErasure, settleErasedSessions, sandboxReaper, handslessRunner, hookAgentRunner, imageBakes, instanceId, localRoot, logger, mailboxStore, metrics, permissionRuleStores, pricing, rateLimiter, retentionExecutor, retentionLaneStore, runStore, runner, sqlWorkflowRunStore, storeSweep, subRunner, taskAttachmentStore, toolApproval, userInputLedger, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, worktreeReap } = ctx;
9
+ const { approvalAskAudit, approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, parkCommits, config, webAdmin, consolidationSeatWatch, costQuota, degradeRouteWatch, fileHistoryErasure, settleErasedSessions, sandboxReaper, handslessRunner, hookAgentRunner, imageBakes, instanceId, localRoot, logger, mailboxStore, metrics, permissionRuleStores, pricing, rateLimiter, retentionExecutor, retentionLaneStore, runStore, runner, sqlWorkflowRunStore, storeSweep, subRunner, taskAttachmentStore, toolApproval, userInputLedger, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, worktreeReap, workflowParkHolderPull } = ctx;
10
10
  const reaper = startReapers({
11
11
  config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, parkCommits,
12
12
  rateLimiter, costQuota, storeSweep, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap,
@@ -14,6 +14,8 @@ export function runStage08(ctx) {
14
14
  backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore, userInputLedger, approvalAskAudit,
15
15
  ...(sandboxReaper !== undefined ? { sandboxReaper } : {}),
16
16
  getRunDenySweep: () => runDenySweep,
17
+ getSessionAgeOut: () => sessionAgeOut,
18
+ ...(workflowParkHolderPull !== undefined ? { workflowParkHolderPull } : {}),
17
19
  });
18
20
  const ttlMs = config.retentionSweep.intervalSec * 1000 * RETENTION_LEASE_TTL_FACTOR;
19
21
  const retentionLaneStarted = retentionExecutor !== undefined && retentionLaneStore !== undefined && config.retentionPolicy !== undefined
@@ -9,9 +9,12 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
9
9
  leaderEndpoint: import("../leader/endpoint.js").LeaderEndpoint | undefined;
10
10
  ownerAware: import("../security.js").OwnerAwareSessionStore;
11
11
  planCacheProbe: import("../plan-cache-probe.js").PlanCacheProbe;
12
- purgeSession: ((sessionId: string, owner: string | null) => Promise<import("../session-deletion.js").SessionPurgeOutcome>) | undefined;
12
+ purgeSession: ((sessionId: string, owner: string | null, opts?: {
13
+ readonly ageOut?: import("../session-deletion.js").SessionAgeOutExpectation;
14
+ }) => Promise<import("../session-deletion.js").SessionPurgeOutcome>) | undefined;
13
15
  webAdminJwtVerifier: import("../auth-bridge.js").WebAdminJwtVerifier | undefined;
14
16
  sessionAudit: ((sessionId: string, opts?: import("../audit.js").SessionAuditReadOpts) => Promise<{
17
+ sessionKind?: "sidechain" | undefined;
15
18
  projectId?: string | undefined;
16
19
  agent?: import("../session-agent.js").SessionAgent | undefined;
17
20
  owner: string | null;
@@ -88,7 +91,7 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
88
91
  sendUserFileToolSpec: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
89
92
  sessionTitler: import("../session-titler.js").SessionTitler | undefined;
90
93
  sharedMemoryStore: import("../plugins/shared-memory-store-sql.js").SqlSharedMemoryStore | undefined;
91
- sqlWorkflowRunStore: import("@sema-agent/core").WorkflowRunStore | undefined;
94
+ sqlWorkflowRunStore: import("../plugins/workflow-run-store-sql.js").SqlWorkflowRunStore | undefined;
92
95
  streamApprovalGate: import("../tool-approval.js").StreamApprovalGate<import("../approval-gate-currency.js").GateCurrencyStore>;
93
96
  subRunner: import("@sema-agent/core").Runner;
94
97
  subagentSteerRegistry: import("../orchestration/subagent-steer.js").SubagentSteerRegistry;
@@ -99,6 +102,7 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
99
102
  workflowJournalStore: import("../plugins/store-backend.js").ServiceWorkflowJournalStore | undefined;
100
103
  workflowModelAllowlistSnapshot: readonly string[];
101
104
  workflowParkDecisions: import("../orchestration/workflow-park-decision.js").WorkflowParkDecisionStore | undefined;
105
+ workflowParkHolderPull: (() => Promise<import("../orchestration/workflow-park-holder.js").HolderPullTally>) | undefined;
102
106
  workflowNotifyGate: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyGate | undefined;
103
107
  workflowNotifyJournal: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyJournalStore | undefined;
104
108
  workflowRecoverOpts: {
@@ -127,10 +131,12 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
127
131
  perSessionCwd: Map<string, string>;
128
132
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
129
133
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
134
+ sessionBindings: {
135
+ commitSessionBindings: (sessionId: string, bindings: import("../session-bindings.js").SessionBindings) => import("../session-bindings.js").SessionBindingReceipt;
136
+ withdrawSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
137
+ settleSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
138
+ };
130
139
  sessionEnvSelection: import("../capabilities/select-environment-tool.js").SessionEnvironmentSelection;
131
- setSessionCwd: (sid: string, cwd: string) => void;
132
- setSessionInheritEnv: (sid: string, policy: import("../request-value-closure.js").TaskInheritEnv | undefined) => void;
133
- setSessionShellEnv: (sid: string, env: Record<string, string>) => void;
134
140
  worktreeReap: (() => Promise<void>) | undefined;
135
141
  brain: import("@sema-agent/core").Brain;
136
142
  consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
@@ -1,8 +1,11 @@
1
1
  import { describeStaticWiring } from "@sema-agent/core";
2
2
  import { encodeCheckpointScope } from "../security.js";
3
- import { createWebAdminJwtVerifier } from "../auth-bridge.js";
3
+ import { createWebAdminJwtVerifier, ssoBoundScopeOf } from "../auth-bridge.js";
4
4
  import { authBridgeIssuerOf } from "../identity-source.js";
5
5
  import { createSessionFaces } from "./session-faces.js";
6
+ import { createSessionAgeOut } from "./session-age-out.js";
7
+ import { bindSessionAgeOut } from "./late-binds.js";
8
+ import * as facts from "../capability-facts.js";
6
9
  import { createLeaderFace } from "./leader.js";
7
10
  import { assertStaticWiringConsistent } from "../http/routes/diagnostics.js";
8
11
  import { seatText } from "../trace/exit-seat.js";
@@ -24,6 +27,10 @@ export function runStage09(ctx) {
24
27
  if (recoverPendingDeletions !== undefined) {
25
28
  void recoverPendingDeletions().catch((err) => logger.warn("session_delete_recovery_unfinished", { outcome: "pending_unreadable", err: seatText("operator-log-text", String(err)), effect: "sessions left in the deleting state by an earlier process stay so (they read as gone); the next start or a repeated DELETE finishes them" }));
26
29
  }
30
+ const ageOutStore = ownerAware.listIdleOfKind !== undefined ? { listIdleOfKind: ownerAware.listIdleOfKind.bind(ownerAware) } : undefined;
31
+ bindSessionAgeOut(purgeSession !== undefined && ageOutStore !== undefined && facts.sessionKinds({ sessionStorage: ownerAware, purgeSession }).available
32
+ ? createSessionAgeOut({ store: ageOutStore, purge: purgeSession, retentionMs: () => config.backgroundAgentRetentionMs, logger, metrics })
33
+ : undefined);
27
34
  const leaderEndpoint = createLeaderFace({ config, logger, brain, pricing, executionEnvFactory, toolResultStore, sessionStore, checkpointStore, checkpointCtxSealing, governanceSeams, backend, tracer, usageWindowStore, promptSource: webAdmin.promptSource, onError: runnerDeps.onError, deploymentMods });
28
35
  const drainState = { draining: false };
29
36
  const authBridgeIssuer = authBridgeIssuerOf(config)?.issuer;
@@ -36,8 +43,10 @@ export function runStage09(ctx) {
36
43
  metrics,
37
44
  })
38
45
  : undefined;
39
- if (webAdminJwtVerifier)
40
- logger.info("auth_bridge_enabled", { issuer: buildDisplaySafeUrl(authBridgeIssuer ?? "") });
46
+ if (webAdminJwtVerifier) {
47
+ const boundScope = ssoBoundScopeOf(config);
48
+ logger.info("auth_bridge_enabled", { issuer: buildDisplaySafeUrl(authBridgeIssuer ?? ""), scopeAdmission: boundScope === undefined ? { judged: false } : { judged: true, scope: boundScope } });
49
+ }
41
50
  const hookWakeBus = {};
42
51
  const wiringSpecTemplate = durableEnabled
43
52
  ? { checkpointStore, durableApproval: { scope: encodeCheckpointScope(undefined) } }
@@ -40,9 +40,12 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
40
40
  leaderEndpoint: import("../leader/endpoint.js").LeaderEndpoint | undefined;
41
41
  ownerAware: import("../security.js").OwnerAwareSessionStore;
42
42
  planCacheProbe: import("../plan-cache-probe.js").PlanCacheProbe;
43
- purgeSession: ((sessionId: string, owner: string | null) => Promise<import("../session-deletion.js").SessionPurgeOutcome>) | undefined;
43
+ purgeSession: ((sessionId: string, owner: string | null, opts?: {
44
+ readonly ageOut?: import("../session-deletion.js").SessionAgeOutExpectation;
45
+ }) => Promise<import("../session-deletion.js").SessionPurgeOutcome>) | undefined;
44
46
  webAdminJwtVerifier: import("../auth-bridge.js").WebAdminJwtVerifier | undefined;
45
47
  sessionAudit: ((sessionId: string, opts?: import("../audit.js").SessionAuditReadOpts) => Promise<{
48
+ sessionKind?: "sidechain" | undefined;
46
49
  projectId?: string | undefined;
47
50
  agent?: import("../session-agent.js").SessionAgent | undefined;
48
51
  owner: string | null;
@@ -119,7 +122,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
119
122
  sendUserFileToolSpec: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
120
123
  sessionTitler: import("../session-titler.js").SessionTitler | undefined;
121
124
  sharedMemoryStore: import("../plugins/shared-memory-store-sql.js").SqlSharedMemoryStore | undefined;
122
- sqlWorkflowRunStore: import("@sema-agent/core").WorkflowRunStore | undefined;
125
+ sqlWorkflowRunStore: import("../plugins/workflow-run-store-sql.js").SqlWorkflowRunStore | undefined;
123
126
  streamApprovalGate: import("../tool-approval.js").StreamApprovalGate<import("../approval-gate-currency.js").GateCurrencyStore>;
124
127
  subRunner: import("@sema-agent/core").Runner;
125
128
  subagentSteerRegistry: import("../orchestration/subagent-steer.js").SubagentSteerRegistry;
@@ -130,6 +133,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
130
133
  workflowJournalStore: import("../plugins/store-backend.js").ServiceWorkflowJournalStore | undefined;
131
134
  workflowModelAllowlistSnapshot: readonly string[];
132
135
  workflowParkDecisions: import("../orchestration/workflow-park-decision.js").WorkflowParkDecisionStore | undefined;
136
+ workflowParkHolderPull: (() => Promise<import("../orchestration/workflow-park-holder.js").HolderPullTally>) | undefined;
133
137
  workflowNotifyGate: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyGate | undefined;
134
138
  workflowNotifyJournal: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyJournalStore | undefined;
135
139
  workflowRecoverOpts: {
@@ -158,10 +162,12 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
158
162
  perSessionCwd: Map<string, string>;
159
163
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
160
164
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
165
+ sessionBindings: {
166
+ commitSessionBindings: (sessionId: string, bindings: import("../session-bindings.js").SessionBindings) => import("../session-bindings.js").SessionBindingReceipt;
167
+ withdrawSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
168
+ settleSessionBindings: (receipt: import("../session-bindings.js").SessionBindingReceipt) => boolean;
169
+ };
161
170
  sessionEnvSelection: import("../capabilities/select-environment-tool.js").SessionEnvironmentSelection;
162
- setSessionCwd: (sid: string, cwd: string) => void;
163
- setSessionInheritEnv: (sid: string, policy: import("../request-value-closure.js").TaskInheritEnv | undefined) => void;
164
- setSessionShellEnv: (sid: string, env: Record<string, string>) => void;
165
171
  worktreeReap: (() => Promise<void>) | undefined;
166
172
  brain: import("@sema-agent/core").Brain;
167
173
  consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
@@ -35,17 +35,14 @@ function exactListeningLine(line) {
35
35
  return line;
36
36
  }
37
37
  export async function runStage10(ctx) {
38
- const { peerDesk, approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, config, webAdmin, consolidationValve, costQuota, belowTaskChainPatterns, deploymentMods, deploymentModsLoaded, deviceLane, drainState, dropSessionScopedOf, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, loadedSkills, localRoot, logger, lspManager, mcpRevocations, sandboxCapacity, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportStores, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, memorySyncRunner, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveSurface, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, webAdminJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekReading, sandboxGitPlane, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionInheritEnv, setSessionShellEnv, sessionResidentBackground, sharedMemoryStore, sideQueryAccounting, sqlEngine, sqlWorkflowRunStore, staticWiring, storePosture, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, userInputLedger, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowParkDecisions, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate } = ctx;
38
+ const { peerDesk, approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, config, webAdmin, consolidationValve, costQuota, belowTaskChainPatterns, deploymentMods, deploymentModsLoaded, deviceLane, drainState, dropSessionScopedOf, durableEnabled, elicitation, fenceSessionOwner, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, loadedSkills, localRoot, logger, lspManager, mcpRevocations, sandboxCapacity, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportStores, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, memorySyncRunner, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveSurface, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, webAdminJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekReading, sandboxGitPlane, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionTitler, sessionWatchRegistry, sessionBindings, sessionResidentBackground, sharedMemoryStore, sideQueryAccounting, sqlEngine, sqlWorkflowRunStore, staticWiring, storePosture, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, userInputLedger, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowParkDecisions, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate } = ctx;
39
39
  const stores = {
40
40
  runStore,
41
- resumeAnchorStore: resumeAnchorStore ? resumeAnchorStore : undefined,
42
41
  approvalExemptionStore: approvalExemptionStore ? approvalExemptionStore : undefined,
43
42
  approvalNonceStore: approvalNonceStore ? approvalNonceStore : undefined,
44
43
  checkpointStore,
45
44
  checkpointCtxSealing,
46
- sessionPolicyStore: sessionPolicyStore ? sessionPolicyStore : undefined,
47
45
  ruleConsent,
48
- fileHistoryStore: fileHistoryStore ? fileHistoryStore : undefined,
49
46
  toolResultStore,
50
47
  taskAttachmentStore: taskAttachmentStore ? taskAttachmentStore : undefined,
51
48
  backgroundAgentStore: backgroundAgentStore ? backgroundAgentStore : undefined,
@@ -88,7 +85,7 @@ export async function runStage10(ctx) {
88
85
  sessionAudit,
89
86
  routeJudgeBrain: brain,
90
87
  purgeSession: purgeSession ? purgeSession : undefined,
91
- bindSessionInheritEnv: config.remoteExec.provider === "host" ? setSessionInheritEnv : undefined,
88
+ sessionBindings,
92
89
  dropSessionScopedOf,
93
90
  subagentTaskOutput: (handle, access) => backgroundAgentOutput(defaultTaskRegistry, handle, access, backgroundAgentStore),
94
91
  taskHandleOutput: (handle, access) => taskHandleOutput(defaultTaskRegistry, handle, access, backgroundAgentStore),
@@ -214,7 +211,7 @@ export async function runStage10(ctx) {
214
211
  config, logger, metrics, localRoot, scenarios, loadedSkills, principalCaps, centerRuntimeCapsResolver,
215
212
  peerDesk,
216
213
  getKeyResolver: () => webAdmin.getKeyResolver(),
217
- taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner,
214
+ taskAttachmentStore, perSessionCwd, fenceSessionOwner,
218
215
  hookLlm, hookAgent, belowTaskChainPatterns, fleetBus, hookWakeBus, ownerAware, taskLimitCaps, taskTimeoutSec,
219
216
  historyAnchors: resumeAnchorStore && runStore ? { anchors: resumeAnchorStore, runs: runStore } : undefined,
220
217
  selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore,
@@ -13,7 +13,7 @@ import { centerScenarios, centerScenarioDetails } from "../capabilities/scenario
13
13
  import { isRosterGateArmed } from "../config.js";
14
14
  import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
15
15
  import { defaultLkgPath, defaultSkillCacheDir, saveLkg, loadLkg, preIdentityLkgLeftover, PRE_IDENTITY_LKG_REASON } from "../config-lkg.js";
16
- import { answerStillCurrent, centerStateBin, credentialIdentityNow, judgeCenterCredentialAtBoot } from "../center-credential.js";
16
+ import { answerStillCurrent, buildAssertionTokenBootFields, centerStateBin, credentialIdentityNow, judgeCenterCredentialAtBoot } from "../center-credential.js";
17
17
  import { createCenterConfigTier } from "../center-config-tier.js";
18
18
  import { buildCenterCredentialHealthView, createCenterCredentialRenewer } from "../center-credential-renewer.js";
19
19
  import { centerManagedConfigKeys } from "../web-admin-client/apply-effective.js";
@@ -103,6 +103,8 @@ export async function createWebAdminRuntime(ctx) {
103
103
  if (bootVerdict?.verdict === "loud") {
104
104
  logger.error("center_credential_unreadable", { key: WEB_ADMIN_ENV.tokenFile, failure: bootVerdict.failure, reason: bootVerdict.reason, effect: bootVerdict.effect });
105
105
  }
106
+ if (cc !== undefined)
107
+ logger.info("center_assertion_token", buildAssertionTokenBootFields(cc.assertionToken));
106
108
  const credentialRenewer = cc !== undefined && cc.credential.origin.from === "file"
107
109
  ? createCenterCredentialRenewer({ source: cc.credential, centerUrl: cc.baseUrl, leadMs: config.centerCredentialRenewLeadMs, logger })
108
110
  : undefined;
@@ -11,11 +11,12 @@
11
11
  * → `workflowRunStore`(包装体)的顺序是数据依赖链,不可重排。
12
12
  * 3. `getRunStore()` 是晚绑取值(runStore 在本段之后构造),原文靠同作用域前向引用。
13
13
  */
14
- import { type WorkflowRun, type WorkflowRunStore } from "@sema-agent/core";
14
+ import { type WorkflowRun } from "@sema-agent/core";
15
15
  import type { ServiceConfig } from "../config.js";
16
16
  import { FleetEventBus } from "../fleet/fleet-bus.js";
17
17
  import { type WorkflowAgentSessionIndex } from "../orchestration/workflow-agent-session-index.js";
18
18
  import type { WorkflowParkDecisionStore } from "../orchestration/workflow-park-decision.js";
19
+ import { HeldParksHere } from "../orchestration/workflow-park-holder.js";
19
20
  import type { Logger } from "../observability/logger.js";
20
21
  import type { Metrics } from "../observability/metrics.js";
21
22
  import { type WorkflowCompletionInbox } from "../orchestration/workflow-completion-inbox.js";
@@ -31,9 +32,12 @@ export interface WorkflowOrchestrationCtx {
31
32
  backend: StoreBackend | undefined;
32
33
  /** 晚绑(runStore 在本段之后构造)——见文件头「位置即契约」③。 */
33
34
  getRunStore: () => ReturnType<StoreBackend["run"]> | undefined;
35
+ /** 晚绑(HTTP 服务的产物,第 10 段之后才有):run 收场送达里把「带着已受理、未交付的决定收场」的那条 run 的行交给续跑车道的那一手。
36
+ * 抛 = 需要重投(会话正忙 / 店瞬态 / 收编弧在跑 / 本座还没绑)⇒ 不 ack、`recover` 在维护拍上重投。契约属主 = `http/resume-legs.ts` 的 `handOverRunEndedDecisions`。 */
37
+ getRunEndedHandoff: () => ((runId: string) => Promise<void>) | undefined;
34
38
  }
35
39
  export declare function createWorkflowOrchestration(ctx: WorkflowOrchestrationCtx): {
36
- sqlWorkflowRunStore: WorkflowRunStore | undefined;
40
+ sqlWorkflowRunStore: import("../plugins/workflow-run-store-sql.js").SqlWorkflowRunStore | undefined;
37
41
  workflowNotifyJournal: import("../orchestration/workflow-notify-journal.js").WorkflowNotifyJournalStore | undefined;
38
42
  workflowCompletionInbox: WorkflowCompletionInbox | undefined;
39
43
  deliverWorkflowCompletion: (p: WorkflowCompletionPayload) => Promise<void>;
@@ -51,5 +55,6 @@ export declare function createWorkflowOrchestration(ctx: WorkflowOrchestrationCt
51
55
  };
52
56
  workflowAgentSessionIndex: WorkflowAgentSessionIndex | undefined;
53
57
  workflowParkDecisions: WorkflowParkDecisionStore | undefined;
58
+ heldParksHere: HeldParksHere | undefined;
54
59
  };
55
60
  //# sourceMappingURL=workflow-orchestration.d.ts.map
@@ -2,6 +2,8 @@ import { FileWorkflowRunStore, InMemoryWorkflowRunStore } from "@sema-agent/core
2
2
  import { join } from "node:path";
3
3
  import { FleetEventBus } from "../fleet/fleet-bus.js";
4
4
  import { LocalWorkflowAgentSessionIndex } from "../orchestration/workflow-agent-session-index.js";
5
+ import { FencedWorkflowRecordStore } from "../orchestration/workflow-record-fence.js";
6
+ import { HeldParksHere } from "../orchestration/workflow-park-holder.js";
5
7
  import { createCorruptReadFailOpenSeat } from "../observability/corrupt-read-seat.js";
6
8
  import { FileWorkflowCompletionInbox, InMemoryWorkflowCompletionInbox, buildWorkflowCompleteInboxEntry, resolveCompletionRoute } from "../orchestration/workflow-completion-inbox.js";
7
9
  import { FileWorkflowNotifyJournalStore, JournalingWorkflowRunStore, WorkflowNotifyGate } from "../orchestration/workflow-notify-journal.js";
@@ -10,16 +12,16 @@ import { WorkflowAgentRegistry } from "../orchestration/workflow-agent-steer.js"
10
12
  import { workflowJournalOf } from "../plugins/store-backend.js";
11
13
  import { seatText } from "../trace/exit-seat.js";
12
14
  export function createWorkflowOrchestration(ctx) {
13
- const { config, logger, metrics, localRoot, backend, getRunStore } = ctx;
15
+ const { config, logger, metrics, localRoot, backend, getRunStore, getRunEndedHandoff } = ctx;
14
16
  const workflowBootAtMs = Date.now();
15
17
  const sqlWorkflowRunStore = config.workflowRunStoreBackend === "auto" ? backend?.workflowRun?.((msg, meta) => logger.warn(msg, meta)) : undefined;
16
18
  const baseWorkflowRunStore = config.selfOrchestrationEnabled
17
19
  ? config.workflowRunStoreBackend === "memory"
18
- ? new InMemoryWorkflowRunStore()
20
+ ? new FencedWorkflowRecordStore(new InMemoryWorkflowRunStore())
19
21
  : (sqlWorkflowRunStore ??
20
- new FileWorkflowRunStore(join(config.localDataRoot ?? localRoot, "workflows"), {
22
+ new FencedWorkflowRecordStore(new FileWorkflowRunStore(join(config.localDataRoot ?? localRoot, "workflows"), {
21
23
  onCorruptRead: createCorruptReadFailOpenSeat("server.workflow-run.corrupt-record-skipped"),
22
- }))
24
+ })))
23
25
  : undefined;
24
26
  const workflowNotifyJournal = config.selfOrchestrationEnabled && config.workflowRunStoreBackend !== "memory"
25
27
  ? (sqlWorkflowRunStore ? backend.notifyJournal() : new FileWorkflowNotifyJournalStore(join(config.localDataRoot ?? localRoot, "workflows"), undefined))
@@ -36,6 +38,20 @@ export function createWorkflowOrchestration(ctx) {
36
38
  ...(p.sourceTaskId ? { sourceTaskId: p.sourceTaskId } : {}),
37
39
  });
38
40
  metrics.inc("workflow_runs_total", { status: p.status });
41
+ if (workflowParkDecisions !== undefined) {
42
+ const handOver = getRunEndedHandoff();
43
+ try {
44
+ if (handOver === undefined)
45
+ throw new Error(`workflow run ${p.runId}: the run-ended decision handoff is not bound yet (the HTTP server is not up) — leaving the completion pending for the next recovery sweep`);
46
+ await handOver(p.runId);
47
+ }
48
+ catch (err) {
49
+ if (workflowNotifyGate !== undefined)
50
+ throw err;
51
+ metrics.inc("workflow_park_handoff_total", { result: "not_redelivered" });
52
+ logger.warn("workflow_park_handoff_not_redelivered", { runId: p.runId, err: seatText("operator-log-text", String(err)) });
53
+ }
54
+ }
39
55
  if (!workflowCompletionInbox)
40
56
  return;
41
57
  try {
@@ -61,9 +77,10 @@ export function createWorkflowOrchestration(ctx) {
61
77
  ? backend.workflowAgentSessionIndex()
62
78
  : new LocalWorkflowAgentSessionIndex(join(config.localDataRoot ?? localRoot, "workflows"), undefined))
63
79
  : undefined;
64
- const workflowParkDecisions = config.selfOrchestrationEnabled && backend !== undefined && (sqlWorkflowRunStore !== undefined || backend.kind === "local") ? backend.workflowParkDecisions?.() : undefined;
80
+ const workflowParkDecisions = config.selfOrchestrationEnabled && backend !== undefined && baseWorkflowRunStore !== undefined && (sqlWorkflowRunStore !== undefined || backend.kind === "local") ? backend.workflowParkDecisions?.(baseWorkflowRunStore) : undefined;
81
+ const heldParksHere = workflowParkDecisions !== undefined ? new HeldParksHere() : undefined;
65
82
  const workflowRunStore = baseWorkflowRunStore
66
- ? new JournalingWorkflowRunStore(baseWorkflowRunStore, workflowNotifyGate, fleetBus, workflowAgentSessionIndex)
83
+ ? new JournalingWorkflowRunStore(baseWorkflowRunStore, workflowNotifyGate, fleetBus, workflowAgentSessionIndex, heldParksHere)
67
84
  : undefined;
68
85
  const replicaLocalNotifyJournal = workflowNotifyJournal instanceof FileWorkflowNotifyJournalStore;
69
86
  const workflowRecoverOpts = {
@@ -78,7 +95,7 @@ export function createWorkflowOrchestration(ctx) {
78
95
  return {
79
96
  sqlWorkflowRunStore, workflowNotifyJournal, workflowCompletionInbox, deliverWorkflowCompletion,
80
97
  workflowNotifyGate, fleetBus, workflowRunStore, workflowJournalStore, outcomeSink,
81
- workflowAgentRegistry, subagentSteerRegistry, workflowRecoverOpts, workflowAgentSessionIndex, workflowParkDecisions,
98
+ workflowAgentRegistry, subagentSteerRegistry, workflowRecoverOpts, workflowAgentSessionIndex, workflowParkDecisions, heldParksHere,
82
99
  };
83
100
  }
84
101
  //# sourceMappingURL=workflow-orchestration.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * **维护拍上有界轮转扫一组候选**的唯一实现(两个调用方:审批族悬挂 ask 的跨副本执行通知 `ToolApprovalCoordinator.pollSuspendedDecisions`、
3
+ * workflow 停驻卡持有进程的拉取腿 `orchestration/workflow-park-holder.ts`)。
4
+ *
5
+ * 判据(审批族 codex R3 / R5 的两条修,原样搬来):
6
+ * · **帽**:每拍最多 `maxPerTick` 条;**预算**:每拍最多 `budgetMs` 墙钟,超了当场停(剩下的下拍接着扫)—— 串行点读在慢店上不许把「一拍的延迟」变成分钟级;
7
+ * · **轮转**:起点是「上一拍扫到第几个」的下一位 —— 没有它,帽把同样的前 N 条锁成永久前缀,后面的永远轮不到;
8
+ * · 游标是**整数偏移**,不是条目身份:上一拍最后碰的那条恰好消失时,按身份找位置会塌回队首(永久饥饿);偏移只回答「扫到第几个」,集合变了也只是近似。
9
+ * 多层(`tiers`):按层序扫,每层各一只游标;前一层吃满帽 / 预算,后一层这一拍轮不到。截断的那一拍由调用方响亮报(`truncated` / `backlog`)。
10
+ */
11
+ /** 一层候选的轮转游标(调用方持有,跨拍存活)。 */
12
+ export interface RotationCursor {
13
+ offset: number;
14
+ }
15
+ export interface RotationLimits {
16
+ readonly maxPerTick: number;
17
+ readonly budgetMs: number;
18
+ }
19
+ /** 一拍的读数:`visited` = 本拍真处理的条数;`backlog` = 还没轮到的(下界 0);`truncated` = 帽 / 预算截断位。 */
20
+ export interface RotationTally {
21
+ readonly visited: number;
22
+ readonly backlog: number;
23
+ readonly truncated: boolean;
24
+ }
25
+ export declare function boundedRotation<T>(tiers: ReadonlyArray<{
26
+ readonly items: readonly T[];
27
+ readonly cursor: RotationCursor;
28
+ }>, limits: RotationLimits, visit: (item: T) => Promise<void>, now?: () => number): Promise<RotationTally>;
29
+ //# sourceMappingURL=bounded-rotation.d.ts.map
@@ -0,0 +1,24 @@
1
+ export async function boundedRotation(tiers, limits, visit, now = Date.now) {
2
+ const ordered = [];
3
+ tiers.forEach(({ items, cursor }, tier) => {
4
+ const start = items.length > 0 ? cursor.offset % items.length : 0;
5
+ for (const item of [...items.slice(start), ...items.slice(0, start)])
6
+ ordered.push({ item, tier, start });
7
+ });
8
+ const deadlineMs = now() + limits.budgetMs;
9
+ const visitedPerTier = tiers.map(() => 0);
10
+ let visited = 0;
11
+ let truncated = false;
12
+ for (const { item, tier, start } of ordered) {
13
+ if (visited >= limits.maxPerTick || now() >= deadlineMs) {
14
+ truncated = true;
15
+ break;
16
+ }
17
+ visited++;
18
+ tiers[tier].cursor.offset = start + ++visitedPerTier[tier];
19
+ await visit(item);
20
+ }
21
+ const total = tiers.reduce((n, t) => n + t.items.length, 0);
22
+ return { visited, backlog: Math.max(0, total - visited), truncated };
23
+ }
24
+ //# sourceMappingURL=bounded-rotation.js.map