deepline 0.3.89 → 0.3.91

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 (267) hide show
  1. package/contracts/install-commands.json +29 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +221 -43
  3. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  4. package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +2 -556
  5. package/dist/bundling-sources/sdk/src/monitor-fleets.ts +2 -2
  6. package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
  7. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  8. package/dist/bundling-sources/sdk/src/release.ts +11 -9
  9. package/dist/bundling-sources/sdk/src/types.ts +29 -1
  10. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +549 -0
  11. package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
  12. package/dist/bundling-sources/shared_libs/monitors/fleets/errors.ts +96 -0
  13. package/dist/bundling-sources/shared_libs/monitors/fleets/limits.ts +8 -0
  14. package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +320 -0
  15. package/dist/bundling-sources/shared_libs/monitors/fleets/verdict.ts +106 -0
  16. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +8 -1
  17. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
  18. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
  19. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
  20. package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +2 -12
  21. package/dist/bundling-sources/shared_libs/monitors/package.json +113 -4
  22. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +56 -9
  23. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
  24. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
  25. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
  26. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
  27. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
  28. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
  29. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
  30. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
  31. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
  32. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
  33. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
  34. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
  35. package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
  36. package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
  37. package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
  38. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +690 -0
  39. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
  40. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
  41. package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
  42. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +46 -1
  44. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
  45. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
  46. package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
  48. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
  52. package/dist/bundling-sources/shared_libs/play-runtime/db-session-lease-store.ts +578 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-execution-relay.ts +521 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-receipt-gateway.ts +1378 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/runtime-topology.ts +1024 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-gateway-route-probe.ts +193 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machine-lifecycle.ts +104 -0
  58. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +1844 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +21 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/deployment/process-tree.ts +40 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-gateway-drain.ts +262 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-surface.ts +98 -0
  63. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-topology.ts +303 -0
  64. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-publication-guardian.ts +70 -0
  65. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-recovery.ts +519 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-fly-rollback-alignment.ts +280 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-production-gate.ts +159 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
  71. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
  72. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
  75. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
  76. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/memory-store.ts +114 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
  80. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
  83. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
  84. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
  85. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
  87. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
  89. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
  90. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
  95. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
  96. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
  97. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
  98. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
  100. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
  101. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
  102. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
  103. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
  108. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
  109. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
  110. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
  111. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
  113. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
  114. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
  115. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
  116. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
  117. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  118. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
  119. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
  120. package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
  121. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +44 -5
  122. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/child-play-resolver.ts +26 -0
  123. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +3662 -0
  124. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/progress-sidecar.ts +47 -0
  125. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-deadline.ts +84 -0
  126. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +91 -0
  127. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +424 -0
  128. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +321 -0
  129. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +110 -0
  130. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +625 -0
  131. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
  132. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
  133. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
  134. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
  135. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
  136. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +103 -208
  137. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
  138. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  139. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
  140. package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
  141. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
  142. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
  143. package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
  144. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
  145. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
  146. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
  147. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
  148. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
  149. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
  150. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
  151. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
  152. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
  153. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
  154. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
  155. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
  156. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
  157. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
  158. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
  159. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
  160. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
  161. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
  162. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
  163. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
  164. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
  165. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
  166. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
  167. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
  168. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
  169. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
  170. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
  171. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
  172. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
  173. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
  174. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
  175. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
  176. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
  177. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
  178. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
  179. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
  180. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
  181. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
  182. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
  183. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
  184. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
  185. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
  186. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
  187. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
  188. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
  189. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
  190. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
  191. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
  192. package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-retry.ts +50 -0
  193. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
  194. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
  195. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
  196. package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
  197. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
  198. package/dist/bundling-sources/shared_libs/plays/bundling/repository-adapter.ts +24 -0
  199. package/dist/bundling-sources/shared_libs/plays/child-run-projection.ts +174 -0
  200. package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
  201. package/dist/bundling-sources/shared_libs/plays/deploy/api-client.ts +267 -0
  202. package/dist/bundling-sources/shared_libs/plays/deploy/control-plane-types.ts +73 -0
  203. package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +162 -0
  204. package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +87 -0
  205. package/dist/bundling-sources/shared_libs/plays/deploy/source-file-path.ts +26 -0
  206. package/dist/bundling-sources/shared_libs/plays/deploy/target-paths.ts +36 -0
  207. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
  208. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
  209. package/dist/bundling-sources/shared_libs/plays/launch/input-contract.ts +400 -0
  210. package/dist/bundling-sources/shared_libs/plays/launch/prepare.ts +96 -0
  211. package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +385 -0
  212. package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +112 -0
  213. package/dist/bundling-sources/shared_libs/plays/play-reference.ts +117 -0
  214. package/dist/bundling-sources/shared_libs/plays/run-input-summary.ts +260 -0
  215. package/dist/bundling-sources/shared_libs/plays/run-summary-types.ts +49 -0
  216. package/dist/bundling-sources/shared_libs/plays/secrets/errors.ts +19 -0
  217. package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
  218. package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
  219. package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
  220. package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
  221. package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
  222. package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
  223. package/dist/bundling-sources/shared_libs/plays/sheet-filter.ts +347 -0
  224. package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
  225. package/dist/bundling-sources/shared_libs/plays/standard-webhooks.ts +117 -0
  226. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
  227. package/dist/bundling-sources/shared_libs/plays/status-result.ts +388 -0
  228. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  229. package/dist/bundling-sources/shared_libs/plays/transform-factor-structure.ts +377 -0
  230. package/dist/bundling-sources/shared_libs/plays/webhook-payload.ts +113 -0
  231. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
  232. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
  233. package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
  234. package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
  235. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
  236. package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
  237. package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
  238. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  239. package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
  240. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
  241. package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
  242. package/dist/cli/getting-started.d.mts +52 -0
  243. package/dist/cli/getting-started.d.ts +52 -0
  244. package/dist/cli/getting-started.js +65 -0
  245. package/dist/cli/getting-started.mjs +36 -0
  246. package/dist/cli/index.d.mts +9 -0
  247. package/dist/cli/index.d.ts +9 -0
  248. package/dist/cli/index.js +895 -407
  249. package/dist/cli/index.mjs +893 -414
  250. package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-x14KL83E.d.mts} +4 -2
  251. package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-x14KL83E.d.ts} +4 -2
  252. package/dist/index.d.mts +124 -154
  253. package/dist/index.d.ts +124 -154
  254. package/dist/index.js +132 -28
  255. package/dist/index.mjs +132 -28
  256. package/dist/install-integrity.json +182 -2
  257. package/dist/monitor-fleet-contract.d.mts +131 -0
  258. package/dist/monitor-fleet-contract.d.ts +131 -0
  259. package/dist/monitor-fleet-contract.js +406 -0
  260. package/dist/monitor-fleet-contract.mjs +367 -0
  261. package/dist/plays/bundle-play-file.d.mts +2 -2
  262. package/dist/plays/bundle-play-file.d.ts +2 -2
  263. package/dist/release.d.mts +255 -0
  264. package/dist/release.d.ts +255 -0
  265. package/dist/release.js +210 -0
  266. package/dist/release.mjs +183 -0
  267. package/package.json +21 -4
@@ -0,0 +1,725 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Fleet-wide Daytona sandbox janitor for the absurd play runtime.
4
+ *
5
+ * Why this exists
6
+ * ---------------
7
+ * One-shot play sandboxes are created with the label `source:
8
+ * 'deepline-play-runner'` plus `orgId/workflowId/playId/runId`, `ephemeral:
9
+ * true`, and `autoStopInterval: 5` (see
10
+ * `packages/play-runtime/runner-backends/backends/daytona-lifecycle.ts`).
11
+ * Per-run deletion happens through the durable Sandbox Cleanup state machine,
12
+ * but a worker crash can lose the cleanup enqueue after the physical resource
13
+ * was recorded. This janitor is the inventory backstop: Daytona labels discover
14
+ * candidates, while the exact Runtime Sandbox Operation ledger alone decides
15
+ * ownership and deletion eligibility. The janitor restores cleanup obligations;
16
+ * it never performs an unledgered provider deletion.
17
+ *
18
+ * A candidate is eligible only when the durable ledger has one exact physical
19
+ * owner at `(daytona, sandboxId, routingDomain)` and either the owning Run is
20
+ * terminal, deletion was already authorized, or the creation-time configured
21
+ * execution ceiling plus terminal/grace windows has elapsed. Daytona's runId
22
+ * label is intentionally excluded from authority: Daytona truncates label
23
+ * values to 63 characters, so it is only a correlation hint.
24
+ *
25
+ * Fleet scoping (IMPORTANT): the sandbox label scope is `source`-only and the
26
+ * Daytona account is SHARED across every lane (prod, every preview PR fleet,
27
+ * worktree dev — all use the same DAYTONA_API_KEY and stamp the identical
28
+ * `source` label; nothing on the sandbox names its lane/schema). A `list` by
29
+ * `source` therefore returns EVERY lane's sandboxes. The janitor may run only
30
+ * against the prod-default schema, and even there it may authorize deletion
31
+ * only for a resource exactly bound in that schema's operation ledger. A
32
+ * sandbox owned by another lane is therefore unresolved and spared. The worker
33
+ * wiring and CLI both refuse to sweep on an isolated schema (see
34
+ * `isIsolatedRuntimeSchedulerSchema`). This module's core assumes that gate has
35
+ * already been applied by its caller.
36
+ *
37
+ * Everything here is best-effort by design. A single ownership read or cleanup
38
+ * authorization failure is logged and the sweep continues — one wedged sandbox
39
+ * must never abort the fleet-wide pass. The only hard failure is an inability
40
+ * to enumerate at all.
41
+ */
42
+ import { PLAY_RUNNER_TERMINAL_GRACE_SECONDS } from './/runtime-constants';
43
+ import { DAYTONA_PLAY_RUNNER_LABEL_SOURCE } from './/runner-backends/backends/daytona-labels';
44
+
45
+ export { DAYTONA_PLAY_RUNNER_LABEL_SOURCE };
46
+
47
+ /**
48
+ * Slack added on top of the play runtime ceiling before a sandbox is eligible
49
+ * for reaping. The ceiling is the max user-code runtime; the grace covers
50
+ * setup, cleanup, and clock skew so we never race a sandbox that is legitimately
51
+ * still finishing. Constant, not env — this is a tuning number, not a secret.
52
+ */
53
+ export const REAP_AGE_GRACE_MS = 5 * 60 * 1000;
54
+
55
+ /**
56
+ * A single sandbox as seen by the janitor. Structurally a subset of the Daytona
57
+ * SDK `Sandbox`, so a real `Sandbox` satisfies it directly.
58
+ */
59
+ export type ReapableSandbox = {
60
+ id: string;
61
+ labels: Record<string, string>;
62
+ /** Physical Daytona organization returned by the provider, not a label. */
63
+ organizationId?: string;
64
+ /** ISO-8601 creation timestamp, per the Daytona SDK `Sandbox.createdAt`. */
65
+ createdAt?: string;
66
+ };
67
+
68
+ /**
69
+ * Injected Daytona port. `list` yields our label-scoped sandboxes (the SDK
70
+ * `list` returns an async iterator that auto-pages, so we consume it lazily).
71
+ * Inventory is the only Daytona surface the janitor touches.
72
+ */
73
+ export type DaytonaJanitorClientPort = {
74
+ list(query: {
75
+ labels: Record<string, string>;
76
+ }): AsyncIterable<ReapableSandbox>;
77
+ };
78
+
79
+ export type DaytonaJanitorOwnershipAlertCode =
80
+ | 'missing_routing_domain'
81
+ | 'ownership_missing'
82
+ | 'routing_domain_conflict'
83
+ | 'legacy_unbound_ownership'
84
+ | 'ownership_ambiguous'
85
+ | 'invalid_execution_ceiling'
86
+ | 'provider_inventory_conflicts_deleted_ledger'
87
+ | 'cleanup_ownership_conflict';
88
+
89
+ export type DaytonaJanitorOwnership =
90
+ | {
91
+ kind: 'owned';
92
+ operationKey: string;
93
+ runId: string;
94
+ attempt: number;
95
+ orgId: string;
96
+ operationState: 'live' | 'deleting' | 'deleted';
97
+ runStatus:
98
+ | 'queued'
99
+ | 'running'
100
+ | 'waiting'
101
+ | 'completed'
102
+ | 'failed'
103
+ | 'cancelled';
104
+ providerCreatedAtMs: number;
105
+ waitDeadlineMs: number | null;
106
+ runtimeLimitSeconds: number | null;
107
+ cleanupStatus: 'pending' | 'deleting' | 'deleted' | null;
108
+ }
109
+ | {
110
+ kind: 'unresolved';
111
+ code: DaytonaJanitorOwnershipAlertCode;
112
+ candidateRunIds: string[];
113
+ candidateRoutingDomains: Array<string | null>;
114
+ };
115
+
116
+ export type DaytonaJanitorCleanupAuthorization =
117
+ | 'scheduled'
118
+ | 'already_authorized'
119
+ | 'already_deleted'
120
+ | 'ownership_conflict'
121
+ | 'ownership_missing';
122
+
123
+ /** Durable exact-ownership authority. Provider labels are never inputs. */
124
+ export type DaytonaJanitorOwnershipPort = {
125
+ inspect(input: {
126
+ sandboxId: string;
127
+ routingDomain: string | null;
128
+ }): Promise<DaytonaJanitorOwnership>;
129
+ authorizeCleanup(input: {
130
+ operationKey: string;
131
+ sandboxId: string;
132
+ routingDomain: string;
133
+ runId: string;
134
+ attempt: number;
135
+ }): Promise<DaytonaJanitorCleanupAuthorization>;
136
+ };
137
+
138
+ export type ReapOptions = {
139
+ /** Injected clock for testability; defaults to Date.now. */
140
+ now?: () => number;
141
+ /** When true, decide without restoring a durable cleanup obligation. */
142
+ dryRun?: boolean;
143
+ /** Structured logger; defaults to console. */
144
+ logger?: Pick<Console, 'info' | 'warn'>;
145
+ };
146
+
147
+ export type ReapSummary = {
148
+ scanned: number;
149
+ cleanupEligible: number;
150
+ cleanupScheduled: number;
151
+ alreadyAuthorized: number;
152
+ spared: number;
153
+ alerts: number;
154
+ errors: number;
155
+ };
156
+
157
+ type ReapDecision =
158
+ | { authorizeCleanup: false; reason: string }
159
+ | { authorizeCleanup: true; reason: string };
160
+
161
+ /**
162
+ * Pure per-sandbox decision. Returns whether to authorize durable cleanup and a
163
+ * short reason for the structured log line.
164
+ */
165
+ async function decideSandbox(input: {
166
+ ownership: Extract<DaytonaJanitorOwnership, { kind: 'owned' }>;
167
+ nowMs: number;
168
+ }): Promise<ReapDecision> {
169
+ const { ownership, nowMs } = input;
170
+ if (ownership.operationState === 'deleting') {
171
+ return { authorizeCleanup: true, reason: 'deletion_already_authorized' };
172
+ }
173
+ if (
174
+ ownership.runStatus === 'completed' ||
175
+ ownership.runStatus === 'failed' ||
176
+ ownership.runStatus === 'cancelled'
177
+ ) {
178
+ return { authorizeCleanup: true, reason: 'run_terminal' };
179
+ }
180
+ if (
181
+ ownership.runtimeLimitSeconds === null ||
182
+ !Number.isSafeInteger(ownership.runtimeLimitSeconds) ||
183
+ ownership.runtimeLimitSeconds <= 0 ||
184
+ !Number.isFinite(ownership.providerCreatedAtMs)
185
+ ) {
186
+ return { authorizeCleanup: false, reason: 'invalid_execution_ceiling' };
187
+ }
188
+ const configuredFloorMs =
189
+ ownership.providerCreatedAtMs +
190
+ (ownership.runtimeLimitSeconds + PLAY_RUNNER_TERMINAL_GRACE_SECONDS) *
191
+ 1_000 +
192
+ REAP_AGE_GRACE_MS;
193
+ const deletionNotBeforeMs = Math.max(
194
+ configuredFloorMs,
195
+ ownership.waitDeadlineMs === null
196
+ ? Number.NEGATIVE_INFINITY
197
+ : ownership.waitDeadlineMs + REAP_AGE_GRACE_MS,
198
+ );
199
+ return nowMs < deletionNotBeforeMs
200
+ ? { authorizeCleanup: false, reason: 'before_deletion_not_before' }
201
+ : { authorizeCleanup: true, reason: 'execution_ceiling_elapsed' };
202
+ }
203
+
204
+ function parseCreatedAtMs(createdAt: string | undefined): number | null {
205
+ if (!createdAt) return null;
206
+ const parsed = Date.parse(createdAt);
207
+ return Number.isFinite(parsed) ? parsed : null;
208
+ }
209
+
210
+ /**
211
+ * Pure, testable core. Enumerate our label-scoped sandboxes, decide each
212
+ * against the scheduler store, and best-effort restore cleanup obligations for
213
+ * resources that should be dead. Never throws past a single sandbox failure:
214
+ * an authorization or ownership-read error is logged and the sweep continues.
215
+ * Enumeration failure is the one hard error — with nothing to iterate there is
216
+ * no sweep to salvage.
217
+ */
218
+ export async function reapOrphanDaytonaSandboxes(input: {
219
+ daytona: DaytonaJanitorClientPort;
220
+ ownership: DaytonaJanitorOwnershipPort;
221
+ options?: ReapOptions;
222
+ }): Promise<ReapSummary> {
223
+ const now = input.options?.now ?? Date.now;
224
+ const dryRun = input.options?.dryRun ?? false;
225
+ const logger = input.options?.logger ?? console;
226
+
227
+ const summary: ReapSummary = {
228
+ scanned: 0,
229
+ cleanupEligible: 0,
230
+ cleanupScheduled: 0,
231
+ alreadyAuthorized: 0,
232
+ spared: 0,
233
+ alerts: 0,
234
+ errors: 0,
235
+ };
236
+
237
+ const iterator = input.daytona.list({
238
+ labels: { source: DAYTONA_PLAY_RUNNER_LABEL_SOURCE },
239
+ });
240
+
241
+ for await (const sandbox of iterator) {
242
+ summary.scanned += 1;
243
+ const createdAtMs = parseCreatedAtMs(sandbox.createdAt);
244
+ const ageMs =
245
+ createdAtMs === null ? null : Math.max(0, now() - createdAtMs);
246
+ const labelRunId = sandbox.labels.runId?.trim() || null;
247
+ const routingDomain = sandbox.organizationId?.trim() || null;
248
+
249
+ let ownership: DaytonaJanitorOwnership;
250
+ try {
251
+ ownership = await input.ownership.inspect({
252
+ sandboxId: sandbox.id,
253
+ routingDomain,
254
+ });
255
+ } catch (error) {
256
+ summary.errors += 1;
257
+ summary.spared += 1;
258
+ logger.warn('[daytona-janitor.ownership_read_failed]', {
259
+ sandboxId: sandbox.id,
260
+ routingDomain,
261
+ labelRunId,
262
+ error: error instanceof Error ? error.message : String(error),
263
+ });
264
+ continue;
265
+ }
266
+
267
+ if (ownership.kind === 'unresolved') {
268
+ summary.alerts += 1;
269
+ summary.spared += 1;
270
+ logger.warn('[daytona-janitor.ownership_alert]', {
271
+ provider: 'daytona',
272
+ code: ownership.code,
273
+ sandboxId: sandbox.id,
274
+ routingDomain,
275
+ labelRunId,
276
+ candidateRunIds: ownership.candidateRunIds,
277
+ candidateRoutingDomains: ownership.candidateRoutingDomains,
278
+ });
279
+ continue;
280
+ }
281
+
282
+ if (labelRunId && labelRunId !== ownership.runId) {
283
+ logger.info('[daytona-janitor.label_correlation_mismatch]', {
284
+ sandboxId: sandbox.id,
285
+ routingDomain,
286
+ labelRunId,
287
+ ownerRunId: ownership.runId,
288
+ });
289
+ }
290
+
291
+ if (ownership.operationState === 'deleted') {
292
+ summary.alerts += 1;
293
+ summary.spared += 1;
294
+ logger.warn('[daytona-janitor.ownership_alert]', {
295
+ provider: 'daytona',
296
+ code: 'provider_inventory_conflicts_deleted_ledger',
297
+ sandboxId: sandbox.id,
298
+ routingDomain,
299
+ labelRunId,
300
+ ownerRunId: ownership.runId,
301
+ operationKey: ownership.operationKey,
302
+ });
303
+ continue;
304
+ }
305
+
306
+ const decision = await decideSandbox({ ownership, nowMs: now() });
307
+ if (!decision.authorizeCleanup) {
308
+ summary.spared += 1;
309
+ if (decision.reason === 'invalid_execution_ceiling') {
310
+ summary.alerts += 1;
311
+ logger.warn('[daytona-janitor.ownership_alert]', {
312
+ provider: 'daytona',
313
+ code: 'invalid_execution_ceiling',
314
+ sandboxId: sandbox.id,
315
+ routingDomain,
316
+ labelRunId,
317
+ ownerRunId: ownership.runId,
318
+ operationKey: ownership.operationKey,
319
+ });
320
+ }
321
+ continue;
322
+ }
323
+
324
+ summary.cleanupEligible += 1;
325
+ if (dryRun) {
326
+ logger.info('[daytona-janitor.would_schedule_cleanup]', {
327
+ sandboxId: sandbox.id,
328
+ routingDomain,
329
+ runId: ownership.runId,
330
+ ageMs,
331
+ reason: decision.reason,
332
+ dryRun: true,
333
+ });
334
+ continue;
335
+ }
336
+
337
+ try {
338
+ const authorization = await input.ownership.authorizeCleanup({
339
+ operationKey: ownership.operationKey,
340
+ sandboxId: sandbox.id,
341
+ routingDomain: routingDomain!,
342
+ runId: ownership.runId,
343
+ attempt: ownership.attempt,
344
+ });
345
+ if (authorization === 'scheduled') {
346
+ summary.cleanupScheduled += 1;
347
+ } else if (
348
+ authorization === 'already_authorized' ||
349
+ authorization === 'already_deleted'
350
+ ) {
351
+ summary.alreadyAuthorized += 1;
352
+ } else {
353
+ summary.alerts += 1;
354
+ summary.spared += 1;
355
+ logger.warn('[daytona-janitor.ownership_alert]', {
356
+ provider: 'daytona',
357
+ code:
358
+ authorization === 'ownership_conflict'
359
+ ? 'cleanup_ownership_conflict'
360
+ : 'ownership_missing',
361
+ sandboxId: sandbox.id,
362
+ routingDomain,
363
+ labelRunId,
364
+ ownerRunId: ownership.runId,
365
+ operationKey: ownership.operationKey,
366
+ });
367
+ continue;
368
+ }
369
+ logger.info('[daytona-janitor.cleanup_authorized]', {
370
+ sandboxId: sandbox.id,
371
+ routingDomain,
372
+ runId: ownership.runId,
373
+ ageMs,
374
+ reason: decision.reason,
375
+ authorization,
376
+ });
377
+ } catch (error) {
378
+ summary.errors += 1;
379
+ summary.spared += 1;
380
+ logger.warn('[daytona-janitor.cleanup_authorization_failed]', {
381
+ sandboxId: sandbox.id,
382
+ routingDomain,
383
+ runId: ownership.runId,
384
+ ageMs,
385
+ reason: decision.reason,
386
+ error: error instanceof Error ? error.message : String(error),
387
+ });
388
+ }
389
+ }
390
+
391
+ logger.info('[daytona-janitor.summary]', { ...summary, dryRun });
392
+ return summary;
393
+ }
394
+
395
+ // ---------------------------------------------------------------------------
396
+ // Production adapters (thin, imported by the CLI entry and the worker wiring).
397
+ // ---------------------------------------------------------------------------
398
+
399
+ type SchedulerQueryClient = {
400
+ query<Row extends Record<string, unknown> = Record<string, unknown>>(
401
+ sql: string,
402
+ params?: unknown[],
403
+ ): Promise<{ rows: Row[] }>;
404
+ };
405
+
406
+ function quoteIdent(value: string): string {
407
+ return `"${value.replace(/"/g, '""')}"`;
408
+ }
409
+
410
+ type JanitorOwnershipRow = {
411
+ operation_key: string;
412
+ run_id: string;
413
+ attempt: number;
414
+ org_id: string;
415
+ routing_domain: string | null;
416
+ state: 'reserved' | 'live' | 'deleting' | 'deleted' | 'abandoned';
417
+ provider_created_at_ms: string | null;
418
+ run_status: Extract<DaytonaJanitorOwnership, { kind: 'owned' }>['runStatus'];
419
+ wait_deadline_ms: string | null;
420
+ launch_json: unknown;
421
+ cleanup_status: 'pending' | 'deleting' | 'deleted' | null;
422
+ cleanup_run_id: string | null;
423
+ cleanup_attempt: number | null;
424
+ };
425
+
426
+ function runtimeLimitSecondsFromLaunch(launch: unknown): number | null {
427
+ if (!launch || typeof launch !== 'object' || Array.isArray(launch)) {
428
+ return null;
429
+ }
430
+ const contract = (launch as Record<string, unknown>).contractSnapshot;
431
+ if (!contract || typeof contract !== 'object' || Array.isArray(contract)) {
432
+ return null;
433
+ }
434
+ const runtimeLimit = (contract as Record<string, unknown>).runtimeLimit;
435
+ if (
436
+ !runtimeLimit ||
437
+ typeof runtimeLimit !== 'object' ||
438
+ Array.isArray(runtimeLimit)
439
+ ) {
440
+ return null;
441
+ }
442
+ const seconds = (runtimeLimit as Record<string, unknown>).timeoutSeconds;
443
+ return typeof seconds === 'number' &&
444
+ Number.isSafeInteger(seconds) &&
445
+ seconds > 0
446
+ ? seconds
447
+ : null;
448
+ }
449
+
450
+ /** Runtime Postgres Adapter for the janitor's exact ownership authority. */
451
+ export function createPostgresDaytonaJanitorOwnershipPort(input: {
452
+ client: SchedulerQueryClient;
453
+ schema: string;
454
+ }): DaytonaJanitorOwnershipPort {
455
+ const runs = `${quoteIdent(input.schema)}.${quoteIdent('runs')}`;
456
+ const operations = `${quoteIdent(input.schema)}.${quoteIdent(
457
+ 'runtime_sandbox_operations',
458
+ )}`;
459
+ const cleanup = `${quoteIdent(input.schema)}.${quoteIdent(
460
+ 'sandbox_cleanup_jobs_v2',
461
+ )}`;
462
+ return {
463
+ async inspect({ sandboxId, routingDomain }) {
464
+ if (!routingDomain) {
465
+ return {
466
+ kind: 'unresolved',
467
+ code: 'missing_routing_domain',
468
+ candidateRunIds: [],
469
+ candidateRoutingDomains: [],
470
+ };
471
+ }
472
+ const result = await input.client.query<JanitorOwnershipRow>(
473
+ `
474
+ SELECT
475
+ operation.operation_key,
476
+ operation.run_id,
477
+ operation.attempt,
478
+ operation.org_id,
479
+ operation.routing_domain,
480
+ operation.state,
481
+ (extract(epoch FROM operation.provider_created_at) * 1000)::bigint::text
482
+ AS provider_created_at_ms,
483
+ run.status AS run_status,
484
+ (extract(epoch FROM run.wait_deadline) * 1000)::bigint::text
485
+ AS wait_deadline_ms,
486
+ run.launch_json,
487
+ cleanup.status AS cleanup_status,
488
+ cleanup.run_id AS cleanup_run_id,
489
+ cleanup.attempt AS cleanup_attempt
490
+ FROM ${operations} AS operation
491
+ JOIN ${runs} AS run ON run.run_id = operation.run_id
492
+ LEFT JOIN ${cleanup} AS cleanup
493
+ ON cleanup.provider = operation.provider
494
+ AND cleanup.sandbox_id = operation.sandbox_id
495
+ AND cleanup.routing_domain IS NOT DISTINCT FROM operation.routing_domain
496
+ WHERE operation.provider = 'daytona'
497
+ AND operation.sandbox_id = $1
498
+ ORDER BY operation.routing_domain_key, operation.operation_key
499
+ `,
500
+ [sandboxId],
501
+ );
502
+ const exact = result.rows.filter(
503
+ (row) => row.routing_domain === routingDomain,
504
+ );
505
+ if (exact.length !== 1) {
506
+ const code: DaytonaJanitorOwnershipAlertCode =
507
+ exact.length > 1
508
+ ? 'ownership_ambiguous'
509
+ : result.rows.length === 0
510
+ ? 'ownership_missing'
511
+ : result.rows.some((row) => row.routing_domain === null)
512
+ ? 'legacy_unbound_ownership'
513
+ : 'routing_domain_conflict';
514
+ return {
515
+ kind: 'unresolved',
516
+ code,
517
+ candidateRunIds: result.rows.map((row) => row.run_id),
518
+ candidateRoutingDomains: result.rows.map((row) => row.routing_domain),
519
+ };
520
+ }
521
+ const row = exact[0]!;
522
+ if (
523
+ row.state !== 'live' &&
524
+ row.state !== 'deleting' &&
525
+ row.state !== 'deleted'
526
+ ) {
527
+ return {
528
+ kind: 'unresolved',
529
+ code: 'legacy_unbound_ownership',
530
+ candidateRunIds: [row.run_id],
531
+ candidateRoutingDomains: [row.routing_domain],
532
+ };
533
+ }
534
+ if (
535
+ row.cleanup_status !== null &&
536
+ (row.cleanup_run_id !== row.run_id ||
537
+ Number(row.cleanup_attempt) !== Number(row.attempt))
538
+ ) {
539
+ return {
540
+ kind: 'unresolved',
541
+ code: 'cleanup_ownership_conflict',
542
+ candidateRunIds: [row.run_id, row.cleanup_run_id ?? ''].filter(
543
+ Boolean,
544
+ ),
545
+ candidateRoutingDomains: [row.routing_domain],
546
+ };
547
+ }
548
+ return {
549
+ kind: 'owned',
550
+ operationKey: row.operation_key,
551
+ runId: row.run_id,
552
+ attempt: Number(row.attempt),
553
+ orgId: row.org_id,
554
+ operationState: row.state,
555
+ runStatus: row.run_status,
556
+ providerCreatedAtMs:
557
+ row.provider_created_at_ms === null
558
+ ? Number.NaN
559
+ : Number(row.provider_created_at_ms),
560
+ waitDeadlineMs:
561
+ row.wait_deadline_ms === null ? null : Number(row.wait_deadline_ms),
562
+ runtimeLimitSeconds: runtimeLimitSecondsFromLaunch(row.launch_json),
563
+ cleanupStatus: row.cleanup_status,
564
+ };
565
+ },
566
+ async authorizeCleanup({
567
+ operationKey,
568
+ sandboxId,
569
+ routingDomain,
570
+ runId,
571
+ attempt,
572
+ }) {
573
+ const result = await input.client.query<{
574
+ operation_state: string;
575
+ cleanup_status: string | null;
576
+ cleanup_run_id: string | null;
577
+ cleanup_attempt: number | null;
578
+ inserted: boolean;
579
+ }>(
580
+ `
581
+ WITH owned AS MATERIALIZED (
582
+ SELECT operation_key, provider, sandbox_id, routing_domain,
583
+ run_id, attempt, environment, state
584
+ FROM ${operations}
585
+ WHERE operation_key = $1
586
+ AND provider = 'daytona'
587
+ AND sandbox_id = $2
588
+ AND routing_domain = $3
589
+ AND run_id = $4
590
+ AND attempt = $5
591
+ FOR UPDATE
592
+ ), inserted AS (
593
+ INSERT INTO ${cleanup} (
594
+ provider, sandbox_id, run_id, attempt, environment, routing_domain
595
+ )
596
+ SELECT provider, sandbox_id, run_id, attempt, environment, routing_domain
597
+ FROM owned
598
+ WHERE state IN ('live', 'deleting')
599
+ ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
600
+ RETURNING provider, sandbox_id, routing_domain,
601
+ status, run_id, attempt
602
+ ), current_cleanup AS MATERIALIZED (
603
+ SELECT inserted.status, inserted.run_id, inserted.attempt
604
+ FROM inserted
605
+ UNION ALL
606
+ SELECT cleanup.status, cleanup.run_id, cleanup.attempt
607
+ FROM ${cleanup} AS cleanup
608
+ JOIN owned
609
+ ON cleanup.provider = owned.provider
610
+ AND cleanup.sandbox_id = owned.sandbox_id
611
+ AND cleanup.routing_domain IS NOT DISTINCT FROM owned.routing_domain
612
+ WHERE NOT EXISTS (SELECT 1 FROM inserted)
613
+ ), transitioned AS (
614
+ UPDATE ${operations} AS operation
615
+ SET state = 'deleting', updated_at = clock_timestamp()
616
+ FROM owned
617
+ WHERE operation.operation_key = owned.operation_key
618
+ AND operation.state = 'live'
619
+ AND EXISTS (
620
+ SELECT 1 FROM current_cleanup
621
+ WHERE current_cleanup.run_id = owned.run_id
622
+ AND current_cleanup.attempt = owned.attempt
623
+ AND current_cleanup.status <> 'deleted'
624
+ )
625
+ RETURNING operation.operation_key
626
+ )
627
+ SELECT
628
+ owned.state AS operation_state,
629
+ current_cleanup.status AS cleanup_status,
630
+ current_cleanup.run_id AS cleanup_run_id,
631
+ current_cleanup.attempt AS cleanup_attempt,
632
+ EXISTS (SELECT 1 FROM inserted) AS inserted
633
+ FROM owned
634
+ LEFT JOIN current_cleanup ON TRUE
635
+ `,
636
+ [operationKey, sandboxId, routingDomain, runId, attempt],
637
+ );
638
+ const row = result.rows[0];
639
+ if (!row) return 'ownership_missing';
640
+ if (
641
+ row.cleanup_status !== null &&
642
+ (row.cleanup_run_id !== runId ||
643
+ Number(row.cleanup_attempt) !== attempt)
644
+ ) {
645
+ return 'ownership_conflict';
646
+ }
647
+ if (
648
+ row.operation_state === 'deleted' ||
649
+ row.cleanup_status === 'deleted'
650
+ ) {
651
+ return 'already_deleted';
652
+ }
653
+ return row.inserted ? 'scheduled' : 'already_authorized';
654
+ },
655
+ };
656
+ }
657
+
658
+ // ---------------------------------------------------------------------------
659
+ // CLI entry.
660
+ // ---------------------------------------------------------------------------
661
+
662
+ export async function runDaytonaSandboxJanitorCli(argv: string[]): Promise<void> {
663
+ const dryRun = argv.includes('--dry-run');
664
+ // Escape hatch for deliberate debugging only: reaping against an isolated
665
+ // schema is unsafe because the `source`-scoped fleet is shared across lanes
666
+ // (see startDaytonaSandboxJanitor). Combine with --dry-run to inspect.
667
+ const allowIsolated = argv.includes('--allow-isolated-schema');
668
+
669
+ // Lazy imports so the pure core above stays free of heavy runtime deps and
670
+ // remains trivially unit-testable with fake ports.
671
+ const [
672
+ { Daytona },
673
+ { loadDaytonaRequiredConfig },
674
+ poolModule,
675
+ schemaModule,
676
+ { isIsolatedRuntimeSchedulerSchema },
677
+ ] = await Promise.all([
678
+ import('@daytonaio/sdk'),
679
+ import('.//daytona-runtime-config'),
680
+ import('.//scheduler-backends/postgres-pool'),
681
+ import('.//scheduler-backends/runtime-scheduler-schema'),
682
+ import('.//runtime-scheduler-topology'),
683
+ ]);
684
+
685
+ const url = poolModule.resolveWorkflowRuntimePostgresUrl();
686
+ if (!url) {
687
+ throw new Error(
688
+ 'WORKFLOW_RUNTIME_POSTGRES is required for the Daytona sandbox janitor.',
689
+ );
690
+ }
691
+ const schema =
692
+ schemaModule.resolveRuntimeSchedulerSchemaEnv() || 'runtime_scheduler';
693
+
694
+ if (isIsolatedRuntimeSchedulerSchema(schema) && !allowIsolated) {
695
+ // The label scope is shared across every lane on this Daytona account, so a
696
+ // non-prod schema cannot authoritatively resolve the fleet. Refuse loudly
697
+ // rather than reap sandboxes owned by prod or another PR.
698
+ throw new Error(
699
+ `Refusing to reap on isolated schema "${schema}": the Daytona ` +
700
+ `source-label scope is shared across lanes, so runs absent from this ` +
701
+ `store may belong to prod or another PR. Pass --allow-isolated-schema ` +
702
+ `--dry-run only for deliberate debugging.`,
703
+ );
704
+ }
705
+
706
+ const { clientOptions } = loadDaytonaRequiredConfig();
707
+ const daytona = new Daytona(clientOptions);
708
+
709
+ const summary = await poolModule.withRuntimeSchedulerClient(
710
+ { url, applicationName: 'deepline-daytona-janitor' },
711
+ (client) =>
712
+ reapOrphanDaytonaSandboxes({
713
+ daytona: {
714
+ list: (query) => daytona.list(query),
715
+ },
716
+ ownership: createPostgresDaytonaJanitorOwnershipPort({
717
+ client,
718
+ schema,
719
+ }),
720
+ options: { dryRun },
721
+ }),
722
+ );
723
+
724
+ console.info('[daytona-janitor.cli_done]', { ...summary, schema, dryRun });
725
+ }