deepline 0.3.461 → 0.3.462

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 (296) hide show
  1. package/dist/bundling-sources/sdk/src/client-core.ts +7593 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +8 -7366
  3. package/dist/bundling-sources/sdk/src/http-core.ts +1239 -0
  4. package/dist/bundling-sources/sdk/src/http.ts +6 -1231
  5. package/dist/bundling-sources/sdk/src/index.ts +4 -1
  6. package/dist/bundling-sources/sdk/src/play.ts +5 -5
  7. package/dist/bundling-sources/sdk/src/plays/client-core.ts +437 -0
  8. package/dist/bundling-sources/sdk/src/plays/client.ts +4 -421
  9. package/dist/bundling-sources/sdk/src/plays/input-example.ts +3 -4
  10. package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
  11. package/dist/bundling-sources/sdk/src/plays/run-request.ts +1 -1
  12. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  13. package/dist/bundling-sources/sdk/src/server.ts +43 -0
  14. package/dist/bundling-sources/sdk/src/types.ts +15 -5
  15. package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +15 -0
  16. package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +0 -307
  17. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
  18. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +3 -2
  19. package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
  20. package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +34 -0
  21. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +59 -0
  22. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +94 -1
  23. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +11 -1
  24. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-failure-codes.ts +24 -0
  25. package/dist/bundling-sources/shared_libs/observability/dlq.ts +32 -0
  26. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +57 -3
  27. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +1 -0
  28. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +66 -1
  29. package/dist/bundling-sources/shared_libs/play-data-plane/sheet-column-storage.ts +36 -7
  30. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +250 -11
  31. package/dist/bundling-sources/shared_libs/play-runtime/array-input-store.ts +319 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +991 -359
  33. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +17 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +13 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +110 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +155 -6
  37. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +110 -6
  38. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -13
  39. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +14 -1
  40. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +57 -1
  41. package/dist/bundling-sources/shared_libs/play-runtime/free-company-lookup-batching.ts +218 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +42 -5
  43. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts +6 -1
  44. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +92 -31
  45. package/dist/bundling-sources/shared_libs/play-runtime/governor/block-reserving-budget-state-backend.ts +69 -14
  46. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +93 -23
  47. package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +15 -4
  48. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +22 -18
  49. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +5 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +2 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +190 -14
  52. package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +131 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +77 -2
  54. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +271 -2
  55. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +51 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +2 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +27 -1
  58. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/provider-text-for-log.ts +63 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +19 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +112 -16
  63. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +104 -2
  64. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +265 -151
  65. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +17 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +35 -14
  67. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +12 -1
  68. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +4 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts +36 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +136 -70
  71. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +237 -36
  72. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +148 -4
  73. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +6 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +285 -32
  75. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +251 -56
  76. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +29 -4
  77. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts +27 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +22 -1
  79. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1397 -382
  80. package/dist/bundling-sources/shared_libs/play-runtime/runtime-array-input-receipts.ts +920 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +16 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +38 -0
  83. package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +6 -0
  84. package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -1
  85. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +30 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +14 -3
  87. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +31 -4
  88. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -0
  89. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +20 -7
  90. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +12 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/index.ts +9 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +10 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +4 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1496 -320
  95. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +31 -1
  96. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1389 -129
  97. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +36 -0
  98. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +162 -23
  100. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +499 -115
  101. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +377 -9
  102. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +117 -8
  103. package/dist/bundling-sources/shared_libs/play-runtime/secret-resolution-retry-policy.ts +25 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/terminal-runtime-performance.ts +391 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +40 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +6 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/mapped-calls.ts +171 -0
  108. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +16 -1
  109. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +26 -3
  110. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +16 -2
  111. package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +28 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +55 -5
  113. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +41 -1
  114. package/dist/bundling-sources/shared_libs/plays/contracts.ts +4 -0
  115. package/dist/bundling-sources/shared_libs/plays/dataset.ts +9 -3
  116. package/dist/bundling-sources/shared_libs/plays/deploy/manifest-contract.ts +2 -0
  117. package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +3 -2
  118. package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +2 -2
  119. package/dist/bundling-sources/shared_libs/plays/run-output-summary.ts +66 -0
  120. package/dist/bundling-sources/shared_libs/plays/script-entry.ts +1 -1
  121. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +43 -1
  122. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +9 -0
  123. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +91 -13
  124. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +3 -0
  125. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +41 -24
  126. package/dist/bundling-sources/shared_libs/security/attested-client-ip.ts +91 -0
  127. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +0 -11
  128. package/dist/cli/{auth-6HJXNWUG.mjs → auth-JDLEY7VU.mjs} +5 -4
  129. package/dist/cli/auth-UXKY6TCC.js +41 -0
  130. package/dist/cli/{billing-6P5HO6QG.js → billing-HXAXB3XZ.js} +152 -78
  131. package/dist/cli/{billing-MJ42N7YF.mjs → billing-SDHLBLMV.mjs} +84 -10
  132. package/dist/cli/{chunk-5MDIZX7M.js → chunk-3ACMRZRV.js} +8 -6
  133. package/dist/cli/{chunk-FGLKOWSC.mjs → chunk-3KZCFOZ6.mjs} +1 -1
  134. package/dist/cli/chunk-4KQ6SIBC.mjs +1038 -0
  135. package/dist/cli/{chunk-Z2GUFYT6.js → chunk-5LEAXRHV.js} +11 -11
  136. package/dist/cli/{chunk-MEAIOXJL.mjs → chunk-6NNVJDVR.mjs} +7 -5
  137. package/dist/cli/{chunk-NMJ4D2WO.js → chunk-6PMCRYDA.js} +216 -91
  138. package/dist/cli/{chunk-RY4IVOU3.mjs → chunk-6RNQGWFD.mjs} +16 -806
  139. package/dist/cli/{chunk-EBU7LQ64.js → chunk-6V7KVRR5.js} +3 -3
  140. package/dist/cli/{chunk-OZBWRICM.js → chunk-7LFIMWMW.js} +2 -2
  141. package/dist/cli/chunk-7MJ6VI2T.mjs +19 -0
  142. package/dist/cli/chunk-7SWNPNML.js +1039 -0
  143. package/dist/cli/{chunk-IHHLTHE7.mjs → chunk-7U3XNPOA.mjs} +267 -38
  144. package/dist/cli/{chunk-5FDKJQZE.js → chunk-7VZHXVOQ.js} +1 -1
  145. package/dist/cli/{chunk-R64BGGRQ.mjs → chunk-AT636LLU.mjs} +2 -2
  146. package/dist/cli/{chunk-MDJPEGVN.js → chunk-BGTPIMSM.js} +392 -261
  147. package/dist/cli/{chunk-KVJ5VHW5.mjs → chunk-CKSOY47X.mjs} +2 -2
  148. package/dist/cli/{chunk-7DH2FD7Y.mjs → chunk-D464JW3N.mjs} +5 -85
  149. package/dist/cli/chunk-D6DXOUTO.mjs +827 -0
  150. package/dist/cli/{describe-2WQY7ZCY.js → chunk-EM4TXCCI.js} +27 -44
  151. package/dist/cli/chunk-F6QV42MC.mjs +91 -0
  152. package/dist/cli/chunk-FKVYR3QA.mjs +1039 -0
  153. package/dist/cli/{chunk-FGMX4HUZ.js → chunk-GEGW5HPZ.js} +29 -27
  154. package/dist/cli/{chunk-TNMBPMMC.js → chunk-HUB3CCM2.js} +13 -4
  155. package/dist/cli/{chunk-ACCR7POB.js → chunk-I6VHOU5O.js} +27 -27
  156. package/dist/cli/{chunk-Z2XUZC34.js → chunk-IAYSWZDJ.js} +188 -76
  157. package/dist/cli/chunk-JF3TLIMQ.js +19 -0
  158. package/dist/cli/{chunk-HDFRJ4IT.mjs → chunk-JVHOS3K3.mjs} +177 -65
  159. package/dist/cli/{chunk-V7REJRDZ.mjs → chunk-LFXLQEZN.mjs} +1 -1
  160. package/dist/cli/{chunk-CRYOUPEB.js → chunk-LROWFPGN.js} +16 -16
  161. package/dist/cli/{chunk-SLEUWLJE.mjs → chunk-MSY22NQW.mjs} +5 -5
  162. package/dist/cli/{chunk-BGY2PLP7.mjs → chunk-MUUQZIOF.mjs} +23 -49
  163. package/dist/cli/{chunk-FCAZQ7WV.js → chunk-NBLSCHKK.js} +52 -50
  164. package/dist/cli/{chunk-QAJAJPKK.mjs → chunk-NHRWZPWZ.mjs} +4 -2
  165. package/dist/cli/{chunk-KXMNM4AQ.js → chunk-NMU3VR5U.js} +4 -5
  166. package/dist/cli/{chunk-QIW7TVV6.mjs → chunk-O2RX5A66.mjs} +14 -12
  167. package/dist/cli/{chunk-SAZFZQRI.js → chunk-OMQ23IXL.js} +2 -2
  168. package/dist/cli/{chunk-5IYOUBFZ.js → chunk-OPJAJBD4.js} +28 -54
  169. package/dist/cli/{chunk-FJZILBL7.mjs → chunk-PHSEINNH.mjs} +5 -5
  170. package/dist/cli/{chunk-3DNKFH2G.mjs → chunk-PKHVSIJG.mjs} +19 -1
  171. package/dist/cli/{chunk-WIYWSYDS.mjs → chunk-Q2EIZKVX.mjs} +3 -3
  172. package/dist/cli/{chunk-5FY72YOV.js → chunk-QJZ6WNWD.js} +8 -8
  173. package/dist/cli/{chunk-EIMG75BT.mjs → chunk-S3A4IXBQ.mjs} +4 -5
  174. package/dist/cli/{chunk-3BMLICF7.mjs → chunk-S42YIQNE.mjs} +13 -8
  175. package/dist/cli/{chunk-RFONC4WJ.mjs → chunk-S6UAJR6V.mjs} +3 -3
  176. package/dist/cli/{chunk-G7L27KZB.mjs → chunk-TKAQR3IB.mjs} +31 -21
  177. package/dist/cli/{chunk-QWRHGGUH.js → chunk-UAJFWWZE.js} +20 -2
  178. package/dist/cli/{chunk-VZBCEA5S.mjs → chunk-UDRPEZ5F.mjs} +223 -92
  179. package/dist/cli/{chunk-KCCOQ5G5.js → chunk-ULK7JGGI.js} +511 -282
  180. package/dist/cli/chunk-V335HGX5.js +1038 -0
  181. package/dist/cli/{chunk-MGXEUZHL.mjs → chunk-V3MEA7NB.mjs} +7 -5
  182. package/dist/cli/{chunk-O6QOMHCH.js → chunk-VFGVXXZP.js} +37 -35
  183. package/dist/cli/chunk-VLEVVDWG.js +91 -0
  184. package/dist/cli/{chunk-R2GLGLDR.mjs → chunk-VPHN2HAL.mjs} +216 -91
  185. package/dist/cli/{chunk-CFUTOWE4.js → chunk-WG3KGAII.js} +8 -88
  186. package/dist/cli/{describe-FRAVCY5F.mjs → chunk-WIY6U6GD.mjs} +19 -36
  187. package/dist/cli/{chunk-PNATXKLP.js → chunk-XANRM3QA.js} +6 -6
  188. package/dist/cli/{chunk-KGQNIA37.js → chunk-XQCTG5OO.js} +44 -34
  189. package/dist/cli/{chunk-T3MVIPHG.mjs → chunk-XZAFIOUQ.mjs} +1 -1
  190. package/dist/cli/chunk-Y4DPU4OM.js +827 -0
  191. package/dist/cli/chunk-YT5EODJO.js +920 -0
  192. package/dist/cli/{chunk-SCIR5JXW.js → chunk-ZGQSFYD2.js} +56 -51
  193. package/dist/cli/{chunk-QEYHTIV4.mjs → chunk-ZUK6LIJB.mjs} +10 -1
  194. package/dist/cli/command-docs.d.mts +5 -0
  195. package/dist/cli/command-docs.d.ts +5 -0
  196. package/dist/cli/command-docs.js +2 -2
  197. package/dist/cli/command-docs.mjs +1 -1
  198. package/dist/cli/{csv-NX7NO3O6.js → csv-C56GSCEU.js} +13 -12
  199. package/dist/cli/{csv-DQ6GW5B5.mjs → csv-L54JS7TF.mjs} +4 -3
  200. package/dist/cli/{db-R72DFMP6.js → db-MOGRMZTA.js} +30 -27
  201. package/dist/cli/{db-2YP33M4K.mjs → db-YVBUW2DX.mjs} +10 -7
  202. package/dist/cli/describe-KYEULWPG.js +48 -0
  203. package/dist/cli/describe-NLZKKT7C.mjs +48 -0
  204. package/dist/cli/describe-core.d.mts +153 -5
  205. package/dist/cli/describe-core.d.ts +153 -5
  206. package/dist/cli/describe-core.js +9 -5
  207. package/dist/cli/describe-core.mjs +10 -6
  208. package/dist/cli/{executions-ZLHD4QIT.js → executions-A7L4ULPP.js} +9 -7
  209. package/dist/cli/{executions-WFBU7L2Q.mjs → executions-ZBGSTT37.mjs} +7 -5
  210. package/dist/cli/{feedback-CN3HJFVF.mjs → feedback-G6GU37FD.mjs} +6 -5
  211. package/dist/cli/{feedback-NDV6TPHG.js → feedback-OHLY7RYD.js} +10 -9
  212. package/dist/cli/getting-started.d.mts +6 -6
  213. package/dist/cli/getting-started.d.ts +6 -6
  214. package/dist/cli/getting-started.js +2 -2
  215. package/dist/cli/getting-started.mjs +1 -1
  216. package/dist/cli/git-P76N4NDQ.js +25 -0
  217. package/dist/cli/{git-QAD6E3HW.mjs → git-PKZW3QD5.mjs} +5 -4
  218. package/dist/cli/index.js +152 -142
  219. package/dist/cli/index.mjs +56 -46
  220. package/dist/cli/{legacy-noops-KVC5QJ74.js → legacy-noops-5LM3D724.js} +8 -7
  221. package/dist/cli/{legacy-noops-TPTKNBI2.mjs → legacy-noops-LJJYG6YA.mjs} +5 -4
  222. package/dist/cli/{monitors-SV57JFLO.mjs → monitors-72QV4ALO.mjs} +19 -6
  223. package/dist/cli/{monitors-KCROV6PJ.js → monitors-UX3H5DC2.js} +103 -90
  224. package/dist/cli/{org-KX6QIR7A.mjs → org-6RRRKOCP.mjs} +9 -6
  225. package/dist/cli/{org-NJYX5743.js → org-IF7ISUVB.js} +70 -67
  226. package/dist/cli/pages-3SU3HKL7.js +252 -0
  227. package/dist/cli/pages-DXDYYKEK.mjs +252 -0
  228. package/dist/cli/{play-IQQ57L7Z.mjs → play-AHASKRLA.mjs} +512 -1508
  229. package/dist/cli/{play-32L7EQN4.js → play-EUIUVLUH.js} +1090 -2086
  230. package/dist/cli/{providers-4WEC2EQN.mjs → providers-GWGE3WY3.mjs} +7 -5
  231. package/dist/cli/{providers-ZQV6QLVQ.js → providers-V5WU4VXJ.js} +10 -8
  232. package/dist/cli/{quickstart-RQ76RIUE.mjs → quickstart-OXKQ5ZST.mjs} +5 -4
  233. package/dist/cli/{quickstart-HKUSFADF.js → quickstart-QP65I5PF.js} +13 -12
  234. package/dist/cli/run-6MM72IGL.mjs +443 -0
  235. package/dist/cli/run-F3FTYS56.js +443 -0
  236. package/dist/cli/search-OYKOOI7A.js +32 -0
  237. package/dist/cli/{search-ZRAVFBZC.mjs → search-ZMEBVJZB.mjs} +8 -6
  238. package/dist/cli/{secrets-J3G5Y43U.js → secrets-ACND5N6A.js} +16 -14
  239. package/dist/cli/{secrets-CMJOVNVH.mjs → secrets-XRCJFF3L.mjs} +7 -5
  240. package/dist/cli/{sessions-MDQYY5CB.mjs → sessions-RTK3CEW6.mjs} +5 -4
  241. package/dist/cli/{sessions-WY7VN4AE.js → sessions-ZGRJPCFF.js} +6 -5
  242. package/dist/cli/{settings-HTNTFKCE.js → settings-PD5KWQQZ.js} +80 -77
  243. package/dist/cli/{settings-4RWZPCT5.mjs → settings-XDRBPRDE.mjs} +14 -11
  244. package/dist/cli/{setup-P3GYYZWG.mjs → setup-3HPYAOCC.mjs} +12 -10
  245. package/dist/cli/{setup-QGCAP62X.js → setup-E2Q6PXHC.js} +53 -51
  246. package/dist/cli/{skills-7NAE4ICL.mjs → skills-OOQFMPOV.mjs} +7 -6
  247. package/dist/cli/skills-XYWV52KB.js +31 -0
  248. package/dist/cli/tools-ASCDZJCK.js +55 -0
  249. package/dist/cli/tools-C5ZT3UIC.mjs +55 -0
  250. package/dist/cli/update-5RQSEIFM.js +33 -0
  251. package/dist/cli/{update-GODLRKNB.mjs → update-ZWJTADIW.mjs} +9 -8
  252. package/dist/cli/{workflow-4BXOUVEO.mjs → workflow-23NMPAJ7.mjs} +10 -8
  253. package/dist/cli/{workflow-AO3A6LXN.js → workflow-TCXU5YJV.js} +20 -18
  254. package/dist/client-DS2IWYZF.d.ts +10 -0
  255. package/dist/client-DTwnz_AW.d.mts +10 -0
  256. package/dist/{client-CYqG23K1.d.ts → client-core-B_6HAIBy.d.ts} +385 -12
  257. package/dist/{client-BbU5_j7n.d.mts → client-core-DzBSlY1U.d.mts} +385 -12
  258. package/dist/{compiler-manifest-CWz_sNOQ.d.ts → compiler-manifest-Dcyd3-Zd.d.mts} +43 -1
  259. package/dist/{compiler-manifest-CWz_sNOQ.d.mts → compiler-manifest-Dcyd3-Zd.d.ts} +43 -1
  260. package/dist/errors-d-sTrZhe.d.mts +142 -0
  261. package/dist/errors-yQwfgrcX.d.ts +142 -0
  262. package/dist/{index-BF2JB_Ug.d.mts → index-C6oXchjN.d.mts} +1 -1
  263. package/dist/{index-4NPXDzlD.d.ts → index-P56zy_z5.d.ts} +1 -1
  264. package/dist/index.d.mts +11 -147
  265. package/dist/index.d.ts +11 -147
  266. package/dist/index.js +15 -11
  267. package/dist/index.mjs +14 -10
  268. package/dist/install-integrity.json +141 -104
  269. package/dist/plays/bundle-play-file.d.mts +3 -3
  270. package/dist/plays/bundle-play-file.d.ts +3 -3
  271. package/dist/plays/bundle-play-file.mjs +2 -1
  272. package/dist/plays/play-description.d.mts +2 -2
  273. package/dist/plays/play-description.d.ts +2 -2
  274. package/dist/plays/play-description.js +2 -2
  275. package/dist/plays/play-description.mjs +1 -1
  276. package/dist/plays/run-request.d.mts +2 -2
  277. package/dist/plays/run-request.d.ts +2 -2
  278. package/dist/release.d.mts +1 -1
  279. package/dist/release.d.ts +1 -1
  280. package/dist/release.js +2 -2
  281. package/dist/release.mjs +1 -1
  282. package/dist/server.d.mts +17 -0
  283. package/dist/server.d.ts +17 -0
  284. package/dist/server.js +76 -0
  285. package/dist/server.mjs +76 -0
  286. package/package.json +6 -1
  287. package/dist/cli/auth-IACERYQH.js +0 -40
  288. package/dist/cli/chunk-PQUUWFXY.js +0 -95
  289. package/dist/cli/chunk-YBWAG72P.mjs +0 -95
  290. package/dist/cli/chunk-YQDUODZW.js +0 -1710
  291. package/dist/cli/git-JVI36ZFV.js +0 -24
  292. package/dist/cli/search-75X5LTDE.js +0 -30
  293. package/dist/cli/skills-BKJ53JOQ.js +0 -30
  294. package/dist/cli/tools-COWMIEJ6.mjs +0 -45
  295. package/dist/cli/tools-TASOCE7I.js +0 -45
  296. package/dist/cli/update-SJIKVME6.js +0 -32
@@ -1,4 +1,13 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import {
3
+ chmodSync,
4
+ lstatSync,
5
+ mkdtempSync,
6
+ rmSync,
7
+ writeFileSync,
8
+ } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { isAbsolute, join } from 'node:path';
2
11
 
3
12
  const FLY_REGISTRY_COMMAND_TIMEOUT_MS = 30_000;
4
13
  const RUNTIME_IMAGE_MANIFEST_TIMEOUT_MS = 10_000;
@@ -33,7 +42,12 @@ function run(
33
42
  const spawnCommand: FlyRegistryCommandSpawn =
34
43
  spawnOverride ??
35
44
  ((executable, commandArgs, spawnOptions) =>
36
- spawnSync(executable, [...commandArgs], spawnOptions));
45
+ spawnSync(executable, [...commandArgs], {
46
+ ...spawnOptions,
47
+ // Bun's default child environment can retain startup values; pass the
48
+ // current operation environment explicitly to every native command.
49
+ env: { ...process.env },
50
+ }));
37
51
  const result = spawnCommand(command, args, {
38
52
  encoding: 'utf8',
39
53
  killSignal: 'SIGKILL',
@@ -101,11 +115,9 @@ export const FLY_REGISTRY_AUTH_ATTEMPTS = 5;
101
115
  const FLY_REGISTRY_AUTH_RETRY_DELAY_MS = 1_500;
102
116
 
103
117
  /**
104
- * Authenticate the local docker client against the Fly registry. Concurrent
105
- * release tracks each run this; on macOS two simultaneous credential-store
106
- * writes race on the keychain item ("already exists", -25299) and one of
107
- * them fails even though the credentials are in place, so a failed attempt
108
- * is retried after a short pause instead of failing the track.
118
+ * Authenticate the native Docker client with bounded retries. Standalone
119
+ * callers retain their credential configuration; Preview image operations
120
+ * isolate their stores for the complete auth/read/publish lifecycle.
109
121
  */
110
122
  export function authenticateFlyRegistry(
111
123
  sleep: (ms: number) => void = sleepSync,
@@ -148,3 +160,95 @@ export function authenticateFlyRegistry(
148
160
  function sleepSync(ms: number): void {
149
161
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
150
162
  }
163
+
164
+ /**
165
+ * One synchronous image operation owns its registry credentials. No inherited
166
+ * Docker config or credential helper is read, copied, changed or restored.
167
+ * Native auth and every registry command in operation inherit this directory.
168
+ */
169
+ export function withIsolatedFlyRegistryCredentialsSync<T>(
170
+ operation: () => T,
171
+ operationRoot?: string,
172
+ ): T {
173
+ // Standalone image tooling keeps its existing credential/config behavior.
174
+ // The prepared Preview gate supplies this already-owned private root and
175
+ // also removes it after every image track has stopped, including crashes.
176
+ if (!operationRoot) return operation();
177
+ const root = lstatSync(operationRoot);
178
+ if (
179
+ !isAbsolute(operationRoot) ||
180
+ !root.isDirectory() ||
181
+ root.isSymbolicLink() ||
182
+ (root.mode & 0o077) !== 0 ||
183
+ (process.getuid !== undefined && root.uid !== process.getuid())
184
+ ) {
185
+ throw new Error(
186
+ 'Isolated registry credentials require an owned private operation directory.',
187
+ );
188
+ }
189
+ for (const name of ['DOCKER_CONTEXT', 'BUILDX_BUILDER']) {
190
+ if (process.env[name]) {
191
+ throw new Error(
192
+ `Isolated Preview registry commands do not support custom ${name}.`,
193
+ );
194
+ }
195
+ }
196
+ const inherited = process.env.DOCKER_CONFIG;
197
+ const inheritedAuth = process.env.DOCKER_AUTH_CONFIG;
198
+ const inheritedDirectory = inherited || join(homedir(), '.docker');
199
+ const directory = mkdtempSync(join(operationRoot, 'registry-'));
200
+ let failed = false;
201
+ let originalError: unknown;
202
+ try {
203
+ chmodSync(directory, 0o700);
204
+ writeFileSync(
205
+ join(directory, 'config.json'),
206
+ JSON.stringify({
207
+ // An actual auth-map entry prevents Docker's automatic native-helper
208
+ // discovery. An empty config alone can still select the shared keychain.
209
+ auths: { 'registry.fly.io': {} },
210
+ // Preserve the ordinary user plugin search path without copying auth,
211
+ // native-helper configuration, contexts, certificates or builder state.
212
+ cliPluginsExtraDirs: [join(inheritedDirectory, 'cli-plugins')],
213
+ }),
214
+ { mode: 0o600, flag: 'wx' },
215
+ );
216
+ process.env.DOCKER_CONFIG = directory;
217
+ delete process.env.DOCKER_AUTH_CONFIG;
218
+ // Require the CLI so Fly cannot fall back to writing ~/.docker/config.json.
219
+ // This also proves Buildx is discoverable with the isolated plugin config.
220
+ if (
221
+ !run('docker', ['buildx', 'version'], true, 10_000) ||
222
+ !run(
223
+ 'docker',
224
+ ['buildx', 'imagetools', 'inspect', '--help'],
225
+ true,
226
+ 10_000,
227
+ )
228
+ ) {
229
+ throw new Error(
230
+ 'Runtime images require Docker Buildx in the isolated registry configuration.',
231
+ );
232
+ }
233
+ return operation();
234
+ } catch (error) {
235
+ failed = true;
236
+ originalError = error;
237
+ throw error;
238
+ } finally {
239
+ if (inherited === undefined) delete process.env.DOCKER_CONFIG;
240
+ else process.env.DOCKER_CONFIG = inherited;
241
+ if (inheritedAuth === undefined) delete process.env.DOCKER_AUTH_CONFIG;
242
+ else process.env.DOCKER_AUTH_CONFIG = inheritedAuth;
243
+ try {
244
+ rmSync(directory, { recursive: true, force: true });
245
+ } catch (cleanupError) {
246
+ if (failed)
247
+ throw new AggregateError(
248
+ [originalError, cleanupError],
249
+ 'Registry operation and private credential cleanup failed.',
250
+ );
251
+ throw cleanupError;
252
+ }
253
+ }
254
+ }
@@ -11,6 +11,7 @@ import {
11
11
  percentile,
12
12
  runtimeJsonByteLength,
13
13
  type RuntimeMemoryLedgerHandle,
14
+ type RuntimeMemoryLedgerCategory,
14
15
  } from './memory-ledger';
15
16
  import type {
16
17
  RuntimeMemoryOccupancy,
@@ -97,6 +98,10 @@ export type RuntimeReceiptHydrationGateSnapshot = {
97
98
  bytesAdmitted: number;
98
99
  /** Bytes turns reported actually holding, replacing their reservation. */
99
100
  bytesMeasured: number;
101
+ /** Turns with a successful first byte settlement, including zero bytes. */
102
+ measuredTurns: number;
103
+ /** Largest first successful settlement, not an admission estimate. */
104
+ bytesMeasuredMax: number;
100
105
  /** Admission attempts the byte budget refused. */
101
106
  holds: number;
102
107
  /** Collections taken to answer a hold before it was declared. */
@@ -129,6 +134,8 @@ export type RuntimeReceiptHydrationTurn = {
129
134
  * ledger stops carrying an estimate the moment a measurement exists.
130
135
  */
131
136
  settleBytes(bytes: number): void;
137
+ /** Opt-in cooperative scheduling after measured text, before expanding it. */
138
+ waitForCooperativeWork?(signal?: AbortSignal): void | Promise<void>;
132
139
  /** Drop the reservation. Idempotent. */
133
140
  release(): void;
134
141
  };
@@ -208,6 +215,10 @@ export function createRuntimeReceiptHydrationGate(input: {
208
215
  occupancy: RuntimeMemoryOccupancyReader;
209
216
  /** Registers this lane's reservations on the runtime byte ledger. */
210
217
  reserve: (bytes: number) => RuntimeMemoryLedgerHandle;
218
+ /** Must match the category registered by reserve; omitted keeps hydration compatibility. */
219
+ reservationCategory?: RuntimeMemoryLedgerCategory;
220
+ /** Process-local measured-work handoff; omitted preserves existing scheduling. */
221
+ cooperativeYieldBytes?: number;
211
222
  /**
212
223
  * Re-examines the queue while turns wait, so headroom freed by work outside
213
224
  * this lane (a row settling, a body released) reaches a waiter without
@@ -221,6 +232,16 @@ export function createRuntimeReceiptHydrationGate(input: {
221
232
  now?: () => number;
222
233
  }): RuntimeReceiptHydrationGate {
223
234
  const occupancyReader = input.occupancy;
235
+ const reservationCategory = input.reservationCategory ?? 'hydrationReadBack';
236
+ const cooperativeYieldBytes = input.cooperativeYieldBytes ?? null;
237
+ if (
238
+ cooperativeYieldBytes !== null &&
239
+ (!Number.isSafeInteger(cooperativeYieldBytes) || cooperativeYieldBytes <= 0)
240
+ ) {
241
+ throw new RangeError(
242
+ 'Cooperative byte-work budget must be a positive safe integer.',
243
+ );
244
+ }
224
245
  const now = input.now ?? Date.now;
225
246
  const probeIntervalMs = Math.max(
226
247
  1,
@@ -252,6 +273,7 @@ export function createRuntimeReceiptHydrationGate(input: {
252
273
  let bytesHeldPeak = 0;
253
274
  let bytesAdmitted = 0;
254
275
  let bytesMeasured = 0;
276
+ let bytesMeasuredMax = 0;
255
277
  let holds = 0;
256
278
  let holdCollections = 0;
257
279
  let progressAdmissions = 0;
@@ -285,6 +307,50 @@ export function createRuntimeReceiptHydrationGate(input: {
285
307
  };
286
308
  const waiters: HydrationWaiter[] = [];
287
309
  let timer: ReturnType<typeof setInterval> | null = null;
310
+ let cooperativeWorkBytes = 0;
311
+ let cooperativeTimer: ReturnType<typeof setTimeout> | null = null;
312
+ let cooperativeWait: Promise<void> | null = null;
313
+ let finishCooperativeWait: ((error?: Error) => void) | null = null;
314
+
315
+ function waitForCooperativeBudget(
316
+ bytes: number,
317
+ isPending: () => boolean,
318
+ ): void | Promise<void> {
319
+ if (!isPending()) return;
320
+ if (closed) throw new RuntimeReceiptHydrationGateClosedError();
321
+ if (cooperativeYieldBytes === null) return;
322
+ if (cooperativeWait !== null) {
323
+ // A callback is not permission for every ready decoder. Recheck each
324
+ // measured body in arrival order before its caller can expand JSON.
325
+ return cooperativeWait.then(() =>
326
+ waitForCooperativeBudget(bytes, isPending),
327
+ );
328
+ }
329
+ if (
330
+ cooperativeWorkBytes > 0 &&
331
+ bytes > cooperativeYieldBytes - cooperativeWorkBytes
332
+ ) {
333
+ cooperativeWait = new Promise<void>((resolve, reject) => {
334
+ finishCooperativeWait = (error) => (error ? reject(error) : resolve());
335
+ cooperativeTimer = setTimeout(() => {
336
+ cooperativeTimer = null;
337
+ cooperativeWorkBytes = 0;
338
+ cooperativeWait = null;
339
+ const finish = finishCooperativeWait;
340
+ finishCooperativeWait = null;
341
+ finish?.();
342
+ }, 0);
343
+ });
344
+ return cooperativeWait.then(() =>
345
+ waitForCooperativeBudget(bytes, isPending),
346
+ );
347
+ }
348
+ // Threshold state only: a single legal oversized body retains progress.
349
+ cooperativeWorkBytes = Math.min(
350
+ cooperativeYieldBytes,
351
+ cooperativeWorkBytes + bytes,
352
+ );
353
+ }
288
354
 
289
355
  const recordPerKeySample = (bytesPerKey: number): void => {
290
356
  sampledTurns += 1;
@@ -323,17 +389,9 @@ export function createRuntimeReceiptHydrationGate(input: {
323
389
  ? Math.max(1, Math.ceil(waiter.receiptKeys * priceKey(occupancy)))
324
390
  : Math.max(1, waiter.expectedBytes);
325
391
 
326
- /**
327
- * Live bytes per ledger byte for what this lane actually registers.
328
- *
329
- * The lane's reservations land on `hydrationReadBack`, so that is the
330
- * category whose factor converts them. The process-wide mix-weighted factor
331
- * is a different question's answer: a run whose ledger is mostly decoded
332
- * provider bodies reports ~3x, and pricing a receipt read at 3x its wire
333
- * size holds turns against headroom the read was never going to occupy.
334
- */
335
- const hydrationFactor = (occupancy: RuntimeMemoryOccupancy): number =>
336
- occupancy.categoryFactors.hydrationReadBack;
392
+ /** Convert expected bytes at the factor of this lane's actual reservation. */
393
+ const reservationFactor = (occupancy: RuntimeMemoryOccupancy): number =>
394
+ occupancy.categoryFactors[reservationCategory];
337
395
 
338
396
  const stopTimer = (): void => {
339
397
  if (timer === null) return;
@@ -380,6 +438,10 @@ export function createRuntimeReceiptHydrationGate(input: {
380
438
  let entryBytes = reservedBytes;
381
439
  let settled = false;
382
440
  let released = false;
441
+ let measuredWorkBytes: number | null = null;
442
+ let workWait: Promise<void> | null = null;
443
+ let workAccounted = false;
444
+ let cancelWorkWait: ((error: unknown) => void) | null = null;
383
445
  waiter.resolve({
384
446
  settleBytes(bytes) {
385
447
  if (released || settled) return;
@@ -390,10 +452,12 @@ export function createRuntimeReceiptHydrationGate(input: {
390
452
  }
391
453
  settled = true;
392
454
  const measuredBytes = Math.ceil(bytes);
455
+ measuredWorkBytes = measuredBytes;
393
456
  handle.update(measuredBytes);
394
457
  bytesHeld = Math.max(0, bytesHeld - entryBytes + measuredBytes);
395
458
  bytesHeldPeak = Math.max(bytesHeldPeak, bytesHeld);
396
459
  bytesMeasured += measuredBytes;
460
+ bytesMeasuredMax = Math.max(bytesMeasuredMax, measuredBytes);
397
461
  source.bytesMeasured += measuredBytes;
398
462
  entryBytes = measuredBytes;
399
463
  recordPerKeySample(
@@ -403,9 +467,51 @@ export function createRuntimeReceiptHydrationGate(input: {
403
467
  // headroom; hand it to whoever is waiting rather than to the clock.
404
468
  admitWaiters();
405
469
  },
470
+ waitForCooperativeWork(signal) {
471
+ if (cooperativeYieldBytes === null) return;
472
+ if (workWait !== null) return workWait;
473
+ if (workAccounted) return;
474
+ if (released || closed)
475
+ return Promise.reject(new RuntimeReceiptHydrationGateClosedError());
476
+ if (signal?.aborted)
477
+ return Promise.reject(hydrationAbortReason(signal));
478
+ if (measuredWorkBytes === null) {
479
+ return Promise.reject(
480
+ new Error('Cooperative body work requires settled bytes.'),
481
+ );
482
+ }
483
+ let pending = true;
484
+ const wait = waitForCooperativeBudget(measuredWorkBytes, () => pending);
485
+ if (!wait) {
486
+ // Preserve the healthy thin path: no promise, callback or new await.
487
+ workAccounted = true;
488
+ return;
489
+ }
490
+ workWait = new Promise<void>((resolve, reject) => {
491
+ const finish = (ok: boolean, error?: unknown) => {
492
+ if (!pending) return;
493
+ pending = false;
494
+ signal?.removeEventListener('abort', onAbort);
495
+ cancelWorkWait = null;
496
+ if (ok) {
497
+ workAccounted = true;
498
+ resolve();
499
+ } else reject(error);
500
+ };
501
+ const onAbort = () => finish(false, hydrationAbortReason(signal!));
502
+ cancelWorkWait = (error) => finish(false, error);
503
+ signal?.addEventListener('abort', onAbort, { once: true });
504
+ void wait.then(
505
+ () => finish(true),
506
+ (error: unknown) => finish(false, error),
507
+ );
508
+ });
509
+ return workWait;
510
+ },
406
511
  release() {
407
512
  if (released) return;
408
513
  released = true;
514
+ cancelWorkWait?.(new RuntimeReceiptHydrationGateClosedError());
409
515
  handle.release();
410
516
  bytesHeld = Math.max(0, bytesHeld - entryBytes);
411
517
  entryBytes = 0;
@@ -444,7 +550,7 @@ export function createRuntimeReceiptHydrationGate(input: {
444
550
  perKeyBytes = Math.ceil(reservedBytes / Math.max(1, waiter.receiptKeys));
445
551
  headroomBytes = occupancy.headroomBytes;
446
552
  if (
447
- reservedBytes * hydrationFactor(occupancy) <=
553
+ reservedBytes * reservationFactor(occupancy) <=
448
554
  occupancy.headroomBytes
449
555
  ) {
450
556
  admit(waiter, reservedBytes);
@@ -462,7 +568,7 @@ export function createRuntimeReceiptHydrationGate(input: {
462
568
  );
463
569
  headroomBytes = occupancy.headroomBytes;
464
570
  if (
465
- reservedBytes * hydrationFactor(occupancy) <=
571
+ reservedBytes * reservationFactor(occupancy) <=
466
572
  occupancy.headroomBytes
467
573
  ) {
468
574
  admit(waiter, reservedBytes);
@@ -560,6 +666,8 @@ export function createRuntimeReceiptHydrationGate(input: {
560
666
  bytesHeldPeak,
561
667
  bytesAdmitted,
562
668
  bytesMeasured,
669
+ measuredTurns: sampledTurns,
670
+ bytesMeasuredMax,
563
671
  holds,
564
672
  holdCollections,
565
673
  progressAdmissions,
@@ -580,6 +688,12 @@ export function createRuntimeReceiptHydrationGate(input: {
580
688
  close() {
581
689
  closed = true;
582
690
  stopTimer();
691
+ if (cooperativeTimer !== null) clearTimeout(cooperativeTimer);
692
+ cooperativeTimer = null;
693
+ cooperativeWait = null;
694
+ const finish = finishCooperativeWait;
695
+ finishCooperativeWait = null;
696
+ finish?.(new RuntimeReceiptHydrationGateClosedError());
583
697
  // A closed lane will never admit again. Stranding queued turns on an
584
698
  // unsettleable promise is the wait this contract forbids.
585
699
  const stranded = waiters.splice(0, waiters.length);
@@ -35,6 +35,7 @@ export const RUNTIME_EXECUTION_CAPABILITIES = [
35
35
  'billing.write',
36
36
  'egress.fetch',
37
37
  'secret.resolve',
38
+ 'page.write',
38
39
  ] as const;
39
40
 
40
41
  export type RuntimeExecutionCapability =
@@ -90,9 +91,21 @@ export type RuntimeAuthorityDescriptor = {
90
91
  capabilities: RuntimeExecutionCapability[];
91
92
  };
92
93
 
94
+ /**
95
+ * Readers reject a token naming a capability they do not know, and the release
96
+ * canary mints with a new app against the deployed gateway. So a new capability
97
+ * ships known-but-withheld here, and joins the defaults only once every reader
98
+ * that verifies these tokens has deployed it. `page.write` is withheld until
99
+ * then; Play page writes fail closed (PAGES_UNAVAILABLE) meanwhile.
100
+ */
101
+ const WITHHELD_FROM_DEFAULT_CAPABILITIES = new Set<RuntimeExecutionCapability>([
102
+ 'run.ledger.project',
103
+ 'page.write',
104
+ ]);
105
+
93
106
  export const DEFAULT_RUNTIME_EXECUTION_CAPABILITIES = [
94
107
  ...RUNTIME_EXECUTION_CAPABILITIES.filter(
95
- (capability) => capability !== 'run.ledger.project',
108
+ (capability) => !WITHHELD_FROM_DEFAULT_CAPABILITIES.has(capability),
96
109
  ),
97
110
  ] as const satisfies readonly RuntimeExecutionCapability[];
98
111
 
@@ -62,8 +62,14 @@ export type FixtureReplayBundle = {
62
62
  bundleId: string;
63
63
  manifestSha256: string;
64
64
  syntheticFallbackToolIds?: string[];
65
+ /** Opt-in response selection by seed + semantic payload, independent of run/org identities. */
66
+ selectionSeed?: string;
65
67
  };
66
68
 
69
+ export function isFixtureReplaySelectionSeed(value: unknown): value is string {
70
+ return typeof value === 'string' && /^[A-Za-z0-9._:-]{1,128}$/.test(value);
71
+ }
72
+
67
73
  export type FixtureBehaviorV3 = {
68
74
  version: typeof FIXTURE_BEHAVIOR_REPLAY_VERSION;
69
75
  responseSamples: FixtureResponseSample[];
@@ -519,7 +525,8 @@ export function validateFixtureBehavior(
519
525
  (key) =>
520
526
  key !== 'bundleId' &&
521
527
  key !== 'manifestSha256' &&
522
- key !== 'syntheticFallbackToolIds',
528
+ key !== 'syntheticFallbackToolIds' &&
529
+ key !== 'selectionSeed',
523
530
  );
524
531
  if (replayUnknownKeys.length > 0) {
525
532
  return {
@@ -530,6 +537,16 @@ export function validateFixtureBehavior(
530
537
  };
531
538
  }
532
539
  const digestPattern = /^[a-f0-9]{64}$/;
540
+ if (
541
+ replay.selectionSeed !== undefined &&
542
+ !isFixtureReplaySelectionSeed(replay.selectionSeed)
543
+ ) {
544
+ return {
545
+ ok: false,
546
+ error:
547
+ 'fixtureBehavior.replayBundle.selectionSeed must contain 1-128 letters, digits, dots, underscores, colons or hyphens.',
548
+ };
549
+ }
533
550
  if (
534
551
  typeof replay.bundleId !== 'string' ||
535
552
  !digestPattern.test(replay.bundleId)
@@ -585,6 +602,9 @@ export function validateFixtureBehavior(
585
602
  bundleId: replay.bundleId,
586
603
  manifestSha256: replay.manifestSha256,
587
604
  ...(syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}),
605
+ ...(replay.selectionSeed !== undefined
606
+ ? { selectionSeed: replay.selectionSeed as string }
607
+ : {}),
588
608
  };
589
609
  }
590
610
  if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
@@ -778,6 +798,29 @@ export type FixtureExecuteBoundaryCounts = {
778
798
  unprovenResponses: number;
779
799
  };
780
800
 
801
+ /** Fixture-only evidence; no provider payload, identity, or resource path. */
802
+ export type FixtureReplaySelectionWitness = {
803
+ kind: 'retained_response' | 'synthetic_fallback' | 'unproven';
804
+ toolId: string;
805
+ selectionKeySha256: string | null;
806
+ responseStatus: 'completed' | 'no_result' | null;
807
+ normalizedResponseSha256: string | null;
808
+ normalizedResponseBytes: number | null;
809
+ bundleId: string;
810
+ manifestSha256: string;
811
+ sampleIndex: number | null;
812
+ sampleKeySha256: string | null;
813
+ sampleSha256: string | null;
814
+ compressedBytes: number | null;
815
+ uncompressedBytes: number | null;
816
+ unprovenReason:
817
+ | 'missing_selection'
818
+ | 'multiple_selections'
819
+ | 'streaming'
820
+ | 'async_boundary'
821
+ | null;
822
+ };
823
+
781
824
  export const FIXTURE_EXECUTE_BOUNDARY_COUNTER_KINDS = {
782
825
  started: 'boundary_started',
783
826
  finished: 'boundary_finished',
@@ -798,6 +841,7 @@ export function fixtureRunCallCounterKey(input: {
798
841
  | 'duplicate_success_members'
799
842
  | 'unproven_successes'
800
843
  | 'quota_attempts'
844
+ | 'replay_selections'
801
845
  | 'boundary_started'
802
846
  | 'boundary_finished'
803
847
  | 'boundary_expected_failures'
@@ -834,6 +878,18 @@ export function fixtureQuotaAttemptKey(input: {
834
878
  return `${fixtureRunCallCounterKey({ ...input, kind: 'quota_attempts' })}:attempt:${input.ordinal}`;
835
879
  }
836
880
 
881
+ /** Every successful fixture boundary owns a slot, including repeated inputs. */
882
+ export function fixtureReplaySelectionWitnessKey(input: {
883
+ orgId: string;
884
+ runId: string;
885
+ shard: number;
886
+ ordinal: number;
887
+ }): string {
888
+ if (!Number.isSafeInteger(input.ordinal) || input.ordinal < 1)
889
+ throw new Error('Fixture replay witness requires a positive safe ordinal.');
890
+ return `${fixtureRunCallCounterKey({ ...input, kind: 'replay_selections' })}:selection:${input.ordinal}`;
891
+ }
892
+
837
893
  export function fixtureRunCallCounterShard(
838
894
  durableCallReceiptKey: string,
839
895
  ): number {