deepline 0.3.408 → 0.3.410

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 (217) hide show
  1. package/dist/bundling-sources/sdk/src/agent-runtime.ts +18 -1
  2. package/dist/bundling-sources/sdk/src/client.ts +212 -334
  3. package/dist/bundling-sources/sdk/src/compat.ts +45 -2
  4. package/dist/bundling-sources/sdk/src/db/query.ts +9 -10
  5. package/dist/bundling-sources/sdk/src/http.ts +38 -20
  6. package/dist/bundling-sources/sdk/src/index.ts +4 -5
  7. package/dist/bundling-sources/sdk/src/play.ts +10 -10
  8. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +6 -4
  9. package/dist/bundling-sources/sdk/src/plays/check-local-play-graph.ts +114 -0
  10. package/dist/bundling-sources/sdk/src/plays/client.ts +431 -0
  11. package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +2 -2
  12. package/dist/bundling-sources/sdk/src/plays/run-request.ts +106 -16
  13. package/dist/bundling-sources/sdk/src/release.ts +13 -7
  14. package/dist/bundling-sources/sdk/src/runs/read-errors.ts +8 -0
  15. package/dist/bundling-sources/sdk/src/runs/watch-polling.ts +124 -13
  16. package/dist/bundling-sources/sdk/src/tool-calls.ts +108 -19
  17. package/dist/bundling-sources/sdk/src/types.ts +18 -0
  18. package/dist/bundling-sources/shared_libs/integration-contracts/execute-retry-contract.ts +37 -0
  19. package/dist/bundling-sources/shared_libs/integration-contracts/package.json +3 -0
  20. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +3 -1
  21. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +277 -76
  22. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +6 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/dataset-row-input.ts +124 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -62
  25. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +1 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/durable-tool-identity.ts +67 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +64 -6
  28. package/dist/bundling-sources/shared_libs/play-runtime/freshness-receipt-execution.ts +1 -5
  29. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +1 -1
  30. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +3 -0
  31. package/dist/bundling-sources/shared_libs/play-runtime/play-http-request.ts +10 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/query-result-dataset.ts +3 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +3 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +26 -16
  35. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +36 -11
  36. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +35 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +21 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +21 -6
  39. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +11 -2
  40. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +85 -20
  41. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +71 -13
  42. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-execution-queries.ts +100 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +9 -5
  44. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +337 -146
  45. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +26 -12
  46. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +3 -1
  47. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +425 -102
  48. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +4 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +9 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +181 -124
  52. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-worker-wake.ts +152 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -3
  54. package/dist/bundling-sources/shared_libs/play-runtime/tool-cache-policy.ts +31 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +10 -0
  56. package/dist/bundling-sources/shared_libs/plays/ambiguous-write-error.ts +25 -0
  57. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
  58. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +63 -68
  59. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +129 -63
  60. package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
  61. package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +58 -16
  62. package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +50 -0
  63. package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +351 -0
  64. package/dist/bundling-sources/shared_libs/plays/tool-list-getter-mode.ts +9 -0
  65. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  66. package/dist/cli/{auth-UVD3CUBB.mjs → auth-LLXLIILR.mjs} +6 -6
  67. package/dist/cli/auth-UG4WOYGL.js +40 -0
  68. package/dist/cli/{billing-BZVTXXLM.mjs → billing-5FVXZYAC.mjs} +8 -8
  69. package/dist/cli/{billing-BZVYAF6T.js → billing-NFPK7GYP.js} +84 -84
  70. package/dist/cli/{chunk-ZAAKSJAS.js → chunk-27GJKC5Q.js} +17 -10
  71. package/dist/cli/{chunk-UHNDVD3P.js → chunk-2H4EY7KH.js} +100 -41
  72. package/dist/cli/{chunk-WTT6CLED.mjs → chunk-2YR7BIIC.mjs} +5 -2
  73. package/dist/cli/{chunk-3ZB6IIA7.js → chunk-36AHOWVS.js} +26 -26
  74. package/dist/cli/{chunk-OSDXE27V.mjs → chunk-4PG4ARL2.mjs} +17 -10
  75. package/dist/cli/{chunk-LOYISF7S.mjs → chunk-4XQLVUC7.mjs} +738 -512
  76. package/dist/cli/{chunk-J5PTX66Y.js → chunk-5MLCBXXU.js} +8 -1
  77. package/dist/cli/chunk-5TUGWDEB.js +313 -0
  78. package/dist/cli/{chunk-D6FFBSM5.js → chunk-5UUQAGJS.js} +5 -2
  79. package/dist/cli/{chunk-4CFULMRB.mjs → chunk-5V5Y37BC.mjs} +2 -2
  80. package/dist/cli/{chunk-PMVFAYL7.mjs → chunk-63ILLN5H.mjs} +2 -2
  81. package/dist/cli/{chunk-AUMD2VXP.js → chunk-63S7X326.js} +1032 -806
  82. package/dist/cli/{chunk-4QFT5LGV.mjs → chunk-6PGATQ6L.mjs} +6 -3
  83. package/dist/cli/{chunk-6BJK4EJ3.mjs → chunk-AARWVK4C.mjs} +2132 -65
  84. package/dist/cli/{chunk-FERRDNMO.js → chunk-AD47BXN2.js} +5 -5
  85. package/dist/cli/{chunk-4RNDKFNQ.js → chunk-D37FEBES.js} +2 -2
  86. package/dist/cli/{chunk-S6R3OX7B.js → chunk-E4CABWXL.js} +25 -2
  87. package/dist/cli/{chunk-NXGCO4JB.mjs → chunk-E4IXDAZI.mjs} +5 -0
  88. package/dist/cli/chunk-EQ4Z7RJW.mjs +35 -0
  89. package/dist/cli/chunk-FR2ILQ4G.mjs +8 -0
  90. package/dist/cli/{chunk-QUAQX3FQ.js → chunk-FVLNYDI4.js} +128 -376
  91. package/dist/cli/{chunk-BRJUESQV.js → chunk-FZJAM576.js} +50 -50
  92. package/dist/cli/{chunk-BZAMOCPA.mjs → chunk-IMZ56EOH.mjs} +3 -3
  93. package/dist/cli/{chunk-IOHRWLQE.mjs → chunk-IPG42SD2.mjs} +452 -138
  94. package/dist/cli/chunk-J33TSWO5.js +8 -0
  95. package/dist/cli/{chunk-XXLXOUUU.mjs → chunk-JNXJZ577.mjs} +1 -1
  96. package/dist/cli/{chunk-JI2B4RZP.mjs → chunk-KCC3FKIW.mjs} +71 -12
  97. package/dist/cli/{chunk-6IKARAYD.mjs → chunk-L2VKAASU.mjs} +23 -0
  98. package/dist/cli/{chunk-PYZZMAJQ.mjs → chunk-LFSHGNT2.mjs} +8 -1
  99. package/dist/cli/{chunk-2XXXFPTD.js → chunk-LTFL4JRN.js} +426 -721
  100. package/dist/cli/{chunk-YHPYUZZX.mjs → chunk-MAMVGOSC.mjs} +1 -1
  101. package/dist/cli/{chunk-URACNNLO.mjs → chunk-MN2OWLFA.mjs} +2 -2
  102. package/dist/cli/{chunk-Q3PUHXOY.js → chunk-NF4V5DTY.js} +12 -12
  103. package/dist/cli/{chunk-Q2E4E4FJ.js → chunk-NPBJI7RE.js} +8 -8
  104. package/dist/cli/chunk-NTVLGHFM.js +501 -0
  105. package/dist/cli/{chunk-HQXL5526.mjs → chunk-NUX2QHNC.mjs} +1 -1
  106. package/dist/cli/{chunk-E3PJF6YP.js → chunk-OBB4QXHA.js} +19 -4
  107. package/dist/cli/{chunk-SEFMGO3Z.js → chunk-OQQOXSYA.js} +2184 -117
  108. package/dist/cli/chunk-OZ6E3IRZ.js +6084 -0
  109. package/dist/cli/{chunk-7P5AA3SN.js → chunk-PPDBRJRW.js} +6 -1
  110. package/dist/cli/{chunk-IWBXJDZA.mjs → chunk-PZSLPBDA.mjs} +2 -2
  111. package/dist/cli/{chunk-ILHRA7AD.js → chunk-QADCFSGH.js} +7 -7
  112. package/dist/cli/{chunk-ECVLPS67.js → chunk-QJI5FIOW.js} +170 -49
  113. package/dist/cli/{chunk-I3DHIXVJ.mjs → chunk-QL22Y56M.mjs} +149 -28
  114. package/dist/cli/{chunk-SD7MXAJA.mjs → chunk-RFB25DSQ.mjs} +36 -284
  115. package/dist/cli/chunk-T44IIOT6.mjs +501 -0
  116. package/dist/cli/chunk-VK2LZ5IP.js +35 -0
  117. package/dist/cli/chunk-VKKVSFRD.js +62 -0
  118. package/dist/cli/{chunk-RWCY6YI2.js → chunk-VYKV5XHL.js} +644 -330
  119. package/dist/cli/{chunk-GSK6NHVM.js → chunk-WU4U6VSB.js} +5 -5
  120. package/dist/cli/chunk-XHLKJOTN.mjs +313 -0
  121. package/dist/cli/{chunk-MJELBQBU.mjs → chunk-XIHWSXSV.mjs} +330 -625
  122. package/dist/cli/chunk-XNZJKRJA.mjs +6084 -0
  123. package/dist/cli/chunk-ZCALLYF6.mjs +62 -0
  124. package/dist/cli/{chunk-ZBABPK6Y.js → chunk-ZFZ427HN.js} +11 -8
  125. package/dist/cli/{chunk-SJVVBWRL.mjs → chunk-ZKYEW55U.mjs} +16 -1
  126. package/dist/cli/command-docs.js +2 -2
  127. package/dist/cli/command-docs.mjs +1 -1
  128. package/dist/cli/{csv-XLGLHJ6P.js → csv-7U3FJYKZ.js} +14 -14
  129. package/dist/cli/{csv-WPSXG6ZZ.mjs → csv-ZWLDMM4A.mjs} +5 -5
  130. package/dist/cli/{db-5PTNJG4X.js → db-DNCGV5PC.js} +42 -47
  131. package/dist/cli/{db-ABS57ABJ.mjs → db-IMYXVMGI.mjs} +15 -20
  132. package/dist/cli/{describe-PVWQJ2PB.mjs → describe-Q23DWJUK.mjs} +20 -15
  133. package/dist/cli/{describe-EZS6PQXA.js → describe-S34JUX5W.js} +27 -22
  134. package/dist/cli/describe-core.d.mts +2 -2
  135. package/dist/cli/describe-core.d.ts +2 -2
  136. package/dist/cli/describe-core.js +6 -6
  137. package/dist/cli/describe-core.mjs +5 -5
  138. package/dist/cli/{executions-OKJGATQZ.mjs → executions-A73EUGSI.mjs} +8 -8
  139. package/dist/cli/{executions-FNTAFQ7Y.js → executions-XOMPX2YJ.js} +10 -10
  140. package/dist/cli/{feedback-W27HDMRR.mjs → feedback-N4GJ2POI.mjs} +11 -7
  141. package/dist/cli/{feedback-6YBOMSUA.js → feedback-QTCHNJJH.js} +13 -9
  142. package/dist/cli/{git-YOOUEL6M.mjs → git-4Q3JIQYZ.mjs} +6 -6
  143. package/dist/cli/git-I6CPBEVG.js +24 -0
  144. package/dist/cli/index.js +240 -352
  145. package/dist/cli/index.mjs +163 -275
  146. package/dist/cli/{legacy-noops-V6OKW7VR.mjs → legacy-noops-3SOVGFF7.mjs} +6 -6
  147. package/dist/cli/{legacy-noops-2VZ7XT6C.js → legacy-noops-4OSHZM34.js} +9 -9
  148. package/dist/cli/{monitors-FBWGVIUS.js → monitors-LVE2KZNG.js} +94 -94
  149. package/dist/cli/{monitors-P2YYWTWT.mjs → monitors-QP2XID2B.mjs} +8 -8
  150. package/dist/cli/{org-DVMG6H3C.mjs → org-IVRETVQA.mjs} +8 -8
  151. package/dist/cli/{org-3XUSVX5T.js → org-XFLK5IAP.js} +68 -68
  152. package/dist/cli/{play-GNC5CQAS.mjs → play-DE7VH6NU.mjs} +533 -98
  153. package/dist/cli/{play-YG5L4BWQ.js → play-XXTPPP23.js} +1067 -632
  154. package/dist/cli/{providers-7PSWG2OV.js → providers-DLD3I4JF.js} +11 -11
  155. package/dist/cli/{providers-JR33SLWL.mjs → providers-GX2NIZQQ.mjs} +8 -8
  156. package/dist/cli/{quickstart-VUOBQYIQ.mjs → quickstart-72B4L4PK.mjs} +5 -5
  157. package/dist/cli/{quickstart-FDVZ5BL3.js → quickstart-XNS3HSWC.js} +7 -7
  158. package/dist/cli/search-6NCH4HB5.js +30 -0
  159. package/dist/cli/{search-JZYLO33K.mjs → search-SUTRANJI.mjs} +9 -9
  160. package/dist/cli/{secrets-VS266FVA.js → secrets-6OBLOVEV.js} +17 -17
  161. package/dist/cli/{secrets-3MCYBT4I.mjs → secrets-FPFXXNUH.mjs} +8 -8
  162. package/dist/cli/sessions-235532DR.js +16 -0
  163. package/dist/cli/{sessions-ELLLT23E.mjs → sessions-R25I4QKN.mjs} +6 -6
  164. package/dist/cli/{settings-PZCKAFII.mjs → settings-AOP6F5PZ.mjs} +12 -12
  165. package/dist/cli/{settings-7364NMMA.js → settings-VL5FOFPN.js} +79 -79
  166. package/dist/cli/{setup-PMWYLCT6.js → setup-BSC67YT3.js} +45 -44
  167. package/dist/cli/{setup-A7GQ4KIA.mjs → setup-ZMPHBHVJ.mjs} +11 -10
  168. package/dist/cli/skills-3IWLYYRL.js +29 -0
  169. package/dist/cli/{skills-WS6BIFPQ.mjs → skills-KF65TVFO.mjs} +7 -7
  170. package/dist/cli/tools-LR66SPYU.js +44 -0
  171. package/dist/cli/{tools-BR4DOZA2.mjs → tools-SX4XIPM7.mjs} +19 -14
  172. package/dist/cli/{update-D2B7UNFT.mjs → update-QRMFRAQQ.mjs} +11 -9
  173. package/dist/cli/update-SP7UEO53.js +31 -0
  174. package/dist/cli/{workflow-PQXC2R47.mjs → workflow-FOEEEB7G.mjs} +44 -20
  175. package/dist/cli/{workflow-6ODTCYXU.js → workflow-KOCK2FLW.js} +54 -30
  176. package/dist/{client-Z9Pye1Wm.d.mts → client-74k4IPh6.d.mts} +137 -54
  177. package/dist/{client-BcvhDfJJ.d.ts → client-C1IK1f8c.d.ts} +137 -54
  178. package/dist/{compiler-manifest-Ycx-hoAr.d.mts → compiler-manifest-lzWpbV3w.d.mts} +83 -66
  179. package/dist/{compiler-manifest-Ycx-hoAr.d.ts → compiler-manifest-lzWpbV3w.d.ts} +83 -66
  180. package/dist/{index-CZXgiN3E.d.mts → index-C8Cy-YTm.d.ts} +5 -1
  181. package/dist/{index-NPG5pqxQ.d.ts → index-CtNK-0nI.d.mts} +5 -1
  182. package/dist/index.d.mts +47 -9
  183. package/dist/index.d.ts +47 -9
  184. package/dist/index.js +17 -14
  185. package/dist/index.mjs +13 -10
  186. package/dist/install-integrity.json +120 -104
  187. package/dist/plays/bundle-play-file.d.mts +3 -3
  188. package/dist/plays/bundle-play-file.d.ts +3 -3
  189. package/dist/plays/bundle-play-file.mjs +5 -4
  190. package/dist/plays/csv-data-input.js +3 -3
  191. package/dist/plays/csv-data-input.mjs +2 -2
  192. package/dist/plays/play-description.d.mts +2 -2
  193. package/dist/plays/play-description.d.ts +2 -2
  194. package/dist/plays/run-request.d.mts +2 -2
  195. package/dist/plays/run-request.d.ts +2 -2
  196. package/dist/plays/run-request.js +11 -3
  197. package/dist/plays/run-request.mjs +10 -2
  198. package/dist/release.d.mts +15 -6
  199. package/dist/release.d.ts +15 -6
  200. package/dist/release.js +2 -2
  201. package/dist/release.mjs +1 -1
  202. package/package.json +2 -2
  203. package/dist/cli/auth-3GB2K636.js +0 -40
  204. package/dist/cli/chunk-67RWR34T.mjs +0 -155
  205. package/dist/cli/chunk-CLJGSOVM.mjs +0 -1716
  206. package/dist/cli/chunk-HQY2SG3K.js +0 -83
  207. package/dist/cli/chunk-OSFWFV72.js +0 -155
  208. package/dist/cli/chunk-Q3LFI3VH.js +0 -392
  209. package/dist/cli/chunk-WPAB4DCU.mjs +0 -83
  210. package/dist/cli/chunk-YMOFWHGO.mjs +0 -392
  211. package/dist/cli/chunk-Z4VNJOF7.js +0 -1716
  212. package/dist/cli/git-YKUXXJOR.js +0 -24
  213. package/dist/cli/search-PPPYC5OZ.js +0 -30
  214. package/dist/cli/sessions-TEHEWW7O.js +0 -16
  215. package/dist/cli/skills-SYS7VRRK.js +0 -29
  216. package/dist/cli/tools-KK4BKVQR.js +0 -39
  217. package/dist/cli/update-2IV5JTX2.js +0 -29
@@ -11,10 +11,12 @@ import type {
11
11
  import type { ToolExecutionErrorSchemaVersion } from './tool-execution-error';
12
12
  import type { PlayDataset, PlayDatasetInput, PlayDatasetRow } from './dataset';
13
13
 
14
+ export { playToolListGetterMode } from './tool-list-getter-mode';
15
+ export { CtxFetchAmbiguousWriteError } from './ambiguous-write-error';
16
+
14
17
  export const LEGACY_PLAY_AUTHORING_CONTRACT_EDITION = 1 as const;
15
- // Edition 11 readers retain every CSV source row. Promote this writer in the
16
- // follow-up PR after those readers are deployed everywhere.
17
- export const PLAY_AUTHORING_CONTRACT_EDITION = 10 as const;
18
+ // Edition 11 readers are deployed before this writer promotes new artifacts.
19
+ export const PLAY_AUTHORING_CONTRACT_EDITION = 11 as const;
18
20
  export const PLAY_AUTHORING_SLACK_INTERACTIVE_MESSAGE_STRICT_THRESHOLD =
19
21
  10 as const;
20
22
  export const EXPLICIT_FRESHNESS_PLAY_AUTHORING_THRESHOLD = 11 as const;
@@ -108,20 +110,13 @@ const PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS = [
108
110
  },
109
111
  {
110
112
  changed:
111
- 'Requires explicit freshness and semantic identity for supported durable calls, and gives CSV datasets source-row identity so every input occurrence is processed even when key or rowIdentity: "key" is supplied. Edition 10 retains its list-getter behavior and editions 1–10 retain their admitted CSV identity and completed receipts; non-CSV datasets keep explicit key deduplication.',
113
+ 'Requires explicit freshness and semantic identity for supported durable calls, and gives edition 11 CSV datasets source-row occurrence identity so every input occurrence is processed even when key or rowIdentity: "key" is supplied. Edition 10 retains its list-getter behavior; editions 1–10 retain their admitted CSV identity and completed receipts. Non-CSV datasets keep explicit key deduplication.',
112
114
  compatibilityOwner: 'Plays Runtime',
113
115
  newWritesEnd: null,
114
116
  readerRemoval: null,
115
117
  },
116
118
  ] as const;
117
119
 
118
- /** Authoring types and runtime projection must select the same getter contract. */
119
- export function playToolListGetterMode(
120
- edition: PlayAuthoringContractEdition = PLAY_AUTHORING_CONTRACT_EDITION,
121
- ): 'dataset' | 'array' {
122
- return edition >= 10 ? 'array' : 'dataset';
123
- }
124
-
125
120
  export function playCsvDatasetRowIdentity(
126
121
  edition: PlayAuthoringContractEdition,
127
122
  ): 'source_row' | 'key' {
@@ -839,6 +834,8 @@ export type PlayAuthoringBindings<TInput = Record<string, unknown>> = {
839
834
  displayName?: string;
840
835
  description?: string;
841
836
  compatibility?: {
837
+ /** Opt new source into the current explicit-freshness authoring edition. */
838
+ authoringContract?: 'explicit-freshness';
842
839
  toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
843
840
  /**
844
841
  * Bump only when a Play's response transformation changes serialized tool
@@ -1081,15 +1078,19 @@ export type PlayAuthoringStepProgram<
1081
1078
  TContext,
1082
1079
  Return
1083
1080
  >;
1084
- step<Name extends string, Value>(
1081
+ step<
1082
+ Name extends string,
1083
+ Value,
1084
+ Options extends PlayAuthoringStepOptions<Output, Value>,
1085
+ >(
1085
1086
  name: Name,
1086
1087
  resolver:
1087
1088
  | PlayAuthoringStepResolver<Output, Value, TContext>
1088
1089
  | PlayAuthoringStepProgramResolver<Output, Value, TContext>,
1089
- options: PlayAuthoringStepOptions<Output, Value>,
1090
+ options: Options,
1090
1091
  ): PlayAuthoringStepProgram<
1091
1092
  Input,
1092
- Output & Record<Name, Value | null>,
1093
+ Output & Record<Name, 'runIf' extends keyof Options ? Value | null : Value>,
1093
1094
  TContext,
1094
1095
  Return
1095
1096
  >;
@@ -1156,7 +1157,7 @@ export type PlayAuthoringDatasetDefinitionOptions<InputRow extends object> = {
1156
1157
  export type PlayAuthoringDatasetRunOptions<InputRow extends object> = {
1157
1158
  description?: string;
1158
1159
  key?: PlayAuthoringDatasetRowKey<InputRow>;
1159
- /** Edition 11 CSVs always use source-row identity; key-based deduplication remains for non-CSV inputs and earlier editions. */
1160
+ /** Edition 11 CSVs always use source-row occurrence identity; key-based deduplication remains available for non-CSV inputs and editions 1–10. */
1160
1161
  rowIdentity?: 'source_row' | 'key';
1161
1162
  onRowError?: 'isolate' | 'fail';
1162
1163
  mode?: 'upsert' | 'net_new';
@@ -1390,6 +1391,8 @@ export type PlayAuthoringFetchOptions = {
1390
1391
  * @sdkReference runtime 175 PlayFetchResponse
1391
1392
  */
1392
1393
  export type PlayAuthoringFetchResponse = {
1394
+ /** Freshness and same-run recovery metadata for edition 11 calls. */
1395
+ freshness?: import('./tool-result-types').CallFreshnessMetadata;
1393
1396
  /** True when the response status is in the 2xx range. */
1394
1397
  ok: boolean;
1395
1398
  /** HTTP status code as returned by the upstream server. */
@@ -1413,54 +1416,7 @@ export type PlayAuthoringFetchResponse = {
1413
1416
  json: unknown | null;
1414
1417
  };
1415
1418
 
1416
- /**
1417
- * Edition 5+ `ctx.fetch` error for a non-2xx response. Its full readable body is secret-redacted; editions 1–4 retain `PlayFetchResponse { ok: false }`.
1418
- *
1419
- * @sdkReference runtime 178 CtxFetchHttpError
1420
- */
1421
- export class CtxFetchHttpError extends Error {
1422
- /**
1423
- * Play source and the runtime are separately bundled. Recognize the stable
1424
- * public error code so `instanceof` works across that boundary as well.
1425
- */
1426
- static [Symbol.hasInstance](value: unknown): boolean {
1427
- return (
1428
- value !== null &&
1429
- typeof value === 'object' &&
1430
- (value as { code?: unknown }).code === 'CTX_FETCH_HTTP_ERROR'
1431
- );
1432
- }
1433
-
1434
- /** Stable machine-readable HTTP-failure code. */
1435
- readonly code = 'CTX_FETCH_HTTP_ERROR' as const;
1436
- /** Upstream HTTP status. */
1437
- readonly status: number;
1438
- /** Upstream HTTP status text. */
1439
- readonly statusText: string;
1440
- /** Final response URL after redirects. */
1441
- readonly url: string;
1442
- /** Secret-redacted response headers. */
1443
- readonly headers: Record<string, string>;
1444
- /** Complete secret-redacted response body. */
1445
- readonly bodyText: string;
1446
- /** Eagerly parsed secret-redacted JSON, or null. */
1447
- readonly json: unknown | null;
1448
-
1449
- /** Build the error from the durable response record. */
1450
- constructor(readonly response: PlayAuthoringFetchResponse) {
1451
- const body = response.bodyText || 'empty response body';
1452
- super(
1453
- `ctx.fetch(${response.url}) returned HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}: ${body}`,
1454
- );
1455
- this.name = 'CtxFetchHttpError';
1456
- this.status = response.status;
1457
- this.statusText = response.statusText;
1458
- this.url = response.url;
1459
- this.headers = response.headers;
1460
- this.bodyText = response.bodyText;
1461
- this.json = response.json;
1462
- }
1463
- }
1419
+ export { CtxFetchHttpError } from './fetch-http-error';
1464
1420
 
1465
1421
  export type PlayAuthoringCustomerDbQueryOptions = {
1466
1422
  id?: string;
@@ -1471,6 +1427,7 @@ export type PlayAuthoringCustomerDbQueryOptions = {
1471
1427
 
1472
1428
  export type PlayAuthoringRunStepsOptions = {
1473
1429
  description?: string;
1430
+ staleAfterSeconds?: DurableCallStaleAfterSeconds;
1474
1431
  };
1475
1432
 
1476
1433
  /**
@@ -1781,6 +1738,24 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
1781
1738
  errorMessage:
1782
1739
  'compatibility.toolErrorSchemaVersion must be the static literal 0 or 1.',
1783
1740
  },
1741
+ 'compatibility.authoringContract': {
1742
+ schema: Type.Literal('explicit-freshness'),
1743
+ fixtures: {
1744
+ valid: 'explicit-freshness',
1745
+ invalid: 'legacy',
1746
+ absent: undefined,
1747
+ unresolved: { expression: 'authoringContract' },
1748
+ edition1: undefined,
1749
+ },
1750
+ referenceType: "'explicit-freshness'",
1751
+ required: false,
1752
+ resolution: 'static-required',
1753
+ issueCode: 'play_authoring_binding_invalid',
1754
+ description:
1755
+ 'Opts new source into the current explicit-freshness authoring edition; an already-pinned edition-10 artifact retains its admitted behavior.',
1756
+ errorMessage:
1757
+ 'compatibility.authoringContract must be the static literal "explicit-freshness".',
1758
+ },
1784
1759
  'compatibility.toolResponseReceiptRevision': {
1785
1760
  schema: Type.String({
1786
1761
  minLength: 1,
@@ -2568,7 +2543,7 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
2568
2543
  resolution: 'static-when-present',
2569
2544
  issueCode: 'play_authoring_dataset_option_invalid',
2570
2545
  description:
2571
- 'Edition 11 CSV inputs always use source-row occurrence identity, even with rowIdentity: key; key-based deduplication remains available for non-CSV inputs and editions 1–10.',
2546
+ 'Edition 11 requires explicit freshness and semantic identity for supported durable calls. CSV inputs always use source-row occurrence identity, even with rowIdentity: "key"; key-based dedup remains available for non-CSV inputs and editions 1–10.',
2572
2547
  errorMessage: 'ctx.dataset run rowIdentity must be "source_row" or "key".',
2573
2548
  },
2574
2549
  'ctx.dataset.run.onRowError': {
@@ -3102,6 +3077,23 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
3102
3077
  description: 'Non-empty purpose for a reusable step program.',
3103
3078
  errorMessage: 'ctx.runSteps options.description must be non-empty.',
3104
3079
  },
3080
+ 'ctx.runSteps.options.staleAfterSeconds': {
3081
+ schema: Type.Union([Type.Null(), Type.Integer({ minimum: 0 })]),
3082
+ fixtures: {
3083
+ valid: 0,
3084
+ invalid: -1,
3085
+ absent: undefined,
3086
+ unresolved: { expression: 'ttl' },
3087
+ edition1: null,
3088
+ },
3089
+ referenceType: 'number | null',
3090
+ required: false,
3091
+ resolution: 'runtime-dynamic',
3092
+ issueCode: 'play_authoring_durable_policy_invalid',
3093
+ description: EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION,
3094
+ errorMessage:
3095
+ 'staleAfterSeconds must be null, 0 (always execute), or a positive whole number of seconds.',
3096
+ },
3105
3097
  'ctx.sleep.ms': {
3106
3098
  schema: Type.Integer({ minimum: 0 }),
3107
3099
  fixtures: {
@@ -3352,7 +3344,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
3352
3344
  'export type PlayBindings<TInput = Record<string, unknown>> = {',
3353
3345
  ` displayName?: ${cloudReferenceType('displayName')};`,
3354
3346
  ` description?: ${cloudReferenceType('description')};`,
3355
- ` compatibility?: { toolErrorSchemaVersion?: ${cloudReferenceType('compatibility.toolErrorSchemaVersion')}; toolResponseReceiptRevision?: ${cloudReferenceType('compatibility.toolResponseReceiptRevision')} };`,
3347
+ ` compatibility?: { authoringContract?: ${cloudReferenceType('compatibility.authoringContract')}; toolErrorSchemaVersion?: ${cloudReferenceType('compatibility.toolErrorSchemaVersion')}; toolResponseReceiptRevision?: ${cloudReferenceType('compatibility.toolResponseReceiptRevision')} };`,
3356
3348
  ` inline?: ${cloudReferenceType('inline')};`,
3357
3349
  ` billing?: { maxCreditsPerRun?: ${cloudReferenceType('billing.maxCreditsPerRun')} };`,
3358
3350
  ` runtime?: { timeout?: ${cloudReferenceType('runtime.timeout')}; size?: ${cloudReferenceType('runtime.size')} };`,
@@ -3383,7 +3375,10 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
3383
3375
  'export type AsyncPlayRunRef = Readonly<{ runId: PlayRunId }>;',
3384
3376
  `export type RuntimeStepOptions = { semanticKey?: ${cloudReferenceType('ctx.step.semanticKey')}; staleAfterSeconds?: ${cloudReferenceType('ctx.step.staleAfterSeconds')} };`,
3385
3377
  `export type FetchOptions = { staleAfterSeconds?: ${cloudReferenceType('ctx.fetch.staleAfterSeconds')}; transient?: boolean };`,
3386
- 'export type PlayFetchResponse = { ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null };',
3378
+ "export type CallFreshnessMetadata = { requestedStaleAfterSeconds: number | null; effectiveStaleAfterSeconds: number | null; source: 'executed' | 'operation_recovery' | 'reusable_result' | 'live_observation'; resultAgeMs: number; completedAt: number; operationReceiptKey?: string; unavailableReason?: string };",
3379
+ "export type ToolResultExecutionMetadata = { idempotent: true; cached: boolean; source: 'live' | 'checkpoint' | 'cache' | 'in_flight' | 'source_run'; cacheKey?: string; receiptRole?: 'owner' | 'follower'; receiptKey?: string; resultReceiptKey?: string; attachedToReceiptKey?: string; freshness?: CallFreshnessMetadata; completedAt?: number };",
3380
+ 'export type PlayFetchResponse = { freshness?: CallFreshnessMetadata; ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null };',
3381
+ "export declare class CtxFetchAmbiguousWriteError extends Error { readonly code: 'CTX_FETCH_WRITE_OUTCOME_UNKNOWN'; readonly outcome: 'unknown'; readonly method: string; readonly origin: string; }",
3387
3382
  "export declare class CtxFetchHttpError extends Error { readonly code: 'CTX_FETCH_HTTP_ERROR'; readonly response: PlayFetchResponse; readonly status: number; readonly statusText: string; readonly url: string; readonly headers: Record<string, string>; readonly bodyText: string; readonly json: unknown | null; }",
3388
3383
  'export type StepResolver<Row, Value> = (row: Row, ctx: DeeplinePlayRuntimeContext, index: number, previousCell?: PreviousCell<Value>) => Value | Promise<Value>;',
3389
3384
  'export type DatasetColumnRunInput<Row, Value> = { readonly row: Row; readonly ctx: DeeplinePlayRuntimeContext; readonly index: number; readonly previousCell?: PreviousCell<Value> };',
@@ -3391,7 +3386,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
3391
3386
  "export type ConditionalStepResolver<Row, Value, Else = null> = { readonly kind: 'conditional'; readonly when: (row: Row, index: number) => boolean | Promise<boolean>; readonly run: StepResolver<Row, Value>; readonly elseValue: Else; else<ValueElse>(value: ValueElse): ConditionalStepResolver<Row, Value, ValueElse>; };",
3392
3387
  'export type StepOptions<Row, Value = unknown> = { readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>; readonly recompute?: boolean; readonly recomputeOnError?: boolean; readonly staleAfterSeconds?: DurableCallStaleAfterSeconds };',
3393
3388
  'export type StepProgramOptions = { readonly continueOnProviderUnavailable?: boolean };',
3394
- "export type StepProgram<Input, Output, Return = Output> = { readonly kind: 'steps'; readonly steps: readonly PlayStepProgramStep[]; readonly returnResolver?: StepResolver<Output, Return>; readonly continueOnProviderUnavailable?: boolean; readonly __inputType?: (input: Input) => void; step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | ConditionalStepResolver<Output, Value> | StepProgramResolver<Output, Value>): StepProgram<Input, Output & Record<Name, Value>, Return>; step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>, options: StepOptions<Output, Value>): StepProgram<Input, Output & Record<Name, Value | null>, Return>; return<Value>(resolver: StepResolver<Output, Value>): StepProgram<Input, Output, Value>; };",
3389
+ "export type StepProgram<Input, Output, Return = Output> = { readonly kind: 'steps'; readonly steps: readonly PlayStepProgramStep[]; readonly returnResolver?: StepResolver<Output, Return>; readonly continueOnProviderUnavailable?: boolean; readonly __inputType?: (input: Input) => void; step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | ConditionalStepResolver<Output, Value> | StepProgramResolver<Output, Value>): StepProgram<Input, Output & Record<Name, Value>, Return>; step<Name extends string, Value, Options extends StepOptions<Output, Value>>(name: Name, resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>, options: Options): StepProgram<Input, Output & Record<Name, 'runIf' extends keyof Options ? Value | null : Value>, Return>; return<Value>(resolver: StepResolver<Output, Value>): StepProgram<Input, Output, Value>; };",
3395
3390
  "export type StepProgramResolver<Input, Return> = { readonly kind: 'steps'; readonly steps: readonly PlayStepProgramStep[]; readonly returnResolver?: StepResolver<never, Return>; readonly __inputType?: (input: Input) => void };",
3396
3391
  "export type RunnableStepProgram<Input, Return> = Pick<StepProgram<Input, never, Return>, 'kind' | 'steps' | 'returnResolver' | '__inputType'>;",
3397
3392
  "export type RunnableColumnStepProgram<Return> = Pick<StepProgramResolver<unknown, Return>, 'kind' | 'steps' | 'returnResolver'>;",
@@ -3419,7 +3414,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
3419
3414
  ' dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;',
3420
3415
  ' map<TSource extends PlayDatasetInput<object>>(key: string, items: TSource, options?: DatasetDefinitionOptions<PlayDatasetRow<TSource> & object>): never;',
3421
3416
  ' readonly run: { readonly id: string };',
3422
- ` runSteps<TInput extends Record<string, unknown>, TOutput>(program: RunnableStepProgram<TInput, TOutput>, input: TInput, options?: { description?: ${cloudReferenceType('ctx.runSteps.options.description')} }): Promise<TOutput>;`,
3417
+ ` runSteps<TInput extends Record<string, unknown>, TOutput>(program: RunnableStepProgram<TInput, TOutput>, input: TInput, options?: { description?: ${cloudReferenceType('ctx.runSteps.options.description')}; staleAfterSeconds?: ${cloudReferenceType('ctx.runSteps.options.staleAfterSeconds')} }): Promise<TOutput>;`,
3423
3418
  ' tools: { execute<K extends string>(request: ToolExecutionRequest<K>): Promise<ToolExecutionOutput<K>> };',
3424
3419
  ` customerDb: { query<TRow extends Record<string, unknown> = Record<string, unknown>>(statement: SqlQuery, options?: { id?: ${cloudReferenceType('ctx.customerDb.query.options.id')}; staleAfterSeconds?: ${cloudReferenceType('ctx.customerDb.query.options.staleAfterSeconds')}; maxRows?: ${cloudReferenceType('ctx.customerDb.query.options.maxRows')}; timeoutMs?: ${cloudReferenceType('ctx.customerDb.query.options.timeoutMs')} }): Promise<TRow[]> };`,
3425
3420
  ` tool<K extends string>(key: ${cloudReferenceType('ctx.tool.key')}, toolId: K, input: ${cloudReferenceType('ctx.tool.input')}, options?: { description?: ${cloudReferenceType('ctx.tool.options.description')}; staleAfterSeconds?: DurableCallStaleAfterSeconds }): Promise<ToolExecutionOutput<K>>;`,
@@ -30,7 +30,10 @@ import type {
30
30
  PlayPackageImport,
31
31
  PlayRuntimeFeature,
32
32
  } from '../artifact-types';
33
- import { buildPlayContractCompatibility } from '../contracts';
33
+ import {
34
+ buildPlayContractCompatibility,
35
+ normalizePlayContractCompatibility,
36
+ } from '../contracts';
34
37
  import { parsePlayDocflowFile, type PlayDocflowBinding } from '../docflow';
35
38
  import {
36
39
  TypeScriptParser,
@@ -57,12 +60,16 @@ import type { ToolExecutionErrorSchemaVersion } from '../tool-execution-error';
57
60
  import type { PlaySandboxRuntimeDeclaration } from '../sandbox-runtime-limits';
58
61
  import { validatePlaySourceFilesHaveNoInlineSecrets } from '../secret-guardrails';
59
62
  import { MAX_PLAY_BUNDLE_BYTES } from './limits';
60
- import { PLAY_AUTHORING_CONTRACT_EDITION } from '../authoring-contract';
63
+ import {
64
+ extractPlaySourceAuthoringEdition,
65
+ resolvePlaySourceAuthoringContractEdition,
66
+ type PlaySourceAuthoringEdition,
67
+ } from '../source-authoring-edition';
61
68
 
62
69
  // Local bundle caches may be discarded when compiler-only analysis changes;
63
70
  // this descriptive namespace is not a runtime wire or schema version.
64
71
  export const PLAY_BUNDLE_CACHE_NAMESPACE =
65
- 'deepline-play-artifacts-docflow-jsdoc';
72
+ 'deepline-play-artifacts-docflow-jsdoc-pure-contracts';
66
73
  const PLAY_ARTIFACT_CACHE_DIR = join(tmpdir(), PLAY_BUNDLE_CACHE_NAMESPACE);
67
74
  const PLAY_PROXY_NAMESPACE = 'deepline-play-runtime-ref';
68
75
  const SOURCE_EXTENSIONS = [
@@ -209,6 +216,8 @@ type SourceGraphAnalysis = {
209
216
  sandboxRuntimeDeclaration: PlaySandboxRuntimeDeclaration | null;
210
217
  toolErrorSchemaVersion: ToolExecutionErrorSchemaVersion | null;
211
218
  toolResponseReceiptRevision: string | null;
219
+ sourceAuthoringEdition: PlaySourceAuthoringEdition;
220
+ sourceHasLocalPlayExport: boolean;
212
221
  importedPlayDependencies: ImportedPlayDependency[];
213
222
  };
214
223
 
@@ -997,29 +1006,46 @@ function staticNumberFromExpression(
997
1006
  );
998
1007
  }
999
1008
 
1000
- function toolErrorSchemaVersionFromOptions(
1009
+ function compatibilityFromOptions(
1001
1010
  node: AstNode | null | undefined,
1002
1011
  context: PlayMetadataExtractionContext,
1003
- ): ToolExecutionErrorSchemaVersion | null | undefined {
1004
- const directCompatibility = resolveStaticProperty(
1005
- node,
1006
- 'compatibility',
1007
- context,
1008
- );
1009
- if (directCompatibility.kind === 'unknown') return null;
1010
-
1012
+ ): StaticPropertyResolution {
1013
+ const direct = resolveStaticProperty(node, 'compatibility', context);
1014
+ if (direct.kind !== 'found') {
1015
+ if (direct.kind === 'unknown') return direct;
1016
+ } else {
1017
+ let value: AstNode | null = unwrapStaticExpression(direct.value);
1018
+ const seen = new Set<string>();
1019
+ while (value?.type === 'Identifier') {
1020
+ const name = getIdentifierName(value)!;
1021
+ if (name === 'undefined' && !context.declarations.has(name)) {
1022
+ value = { type: 'Literal', value: undefined };
1023
+ break;
1024
+ }
1025
+ if (seen.has(name)) return { kind: 'unknown' };
1026
+ seen.add(name);
1027
+ value = unwrapStaticExpression(context.declarations.get(name));
1028
+ }
1029
+ const nullish = value?.type === 'Literal' && value.value == null;
1030
+ const voidLiteral =
1031
+ value?.type === 'UnaryExpression' &&
1032
+ value.operator === 'void' &&
1033
+ isAstNode(value.argument) &&
1034
+ value.argument.type === 'Literal';
1035
+ if (!nullish && !voidLiteral) return direct;
1036
+ }
1011
1037
  const bindings = resolveStaticProperty(node, 'bindings', context);
1012
- if (bindings.kind === 'unknown') return null;
1013
- const bindingCompatibility =
1014
- bindings.kind === 'found'
1015
- ? resolveStaticProperty(bindings.value, 'compatibility', context)
1016
- : ({ kind: 'absent' } satisfies StaticPropertyResolution);
1017
- if (bindingCompatibility.kind === 'unknown') return null;
1038
+ return bindings.kind === 'found'
1039
+ ? resolveStaticProperty(bindings.value, 'compatibility', context)
1040
+ : bindings;
1041
+ }
1018
1042
 
1019
- const compatibility =
1020
- directCompatibility.kind === 'found'
1021
- ? directCompatibility
1022
- : bindingCompatibility;
1043
+ function toolErrorSchemaVersionFromOptions(
1044
+ node: AstNode | null | undefined,
1045
+ context: PlayMetadataExtractionContext,
1046
+ ): ToolExecutionErrorSchemaVersion | null | undefined {
1047
+ const compatibility = compatibilityFromOptions(node, context);
1048
+ if (compatibility.kind === 'unknown') return null;
1023
1049
  if (compatibility.kind === 'absent') return undefined;
1024
1050
  const schema = resolveStaticProperty(
1025
1051
  compatibility.value,
@@ -1037,25 +1063,8 @@ function toolResponseReceiptRevisionFromOptions(
1037
1063
  node: AstNode | null | undefined,
1038
1064
  context: PlayMetadataExtractionContext,
1039
1065
  ): string | null | undefined {
1040
- const directCompatibility = resolveStaticProperty(
1041
- node,
1042
- 'compatibility',
1043
- context,
1044
- );
1045
- if (directCompatibility.kind === 'unknown') return null;
1046
-
1047
- const bindings = resolveStaticProperty(node, 'bindings', context);
1048
- if (bindings.kind === 'unknown') return null;
1049
- const bindingCompatibility =
1050
- bindings.kind === 'found'
1051
- ? resolveStaticProperty(bindings.value, 'compatibility', context)
1052
- : ({ kind: 'absent' } satisfies StaticPropertyResolution);
1053
- if (bindingCompatibility.kind === 'unknown') return null;
1054
-
1055
- const compatibility =
1056
- directCompatibility.kind === 'found'
1057
- ? directCompatibility
1058
- : bindingCompatibility;
1066
+ const compatibility = compatibilityFromOptions(node, context);
1067
+ if (compatibility.kind === 'unknown') return null;
1059
1068
  if (compatibility.kind === 'absent') return undefined;
1060
1069
  const revision = resolveStaticProperty(
1061
1070
  compatibility.value,
@@ -2234,21 +2243,43 @@ async function analyzeSourceGraph(
2234
2243
  .sort((left, right) => left.filePath.localeCompare(right.filePath)),
2235
2244
  }),
2236
2245
  );
2246
+ const sourceAst = parsePlaySourceAst(sourceCode);
2247
+ if (!sourceAst)
2248
+ throw new Error(
2249
+ 'Play source syntax must be valid before selecting its authoring edition.',
2250
+ );
2251
+ const selection = extractPlaySourceAuthoringEdition(
2252
+ sourceAst,
2253
+ exportName === 'default' ? null : exportName,
2254
+ );
2237
2255
  const metadata =
2238
- extractDefinedPlayMetadata(sourceCode, exportName) ??
2256
+ (selection.marker.kind === 'value' && selection.definition
2257
+ ? playMetadataFromDefinePlayCall(
2258
+ selection.definition,
2259
+ buildPlayMetadataContext(sourceAst),
2260
+ )
2261
+ : extractDefinedPlayMetadata(sourceCode, exportName)) ??
2239
2262
  (exportName === 'default'
2240
2263
  ? extractDefinedPlayMetadata(sourceCode, null)
2241
2264
  : null);
2242
- if (metadata?.toolErrorSchemaVersionUnknown) {
2243
- throw new Error(
2244
- 'definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1.',
2245
- );
2246
- }
2247
- if (metadata?.toolResponseReceiptRevisionUnknown) {
2248
- throw new Error(
2249
- 'definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string.',
2250
- );
2265
+ const compatibilityDiagnostic = metadata?.toolErrorSchemaVersionUnknown
2266
+ ? 'definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1.'
2267
+ : metadata?.toolResponseReceiptRevisionUnknown
2268
+ ? 'definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string.'
2269
+ : null;
2270
+ try {
2271
+ resolvePlaySourceAuthoringContractEdition(selection.marker);
2272
+ } catch (error) {
2273
+ // Unresolved compatibility may hide both an opt-in and a historical pin.
2274
+ // Retain both actionable diagnostics before any cache read or bundle.
2275
+ if (compatibilityDiagnostic && selection.marker.kind === 'unknown') {
2276
+ throw new Error(
2277
+ `${compatibilityDiagnostic}\n${error instanceof Error ? error.message : String(error)}`,
2278
+ );
2279
+ }
2280
+ throw error;
2251
2281
  }
2282
+ if (compatibilityDiagnostic) throw new Error(compatibilityDiagnostic);
2252
2283
  const playName = metadata?.name ?? null;
2253
2284
  const playDescription = metadata?.description ?? null;
2254
2285
  const sandboxRuntimeDeclaration = metadata?.sandboxRuntimeDeclaration ?? null;
@@ -2274,6 +2305,8 @@ async function analyzeSourceGraph(
2274
2305
  sandboxRuntimeDeclaration,
2275
2306
  toolErrorSchemaVersion: metadata?.toolErrorSchemaVersion ?? null,
2276
2307
  toolResponseReceiptRevision: metadata?.toolResponseReceiptRevision ?? null,
2308
+ sourceAuthoringEdition: selection.marker,
2309
+ sourceHasLocalPlayExport: selection.localExport,
2277
2310
  importedPlayDependencies: [...importedPlayDependencies.values()].sort(
2278
2311
  (left, right) => left.filePath.localeCompare(right.filePath),
2279
2312
  ),
@@ -2383,6 +2416,10 @@ export type BundlePlayFileOptions = {
2383
2416
  /** Must be `cjs_node20`; retained as an explicit compile-contract assertion. */
2384
2417
  target?: PlayArtifactKind;
2385
2418
  exportName?: string;
2419
+ /** Retain an existing artifact's full contract when changing only source declarations. */
2420
+ compatibility?: PlayArtifactCompatibility;
2421
+ /** Disable local artifact cache writes for inspection-only bundling. */
2422
+ cache?: boolean;
2386
2423
  };
2387
2424
 
2388
2425
  export type BundlePlayFileCoreOptions = BundlePlayFileOptions & {
@@ -2477,13 +2514,32 @@ export async function bundlePlayFile(
2477
2514
  adapter.warnAboutNonDevelopmentBundling?.(absolutePath);
2478
2515
 
2479
2516
  try {
2517
+ const preservedCompatibility =
2518
+ options.compatibility === undefined
2519
+ ? undefined
2520
+ : {
2521
+ ...options.compatibility,
2522
+ authoringContractEdition: normalizePlayContractCompatibility(
2523
+ options.compatibility,
2524
+ ).authoringContractEdition,
2525
+ };
2480
2526
  const analysis = await analyzeSourceGraph(
2481
2527
  absolutePath,
2482
2528
  adapter,
2483
2529
  exportName,
2484
2530
  );
2531
+ const edition = resolvePlaySourceAuthoringContractEdition(
2532
+ analysis.sourceAuthoringEdition,
2533
+ preservedCompatibility?.authoringContractEdition,
2534
+ );
2535
+ const markedSource = analysis.sourceAuthoringEdition.kind === 'value';
2536
+ if (markedSource && !analysis.sourceHasLocalPlayExport) {
2537
+ throw new Error(
2538
+ 'Edition 10 source must select a local ESM definePlay export.',
2539
+ );
2540
+ }
2485
2541
  analysis.graphHash = sha256(
2486
- `${analysis.graphHash}\nentry-export:${exportName}\nauthoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`,
2542
+ `${analysis.graphHash}\nentry-export:${exportName}\nauthoring-contract-edition:${edition}${edition >= 10 ? '\nimported-proxy-options:description' : ''}${preservedCompatibility === undefined ? '\ndataset-row-input:current_run' : `\npreserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`,
2487
2543
  );
2488
2544
  const sourceFiles = Object.fromEntries(
2489
2545
  Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
@@ -2555,15 +2611,20 @@ export async function bundlePlayFile(
2555
2611
  success: true,
2556
2612
  artifact: {
2557
2613
  ...cachedArtifact,
2614
+ ...(markedSource ? { exportName } : {}),
2558
2615
  entryFile,
2559
2616
  sourceHash: analysis.sourceHash,
2560
2617
  importPolicy,
2561
- compatibility: buildPlayContractCompatibility({
2562
- toolErrorSchemaVersion:
2563
- analysis.toolErrorSchemaVersion ?? undefined,
2564
- toolResponseReceiptRevision:
2565
- analysis.toolResponseReceiptRevision ?? undefined,
2566
- }),
2618
+ compatibility:
2619
+ preservedCompatibility ??
2620
+ buildPlayContractCompatibility({
2621
+ authoringContractEdition: edition,
2622
+ datasetRowInput: 'current_run',
2623
+ toolErrorSchemaVersion:
2624
+ analysis.toolErrorSchemaVersion ?? undefined,
2625
+ toolResponseReceiptRevision:
2626
+ analysis.toolResponseReceiptRevision ?? undefined,
2627
+ }),
2567
2628
  cacheHit: true,
2568
2629
  },
2569
2630
  sourceCode: analysis.sourceCode,
@@ -2620,6 +2681,7 @@ export async function bundlePlayFile(
2620
2681
  }
2621
2682
 
2622
2683
  const artifact: PlayBundleArtifact = {
2684
+ ...(markedSource ? { exportName } : {}),
2623
2685
  codeFormat: 'cjs_module',
2624
2686
  artifactKind: target,
2625
2687
  entryFile,
@@ -2631,11 +2693,15 @@ export async function bundlePlayFile(
2631
2693
  bundledCode: executableCode,
2632
2694
  sourceMap: normalizedSourceMap,
2633
2695
  importPolicy,
2634
- compatibility: buildPlayContractCompatibility({
2635
- toolErrorSchemaVersion: analysis.toolErrorSchemaVersion ?? undefined,
2636
- toolResponseReceiptRevision:
2637
- analysis.toolResponseReceiptRevision ?? undefined,
2638
- }),
2696
+ compatibility:
2697
+ preservedCompatibility ??
2698
+ buildPlayContractCompatibility({
2699
+ authoringContractEdition: edition,
2700
+ datasetRowInput: 'current_run',
2701
+ toolErrorSchemaVersion: analysis.toolErrorSchemaVersion ?? undefined,
2702
+ toolResponseReceiptRevision:
2703
+ analysis.toolResponseReceiptRevision ?? undefined,
2704
+ }),
2639
2705
  generatedAt: Date.now(),
2640
2706
  cacheHit: false,
2641
2707
  };
@@ -49,6 +49,8 @@ export type PlayContractCompatibilitySnapshot = {
49
49
  toolResponseReceiptRevision?: string;
50
50
  /** Missing preserves Slack HITL's historical parked timeout behavior. */
51
51
  slackHitlTimeoutOutcome?: 'error';
52
+ /** Missing preserves historical dataset output hydration into resolver rows. */
53
+ datasetRowInput?: 'current_run';
52
54
  };
53
55
 
54
56
  export type NormalizedPlayContractCompatibilitySnapshot =
@@ -93,6 +95,14 @@ export function normalizePlayContractCompatibility(
93
95
  }
94
96
  const requestedToolErrorSchemaVersion =
95
97
  compatibility.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION;
98
+ if (
99
+ compatibility.datasetRowInput !== undefined &&
100
+ compatibility.datasetRowInput !== 'current_run'
101
+ ) {
102
+ throw new InvalidPlayContractCompatibilityError(
103
+ `Unsupported dataset row input policy ${String(compatibility.datasetRowInput)}.`,
104
+ );
105
+ }
96
106
  if (
97
107
  !SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS.includes(
98
108
  requestedToolErrorSchemaVersion,
@@ -137,9 +147,13 @@ export function buildPlayContractCompatibility(input?: {
137
147
  authoringContractEdition?: PlayAuthoringContractEdition;
138
148
  toolResponseContract?: ToolResponseContract;
139
149
  toolResponseReceiptRevision?: string;
150
+ datasetRowInput?: 'current_run';
140
151
  }): PlayContractCompatibilitySnapshot {
141
152
  return {
142
153
  artifactVersion: PLAY_ARTIFACT_VERSION,
154
+ ...(input?.datasetRowInput
155
+ ? { datasetRowInput: input.datasetRowInput }
156
+ : {}),
143
157
  runtimeBackend: input?.runtimeBackend ?? null,
144
158
  toolErrorSchemaVersion:
145
159
  input?.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION,