deepline 0.3.409 → 0.3.411

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 (215) hide show
  1. package/dist/bundling-sources/sdk/src/agent-runtime.ts +18 -1
  2. package/dist/bundling-sources/sdk/src/client.ts +206 -333
  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/monitors/package.json +1 -1
  21. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +3 -1
  22. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +1 -1
  23. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +277 -76
  24. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +6 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/dataset-row-input.ts +124 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -62
  27. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +1 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/durable-tool-identity.ts +67 -0
  29. package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +64 -6
  30. package/dist/bundling-sources/shared_libs/play-runtime/freshness-receipt-execution.ts +1 -5
  31. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +1 -1
  32. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +3 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/play-http-request.ts +10 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/query-result-dataset.ts +3 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +3 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +26 -16
  37. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +36 -11
  38. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +35 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +21 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +21 -6
  41. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +11 -2
  42. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +85 -20
  43. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +71 -13
  44. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-execution-queries.ts +100 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +9 -5
  46. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +337 -146
  47. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +26 -12
  48. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +3 -1
  49. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +425 -102
  50. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +4 -0
  52. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +9 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +181 -124
  54. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-worker-wake.ts +152 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -3
  56. package/dist/bundling-sources/shared_libs/play-runtime/tool-cache-policy.ts +31 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +10 -0
  58. package/dist/bundling-sources/shared_libs/plays/ambiguous-write-error.ts +25 -0
  59. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
  60. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +63 -68
  61. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +129 -63
  62. package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
  63. package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +58 -16
  64. package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +50 -0
  65. package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +351 -0
  66. package/dist/bundling-sources/shared_libs/plays/tool-list-getter-mode.ts +9 -0
  67. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  68. package/dist/cli/auth-M7TBLW55.js +40 -0
  69. package/dist/cli/{auth-5HIIACF7.mjs → auth-YD6ZTMB2.mjs} +6 -6
  70. package/dist/cli/{billing-4275N7FL.js → billing-2L3MOB42.js} +84 -84
  71. package/dist/cli/{billing-EVZ3ZWKC.mjs → billing-ZT46GV4C.mjs} +8 -8
  72. package/dist/cli/{chunk-ZAAKSJAS.js → chunk-27GJKC5Q.js} +17 -10
  73. package/dist/cli/{chunk-UHNDVD3P.js → chunk-2H4EY7KH.js} +100 -41
  74. package/dist/cli/{chunk-GAICVLKL.js → chunk-2NI6DHN7.js} +2 -2
  75. package/dist/cli/{chunk-JGHG4NBA.js → chunk-2WUY3VNK.js} +19 -4
  76. package/dist/cli/{chunk-FHPCKULR.mjs → chunk-4BA6ATHA.mjs} +2 -2
  77. package/dist/cli/{chunk-RTCDW2GU.js → chunk-4O4WNFFC.js} +170 -49
  78. package/dist/cli/{chunk-OSDXE27V.mjs → chunk-4PG4ARL2.mjs} +17 -10
  79. package/dist/cli/{chunk-AU4OFDFX.js → chunk-5IGDNBG7.js} +26 -26
  80. package/dist/cli/{chunk-WYQO2CBS.mjs → chunk-5LRWWMRV.mjs} +149 -28
  81. package/dist/cli/{chunk-PMVFAYL7.mjs → chunk-63ILLN5H.mjs} +2 -2
  82. package/dist/cli/chunk-6AUE6JXY.js +35 -0
  83. package/dist/cli/chunk-7DSMMCXP.js +501 -0
  84. package/dist/cli/{chunk-6BJK4EJ3.mjs → chunk-AARWVK4C.mjs} +2132 -65
  85. package/dist/cli/{chunk-FERRDNMO.js → chunk-AD47BXN2.js} +5 -5
  86. package/dist/cli/{chunk-J6DCKJNM.mjs → chunk-BJV3VSKE.mjs} +16 -1
  87. package/dist/cli/{chunk-S6R3OX7B.js → chunk-E4CABWXL.js} +25 -2
  88. package/dist/cli/{chunk-NXGCO4JB.mjs → chunk-E4IXDAZI.mjs} +5 -0
  89. package/dist/cli/{chunk-BEVLCKXG.mjs → chunk-E4KBNNNB.mjs} +1 -1
  90. package/dist/cli/{chunk-2PRO2JTX.mjs → chunk-E52TKKVI.mjs} +36 -284
  91. package/dist/cli/chunk-FR2ILQ4G.mjs +8 -0
  92. package/dist/cli/{chunk-2GI3QD3L.js → chunk-FRVPOXGB.js} +644 -330
  93. package/dist/cli/chunk-G43JLBDE.mjs +501 -0
  94. package/dist/cli/{chunk-BZAMOCPA.mjs → chunk-IMZ56EOH.mjs} +3 -3
  95. package/dist/cli/chunk-IPGV6VFA.mjs +6084 -0
  96. package/dist/cli/{chunk-IT3XBJQR.mjs → chunk-IR3AKJAY.mjs} +330 -625
  97. package/dist/cli/chunk-J33TSWO5.js +8 -0
  98. package/dist/cli/chunk-JQMZUWNM.mjs +35 -0
  99. package/dist/cli/chunk-JYHSEGRM.js +6084 -0
  100. package/dist/cli/{chunk-JI2B4RZP.mjs → chunk-KCC3FKIW.mjs} +71 -12
  101. package/dist/cli/{chunk-6IKARAYD.mjs → chunk-L2VKAASU.mjs} +23 -0
  102. package/dist/cli/{chunk-O3VSXP2F.js → chunk-LWBM5FFL.js} +50 -50
  103. package/dist/cli/{chunk-VWBTTJYQ.mjs → chunk-M6OASCVL.mjs} +6 -3
  104. package/dist/cli/{chunk-YHPYUZZX.mjs → chunk-MAMVGOSC.mjs} +1 -1
  105. package/dist/cli/{chunk-Q2E4E4FJ.js → chunk-NPBJI7RE.js} +8 -8
  106. package/dist/cli/chunk-NQWIZ5PZ.js +313 -0
  107. package/dist/cli/{chunk-HQXL5526.mjs → chunk-NUX2QHNC.mjs} +1 -1
  108. package/dist/cli/{chunk-TQNHMWUR.mjs → chunk-OGSXENOF.mjs} +5 -2
  109. package/dist/cli/{chunk-SEFMGO3Z.js → chunk-OQQOXSYA.js} +2184 -117
  110. package/dist/cli/{chunk-FJCIUF34.js → chunk-OZSC6CEW.js} +128 -376
  111. package/dist/cli/{chunk-NZSF57UO.mjs → chunk-PO2VU6WV.mjs} +2 -2
  112. package/dist/cli/{chunk-7P5AA3SN.js → chunk-PPDBRJRW.js} +6 -1
  113. package/dist/cli/{chunk-ILHRA7AD.js → chunk-QADCFSGH.js} +7 -7
  114. package/dist/cli/{chunk-N44JHMKY.mjs → chunk-RFES6Q2J.mjs} +452 -138
  115. package/dist/cli/{chunk-DEC3JECC.js → chunk-RMINBDYY.js} +5 -2
  116. package/dist/cli/{chunk-WLOCMJWV.js → chunk-TPFD4F5S.js} +426 -721
  117. package/dist/cli/{chunk-V76R6HMV.js → chunk-U5AQKE3T.js} +1029 -806
  118. package/dist/cli/{chunk-PBZYY7VZ.mjs → chunk-UAEVKAUR.mjs} +734 -511
  119. package/dist/cli/{chunk-WHG43Z67.js → chunk-VGHWJL4W.js} +11 -8
  120. package/dist/cli/chunk-VKKVSFRD.js +62 -0
  121. package/dist/cli/{chunk-GSK6NHVM.js → chunk-WU4U6VSB.js} +5 -5
  122. package/dist/cli/chunk-XAB47ZRV.mjs +313 -0
  123. package/dist/cli/{chunk-JRAVVJ3T.mjs → chunk-XJD6LZCO.mjs} +2 -2
  124. package/dist/cli/chunk-ZCALLYF6.mjs +62 -0
  125. package/dist/cli/{chunk-YD7B53RW.js → chunk-ZHWBU36H.js} +12 -12
  126. package/dist/cli/{csv-A2MP6EFV.mjs → csv-BKNRRW7D.mjs} +5 -5
  127. package/dist/cli/{csv-BBOTCGQY.js → csv-SVDP2EU7.js} +14 -14
  128. package/dist/cli/{db-3W5DMTUX.mjs → db-LU4KLRM6.mjs} +15 -20
  129. package/dist/cli/{db-G4CODDCA.js → db-OQ6S7TTZ.js} +42 -47
  130. package/dist/cli/{describe-PQTQ5B6F.js → describe-45TGETKR.js} +27 -22
  131. package/dist/cli/{describe-XYJ2ZT4M.mjs → describe-U4KOGDRA.mjs} +20 -15
  132. package/dist/cli/describe-core.d.mts +2 -2
  133. package/dist/cli/describe-core.d.ts +2 -2
  134. package/dist/cli/describe-core.js +6 -6
  135. package/dist/cli/describe-core.mjs +5 -5
  136. package/dist/cli/{executions-UR67CA5H.mjs → executions-2GAAUXLA.mjs} +8 -8
  137. package/dist/cli/{executions-TLANVR7Y.js → executions-VZN56VRC.js} +10 -10
  138. package/dist/cli/{feedback-6C2YTRJL.js → feedback-NS76B5GU.js} +13 -9
  139. package/dist/cli/{feedback-WHCMGEIL.mjs → feedback-XW5IWA5R.mjs} +11 -7
  140. package/dist/cli/{git-GWLB6VSA.mjs → git-CLI66XP6.mjs} +6 -6
  141. package/dist/cli/git-VGYRGFEN.js +24 -0
  142. package/dist/cli/index.js +236 -348
  143. package/dist/cli/index.mjs +162 -274
  144. package/dist/cli/{legacy-noops-ZUFA7RWI.js → legacy-noops-HCFB3ZOV.js} +9 -9
  145. package/dist/cli/{legacy-noops-KF4XIFEF.mjs → legacy-noops-ODDOMLBL.mjs} +6 -6
  146. package/dist/cli/{monitors-TB3K2IVE.js → monitors-7WXQ7JFT.js} +94 -94
  147. package/dist/cli/{monitors-6UOIDIMB.mjs → monitors-ZXX456TE.mjs} +8 -8
  148. package/dist/cli/{org-CKWMBPIR.js → org-YLX5PHBQ.js} +68 -68
  149. package/dist/cli/{org-WGHHMVDZ.mjs → org-YUN3TLNP.mjs} +8 -8
  150. package/dist/cli/{play-LYPAXCLD.mjs → play-LL73A7EP.mjs} +533 -98
  151. package/dist/cli/{play-N2B3KAVS.js → play-YGOXL52D.js} +1067 -632
  152. package/dist/cli/{providers-6DI5BVZJ.mjs → providers-35QSAUHL.mjs} +8 -8
  153. package/dist/cli/{providers-UR42MD6Z.js → providers-RHCIU2PX.js} +11 -11
  154. package/dist/cli/{quickstart-MNA2S6PO.mjs → quickstart-6BN3LCZH.mjs} +5 -5
  155. package/dist/cli/{quickstart-FCJG4XGB.js → quickstart-ORMM4NRK.js} +7 -7
  156. package/dist/cli/search-EWDMUPHR.js +30 -0
  157. package/dist/cli/{search-VPPYUJ2M.mjs → search-GAERWLSE.mjs} +9 -9
  158. package/dist/cli/{secrets-QOSMVO36.js → secrets-3AFCTGT7.js} +17 -17
  159. package/dist/cli/{secrets-DRI4W7Z5.mjs → secrets-FCL5PALY.mjs} +8 -8
  160. package/dist/cli/sessions-3OEHEQG7.js +16 -0
  161. package/dist/cli/{sessions-DQNUKP43.mjs → sessions-RSSL7I7O.mjs} +6 -6
  162. package/dist/cli/{settings-DWDK3Y2R.mjs → settings-GE4NRE7Y.mjs} +12 -12
  163. package/dist/cli/{settings-JUGGCOPS.js → settings-RX5K4I7H.js} +79 -79
  164. package/dist/cli/{setup-AWBHNYXK.js → setup-N3ZNAEL5.js} +45 -44
  165. package/dist/cli/{setup-D5DWVNY4.mjs → setup-X3RXGG4F.mjs} +11 -10
  166. package/dist/cli/{skills-YV2XR35J.mjs → skills-5JEAJBDE.mjs} +7 -7
  167. package/dist/cli/skills-VAAQVEQC.js +29 -0
  168. package/dist/cli/tools-BYYOT2DU.js +44 -0
  169. package/dist/cli/{tools-VFJYHNV2.mjs → tools-JOKUWEBZ.mjs} +19 -14
  170. package/dist/cli/update-36G4ZD7B.js +31 -0
  171. package/dist/cli/{update-IM6VOTGL.mjs → update-UBHEVFR3.mjs} +11 -9
  172. package/dist/cli/{workflow-26URBWPV.mjs → workflow-FR6EXAXF.mjs} +44 -20
  173. package/dist/cli/{workflow-3BS6U6SL.js → workflow-SZAVOHN6.js} +54 -30
  174. package/dist/{client-BfInrZPB.d.mts → client-74k4IPh6.d.mts} +135 -54
  175. package/dist/{client-BMjJFpan.d.ts → client-C1IK1f8c.d.ts} +135 -54
  176. package/dist/{compiler-manifest-Ycx-hoAr.d.mts → compiler-manifest-lzWpbV3w.d.mts} +83 -66
  177. package/dist/{compiler-manifest-Ycx-hoAr.d.ts → compiler-manifest-lzWpbV3w.d.ts} +83 -66
  178. package/dist/{index-CZXgiN3E.d.mts → index-C8Cy-YTm.d.ts} +5 -1
  179. package/dist/{index-NPG5pqxQ.d.ts → index-CtNK-0nI.d.mts} +5 -1
  180. package/dist/index.d.mts +47 -9
  181. package/dist/index.d.ts +47 -9
  182. package/dist/index.js +17 -14
  183. package/dist/index.mjs +13 -10
  184. package/dist/install-integrity.json +118 -102
  185. package/dist/plays/bundle-play-file.d.mts +3 -3
  186. package/dist/plays/bundle-play-file.d.ts +3 -3
  187. package/dist/plays/bundle-play-file.mjs +5 -4
  188. package/dist/plays/csv-data-input.js +3 -3
  189. package/dist/plays/csv-data-input.mjs +2 -2
  190. package/dist/plays/play-description.d.mts +2 -2
  191. package/dist/plays/play-description.d.ts +2 -2
  192. package/dist/plays/run-request.d.mts +2 -2
  193. package/dist/plays/run-request.d.ts +2 -2
  194. package/dist/plays/run-request.js +11 -3
  195. package/dist/plays/run-request.mjs +10 -2
  196. package/dist/release.d.mts +15 -6
  197. package/dist/release.d.ts +15 -6
  198. package/dist/release.js +2 -2
  199. package/dist/release.mjs +1 -1
  200. package/package.json +2 -2
  201. package/dist/cli/auth-F6BX32XZ.js +0 -40
  202. package/dist/cli/chunk-264PC2RN.mjs +0 -83
  203. package/dist/cli/chunk-44ZTYHMQ.mjs +0 -155
  204. package/dist/cli/chunk-53HN7WZN.js +0 -392
  205. package/dist/cli/chunk-7AALNGTA.mjs +0 -392
  206. package/dist/cli/chunk-ALD4COBH.js +0 -155
  207. package/dist/cli/chunk-CLJGSOVM.mjs +0 -1716
  208. package/dist/cli/chunk-WNUR6VP5.js +0 -83
  209. package/dist/cli/chunk-Z4VNJOF7.js +0 -1716
  210. package/dist/cli/git-VQFF6D7C.js +0 -24
  211. package/dist/cli/search-NCEEONMQ.js +0 -30
  212. package/dist/cli/sessions-3WYKQABW.js +0 -16
  213. package/dist/cli/skills-AKPAJVSO.js +0 -29
  214. package/dist/cli/tools-RBKEK6PM.js +0 -39
  215. package/dist/cli/update-VFNUBLDA.js +0 -29
@@ -2,25 +2,25 @@ import {
2
2
  validatePlaySourceFilesHaveNoInlineSecrets
3
3
  } from "./chunk-H7HIDGZ7.mjs";
4
4
  import {
5
- PLAY_AUTHORING_CONTRACT_EDITION
6
- } from "./chunk-CLJGSOVM.mjs";
7
- import {
5
+ InvalidToolResponseReceiptRevisionError,
8
6
  PLAY_ARTIFACT_KINDS,
9
7
  PLAY_RUNTIME_BACKENDS,
10
8
  RAW_V2_TOOL_RESPONSE_CONTRACT,
11
9
  RAW_V2_TOOL_RESPONSE_RECEIPT_REVISION,
10
+ UnsupportedToolResponseContractError,
11
+ normalizeToolResponseContract,
12
12
  normalizeToolResponseReceiptRevision
13
- } from "./chunk-6IKARAYD.mjs";
13
+ } from "./chunk-L2VKAASU.mjs";
14
14
  import {
15
+ SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS,
15
16
  TOOL_EXECUTION_ERROR_SCHEMA_VERSION
16
- } from "./chunk-NXGCO4JB.mjs";
17
+ } from "./chunk-E4IXDAZI.mjs";
17
18
  import {
18
19
  CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION
19
20
  } from "./chunk-WZYKRD7T.mjs";
20
21
 
21
22
  // src/plays/bundle-play-file.ts
22
- import { tmpdir as tmpdir2 } from "os";
23
- import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
23
+ import { dirname as dirname3, resolve as resolve3 } from "path";
24
24
  import { fileURLToPath } from "url";
25
25
  import { existsSync as existsSync2 } from "fs";
26
26
  import { realpath as realpath2 } from "fs/promises";
@@ -47,11 +47,1816 @@ import {
47
47
  transformSync
48
48
  } from "esbuild";
49
49
 
50
+ // ../plays/authoring-contract.ts
51
+ import { Type } from "@sinclair/typebox";
52
+ import { Value } from "@sinclair/typebox/value";
53
+ var LEGACY_PLAY_AUTHORING_CONTRACT_EDITION = 1;
54
+ var PLAY_AUTHORING_CONTRACT_EDITION = 11;
55
+ var EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION = [
56
+ "Edition 11 requires an explicit choice.",
57
+ "`0` starts a fresh logical call, though a matching operation receipt may recover that same operation after resume;",
58
+ "`null` allows indefinite result reuse;",
59
+ "a positive integer is the maximum result age in seconds.",
60
+ "Omitted values retain legacy behavior in older editions."
61
+ ].join(" ");
62
+ var SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS = [
63
+ 1,
64
+ 2,
65
+ 3,
66
+ 4,
67
+ 5,
68
+ 6,
69
+ 7,
70
+ 8,
71
+ 9,
72
+ 10,
73
+ 11
74
+ ];
75
+ var PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS = [
76
+ {
77
+ changed: "Historical extraction semantics. Invalid or unresolved optional authoring fields may normalize to absence.",
78
+ compatibilityOwner: "Plays Runtime",
79
+ newWritesEnd: "2026-11-03",
80
+ readerRemoval: "After every retained edition 1 artifact has a materialized admitted snapshot."
81
+ },
82
+ {
83
+ changed: "Pins admitted authoring snapshots and rejects ambiguous billing, secret, webhook, fetch, timeout, receipt-wait, and freshness contracts.",
84
+ compatibilityOwner: "Plays Runtime",
85
+ newWritesEnd: "2026-08-03",
86
+ readerRemoval: "After every retained edition 2 artifact has an admitted input schema or has been republished."
87
+ },
88
+ {
89
+ changed: "Materializes the declared input schema in the admitted snapshot so launch never reparses current source.",
90
+ compatibilityOwner: "Plays Runtime",
91
+ newWritesEnd: "2026-08-19",
92
+ readerRemoval: null
93
+ },
94
+ {
95
+ changed: "ctx.secrets.get(name) resolves an allowed secret to a plaintext string for ordinary Play code. Editions 1\u20133 retain opaque secret handles.",
96
+ compatibilityOwner: "Plays Runtime",
97
+ newWritesEnd: null,
98
+ readerRemoval: null
99
+ },
100
+ {
101
+ changed: "ctx.fetch throws a typed, redacted CtxFetchHttpError for non-2xx responses. Editions 1\u20134 continue to return the response record for every HTTP status.",
102
+ compatibilityOwner: "Plays Runtime",
103
+ newWritesEnd: null,
104
+ readerRemoval: null
105
+ },
106
+ {
107
+ changed: "Adds static cron input and rejects unknown definePlay and binding fields during new admission. Editions 1\u20135 retain their admitted binding semantics.",
108
+ compatibilityOwner: "Plays Runtime",
109
+ newWritesEnd: null,
110
+ readerRemoval: null
111
+ },
112
+ {
113
+ changed: "Slack HITL calls that omit timeout wait one week. Editions 1\u20136 retain the historical 24-hour default.",
114
+ compatibilityOwner: "Plays Runtime",
115
+ newWritesEnd: null,
116
+ readerRemoval: null
117
+ },
118
+ {
119
+ changed: "Lets an inline scalar child execute without a stored static pipeline. Dataset creation and suspension remain rejected by the authoritative runtime capability boundary; editions 1\u20137 retain static-contract preflight rejection.",
120
+ compatibilityOwner: "Plays Runtime",
121
+ newWritesEnd: null,
122
+ readerRemoval: null
123
+ },
124
+ {
125
+ changed: "Projects native-batch rawV2 to the logical source response at the Play boundary. Editions 1\u20138 retain their admitted response nesting; completed tool receipts and provider identities are unchanged.",
126
+ compatibilityOwner: "Plays Runtime",
127
+ newWritesEnd: null,
128
+ readerRemoval: null
129
+ },
130
+ {
131
+ changed: "List getters return ordinary arrays from the complete resident tool response. Lazy database datasets require an explicit dataset read; incomplete historical previews fail rather than masquerade as complete arrays. Editions 1\u20139 retain dataset-valued getters; stored tool receipts are unchanged.",
132
+ compatibilityOwner: "Plays Runtime",
133
+ newWritesEnd: null,
134
+ readerRemoval: null
135
+ },
136
+ {
137
+ changed: '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\u201310 retain their admitted CSV identity and completed receipts. Non-CSV datasets keep explicit key deduplication.',
138
+ compatibilityOwner: "Plays Runtime",
139
+ newWritesEnd: null,
140
+ readerRemoval: null
141
+ }
142
+ ];
143
+ var PLAY_AUTHORING_CONTRACT_CHANGELOG = SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS.map((edition, index) => ({
144
+ edition,
145
+ ...PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS[index]
146
+ }));
147
+ var PLAY_SQL_LISTENER_WHERE_OPERATORS = [
148
+ "eq",
149
+ "neq",
150
+ "in",
151
+ "notIn",
152
+ "isNull",
153
+ "isNotNull",
154
+ "ilike"
155
+ ];
156
+ var PLAY_SQL_LISTENER_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
157
+ var PLAY_SQL_LISTENER_TOOL_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*\.[a-zA-Z][a-zA-Z0-9_-]*$/;
158
+ var PLAY_SQL_LISTENER_WHERE_OPERATOR_SET = new Set(
159
+ PLAY_SQL_LISTENER_WHERE_OPERATORS
160
+ );
161
+ var PLAY_AUTHORING_BINDING_FIELDS = {
162
+ root: [
163
+ "displayName",
164
+ "billing",
165
+ "compatibility",
166
+ "cron",
167
+ "inline",
168
+ "runtime",
169
+ "secrets",
170
+ "sqlListeners",
171
+ "webhook"
172
+ ],
173
+ cron: ["schedule", "timezone", "input"],
174
+ webhook: ["auth", "hmac"],
175
+ sqlListener: [
176
+ "id",
177
+ "tool",
178
+ "stream",
179
+ "where",
180
+ "table",
181
+ "monitor",
182
+ "output",
183
+ "operations"
184
+ ]
185
+ };
186
+ var PLAY_AUTHORING_DEFINE_PLAY_OPTION_FIELDS = [
187
+ "id",
188
+ "name",
189
+ "description",
190
+ "input",
191
+ "run",
192
+ "bindings",
193
+ ...PLAY_AUTHORING_BINDING_FIELDS.root
194
+ ];
195
+ var PLAY_AUTHORING_DOCUMENTATION = {
196
+ fetchBatching: {
197
+ warning: "A static ctx.fetch key inside a loop is a warning because every iteration must still have distinct method, URL, body, or safe headers. One durable receipt must never stand in for every request.",
198
+ guidance: "Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${ctx.run.id}:signals:${batchIndex}`."
199
+ },
200
+ runId: {
201
+ semantics: "ctx.run.id is stable while Deepline retries or resumes one durable run. A separately submitted run receives a new id.",
202
+ use: "Use it when deriving an external idempotency key for a sequence of batches."
203
+ },
204
+ staticCallKeys: {
205
+ constraint: "Durable call keys \u2014 the ctx.fetch key, the ctx.dataset key, the ctx.step id \u2014 must be static string literals. The key names a durable receipt, so check, publish, and replay have to agree on it before the body runs. A key computed at runtime cannot be resolved at check time and is rejected.",
206
+ consequence: "This is an architectural constraint, not a style rule. A play cannot loop over a computed key, so it cannot page a large table with a helper like page(pageNumber). Unrolling one literal key per page is not a design at any real page count.",
207
+ workaround: "Push the aggregation server-side and call it once: a SQL function, a view, or a provider endpoint that returns the whole result. Keep unrolled literal keys only for a handful of genuinely distinct calls. To fan out over rows, use ctx.dataset with a static key \u2014 the per-row receipt identity comes from the row, not from the key."
208
+ }
209
+ };
210
+ var PLAY_AUTHORING_STATIC_FETCH_KEY_HINT = `${PLAY_AUTHORING_DOCUMENTATION.staticCallKeys.workaround} Do not compute the key.`;
211
+ var SecretEnvironmentNameSchema = Type.String({
212
+ pattern: "^[A-Z][A-Z0-9_]{1,63}$",
213
+ description: "An uppercase environment variable name beginning with a letter."
214
+ });
215
+ var SqlListenerFilterScalarSchema = Type.Union([
216
+ Type.String(),
217
+ Type.Number(),
218
+ Type.Boolean(),
219
+ Type.Null()
220
+ ]);
221
+ var PLAY_AUTHORING_FIELD_REGISTRY = {
222
+ displayName: {
223
+ schema: Type.String(),
224
+ fixtures: {
225
+ valid: "Find verified emails",
226
+ invalid: 42,
227
+ absent: void 0,
228
+ unresolved: { expression: "displayName" },
229
+ edition1: "Legacy play"
230
+ },
231
+ referenceType: "string",
232
+ required: false,
233
+ resolution: "static-required",
234
+ issueCode: "play_authoring_binding_invalid",
235
+ description: "Optional human-readable Play name; empty uses the derived identifier.",
236
+ errorMessage: "displayName must be a static string."
237
+ },
238
+ description: {
239
+ schema: Type.String({ minLength: 1 }),
240
+ fixtures: {
241
+ valid: "Enrich a company.",
242
+ invalid: "",
243
+ absent: void 0,
244
+ unresolved: { expression: "description" },
245
+ edition1: "Legacy play."
246
+ },
247
+ referenceType: "string",
248
+ required: false,
249
+ resolution: "static-required",
250
+ issueCode: "play_authoring_binding_invalid",
251
+ description: "Optional non-empty human-readable summary of the Play.",
252
+ errorMessage: "description must be a non-empty static string."
253
+ },
254
+ "compatibility.toolErrorSchemaVersion": {
255
+ schema: Type.Union([Type.Literal(0), Type.Literal(1)]),
256
+ fixtures: {
257
+ valid: 1,
258
+ invalid: 2,
259
+ absent: void 0,
260
+ unresolved: { expression: "version" },
261
+ edition1: 0
262
+ },
263
+ referenceType: "0 | 1",
264
+ required: false,
265
+ resolution: "static-required",
266
+ issueCode: "play_authoring_binding_invalid",
267
+ description: "Artifact-pinned tool error behavior, either 0 or 1.",
268
+ errorMessage: "compatibility.toolErrorSchemaVersion must be the static literal 0 or 1."
269
+ },
270
+ "compatibility.authoringContract": {
271
+ schema: Type.Literal("explicit-freshness"),
272
+ fixtures: {
273
+ valid: "explicit-freshness",
274
+ invalid: "legacy",
275
+ absent: void 0,
276
+ unresolved: { expression: "authoringContract" },
277
+ edition1: void 0
278
+ },
279
+ referenceType: "'explicit-freshness'",
280
+ required: false,
281
+ resolution: "static-required",
282
+ issueCode: "play_authoring_binding_invalid",
283
+ description: "Opts new source into the current explicit-freshness authoring edition; an already-pinned edition-10 artifact retains its admitted behavior.",
284
+ errorMessage: 'compatibility.authoringContract must be the static literal "explicit-freshness".'
285
+ },
286
+ "compatibility.toolResponseReceiptRevision": {
287
+ schema: Type.String({
288
+ minLength: 1,
289
+ maxLength: 64,
290
+ pattern: "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
291
+ }),
292
+ fixtures: {
293
+ valid: "raw-v2-receipt-v1",
294
+ invalid: "has spaces",
295
+ absent: void 0,
296
+ unresolved: { expression: "revision" },
297
+ edition1: void 0
298
+ },
299
+ referenceType: "string",
300
+ required: false,
301
+ resolution: "static-required",
302
+ issueCode: "play_authoring_binding_invalid",
303
+ description: "Explicit durable-receipt revision for a response transformation; bump only when serialized tool output changes.",
304
+ errorMessage: "compatibility.toolResponseReceiptRevision must be a non-empty static identifier using letters, numbers, dots, underscores, or hyphens."
305
+ },
306
+ inline: {
307
+ schema: Type.Boolean(),
308
+ fixtures: {
309
+ valid: true,
310
+ invalid: "true",
311
+ absent: void 0,
312
+ unresolved: { expression: "inline" },
313
+ edition1: false
314
+ },
315
+ referenceType: "boolean",
316
+ required: false,
317
+ resolution: "static-required",
318
+ issueCode: "play_authoring_binding_invalid",
319
+ description: "Compiler hint for an inline named Play handler.",
320
+ errorMessage: "inline must be a static boolean."
321
+ },
322
+ "billing.maxCreditsPerRun": {
323
+ schema: Type.Number({ exclusiveMinimum: 0 }),
324
+ fixtures: {
325
+ valid: 1,
326
+ invalid: 0,
327
+ absent: void 0,
328
+ unresolved: { expression: "cap" },
329
+ edition1: 1
330
+ },
331
+ referenceType: "number",
332
+ required: false,
333
+ resolution: "static-required",
334
+ issueCode: "play_authoring_billing_limit_invalid",
335
+ description: "Maximum Deepline credits permitted for one Play Run.",
336
+ errorMessage: "billing.maxCreditsPerRun must be a static number greater than 0. Remove it for no run cap."
337
+ },
338
+ "bindings.webhook.hmac.secretEnv": {
339
+ schema: SecretEnvironmentNameSchema,
340
+ fixtures: {
341
+ valid: "WEBHOOK_SECRET",
342
+ invalid: "webhook_secret",
343
+ absent: void 0,
344
+ unresolved: { expression: "secretEnv" },
345
+ edition1: "WEBHOOK_SECRET"
346
+ },
347
+ referenceType: "string",
348
+ required: true,
349
+ resolution: "static-required",
350
+ issueCode: "play_authoring_webhook_hmac_invalid",
351
+ description: "Environment variable containing the webhook HMAC secret.",
352
+ errorMessage: "bindings.webhook.hmac.secretEnv must be an uppercase environment variable name beginning with a letter."
353
+ },
354
+ "bindings.webhook.hmac.algorithm": {
355
+ schema: Type.Literal("sha256"),
356
+ fixtures: {
357
+ valid: "sha256",
358
+ invalid: "sha1",
359
+ absent: void 0,
360
+ unresolved: { expression: "algorithm" },
361
+ edition1: "sha256"
362
+ },
363
+ referenceType: "'sha256'",
364
+ required: false,
365
+ resolution: "static-required",
366
+ issueCode: "play_authoring_webhook_hmac_invalid",
367
+ description: "Webhook signature hash algorithm. Only sha256 is supported.",
368
+ errorMessage: 'bindings.webhook.hmac.algorithm must be the static literal "sha256".'
369
+ },
370
+ "bindings.webhook.hmac.header": {
371
+ schema: Type.String({ minLength: 1 }),
372
+ fixtures: {
373
+ valid: "x-signature",
374
+ invalid: "",
375
+ absent: void 0,
376
+ unresolved: { expression: "header" },
377
+ edition1: "x-signature"
378
+ },
379
+ referenceType: "string",
380
+ required: false,
381
+ resolution: "static-required",
382
+ issueCode: "play_authoring_webhook_hmac_invalid",
383
+ description: "HTTP header containing the webhook signature.",
384
+ errorMessage: "bindings.webhook.hmac.header must be a non-empty static string."
385
+ },
386
+ "bindings.webhook.hmac.signaturePrefix": {
387
+ schema: Type.String(),
388
+ fixtures: {
389
+ valid: "",
390
+ invalid: { expression: "signaturePrefix" },
391
+ absent: void 0,
392
+ unresolved: { expression: "signaturePrefix" },
393
+ edition1: void 0
394
+ },
395
+ referenceType: "string",
396
+ required: false,
397
+ resolution: "static-required",
398
+ issueCode: "play_authoring_webhook_hmac_invalid",
399
+ description: "Optional literal before the lowercase hexadecimal HMAC. Set to an empty string for providers that send a bare digest; defaults to sha256= when a signature header is configured.",
400
+ errorMessage: "bindings.webhook.hmac.signaturePrefix must be a static string literal."
401
+ },
402
+ "bindings.webhook.auth.type": {
403
+ schema: Type.Literal("standard-webhooks"),
404
+ fixtures: {
405
+ valid: "standard-webhooks",
406
+ invalid: "svix",
407
+ absent: void 0,
408
+ unresolved: { expression: "type" },
409
+ edition1: void 0
410
+ },
411
+ referenceType: "'standard-webhooks'",
412
+ // auth itself is optional; once present, the AST adapter requires this
413
+ // field together with headerFamily and signingSecrets.
414
+ required: false,
415
+ resolution: "static-required",
416
+ issueCode: "play_authoring_standard_webhooks_invalid",
417
+ description: "Uses the Standard Webhooks v1 symmetric signing scheme.",
418
+ errorMessage: 'bindings.webhook.auth.type must be the static literal "standard-webhooks".'
419
+ },
420
+ "bindings.webhook.auth.headerFamily": {
421
+ schema: Type.Union([Type.Literal("standard"), Type.Literal("svix")]),
422
+ fixtures: {
423
+ valid: "svix",
424
+ invalid: "webhook",
425
+ absent: void 0,
426
+ unresolved: { expression: "headerFamily" },
427
+ edition1: void 0
428
+ },
429
+ referenceType: "'standard' | 'svix'",
430
+ // auth itself is optional; once present, the AST adapter requires this
431
+ // field together with type and signingSecrets.
432
+ required: false,
433
+ resolution: "static-required",
434
+ issueCode: "play_authoring_standard_webhooks_invalid",
435
+ description: "Header namespace expected from the webhook provider.",
436
+ errorMessage: 'bindings.webhook.auth.headerFamily must be the static literal "standard" or "svix".'
437
+ },
438
+ "bindings.webhook.auth.signingSecrets[]": {
439
+ schema: SecretEnvironmentNameSchema,
440
+ fixtures: {
441
+ valid: "VECTOR_WEBHOOK_SECRET",
442
+ invalid: "vector_webhook_secret",
443
+ absent: void 0,
444
+ unresolved: { expression: "secret" },
445
+ edition1: void 0
446
+ },
447
+ referenceType: "string",
448
+ // auth itself is optional; once present, the AST adapter requires this
449
+ // field together with type and headerFamily.
450
+ required: false,
451
+ resolution: "static-required",
452
+ issueCode: "play_authoring_standard_webhooks_invalid",
453
+ description: "Deepline Secret name used to verify Standard Webhooks.",
454
+ errorMessage: "bindings.webhook.auth.signingSecrets entries must be uppercase Deepline Secret names beginning with a letter."
455
+ },
456
+ "bindings.webhook.auth.toleranceSeconds": {
457
+ schema: Type.Integer({ minimum: 1, maximum: 3600 }),
458
+ fixtures: {
459
+ valid: 300,
460
+ invalid: 0,
461
+ absent: void 0,
462
+ unresolved: { expression: "toleranceSeconds" },
463
+ edition1: void 0
464
+ },
465
+ referenceType: "number",
466
+ required: false,
467
+ resolution: "static-required",
468
+ issueCode: "play_authoring_standard_webhooks_invalid",
469
+ description: "Accepted delivery timestamp skew in seconds, from 1 through 3600.",
470
+ errorMessage: "bindings.webhook.auth.toleranceSeconds must be a static whole number from 1 through 3600."
471
+ },
472
+ "bindings.cron.schedule": {
473
+ schema: Type.String({ minLength: 1 }),
474
+ fixtures: {
475
+ valid: "0 9 * * *",
476
+ invalid: "",
477
+ absent: void 0,
478
+ unresolved: { expression: "schedule" },
479
+ edition1: "0 9 * * *"
480
+ },
481
+ referenceType: "string",
482
+ required: true,
483
+ resolution: "static-required",
484
+ issueCode: "play_authoring_binding_invalid",
485
+ description: "Five-field cron expression.",
486
+ errorMessage: "bindings.cron.schedule must be a non-empty static string."
487
+ },
488
+ "bindings.cron.timezone": {
489
+ schema: Type.String({ minLength: 1 }),
490
+ fixtures: {
491
+ valid: "UTC",
492
+ invalid: "",
493
+ absent: void 0,
494
+ unresolved: { expression: "timezone" },
495
+ edition1: "UTC"
496
+ },
497
+ referenceType: "string",
498
+ required: false,
499
+ resolution: "static-required",
500
+ issueCode: "play_authoring_cron_timezone_invalid",
501
+ description: "IANA timezone. Omitted means UTC.",
502
+ errorMessage: "bindings.cron.timezone must be a valid non-empty IANA timezone string."
503
+ },
504
+ "bindings.cron.input": {
505
+ schema: Type.Object({}, { additionalProperties: true }),
506
+ fixtures: {
507
+ valid: { apply: true },
508
+ invalid: ["apply"],
509
+ absent: void 0,
510
+ unresolved: ["cronInput"],
511
+ edition1: void 0
512
+ },
513
+ referenceType: "Record<string, unknown>",
514
+ required: false,
515
+ resolution: "static-required",
516
+ issueCode: "play_authoring_binding_invalid",
517
+ description: "Static JSON object passed to every run created by this cron binding.",
518
+ errorMessage: "bindings.cron.input must be a static JSON object (no variables, spreads, or functions)."
519
+ },
520
+ "bindings.sqlListeners": {
521
+ schema: Type.Array(Type.Object({}, { additionalProperties: true })),
522
+ fixtures: {
523
+ valid: [],
524
+ invalid: "listeners",
525
+ absent: void 0,
526
+ unresolved: { expression: "listeners" },
527
+ edition1: []
528
+ },
529
+ referenceType: "SqlListener[]",
530
+ required: false,
531
+ resolution: "static-required",
532
+ issueCode: "play_authoring_binding_invalid",
533
+ description: "Static provider-monitor listener declarations.",
534
+ errorMessage: "bindings.sqlListeners must be a static array of objects."
535
+ },
536
+ "bindings.sqlListeners[].id": {
537
+ schema: Type.String({ pattern: PLAY_SQL_LISTENER_ID_PATTERN.source }),
538
+ fixtures: {
539
+ valid: "job-openings",
540
+ invalid: "1-job-openings",
541
+ absent: void 0,
542
+ unresolved: { expression: "listenerId" },
543
+ edition1: "job-openings"
544
+ },
545
+ referenceType: "string",
546
+ required: true,
547
+ resolution: "static-required",
548
+ issueCode: "sql_listener_binding_shape",
549
+ description: "Unique static listener identifier within one Play.",
550
+ errorMessage: "bindings.sqlListeners[].id must begin with a letter and contain only letters, numbers, underscores, or hyphens."
551
+ },
552
+ "bindings.sqlListeners[].tool": {
553
+ schema: Type.String({ pattern: PLAY_SQL_LISTENER_TOOL_PATTERN.source }),
554
+ fixtures: {
555
+ valid: "deepline_native.company_radar",
556
+ invalid: "company_radar",
557
+ absent: void 0,
558
+ unresolved: { expression: "toolId" },
559
+ edition1: "deepline_native.company_radar"
560
+ },
561
+ referenceType: "string",
562
+ required: true,
563
+ resolution: "static-required",
564
+ issueCode: "sql_listener_binding_shape",
565
+ description: "Modeled provider monitor tool id in provider.tool form.",
566
+ errorMessage: "bindings.sqlListeners[].tool must use static provider.tool syntax."
567
+ },
568
+ "bindings.sqlListeners[].stream": {
569
+ schema: Type.String({ pattern: PLAY_SQL_LISTENER_ID_PATTERN.source }),
570
+ fixtures: {
571
+ valid: "company_job_openings",
572
+ invalid: "1-company-job-openings",
573
+ absent: void 0,
574
+ unresolved: { expression: "stream" },
575
+ edition1: "company_job_openings"
576
+ },
577
+ referenceType: "string",
578
+ required: true,
579
+ resolution: "static-required",
580
+ issueCode: "sql_listener_binding_shape",
581
+ description: "Static output stream key exposed by the monitor tool.",
582
+ errorMessage: "bindings.sqlListeners[].stream must be a static stream identifier."
583
+ },
584
+ "bindings.sqlListeners[].operations[]": {
585
+ schema: Type.Union([
586
+ Type.Literal("INSERT"),
587
+ Type.Literal("UPDATE"),
588
+ Type.Literal("DELETE")
589
+ ]),
590
+ fixtures: {
591
+ valid: "INSERT",
592
+ invalid: "UPSERT",
593
+ absent: void 0,
594
+ unresolved: { expression: "operation" },
595
+ edition1: "UPDATE"
596
+ },
597
+ referenceType: "'INSERT' | 'UPDATE' | 'DELETE'",
598
+ required: false,
599
+ resolution: "static-required",
600
+ issueCode: "sql_listener_binding_shape",
601
+ description: "Database operation that wakes the listener.",
602
+ errorMessage: "bindings.sqlListeners[].operations entries must be INSERT, UPDATE, or DELETE."
603
+ },
604
+ "bindings.sqlListeners[].where.before": {
605
+ schema: Type.Record(Type.String(), Type.Unknown()),
606
+ fixtures: {
607
+ valid: { status: { eq: "open" } },
608
+ invalid: "status=open",
609
+ absent: void 0,
610
+ unresolved: "beforeFilter",
611
+ edition1: { status: { eq: "open" } }
612
+ },
613
+ referenceType: "Record<string, SqlListenerFilterOperator>",
614
+ required: false,
615
+ resolution: "static-required",
616
+ issueCode: "sql_listener_binding_shape",
617
+ description: "Column filters evaluated against the row before mutation.",
618
+ errorMessage: "bindings.sqlListeners[].where.before must be a static object keyed by column."
619
+ },
620
+ "bindings.sqlListeners[].where.after": {
621
+ schema: Type.Record(Type.String(), Type.Unknown()),
622
+ fixtures: {
623
+ valid: { status: { eq: "open" } },
624
+ invalid: "status=open",
625
+ absent: void 0,
626
+ unresolved: "afterFilter",
627
+ edition1: { status: { eq: "open" } }
628
+ },
629
+ referenceType: "Record<string, SqlListenerFilterOperator>",
630
+ required: false,
631
+ resolution: "static-required",
632
+ issueCode: "sql_listener_binding_shape",
633
+ description: "Column filters evaluated against the row after mutation.",
634
+ errorMessage: "bindings.sqlListeners[].where.after must be a static object keyed by column."
635
+ },
636
+ "bindings.sqlListeners[].where.*.*.eq": {
637
+ schema: SqlListenerFilterScalarSchema,
638
+ fixtures: {
639
+ valid: "open",
640
+ invalid: { nested: true },
641
+ absent: void 0,
642
+ unresolved: { expression: "equalsValue" },
643
+ edition1: "open"
644
+ },
645
+ referenceType: "SqlListenerFilterScalar",
646
+ required: false,
647
+ resolution: "static-required",
648
+ issueCode: "sql_listener_binding_shape",
649
+ description: "Scalar equality condition.",
650
+ errorMessage: "SQL listener eq must compare a scalar value."
651
+ },
652
+ "bindings.sqlListeners[].where.*.*.neq": {
653
+ schema: SqlListenerFilterScalarSchema,
654
+ fixtures: {
655
+ valid: "closed",
656
+ invalid: { nested: true },
657
+ absent: void 0,
658
+ unresolved: { expression: "notEqualsValue" },
659
+ edition1: "closed"
660
+ },
661
+ referenceType: "SqlListenerFilterScalar",
662
+ required: false,
663
+ resolution: "static-required",
664
+ issueCode: "sql_listener_binding_shape",
665
+ description: "Scalar inequality condition.",
666
+ errorMessage: "SQL listener neq must compare a scalar value."
667
+ },
668
+ "bindings.sqlListeners[].where.*.*.in": {
669
+ schema: Type.Array(SqlListenerFilterScalarSchema, { minItems: 1 }),
670
+ fixtures: {
671
+ valid: ["open", "pending"],
672
+ invalid: [],
673
+ absent: void 0,
674
+ unresolved: { expression: "acceptedValues" },
675
+ edition1: ["open"]
676
+ },
677
+ referenceType: "readonly SqlListenerFilterScalar[]",
678
+ required: false,
679
+ resolution: "static-required",
680
+ issueCode: "sql_listener_binding_shape",
681
+ description: "Non-empty scalar membership condition.",
682
+ errorMessage: "SQL listener in must contain at least one scalar value."
683
+ },
684
+ "bindings.sqlListeners[].where.*.*.notIn": {
685
+ schema: Type.Array(SqlListenerFilterScalarSchema, { minItems: 1 }),
686
+ fixtures: {
687
+ valid: ["closed"],
688
+ invalid: [],
689
+ absent: void 0,
690
+ unresolved: { expression: "rejectedValues" },
691
+ edition1: ["closed"]
692
+ },
693
+ referenceType: "readonly SqlListenerFilterScalar[]",
694
+ required: false,
695
+ resolution: "static-required",
696
+ issueCode: "sql_listener_binding_shape",
697
+ description: "Non-empty scalar exclusion condition.",
698
+ errorMessage: "SQL listener notIn must contain at least one scalar value."
699
+ },
700
+ "bindings.sqlListeners[].where.*.*.isNull": {
701
+ schema: Type.Literal(true),
702
+ fixtures: {
703
+ valid: true,
704
+ invalid: false,
705
+ absent: void 0,
706
+ unresolved: { expression: "isNull" },
707
+ edition1: true
708
+ },
709
+ referenceType: "true",
710
+ required: false,
711
+ resolution: "static-required",
712
+ issueCode: "sql_listener_binding_shape",
713
+ description: "Matches null values when set to true.",
714
+ errorMessage: "SQL listener isNull must be the static literal true."
715
+ },
716
+ "bindings.sqlListeners[].where.*.*.isNotNull": {
717
+ schema: Type.Literal(true),
718
+ fixtures: {
719
+ valid: true,
720
+ invalid: false,
721
+ absent: void 0,
722
+ unresolved: { expression: "isNotNull" },
723
+ edition1: true
724
+ },
725
+ referenceType: "true",
726
+ required: false,
727
+ resolution: "static-required",
728
+ issueCode: "sql_listener_binding_shape",
729
+ description: "Matches non-null values when set to true.",
730
+ errorMessage: "SQL listener isNotNull must be the static literal true."
731
+ },
732
+ "bindings.sqlListeners[].where.*.*.ilike": {
733
+ schema: Type.String(),
734
+ fixtures: {
735
+ valid: "%software%",
736
+ invalid: 1,
737
+ absent: void 0,
738
+ unresolved: { expression: "pattern" },
739
+ edition1: "%software%"
740
+ },
741
+ referenceType: "string",
742
+ required: false,
743
+ resolution: "static-required",
744
+ issueCode: "sql_listener_binding_shape",
745
+ description: "Case-insensitive SQL pattern condition.",
746
+ errorMessage: "SQL listener ilike must be a string pattern."
747
+ },
748
+ "bindings.secrets[]": {
749
+ schema: SecretEnvironmentNameSchema,
750
+ fixtures: {
751
+ valid: "API_TOKEN",
752
+ invalid: "api_token",
753
+ absent: void 0,
754
+ unresolved: { expression: "secret" },
755
+ edition1: "API_TOKEN"
756
+ },
757
+ referenceType: "string",
758
+ required: false,
759
+ resolution: "static-required",
760
+ issueCode: "play_authoring_secret_invalid",
761
+ description: "Environment variable made available to the Play.",
762
+ errorMessage: "bindings.secrets entries must be uppercase environment variable names beginning with a letter."
763
+ },
764
+ "ctx.tools.execute.staleAfterSeconds": {
765
+ schema: Type.Union([Type.Null(), Type.Integer({ minimum: 0 })]),
766
+ fixtures: {
767
+ valid: 0,
768
+ invalid: -1,
769
+ absent: void 0,
770
+ unresolved: { expression: "ttl" },
771
+ edition1: null
772
+ },
773
+ referenceType: "number | null",
774
+ required: false,
775
+ resolution: "runtime-allowed",
776
+ issueCode: "play_authoring_durable_policy_invalid",
777
+ description: EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION,
778
+ errorMessage: "staleAfterSeconds must be null, 0 (always execute), or a positive whole number of seconds."
779
+ },
780
+ "ctx.tools.execute.id": {
781
+ schema: Type.String({ pattern: "\\S" }),
782
+ fixtures: {
783
+ valid: "company-enrichment",
784
+ invalid: "",
785
+ absent: void 0,
786
+ unresolved: { expression: "receiptId" },
787
+ edition1: "company-enrichment"
788
+ },
789
+ referenceType: "string",
790
+ required: true,
791
+ resolution: "runtime-allowed",
792
+ issueCode: "play_authoring_tool_request_invalid",
793
+ description: "Stable durable receipt identity within one execution scope.",
794
+ errorMessage: "ctx.tools.execute id must be a non-empty string."
795
+ },
796
+ "ctx.tools.execute.tool": {
797
+ schema: Type.String({ pattern: "\\S" }),
798
+ fixtures: {
799
+ valid: "openmart_enrich_company",
800
+ invalid: "",
801
+ absent: void 0,
802
+ unresolved: { expression: "toolId" },
803
+ edition1: "openmart_enrich_company"
804
+ },
805
+ referenceType: "K",
806
+ required: true,
807
+ resolution: "runtime-allowed",
808
+ issueCode: "play_authoring_tool_request_invalid",
809
+ description: "Integration tool id resolved against the generated ToolMap.",
810
+ errorMessage: "ctx.tools.execute tool must be a non-empty tool id."
811
+ },
812
+ "ctx.tools.execute.input": {
813
+ schema: Type.Record(Type.String(), Type.Unknown()),
814
+ fixtures: {
815
+ valid: { domain: "example.com" },
816
+ invalid: "example.com",
817
+ absent: void 0,
818
+ unresolved: "toolInput",
819
+ edition1: {}
820
+ },
821
+ referenceType: "K extends keyof ToolMap ? ToolMap[K]['input'] : Record<string, unknown>",
822
+ required: true,
823
+ resolution: "runtime-allowed",
824
+ issueCode: "play_authoring_tool_request_invalid",
825
+ description: "Tool-specific input object.",
826
+ errorMessage: "ctx.tools.execute input must be an object."
827
+ },
828
+ "ctx.tools.execute.description": {
829
+ schema: Type.String(),
830
+ fixtures: {
831
+ valid: "Enrich the company.",
832
+ invalid: 1,
833
+ absent: void 0,
834
+ unresolved: { expression: "description" },
835
+ edition1: "Enrich the company."
836
+ },
837
+ referenceType: "string",
838
+ required: false,
839
+ resolution: "runtime-allowed",
840
+ issueCode: "play_authoring_tool_request_invalid",
841
+ description: "Human-readable purpose of the durable tool call.",
842
+ errorMessage: "ctx.tools.execute description must be a string."
843
+ },
844
+ "ctx.tools.execute.force": {
845
+ schema: Type.Boolean(),
846
+ fixtures: {
847
+ valid: true,
848
+ invalid: "true",
849
+ absent: void 0,
850
+ unresolved: { expression: "force" },
851
+ edition1: false
852
+ },
853
+ referenceType: "boolean",
854
+ required: false,
855
+ resolution: "runtime-allowed",
856
+ issueCode: "play_authoring_tool_request_invalid",
857
+ description: "Explicitly bypasses a completed durable tool receipt.",
858
+ errorMessage: "ctx.tools.execute force must be a boolean."
859
+ },
860
+ "ctx.tools.execute.timeoutMs": {
861
+ schema: Type.Integer({ minimum: 1 }),
862
+ fixtures: {
863
+ valid: 1,
864
+ invalid: 0,
865
+ absent: void 0,
866
+ unresolved: { expression: "timeout" },
867
+ edition1: 1
868
+ },
869
+ referenceType: "number",
870
+ required: false,
871
+ resolution: "runtime-allowed",
872
+ issueCode: "play_authoring_durable_policy_invalid",
873
+ description: "Positive whole-number runtime transport timeout in milliseconds.",
874
+ errorMessage: "timeoutMs must be a positive whole number of milliseconds."
875
+ },
876
+ "ctx.tools.execute.receiptWaitMs": {
877
+ schema: Type.Integer({ minimum: 1 }),
878
+ fixtures: {
879
+ valid: 1,
880
+ invalid: 0,
881
+ absent: void 0,
882
+ unresolved: { expression: "receiptWait" },
883
+ edition1: 1
884
+ },
885
+ referenceType: "number",
886
+ required: false,
887
+ resolution: "runtime-allowed",
888
+ issueCode: "play_authoring_durable_policy_invalid",
889
+ description: "Positive whole-number durable receipt wait budget in milliseconds.",
890
+ errorMessage: "receiptWaitMs must be a positive whole number of milliseconds."
891
+ },
892
+ "ctx.csv.options.description": {
893
+ schema: Type.String({ minLength: 1 }),
894
+ fixtures: {
895
+ valid: "Load account rows.",
896
+ invalid: "",
897
+ absent: void 0,
898
+ unresolved: { expression: "description" },
899
+ edition1: "Load rows."
900
+ },
901
+ referenceType: "string",
902
+ required: false,
903
+ resolution: "static-when-present",
904
+ issueCode: "play_authoring_csv_option_invalid",
905
+ description: "Non-empty description for a staged CSV load.",
906
+ errorMessage: "ctx.csv options.description must be non-empty."
907
+ },
908
+ "ctx.csv.options.columns": {
909
+ schema: Type.Record(
910
+ Type.String(),
911
+ Type.Union([
912
+ Type.String({ minLength: 1 }),
913
+ Type.Array(Type.String({ minLength: 1 }), { minItems: 1 })
914
+ ])
915
+ ),
916
+ fixtures: {
917
+ valid: { domain: ["domain", "Company Domain"] },
918
+ invalid: { domain: [] },
919
+ absent: void 0,
920
+ unresolved: { expression: { dynamic: true } },
921
+ edition1: { domain: "domain" }
922
+ },
923
+ referenceType: "CsvRenameMap",
924
+ required: false,
925
+ resolution: "runtime-allowed",
926
+ issueCode: "play_authoring_csv_option_invalid",
927
+ description: "Canonical field-to-header aliases for a staged CSV.",
928
+ errorMessage: "ctx.csv options.columns values must be a non-empty header or alias list."
929
+ },
930
+ "ctx.csv.options.rename": {
931
+ schema: Type.Record(
932
+ Type.String(),
933
+ Type.Union([
934
+ Type.String({ minLength: 1 }),
935
+ Type.Array(Type.String({ minLength: 1 }), { minItems: 1 })
936
+ ])
937
+ ),
938
+ fixtures: {
939
+ valid: { domain: "Company Domain" },
940
+ invalid: { domain: "" },
941
+ absent: void 0,
942
+ unresolved: { expression: { dynamic: true } },
943
+ edition1: { domain: "domain" }
944
+ },
945
+ referenceType: "CsvRenameMap",
946
+ required: false,
947
+ resolution: "static-when-present",
948
+ issueCode: "play_authoring_csv_option_invalid",
949
+ description: "Legacy header rename aliases for a staged CSV.",
950
+ errorMessage: "ctx.csv options.rename values must be a non-empty header or alias list."
951
+ },
952
+ "ctx.csv.options.required": {
953
+ schema: Type.Array(Type.String({ minLength: 1 })),
954
+ fixtures: {
955
+ valid: ["domain"],
956
+ invalid: [""],
957
+ absent: void 0,
958
+ unresolved: { expression: "requiredColumns" },
959
+ edition1: []
960
+ },
961
+ referenceType: "readonly string[]",
962
+ required: false,
963
+ resolution: "static-when-present",
964
+ issueCode: "play_authoring_csv_option_invalid",
965
+ description: "Canonical columns required after CSV normalization.",
966
+ errorMessage: "ctx.csv options.required entries must be non-empty column names."
967
+ },
968
+ "ctx.dataset.key": {
969
+ schema: Type.String({ minLength: 1 }),
970
+ fixtures: {
971
+ valid: "accounts",
972
+ invalid: "",
973
+ absent: void 0,
974
+ unresolved: { expression: "datasetKey" },
975
+ edition1: "rows"
976
+ },
977
+ referenceType: "string",
978
+ required: true,
979
+ resolution: "static-required",
980
+ issueCode: "play_authoring_dataset_option_invalid",
981
+ description: "Stable durable identity for one dataset.",
982
+ errorMessage: "ctx.dataset key must be a non-empty static string."
983
+ },
984
+ "ctx.dataset.run.description": {
985
+ schema: Type.String({ minLength: 1 }),
986
+ fixtures: {
987
+ valid: "Enrich account rows.",
988
+ invalid: "",
989
+ absent: void 0,
990
+ unresolved: { expression: "description" },
991
+ edition1: "Process rows."
992
+ },
993
+ referenceType: "string",
994
+ required: false,
995
+ resolution: "static-when-present",
996
+ issueCode: "play_authoring_dataset_option_invalid",
997
+ description: "Non-empty description for one dataset execution.",
998
+ errorMessage: "ctx.dataset run description must be non-empty."
999
+ },
1000
+ "ctx.dataset.run.key": {
1001
+ schema: Type.Union([
1002
+ Type.String({ minLength: 1 }),
1003
+ Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),
1004
+ Type.Function(
1005
+ [Type.Record(Type.String(), Type.Unknown()), Type.Integer()],
1006
+ Type.Union([
1007
+ Type.String(),
1008
+ Type.Number(),
1009
+ Type.Readonly(Type.Array(Type.Unknown()))
1010
+ ])
1011
+ )
1012
+ ]),
1013
+ fixtures: {
1014
+ valid: (row) => String(row.domain),
1015
+ invalid: [],
1016
+ absent: void 0,
1017
+ unresolved: { expression: "rowKey" },
1018
+ edition1: ["domain"]
1019
+ },
1020
+ referenceType: "DatasetRowKey<InputRow>",
1021
+ required: false,
1022
+ resolution: "runtime-dynamic",
1023
+ issueCode: "play_authoring_dataset_option_invalid",
1024
+ description: "Stable field or fields used for durable row identity.",
1025
+ errorMessage: "ctx.dataset run key must be a non-empty field, field list, or key function."
1026
+ },
1027
+ "ctx.dataset.run.rowIdentity": {
1028
+ schema: Type.Union([Type.Literal("source_row"), Type.Literal("key")]),
1029
+ fixtures: {
1030
+ valid: "source_row",
1031
+ invalid: "dedupe",
1032
+ absent: void 0,
1033
+ unresolved: { expression: "rowIdentity" },
1034
+ edition1: "key"
1035
+ },
1036
+ referenceType: "'source_row' | 'key'",
1037
+ required: false,
1038
+ resolution: "static-when-present",
1039
+ issueCode: "play_authoring_dataset_option_invalid",
1040
+ description: '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\u201310.',
1041
+ errorMessage: 'ctx.dataset run rowIdentity must be "source_row" or "key".'
1042
+ },
1043
+ "ctx.dataset.run.onRowError": {
1044
+ schema: Type.Union([Type.Literal("isolate"), Type.Literal("fail")]),
1045
+ fixtures: {
1046
+ valid: "isolate",
1047
+ invalid: "continue",
1048
+ absent: void 0,
1049
+ unresolved: { expression: "rowErrorPolicy" },
1050
+ edition1: "fail"
1051
+ },
1052
+ referenceType: "'isolate' | 'fail'",
1053
+ required: false,
1054
+ resolution: "static-when-present",
1055
+ issueCode: "play_authoring_dataset_option_invalid",
1056
+ description: "Whether row failures isolate or fail the whole dataset.",
1057
+ errorMessage: 'ctx.dataset run onRowError must be "isolate" or "fail".'
1058
+ },
1059
+ "ctx.dataset.run.mode": {
1060
+ schema: Type.Union([Type.Literal("upsert"), Type.Literal("net_new")]),
1061
+ fixtures: {
1062
+ valid: "upsert",
1063
+ invalid: "append",
1064
+ absent: void 0,
1065
+ unresolved: { expression: "datasetMode" },
1066
+ edition1: "upsert"
1067
+ },
1068
+ referenceType: "'upsert' | 'net_new'",
1069
+ required: false,
1070
+ resolution: "static-when-present",
1071
+ issueCode: "play_authoring_dataset_option_invalid",
1072
+ description: "Whether the dataset returns all rows or only newly admitted rows.",
1073
+ errorMessage: 'ctx.dataset run mode must be "upsert" or "net_new".'
1074
+ },
1075
+ "ctx.dataset.run.undrawnColumns": {
1076
+ schema: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),
1077
+ fixtures: {
1078
+ valid: ["miss_reason"],
1079
+ invalid: [],
1080
+ absent: void 0,
1081
+ unresolved: { expression: "undrawnColumns" },
1082
+ edition1: ["miss_reason"]
1083
+ },
1084
+ referenceType: "readonly string[]",
1085
+ required: false,
1086
+ resolution: "static-when-present",
1087
+ issueCode: "play_authoring_dataset_option_invalid",
1088
+ description: "Computed columns deliberately left out of the authored @mermaid diagram.",
1089
+ errorMessage: "ctx.dataset run undrawnColumns must be a non-empty array of static column-name strings."
1090
+ },
1091
+ "ctx.step.id": {
1092
+ schema: Type.String({ minLength: 1 }),
1093
+ fixtures: {
1094
+ valid: "load-settings",
1095
+ invalid: "",
1096
+ absent: void 0,
1097
+ unresolved: { expression: "stepId" },
1098
+ edition1: "step"
1099
+ },
1100
+ referenceType: "string",
1101
+ required: true,
1102
+ resolution: "static-required",
1103
+ issueCode: "play_authoring_step_option_invalid",
1104
+ description: "Stable durable identity for one scalar checkpoint.",
1105
+ errorMessage: "ctx.step id must be a non-empty static string."
1106
+ },
1107
+ "ctx.step.semanticKey": {
1108
+ schema: Type.String({ minLength: 1 }),
1109
+ fixtures: {
1110
+ valid: "account:stripe.com",
1111
+ invalid: "",
1112
+ absent: void 0,
1113
+ unresolved: { expression: "semanticKey" },
1114
+ edition1: "account"
1115
+ },
1116
+ referenceType: "string",
1117
+ required: false,
1118
+ resolution: "runtime-dynamic",
1119
+ issueCode: "play_authoring_step_option_invalid",
1120
+ description: "Optional semantic receipt identity for a scalar checkpoint.",
1121
+ errorMessage: "ctx.step semanticKey must be a non-empty string."
1122
+ },
1123
+ "ctx.step.staleAfterSeconds": {
1124
+ schema: Type.Union([Type.Null(), Type.Integer({ minimum: 0 })]),
1125
+ fixtures: {
1126
+ valid: 0,
1127
+ invalid: -1,
1128
+ absent: void 0,
1129
+ unresolved: { expression: "ttl" },
1130
+ edition1: null
1131
+ },
1132
+ referenceType: "number | null",
1133
+ required: false,
1134
+ resolution: "runtime-dynamic",
1135
+ issueCode: "play_authoring_durable_policy_invalid",
1136
+ description: EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION,
1137
+ errorMessage: "staleAfterSeconds must be null, 0 (always execute), or a positive whole number of seconds."
1138
+ },
1139
+ "ctx.fetch.key": {
1140
+ schema: Type.String({ minLength: 1 }),
1141
+ fixtures: {
1142
+ valid: "notify-crm",
1143
+ invalid: "",
1144
+ absent: void 0,
1145
+ unresolved: { expression: "fetchKey" },
1146
+ edition1: "fetch"
1147
+ },
1148
+ referenceType: "string",
1149
+ required: true,
1150
+ resolution: "static-required",
1151
+ issueCode: "play_authoring_durable_policy_invalid",
1152
+ description: "Stable durable identity for one external HTTP request.",
1153
+ errorMessage: "ctx.fetch key must be a non-empty static string.",
1154
+ unresolvedHint: PLAY_AUTHORING_STATIC_FETCH_KEY_HINT
1155
+ },
1156
+ "ctx.fetch.staleAfterSeconds": {
1157
+ schema: Type.Union([Type.Null(), Type.Integer({ minimum: 0 })]),
1158
+ fixtures: {
1159
+ valid: null,
1160
+ invalid: 1.5,
1161
+ absent: void 0,
1162
+ unresolved: { expression: "ttl" },
1163
+ edition1: 0
1164
+ },
1165
+ referenceType: "number | null",
1166
+ required: false,
1167
+ resolution: "runtime-dynamic",
1168
+ issueCode: "play_authoring_durable_policy_invalid",
1169
+ description: EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION,
1170
+ errorMessage: "staleAfterSeconds must be null, 0 (always execute), or a positive whole number of seconds."
1171
+ },
1172
+ "ctx.runPlay.key": {
1173
+ schema: Type.String({ minLength: 1 }),
1174
+ fixtures: {
1175
+ valid: "enrich-company",
1176
+ invalid: "",
1177
+ absent: void 0,
1178
+ unresolved: { expression: "callKey" },
1179
+ edition1: "child"
1180
+ },
1181
+ referenceType: "string",
1182
+ required: true,
1183
+ resolution: "runtime-dynamic",
1184
+ issueCode: "play_authoring_run_play_option_invalid",
1185
+ description: "Stable identity for one inline child Play call.",
1186
+ errorMessage: "ctx.runPlay key must be a non-empty string."
1187
+ },
1188
+ "ctx.runPlay.playRef": {
1189
+ schema: Type.Union([
1190
+ Type.String({ minLength: 1 }),
1191
+ Type.Union([
1192
+ Type.Object(
1193
+ { playName: Type.String({ minLength: 1 }) },
1194
+ { additionalProperties: true }
1195
+ ),
1196
+ Type.Object(
1197
+ { name: Type.String({ minLength: 1 }) },
1198
+ { additionalProperties: true }
1199
+ )
1200
+ ])
1201
+ ]),
1202
+ fixtures: {
1203
+ valid: "prebuilt/company-lookup",
1204
+ invalid: {},
1205
+ absent: void 0,
1206
+ unresolved: { expression: "playRef" },
1207
+ edition1: { name: "company-lookup" }
1208
+ },
1209
+ referenceType: "string | PlayReferenceLike",
1210
+ required: true,
1211
+ resolution: "runtime-dynamic",
1212
+ issueCode: "play_authoring_run_play_option_invalid",
1213
+ description: "Child Play name or typed Play definition handle.",
1214
+ errorMessage: "ctx.runPlay playRef must be a non-empty Play name or definition handle."
1215
+ },
1216
+ "ctx.runPlay.input": {
1217
+ schema: Type.Record(Type.String(), Type.Unknown()),
1218
+ fixtures: {
1219
+ valid: { domain: "example.com" },
1220
+ invalid: "example.com",
1221
+ absent: void 0,
1222
+ unresolved: "childInput",
1223
+ edition1: {}
1224
+ },
1225
+ referenceType: "Record<string, unknown>",
1226
+ required: true,
1227
+ resolution: "runtime-dynamic",
1228
+ issueCode: "play_authoring_run_play_option_invalid",
1229
+ description: "Scalar input object submitted to the child Play.",
1230
+ errorMessage: "ctx.runPlay input must be an object."
1231
+ },
1232
+ "ctx.runPlay.options.description": {
1233
+ schema: Type.String({ minLength: 1 }),
1234
+ fixtures: {
1235
+ valid: "Enrich the company.",
1236
+ invalid: "",
1237
+ absent: void 0,
1238
+ unresolved: { expression: "description" },
1239
+ edition1: "Run child."
1240
+ },
1241
+ referenceType: "string",
1242
+ required: true,
1243
+ resolution: "runtime-dynamic",
1244
+ issueCode: "play_authoring_run_play_option_invalid",
1245
+ description: "Non-empty purpose for one inline child Play call.",
1246
+ errorMessage: "ctx.runPlay options.description must be non-empty."
1247
+ },
1248
+ "ctx.runPlay.options.execution": {
1249
+ schema: Type.Literal("inline"),
1250
+ fixtures: {
1251
+ valid: "inline",
1252
+ invalid: "child-workflow",
1253
+ absent: void 0,
1254
+ unresolved: { expression: "execution" },
1255
+ edition1: "inline"
1256
+ },
1257
+ referenceType: "'inline'",
1258
+ required: false,
1259
+ resolution: "static-required",
1260
+ issueCode: "play_authoring_run_play_option_invalid",
1261
+ description: "Child composition strategy. Only inline is supported.",
1262
+ errorMessage: 'ctx.runPlay execution must be "inline".'
1263
+ },
1264
+ "ctx.runPlay.options.timeoutMs": {
1265
+ schema: Type.Undefined(),
1266
+ fixtures: {
1267
+ valid: void 0,
1268
+ invalid: 1e3,
1269
+ absent: void 0,
1270
+ unresolved: { expression: "timeoutMs" },
1271
+ edition1: void 0
1272
+ },
1273
+ referenceType: "never",
1274
+ required: false,
1275
+ resolution: "unsupported",
1276
+ issueCode: "play_authoring_run_play_option_invalid",
1277
+ description: "Unsupported legacy child-workflow timeout.",
1278
+ errorMessage: "ctx.runPlay timeoutMs is unsupported because child Plays execute inline."
1279
+ },
1280
+ "ctx.runPlayAsync.key": {
1281
+ schema: Type.String({ minLength: 1 }),
1282
+ fixtures: {
1283
+ valid: "request-approval",
1284
+ invalid: "",
1285
+ absent: void 0,
1286
+ unresolved: { expression: "callKey" },
1287
+ edition1: "request-approval"
1288
+ },
1289
+ referenceType: "string",
1290
+ required: true,
1291
+ resolution: "runtime-dynamic",
1292
+ issueCode: "play_authoring_run_play_option_invalid",
1293
+ description: "Stable identity for one independent child Play Run.",
1294
+ errorMessage: "ctx.runPlayAsync key must be a non-empty string."
1295
+ },
1296
+ "ctx.runPlayAsync.playRef": {
1297
+ schema: Type.Union([
1298
+ Type.String({ minLength: 1 }),
1299
+ Type.Union([
1300
+ Type.Object(
1301
+ { playName: Type.String({ minLength: 1 }) },
1302
+ { additionalProperties: true }
1303
+ ),
1304
+ Type.Object(
1305
+ { name: Type.String({ minLength: 1 }) },
1306
+ { additionalProperties: true }
1307
+ )
1308
+ ])
1309
+ ]),
1310
+ fixtures: {
1311
+ valid: "request-approval",
1312
+ invalid: {},
1313
+ absent: void 0,
1314
+ unresolved: { expression: "playRef" },
1315
+ edition1: "request-approval"
1316
+ },
1317
+ referenceType: "string | PlayReferenceLike",
1318
+ required: true,
1319
+ resolution: "runtime-dynamic",
1320
+ issueCode: "play_authoring_run_play_option_invalid",
1321
+ description: "Independently published scalar child Play name or strongly typed definition handle.",
1322
+ errorMessage: "ctx.runPlayAsync playRef must be a non-empty Play name or definition handle."
1323
+ },
1324
+ "ctx.runPlayAsync.input": {
1325
+ schema: Type.Record(Type.String(), Type.Unknown()),
1326
+ fixtures: {
1327
+ valid: { draftId: "draft-1" },
1328
+ invalid: "draft-1",
1329
+ absent: void 0,
1330
+ unresolved: "childInput",
1331
+ edition1: {}
1332
+ },
1333
+ referenceType: "Record<string, unknown>",
1334
+ required: true,
1335
+ resolution: "runtime-dynamic",
1336
+ issueCode: "play_authoring_run_play_option_invalid",
1337
+ description: "Scalar input object submitted to the independent child Run.",
1338
+ errorMessage: "ctx.runPlayAsync input must be an object."
1339
+ },
1340
+ "ctx.runPlayAsync.options.description": {
1341
+ schema: Type.String({ minLength: 1 }),
1342
+ fixtures: {
1343
+ valid: "Request approval.",
1344
+ invalid: "",
1345
+ absent: void 0,
1346
+ unresolved: { expression: "description" },
1347
+ edition1: "Request approval."
1348
+ },
1349
+ referenceType: "string",
1350
+ required: true,
1351
+ resolution: "runtime-dynamic",
1352
+ issueCode: "play_authoring_run_play_option_invalid",
1353
+ description: "Non-empty purpose for one independent child Play Run.",
1354
+ errorMessage: "ctx.runPlayAsync options.description must be non-empty."
1355
+ },
1356
+ "runtime.timeout": {
1357
+ schema: Type.String({ pattern: "^\\d+\\s*[mh]$" }),
1358
+ fixtures: {
1359
+ valid: "90m",
1360
+ invalid: "90s",
1361
+ absent: void 0,
1362
+ unresolved: { expression: "timeout" },
1363
+ edition1: "90m"
1364
+ },
1365
+ referenceType: "string",
1366
+ required: false,
1367
+ resolution: "static-required",
1368
+ issueCode: "play_authoring_binding_invalid",
1369
+ description: "Play-level sandbox deadline. The default is 30m; use a static duration such as 90m or 2h, up to 4h.",
1370
+ errorMessage: 'runtime.timeout must be a static duration such as "90m" or "2h".'
1371
+ },
1372
+ "runtime.size": {
1373
+ schema: Type.Literal("standard"),
1374
+ fixtures: {
1375
+ valid: "standard",
1376
+ invalid: "large",
1377
+ absent: void 0,
1378
+ unresolved: { expression: "size" },
1379
+ edition1: "standard"
1380
+ },
1381
+ referenceType: "'standard'",
1382
+ required: false,
1383
+ resolution: "static-required",
1384
+ issueCode: "play_authoring_binding_invalid",
1385
+ description: "Deepline-managed sandbox size. Only standard is supported.",
1386
+ errorMessage: 'runtime.size must be the static literal "standard".'
1387
+ },
1388
+ "ctx.customerDb.query.statement": {
1389
+ schema: Type.Union([
1390
+ Type.String({ minLength: 1 }),
1391
+ Type.Object(
1392
+ {
1393
+ kind: Type.Optional(Type.Literal("sql.query")),
1394
+ text: Type.String({ minLength: 1 }),
1395
+ values: Type.Optional(Type.Array(Type.Unknown(), { maxItems: 0 }))
1396
+ },
1397
+ { additionalProperties: false }
1398
+ )
1399
+ ]),
1400
+ fixtures: {
1401
+ valid: { kind: "sql.query", text: "select 1", values: [] },
1402
+ invalid: { kind: "sql.query", text: "select $1", values: [1] },
1403
+ absent: void 0,
1404
+ unresolved: { expression: "statement" },
1405
+ edition1: "select 1"
1406
+ },
1407
+ referenceType: "SqlQuery",
1408
+ required: true,
1409
+ resolution: "runtime-dynamic",
1410
+ issueCode: "play_authoring_tool_request_invalid",
1411
+ description: "One non-empty Customer DB SQL string; the deprecated SqlQuery object is accepted only without parameter values.",
1412
+ errorMessage: "ctx.customerDb.query statement must be a non-empty SQL string. Deprecated SqlQuery objects cannot contain parameter values."
1413
+ },
1414
+ "ctx.customerDb.query.options.id": {
1415
+ schema: Type.String({ pattern: "\\S" }),
1416
+ fixtures: {
1417
+ valid: "customer-report-read",
1418
+ invalid: "",
1419
+ absent: void 0,
1420
+ unresolved: { expression: "operationId" },
1421
+ edition1: "query"
1422
+ },
1423
+ referenceType: "string",
1424
+ required: true,
1425
+ resolution: "runtime-dynamic",
1426
+ issueCode: "play_authoring_tool_request_invalid",
1427
+ description: "Stable operation identity for Customer DB query recovery.",
1428
+ errorMessage: "ctx.customerDb.query options.id must be a non-empty stable string."
1429
+ },
1430
+ "ctx.customerDb.query.options.staleAfterSeconds": {
1431
+ schema: Type.Literal(0),
1432
+ fixtures: {
1433
+ valid: 0,
1434
+ invalid: 1,
1435
+ absent: void 0,
1436
+ unresolved: { expression: "ttl" },
1437
+ edition1: 0
1438
+ },
1439
+ referenceType: "number | null",
1440
+ required: false,
1441
+ resolution: "runtime-dynamic",
1442
+ issueCode: "play_authoring_durable_policy_invalid",
1443
+ description: "Customer DB queries always execute with freshness 0.",
1444
+ errorMessage: "Customer DB queries must use staleAfterSeconds: 0."
1445
+ },
1446
+ "ctx.customerDb.query.options.maxRows": {
1447
+ schema: Type.Integer({ minimum: 1 }),
1448
+ fixtures: {
1449
+ valid: 100,
1450
+ invalid: 0,
1451
+ absent: void 0,
1452
+ unresolved: { expression: "maxRows" },
1453
+ edition1: 100
1454
+ },
1455
+ referenceType: "number",
1456
+ required: false,
1457
+ resolution: "runtime-dynamic",
1458
+ issueCode: "play_authoring_tool_request_invalid",
1459
+ description: "Positive whole-number Customer DB response row limit.",
1460
+ errorMessage: "ctx.customerDb.query options.maxRows must be a positive whole number."
1461
+ },
1462
+ "ctx.customerDb.query.options.timeoutMs": {
1463
+ schema: Type.Integer({ minimum: 1 }),
1464
+ fixtures: {
1465
+ valid: 1e3,
1466
+ invalid: 0,
1467
+ absent: void 0,
1468
+ unresolved: { expression: "timeoutMs" },
1469
+ edition1: 1e3
1470
+ },
1471
+ referenceType: "number",
1472
+ required: false,
1473
+ resolution: "runtime-dynamic",
1474
+ issueCode: "play_authoring_durable_policy_invalid",
1475
+ description: "Positive whole-number Customer DB timeout in milliseconds.",
1476
+ errorMessage: "ctx.customerDb.query options.timeoutMs must be a positive whole number of milliseconds."
1477
+ },
1478
+ "ctx.tool.key": {
1479
+ schema: Type.String({ minLength: 1 }),
1480
+ fixtures: {
1481
+ valid: "company",
1482
+ invalid: "",
1483
+ absent: void 0,
1484
+ unresolved: { expression: "key" },
1485
+ edition1: "tool"
1486
+ },
1487
+ referenceType: "string",
1488
+ required: true,
1489
+ resolution: "runtime-dynamic",
1490
+ issueCode: "play_authoring_tool_request_invalid",
1491
+ description: "Stable receipt identity for the tool shorthand.",
1492
+ errorMessage: "ctx.tool key must be a non-empty string."
1493
+ },
1494
+ "ctx.tool.tool": {
1495
+ schema: Type.String({ minLength: 1 }),
1496
+ fixtures: {
1497
+ valid: "openmart_enrich_company",
1498
+ invalid: "",
1499
+ absent: void 0,
1500
+ unresolved: { expression: "tool" },
1501
+ edition1: "openmart_enrich_company"
1502
+ },
1503
+ referenceType: "string",
1504
+ required: true,
1505
+ resolution: "runtime-dynamic",
1506
+ issueCode: "play_authoring_tool_request_invalid",
1507
+ description: "Integration tool id for the tool shorthand.",
1508
+ errorMessage: "ctx.tool tool must be a non-empty tool id."
1509
+ },
1510
+ "ctx.tool.input": {
1511
+ schema: Type.Record(Type.String(), Type.Unknown()),
1512
+ fixtures: {
1513
+ valid: { domain: "example.com" },
1514
+ invalid: "example.com",
1515
+ absent: void 0,
1516
+ unresolved: "toolInput",
1517
+ edition1: {}
1518
+ },
1519
+ referenceType: "Record<string, unknown>",
1520
+ required: true,
1521
+ resolution: "runtime-dynamic",
1522
+ issueCode: "play_authoring_tool_request_invalid",
1523
+ description: "Tool-specific input object for the shorthand.",
1524
+ errorMessage: "ctx.tool input must be an object."
1525
+ },
1526
+ "ctx.tool.options.description": {
1527
+ schema: Type.String({ minLength: 1 }),
1528
+ fixtures: {
1529
+ valid: "Enrich the company.",
1530
+ invalid: "",
1531
+ absent: void 0,
1532
+ unresolved: { expression: "description" },
1533
+ edition1: "Run tool."
1534
+ },
1535
+ referenceType: "string",
1536
+ required: false,
1537
+ resolution: "runtime-dynamic",
1538
+ issueCode: "play_authoring_tool_request_invalid",
1539
+ description: "Non-empty purpose for the tool shorthand.",
1540
+ errorMessage: "ctx.tool options.description must be non-empty."
1541
+ },
1542
+ "ctx.runSteps.options.description": {
1543
+ schema: Type.String({ minLength: 1 }),
1544
+ fixtures: {
1545
+ valid: "Score the account.",
1546
+ invalid: "",
1547
+ absent: void 0,
1548
+ unresolved: { expression: "description" },
1549
+ edition1: "Run steps."
1550
+ },
1551
+ referenceType: "string",
1552
+ required: false,
1553
+ resolution: "runtime-dynamic",
1554
+ issueCode: "play_authoring_step_option_invalid",
1555
+ description: "Non-empty purpose for a reusable step program.",
1556
+ errorMessage: "ctx.runSteps options.description must be non-empty."
1557
+ },
1558
+ "ctx.runSteps.options.staleAfterSeconds": {
1559
+ schema: Type.Union([Type.Null(), Type.Integer({ minimum: 0 })]),
1560
+ fixtures: {
1561
+ valid: 0,
1562
+ invalid: -1,
1563
+ absent: void 0,
1564
+ unresolved: { expression: "ttl" },
1565
+ edition1: null
1566
+ },
1567
+ referenceType: "number | null",
1568
+ required: false,
1569
+ resolution: "runtime-dynamic",
1570
+ issueCode: "play_authoring_durable_policy_invalid",
1571
+ description: EXPLICIT_FRESHNESS_STALE_AFTER_SECONDS_DESCRIPTION,
1572
+ errorMessage: "staleAfterSeconds must be null, 0 (always execute), or a positive whole number of seconds."
1573
+ },
1574
+ "ctx.sleep.ms": {
1575
+ schema: Type.Integer({ minimum: 0 }),
1576
+ fixtures: {
1577
+ valid: 0,
1578
+ invalid: -1,
1579
+ absent: void 0,
1580
+ unresolved: { expression: "delayMs" },
1581
+ edition1: 1e3
1582
+ },
1583
+ referenceType: "number",
1584
+ required: true,
1585
+ resolution: "runtime-dynamic",
1586
+ issueCode: "play_authoring_step_option_invalid",
1587
+ description: "Non-negative whole-number sleep duration in milliseconds.",
1588
+ errorMessage: "ctx.sleep ms must be a non-negative whole number."
1589
+ },
1590
+ "ctx.fetch.url": {
1591
+ schema: Type.String({ minLength: 1 }),
1592
+ fixtures: {
1593
+ valid: "https://example.com",
1594
+ invalid: "",
1595
+ absent: void 0,
1596
+ unresolved: { expression: "url" },
1597
+ edition1: "https://example.com"
1598
+ },
1599
+ referenceType: "string",
1600
+ required: true,
1601
+ resolution: "runtime-allowed",
1602
+ issueCode: "play_authoring_fetch_secret_requires_tls",
1603
+ description: "HTTP request URL. Secret authentication requires HTTPS.",
1604
+ errorMessage: "ctx.fetch URL must be a non-empty URL string."
1605
+ },
1606
+ "ctx.fetch.init.method": {
1607
+ schema: Type.String({ minLength: 1 }),
1608
+ fixtures: {
1609
+ valid: "GET",
1610
+ invalid: "",
1611
+ absent: void 0,
1612
+ unresolved: { expression: "method" },
1613
+ edition1: "GET"
1614
+ },
1615
+ referenceType: "string",
1616
+ required: false,
1617
+ resolution: "runtime-allowed",
1618
+ issueCode: "play_authoring_fetch_idempotency_required",
1619
+ description: "HTTP method. Mutating methods require an Idempotency-Key.",
1620
+ errorMessage: "ctx.fetch method must be a non-empty string."
1621
+ },
1622
+ "ctx.fetch.init.headers.Idempotency-Key": {
1623
+ schema: Type.String({ minLength: 1 }),
1624
+ fixtures: {
1625
+ valid: "contact-123-update",
1626
+ invalid: "",
1627
+ absent: void 0,
1628
+ unresolved: { expression: "idempotencyKey" },
1629
+ edition1: "contact-123-update"
1630
+ },
1631
+ referenceType: "string",
1632
+ required: false,
1633
+ resolution: "runtime-allowed",
1634
+ issueCode: "play_authoring_fetch_idempotency_required",
1635
+ description: "Required for mutating HTTP methods. The provider must support idempotency, and the same key must be retained across retries and replay.",
1636
+ errorMessage: "Idempotency-Key must be a non-empty string when provided."
1637
+ }
1638
+ };
1639
+ var UnsupportedPlayAuthoringContractEditionError = class extends Error {
1640
+ constructor(value) {
1641
+ super(
1642
+ `Unsupported Play authoring contract edition ${String(value)}. Supported editions: ${SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS.join(", ")}.`
1643
+ );
1644
+ this.name = "UnsupportedPlayAuthoringContractEditionError";
1645
+ }
1646
+ };
1647
+ var PlayAuthoringContractViolationError = class extends Error {
1648
+ constructor(path, code, detail, hint) {
1649
+ super(`[${code} path=${path}] ${detail}`);
1650
+ this.path = path;
1651
+ this.code = code;
1652
+ this.detail = detail;
1653
+ this.hint = hint;
1654
+ this.name = "PlayAuthoringContractViolationError";
1655
+ }
1656
+ };
1657
+ var PlayAuthoringFieldValidationError = class extends PlayAuthoringContractViolationError {
1658
+ constructor(path, code, message) {
1659
+ super(path, code, message);
1660
+ this.name = "PlayAuthoringFieldValidationError";
1661
+ }
1662
+ };
1663
+ function normalizePlayAuthoringContractEdition(value) {
1664
+ const edition = value ?? LEGACY_PLAY_AUTHORING_CONTRACT_EDITION;
1665
+ if (!SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS.includes(
1666
+ edition
1667
+ )) {
1668
+ throw new UnsupportedPlayAuthoringContractEditionError(edition);
1669
+ }
1670
+ return edition;
1671
+ }
1672
+ function validatePlayAuthoringField(path, value) {
1673
+ const definition = PLAY_AUTHORING_FIELD_REGISTRY[path];
1674
+ if (Value.Check(definition.schema, value)) return;
1675
+ throw new PlayAuthoringFieldValidationError(
1676
+ path,
1677
+ definition.issueCode,
1678
+ definition.errorMessage
1679
+ );
1680
+ }
1681
+ function cloudReferenceType(path) {
1682
+ return PLAY_AUTHORING_FIELD_REGISTRY[path].referenceType;
1683
+ }
1684
+ var PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
1685
+ `export type DurableCallStaleAfterSeconds = ${cloudReferenceType("ctx.tools.execute.staleAfterSeconds")};`,
1686
+ `export type PlayRuntimeTimeoutMs = ${cloudReferenceType("ctx.tools.execute.timeoutMs")};`,
1687
+ `export type PlayReceiptWaitMs = ${cloudReferenceType("ctx.tools.execute.receiptWaitMs")};`,
1688
+ `export type SqlListenerOperation = ${cloudReferenceType("bindings.sqlListeners[].operations[]")};`,
1689
+ "export type SqlListenerFilterScalar = string | number | boolean | null;",
1690
+ `export type SqlListenerFilterOperator = { eq?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.eq")}; neq?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.neq")}; in?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.in")}; notIn?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.notIn")}; isNull?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.isNull")}; isNotNull?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.isNotNull")}; ilike?: ${cloudReferenceType("bindings.sqlListeners[].where.*.*.ilike")} };`,
1691
+ `export type SqlListenerWhere = { before?: ${cloudReferenceType("bindings.sqlListeners[].where.before")}; after?: ${cloudReferenceType("bindings.sqlListeners[].where.after")} };`,
1692
+ `export type SqlListenerDeclaration = { id: ${cloudReferenceType("bindings.sqlListeners[].id")}; tool: ${cloudReferenceType("bindings.sqlListeners[].tool")}; stream: ${cloudReferenceType("bindings.sqlListeners[].stream")}; operations?: readonly SqlListenerOperation[]; where?: SqlListenerWhere };`,
1693
+ "export type SqlListenerEvent<T extends object = Record<string, unknown>> = { tool: string; stream: string; operation: SqlListenerOperation; before: T | null; after: T | null; changedAt: string; metadata: { outboxId: string; listenerId: string; table: string } };",
1694
+ "export type SqlQuery = string | { kind?: 'sql.query'; text: string; values?: readonly unknown[] };",
1695
+ "export type ToolExecutionRequest<K extends string> = {",
1696
+ ` readonly id: ${cloudReferenceType("ctx.tools.execute.id")};`,
1697
+ ` readonly tool: ${cloudReferenceType("ctx.tools.execute.tool")};`,
1698
+ ` readonly input: ${cloudReferenceType("ctx.tools.execute.input")};`,
1699
+ ` readonly description?: ${cloudReferenceType("ctx.tools.execute.description")};`,
1700
+ ` readonly force?: ${cloudReferenceType("ctx.tools.execute.force")};`,
1701
+ " readonly staleAfterSeconds?: DurableCallStaleAfterSeconds;",
1702
+ " readonly timeoutMs?: PlayRuntimeTimeoutMs;",
1703
+ " readonly receiptWaitMs?: PlayReceiptWaitMs;",
1704
+ "};",
1705
+ "export type PlayCronInput<TInput> = TInput extends readonly unknown[] ? never : TInput extends object ? TInput : never;",
1706
+ "export type PlayBindings<TInput = Record<string, unknown>> = {",
1707
+ ` displayName?: ${cloudReferenceType("displayName")};`,
1708
+ ` description?: ${cloudReferenceType("description")};`,
1709
+ ` compatibility?: { authoringContract?: ${cloudReferenceType("compatibility.authoringContract")}; toolErrorSchemaVersion?: ${cloudReferenceType("compatibility.toolErrorSchemaVersion")}; toolResponseReceiptRevision?: ${cloudReferenceType("compatibility.toolResponseReceiptRevision")} };`,
1710
+ ` inline?: ${cloudReferenceType("inline")};`,
1711
+ ` billing?: { maxCreditsPerRun?: ${cloudReferenceType("billing.maxCreditsPerRun")} };`,
1712
+ ` runtime?: { timeout?: ${cloudReferenceType("runtime.timeout")}; size?: ${cloudReferenceType("runtime.size")} };`,
1713
+ ` webhook?: { hmac?: { algorithm?: ${cloudReferenceType("bindings.webhook.hmac.algorithm")}; header?: ${cloudReferenceType("bindings.webhook.hmac.header")}; signaturePrefix?: ${cloudReferenceType("bindings.webhook.hmac.signaturePrefix")}; secretEnv: ${cloudReferenceType("bindings.webhook.hmac.secretEnv")} }; auth?: { type: ${cloudReferenceType("bindings.webhook.auth.type")}; headerFamily: ${cloudReferenceType("bindings.webhook.auth.headerFamily")}; signingSecrets: readonly ${cloudReferenceType("bindings.webhook.auth.signingSecrets[]")}[]; toleranceSeconds?: ${cloudReferenceType("bindings.webhook.auth.toleranceSeconds")} } };`,
1714
+ ` cron?: { schedule: ${cloudReferenceType("bindings.cron.schedule")}; timezone?: ${cloudReferenceType("bindings.cron.timezone")}; input?: PlayCronInput<TInput> };`,
1715
+ " sqlListeners?: readonly SqlListenerDeclaration[];",
1716
+ ` secrets?: readonly ${cloudReferenceType("bindings.secrets[]")}[];`,
1717
+ "};",
1718
+ "declare const SECRET_HANDLE_BRAND: unique symbol;",
1719
+ "declare const SECRET_PROMISE_BRAND: unique symbol;",
1720
+ "export type SecretHandle = { readonly [SECRET_HANDLE_BRAND]: never; readonly name: string; toString(): string; toJSON(): never };",
1721
+ "export type SecretPromise = Promise<string> & { readonly [SECRET_PROMISE_BRAND]: never };",
1722
+ "export type SecretValue = SecretHandle;",
1723
+ "export type SecretAuth = { readonly kind: 'bearer' | 'header'; readonly secret: string | SecretPromise | SecretHandle; readonly header?: string };",
1724
+ "export type SecretAuthInput = SecretAuth | readonly SecretAuth[];",
1725
+ "export type PlayInputContract<TInput> = { readonly schema: Record<string, unknown>; readonly __inputType?: TInput };",
1726
+ "export type PlayReturnObject = Record<string, unknown> & { readonly _metadata?: never };",
1727
+ "export type CsvRenameMap = Record<string, string | readonly string[]>;",
1728
+ "export type FileInput<TMetadata = unknown> = string & { readonly __deeplineFileInputMetadata?: TMetadata };",
1729
+ "export type CsvInput<TRow extends object = Record<string, unknown>> = FileInput<{ readonly kind: 'csv'; readonly row: TRow }>;",
1730
+ "export type ColumnMap<TRow extends object> = { [K in keyof TRow & string]?: string | readonly string[] };",
1731
+ `export type CsvOptions = { description?: ${cloudReferenceType("ctx.csv.options.description")}; columns?: ${cloudReferenceType("ctx.csv.options.columns")}; rename?: ${cloudReferenceType("ctx.csv.options.rename")}; required?: ${cloudReferenceType("ctx.csv.options.required")} };`,
1732
+ "export type PlayCallExecution = 'inline';",
1733
+ `export type PlayCallOptions = { description: ${cloudReferenceType("ctx.runPlay.options.description")}; execution?: ${cloudReferenceType("ctx.runPlay.options.execution")}; timeoutMs?: ${cloudReferenceType("ctx.runPlay.options.timeoutMs")} };`,
1734
+ `export type PlayAsyncCallOptions = { description: ${cloudReferenceType("ctx.runPlayAsync.options.description")} };`,
1735
+ "declare const PLAY_RUN_ID_BRAND: unique symbol;",
1736
+ "export type PlayRunId = string & { readonly [PLAY_RUN_ID_BRAND]: 'PlayRunId' };",
1737
+ "export type AsyncPlayRunRef = Readonly<{ runId: PlayRunId }>;",
1738
+ `export type RuntimeStepOptions = { semanticKey?: ${cloudReferenceType("ctx.step.semanticKey")}; staleAfterSeconds?: ${cloudReferenceType("ctx.step.staleAfterSeconds")} };`,
1739
+ `export type FetchOptions = { staleAfterSeconds?: ${cloudReferenceType("ctx.fetch.staleAfterSeconds")}; transient?: boolean };`,
1740
+ "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 };",
1741
+ "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 };",
1742
+ "export type PlayFetchResponse = { freshness?: CallFreshnessMetadata; ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null };",
1743
+ "export declare class CtxFetchAmbiguousWriteError extends Error { readonly code: 'CTX_FETCH_WRITE_OUTCOME_UNKNOWN'; readonly outcome: 'unknown'; readonly method: string; readonly origin: string; }",
1744
+ "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; }",
1745
+ "export type StepResolver<Row, Value> = (row: Row, ctx: DeeplinePlayRuntimeContext, index: number, previousCell?: PreviousCell<Value>) => Value | Promise<Value>;",
1746
+ "export type DatasetColumnRunInput<Row, Value> = { readonly row: Row; readonly ctx: DeeplinePlayRuntimeContext; readonly index: number; readonly previousCell?: PreviousCell<Value> };",
1747
+ "export type DatasetColumnDefinition<Row, Value> = { readonly run: (input: DatasetColumnRunInput<Row, Value>) => Value | Promise<Value>; readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean> };",
1748
+ "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>; };",
1749
+ "export type StepOptions<Row, Value = unknown> = { readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>; readonly recompute?: boolean; readonly recomputeOnError?: boolean; readonly staleAfterSeconds?: DurableCallStaleAfterSeconds };",
1750
+ "export type StepProgramOptions = { readonly continueOnProviderUnavailable?: boolean };",
1751
+ "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>; };",
1752
+ "export type StepProgramResolver<Input, Return> = { readonly kind: 'steps'; readonly steps: readonly PlayStepProgramStep[]; readonly returnResolver?: StepResolver<never, Return>; readonly __inputType?: (input: Input) => void };",
1753
+ "export type RunnableStepProgram<Input, Return> = Pick<StepProgram<Input, never, Return>, 'kind' | 'steps' | 'returnResolver' | '__inputType'>;",
1754
+ "export type RunnableColumnStepProgram<Return> = Pick<StepProgramResolver<unknown, Return>, 'kind' | 'steps' | 'returnResolver'>;",
1755
+ "export type PlayStepProgramStep = { readonly name: string; readonly recompute?: boolean; readonly recomputeOnError?: boolean; readonly staleAfterSeconds?: DurableCallStaleAfterSeconds; readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown> };",
1756
+ "export type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | RunnableColumnStepProgram<Value>;",
1757
+ "export type StepProgramOutput<TProgram> = TProgram extends StepProgram<unknown, infer Output, unknown> ? Output : never;",
1758
+ "export type DatasetRowKey<InputRow extends object> = (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);",
1759
+ "export type DatasetDefinitionOptions<InputRow extends object> = { key?: DatasetRowKey<InputRow> };",
1760
+ `export type DatasetRunOptions<InputRow extends object> = { description?: ${cloudReferenceType("ctx.dataset.run.description")}; key?: DatasetRowKey<InputRow>; rowIdentity?: ${cloudReferenceType("ctx.dataset.run.rowIdentity")}; onRowError?: ${cloudReferenceType("ctx.dataset.run.onRowError")}; mode?: ${cloudReferenceType("ctx.dataset.run.mode")}; undrawnColumns?: ${cloudReferenceType("ctx.dataset.run.undrawnColumns")} };`,
1761
+ "export type DatasetBuilder<InputRow extends object, OutputRow extends object> = {",
1762
+ " withColumn<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;",
1763
+ " withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value> & { readonly runIf: (row: OutputRow, index: number) => boolean | Promise<boolean> }): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;",
1764
+ " withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;",
1765
+ " withColumn<Name extends string, Value>(name: Name, resolver: StepResolver<OutputRow, Value> | RunnableColumnStepProgram<Value>, options: StepOptions<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;",
1766
+ " withColumns<ProgramOutput extends OutputRow, Return>(program: StepProgram<OutputRow, ProgramOutput, Return>): DatasetBuilder<InputRow, ProgramOutput>;",
1767
+ " step<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): never;",
1768
+ " run(options?: DatasetRunOptions<InputRow>): Promise<PlayDataset<OutputRow>>;",
1769
+ "};",
1770
+ "export type PlayReferenceLike<TInput extends Record<string, unknown> = Record<string, unknown>> = ({ readonly playName: string; readonly name?: string } | { readonly name: string; readonly playName?: string }) & { readonly __inputType?: TInput };",
1771
+ "export type BillingBenefitValues = { quickenrichUnlimited: { enabled: boolean; requestsPerMinute: number } };",
1772
+ "export type BillingEntitlements = { org_id: string; as_of: number; plan: { sku: string; name: string; catalog_revision: string | null; included_credits: number; interval: 'month' | 'year' | null } | null; benefits: { quickenrichUnlimited?: { status: 'active' | 'past_due'; value: BillingBenefitValues['quickenrichUnlimited']; expiresAt?: number } }; effective_limits: { quickenrichUnlimited?: { baseline: number; effective: number; source: 'plan' | 'override'; override_expires_at?: number } } };",
1773
+ "export interface DeeplinePlayRuntimeContext {",
1774
+ " billing: { entitlements(): Promise<BillingEntitlements> };",
1775
+ " csv<T = Record<string, unknown>>(path: string | CsvInput<T & object>, options?: CsvOptions): Promise<PlayDataset<T>>;",
1776
+ " dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;",
1777
+ " map<TSource extends PlayDatasetInput<object>>(key: string, items: TSource, options?: DatasetDefinitionOptions<PlayDatasetRow<TSource> & object>): never;",
1778
+ " readonly run: { readonly id: string };",
1779
+ ` 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>;`,
1780
+ " tools: { execute<K extends string>(request: ToolExecutionRequest<K>): Promise<ToolExecutionOutput<K>> };",
1781
+ ` 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[]> };`,
1782
+ ` 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>>;`,
1783
+ " step<T>(id: string, run: () => T | Promise<T>, options?: RuntimeStepOptions): Promise<T>;",
1784
+ " fetch(key: string, url: string | URL, init?: RequestInit & { headers?: HeadersInit & { 'Idempotency-Key'?: string; 'X-Idempotency-Key'?: string }; auth?: SecretAuthInput }, options?: FetchOptions): Promise<PlayFetchResponse>;",
1785
+ " secrets: { get(name: string): SecretPromise; bearer(secret: string | SecretPromise | SecretHandle): SecretAuth; header(header: string, secret: string | SecretPromise | SecretHandle): SecretAuth };",
1786
+ ` runPlay<TOutput = unknown>(key: string, playRef: ${cloudReferenceType("ctx.runPlay.playRef")}, input: ${cloudReferenceType("ctx.runPlay.input")}, options: PlayCallOptions): Promise<TOutput>;`,
1787
+ " runPlayAsync<TInput extends Record<string, unknown>>(key: string, playRef: PlayReferenceLike<TInput>, input: NoInfer<TInput>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;",
1788
+ " runPlayAsync(key: string, playRef: string, input: Record<string, unknown>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;",
1789
+ " log(message: string, options?: { level?: 'debug' | 'info' | 'warn' | 'error'; context?: Readonly<Record<string, string | number | boolean>> }): void;",
1790
+ ` sleep(ms: ${cloudReferenceType("ctx.sleep.ms")}): Promise<void>;`,
1791
+ "}",
1792
+ "export type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = { id: string; displayName?: string; description?: string; input: PlayInputContract<TInput>; run: (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>; bindings?: PlayBindings<TInput>; billing?: PlayBindings<TInput>['billing']; runtime?: PlayBindings<TInput>['runtime']; compatibility?: PlayBindings<TInput>['compatibility'] };",
1793
+ "export type DefinedPlay<TInput, TOutput extends PlayReturnObject> = ((ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>) & { readonly name: string; readonly __inputType?: TInput; readonly __outputType?: TOutput; readonly bindings?: PlayBindings<TInput>; readonly runtime?: PlayBindings<TInput>['runtime']; readonly compatibility?: PlayBindings<TInput>['compatibility'] };",
1794
+ "export type PlayHandlerInput<THandler> = THandler extends (context: DeeplinePlayRuntimeContext, input: infer TInput) => Promise<PlayReturnObject> ? TInput : never;",
1795
+ "export type PlayHandlerOutput<THandler> = THandler extends (context: DeeplinePlayRuntimeContext, input: unknown) => Promise<infer TOutput extends PlayReturnObject> ? TOutput : never;"
1796
+ ];
1797
+
50
1798
  // ../plays/contracts.ts
51
1799
  var PLAY_ARTIFACT_VERSION = CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION;
1800
+ var UnsupportedPlayToolErrorSchemaVersionError = class extends Error {
1801
+ constructor(value) {
1802
+ super(
1803
+ `Unsupported Play tool error schema version ${String(value)}. Supported versions: ${SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS.join(", ")}.`
1804
+ );
1805
+ this.name = "UnsupportedPlayToolErrorSchemaVersionError";
1806
+ }
1807
+ };
1808
+ var InvalidPlayContractCompatibilityError = class extends Error {
1809
+ constructor(message = "Play artifact compatibility must be an object.") {
1810
+ super(message);
1811
+ this.name = "InvalidPlayContractCompatibilityError";
1812
+ }
1813
+ };
1814
+ function normalizePlayContractCompatibility(compatibility) {
1815
+ if (!compatibility || typeof compatibility !== "object" || Array.isArray(compatibility)) {
1816
+ throw new InvalidPlayContractCompatibilityError();
1817
+ }
1818
+ const requestedToolErrorSchemaVersion = compatibility.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION;
1819
+ if (compatibility.datasetRowInput !== void 0 && compatibility.datasetRowInput !== "current_run") {
1820
+ throw new InvalidPlayContractCompatibilityError(
1821
+ `Unsupported dataset row input policy ${String(compatibility.datasetRowInput)}.`
1822
+ );
1823
+ }
1824
+ if (!SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS.includes(
1825
+ requestedToolErrorSchemaVersion
1826
+ )) {
1827
+ throw new UnsupportedPlayToolErrorSchemaVersionError(
1828
+ requestedToolErrorSchemaVersion
1829
+ );
1830
+ }
1831
+ let toolResponseContract;
1832
+ let toolResponseReceiptRevision;
1833
+ try {
1834
+ toolResponseContract = normalizeToolResponseContract(
1835
+ compatibility.toolResponseContract
1836
+ );
1837
+ toolResponseReceiptRevision = normalizeToolResponseReceiptRevision(
1838
+ compatibility.toolResponseReceiptRevision
1839
+ );
1840
+ } catch (error) {
1841
+ if (error instanceof UnsupportedToolResponseContractError || error instanceof InvalidToolResponseReceiptRevisionError) {
1842
+ throw new InvalidPlayContractCompatibilityError(error.message);
1843
+ }
1844
+ throw error;
1845
+ }
1846
+ return {
1847
+ ...compatibility,
1848
+ toolErrorSchemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
1849
+ toolResponseContract,
1850
+ ...toolResponseReceiptRevision ? { toolResponseReceiptRevision } : {},
1851
+ authoringContractEdition: normalizePlayAuthoringContractEdition(
1852
+ compatibility.authoringContractEdition
1853
+ )
1854
+ };
1855
+ }
52
1856
  function buildPlayContractCompatibility(input) {
53
1857
  return {
54
1858
  artifactVersion: PLAY_ARTIFACT_VERSION,
1859
+ ...input?.datasetRowInput ? { datasetRowInput: input.datasetRowInput } : {},
55
1860
  runtimeBackend: input?.runtimeBackend ?? null,
56
1861
  toolErrorSchemaVersion: input?.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
57
1862
  authoringContractEdition: input?.authoringContractEdition ?? PLAY_AUTHORING_CONTRACT_EDITION,
@@ -387,12 +2192,12 @@ function parseShapedMermaidNodes(fragment) {
387
2192
  const nodes = [];
388
2193
  let cursor = 0;
389
2194
  while (cursor < fragment.length) {
390
- const identifier = /[A-Za-z][\w-]*/.exec(fragment.slice(cursor));
391
- if (!identifier) break;
392
- const start = cursor + (identifier.index ?? 0);
2195
+ const identifier2 = /[A-Za-z][\w-]*/.exec(fragment.slice(cursor));
2196
+ if (!identifier2) break;
2197
+ const start = cursor + (identifier2.index ?? 0);
393
2198
  const parsed = parseMermaidNodeAtStart(fragment.slice(start));
394
2199
  if (parsed?.shaped || parsed?.unterminated) nodes.push(parsed);
395
- cursor = start + Math.max(parsed?.length ?? identifier[0].length, 1);
2200
+ cursor = start + Math.max(parsed?.length ?? identifier2[0].length, 1);
396
2201
  }
397
2202
  return nodes;
398
2203
  }
@@ -433,10 +2238,10 @@ function inferBindingIo(statement) {
433
2238
  const expression2 = returned[1].replace(/(['"`])(?:\\.|(?!\1).)*\1/g, "");
434
2239
  IDENTIFIER.lastIndex = 0;
435
2240
  for (const match of expression2.matchAll(IDENTIFIER)) {
436
- const identifier = match[0];
2241
+ const identifier2 = match[0];
437
2242
  const index = match.index ?? 0;
438
- if (JS_WORDS.has(identifier) || expression2[index - 1] === ".") continue;
439
- inputs2.add(identifier);
2243
+ if (JS_WORDS.has(identifier2) || expression2[index - 1] === ".") continue;
2244
+ inputs2.add(identifier2);
440
2245
  }
441
2246
  return {
442
2247
  inputs: [...inputs2],
@@ -454,14 +2259,14 @@ function inferBindingIo(statement) {
454
2259
  const inputs = /* @__PURE__ */ new Set();
455
2260
  IDENTIFIER.lastIndex = 0;
456
2261
  for (const match of expression.matchAll(IDENTIFIER)) {
457
- const identifier = match[0];
2262
+ const identifier2 = match[0];
458
2263
  const index = match.index ?? 0;
459
2264
  const previous = expression[index - 1] ?? "";
460
- const next = expression[index + identifier.length] ?? "";
461
- if (JS_WORDS.has(identifier) || identifier === output || previous === "." || next === ":" || /^\s*\(/.test(expression.slice(index + identifier.length))) {
2265
+ const next = expression[index + identifier2.length] ?? "";
2266
+ if (JS_WORDS.has(identifier2) || identifier2 === output || previous === "." || next === ":" || /^\s*\(/.test(expression.slice(index + identifier2.length))) {
462
2267
  continue;
463
2268
  }
464
- inputs.add(identifier);
2269
+ inputs.add(identifier2);
465
2270
  }
466
2271
  return {
467
2272
  inputs: [...inputs],
@@ -1266,8 +3071,220 @@ function resolveDocflowBinding(ast, binding, lineStarts, parents) {
1266
3071
  // ../plays/bundling/limits.ts
1267
3072
  var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
1268
3073
 
3074
+ // ../plays/source-authoring-edition.ts
3075
+ function unwrap(node) {
3076
+ let current = node;
3077
+ while (current && [
3078
+ "TSAsExpression",
3079
+ "TSSatisfiesExpression",
3080
+ "TSTypeAssertion",
3081
+ "TSNonNullExpression",
3082
+ "ParenthesizedExpression"
3083
+ ].includes(current.type)) {
3084
+ current = isAstNode(current.expression) ? current.expression : null;
3085
+ }
3086
+ return current;
3087
+ }
3088
+ function identifier(node) {
3089
+ return isAstNode(node) && node.type === "Identifier" && typeof node.name === "string" ? node.name : null;
3090
+ }
3091
+ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3092
+ const declarations = /* @__PURE__ */ new Map();
3093
+ const exports = /* @__PURE__ */ new Map();
3094
+ const legacyExports = /* @__PURE__ */ new Map();
3095
+ const definitions = [];
3096
+ const defineAliases = /* @__PURE__ */ new Set();
3097
+ const record = (statement, exported) => {
3098
+ for (const declaration of astArray(statement.declarations)) {
3099
+ const name = identifier(declaration.id);
3100
+ const initializer = isAstNode(declaration.init) ? declaration.init : null;
3101
+ if (!name) continue;
3102
+ declarations.set(
3103
+ name,
3104
+ statement.kind === "const" || isDefinePlayCall(initializer) ? initializer : null
3105
+ );
3106
+ if (initializer && isDefinePlayCall(initializer))
3107
+ definitions.push(initializer);
3108
+ if (exported) exports.set(name, { type: "Identifier", name });
3109
+ }
3110
+ };
3111
+ for (const statement of astArray(ast.body)) {
3112
+ if (statement.type === "ImportDeclaration") {
3113
+ for (const specifier of astArray(statement.specifiers)) {
3114
+ if (specifier.type === "ImportSpecifier" && ["definePlay", "defineWorkflow"].includes(
3115
+ identifier(specifier.imported) ?? ""
3116
+ )) {
3117
+ const name = identifier(specifier.local);
3118
+ if (name) defineAliases.add(name);
3119
+ }
3120
+ }
3121
+ }
3122
+ if (statement.type === "VariableDeclaration") record(statement, false);
3123
+ if (statement.type === "ExportDefaultDeclaration" && isAstNode(statement.declaration)) {
3124
+ exports.set("default", statement.declaration);
3125
+ }
3126
+ if (statement.type === "TSExportAssignment" && isAstNode(statement.expression)) {
3127
+ legacyExports.set("default", statement.expression);
3128
+ }
3129
+ if (statement.type === "ExportNamedDeclaration") {
3130
+ if (isAstNode(statement.source) || statement.exportKind === "type")
3131
+ continue;
3132
+ if (isAstNode(statement.declaration) && statement.declaration.type === "VariableDeclaration") {
3133
+ record(statement.declaration, true);
3134
+ }
3135
+ for (const specifier of astArray(statement.specifiers)) {
3136
+ if (specifier.exportKind === "type") continue;
3137
+ const local2 = identifier(specifier.local);
3138
+ const exported = identifier(specifier.exported) ?? (isAstNode(specifier.exported) && specifier.exported.type === "Literal" && typeof specifier.exported.value === "string" ? specifier.exported.value : null);
3139
+ if (local2 && exported)
3140
+ exports.set(exported, { type: "Identifier", name: local2 });
3141
+ }
3142
+ }
3143
+ if (statement.type === "ExpressionStatement" && isAstNode(statement.expression) && statement.expression.type === "AssignmentExpression") {
3144
+ const left = isAstNode(statement.expression.left) ? statement.expression.left : null;
3145
+ const right = isAstNode(statement.expression.right) ? statement.expression.right : null;
3146
+ if (left?.type === "MemberExpression" && !left.computed && right) {
3147
+ const object = isAstNode(left.object) ? left.object : null;
3148
+ if (identifier(object) === "module" && identifier(left.property) === "exports") {
3149
+ legacyExports.set("default", right);
3150
+ } else if (identifier(object) === "exports" && identifier(left.property) === "default") {
3151
+ legacyExports.set("default", right);
3152
+ }
3153
+ }
3154
+ }
3155
+ }
3156
+ const resolve4 = (node, seen = /* @__PURE__ */ new Set()) => {
3157
+ const value2 = unwrap(node);
3158
+ if (value2?.type === "UnaryExpression" && value2.operator === "void") {
3159
+ const operand = unwrap(isAstNode(value2.argument) ? value2.argument : null);
3160
+ if (operand?.type === "Literal")
3161
+ return { type: "Literal", value: void 0 };
3162
+ }
3163
+ const name = identifier(value2);
3164
+ if (!name) return value2;
3165
+ if (name === "undefined" && !declarations.has(name))
3166
+ return { type: "Literal", value: void 0 };
3167
+ if (seen.has(name)) return null;
3168
+ return resolve4(declarations.get(name) ?? null, new Set(seen).add(name));
3169
+ };
3170
+ const staticKey = (node) => {
3171
+ const value2 = resolve4(node);
3172
+ if (value2?.type === "Literal" && (typeof value2.value === "string" || typeof value2.value === "number")) {
3173
+ return String(value2.value);
3174
+ }
3175
+ if (value2?.type === "TemplateLiteral" && astArray(value2.expressions).length === 0) {
3176
+ const quasi = astArray(value2.quasis)[0];
3177
+ const cooked = quasi?.value && typeof quasi.value === "object" ? quasi.value.cooked : null;
3178
+ return typeof cooked === "string" ? cooked : null;
3179
+ }
3180
+ return null;
3181
+ };
3182
+ const property = (node, key, ancestors = /* @__PURE__ */ new Set()) => {
3183
+ if (!node) return { kind: "absent" };
3184
+ const object = resolve4(node);
3185
+ if (object?.type === "Literal" && object.value == null)
3186
+ return { kind: "absent" };
3187
+ if (object?.type !== "ObjectExpression" || ancestors.has(object))
3188
+ return { kind: "unknown" };
3189
+ const next = new Set(ancestors).add(object);
3190
+ for (const entry of astArray(object.properties).reverse()) {
3191
+ if (entry.type === "SpreadElement") {
3192
+ const spread = property(
3193
+ isAstNode(entry.argument) ? entry.argument : null,
3194
+ key,
3195
+ next
3196
+ );
3197
+ if (spread.kind !== "absent") return spread;
3198
+ continue;
3199
+ }
3200
+ if (entry.type !== "Property") return { kind: "unknown" };
3201
+ const name = entry.computed ? staticKey(isAstNode(entry.key) ? entry.key : null) : identifier(entry.key) ?? staticKey(isAstNode(entry.key) ? entry.key : null);
3202
+ if (name === null) return { kind: "unknown" };
3203
+ if (name !== key) continue;
3204
+ if (entry.kind !== "init" || entry.method) return { kind: "unknown" };
3205
+ return isAstNode(entry.value) ? { kind: "found", value: entry.value } : { kind: "unknown" };
3206
+ }
3207
+ return { kind: "absent" };
3208
+ };
3209
+ const callMarker = (call) => {
3210
+ const args = astArray(call.arguments);
3211
+ const first = resolve4(args[0] ?? null);
3212
+ const objectForm = first?.type === "ObjectExpression" || args.length === 1;
3213
+ const options = objectForm ? args[0] ?? null : args[2] ?? null;
3214
+ const direct = property(options, "compatibility");
3215
+ let compatibility = direct;
3216
+ if (direct.kind === "absent" || direct.kind === "found" && resolve4(direct.value)?.type === "Literal" && resolve4(direct.value)?.value == null) {
3217
+ const bindings = objectForm ? property(options, "bindings") : { kind: "absent" };
3218
+ compatibility = bindings.kind === "found" ? property(bindings.value, "compatibility") : bindings;
3219
+ }
3220
+ return compatibility.kind === "found" ? property(compatibility.value, "authoringContract") : compatibility;
3221
+ };
3222
+ const reachesMarker = (node, seen = /* @__PURE__ */ new Set()) => {
3223
+ const value2 = resolve4(node);
3224
+ if (!value2 || seen.has(value2)) return false;
3225
+ seen.add(value2);
3226
+ if ([
3227
+ "FunctionExpression",
3228
+ "ArrowFunctionExpression",
3229
+ "FunctionDeclaration"
3230
+ ].includes(value2.type))
3231
+ return false;
3232
+ if ((isDefinePlayCall(value2) || value2.type === "CallExpression" && defineAliases.has(identifier(value2.callee) ?? "")) && callMarker(value2).kind !== "absent")
3233
+ return true;
3234
+ return Object.values(value2).some(
3235
+ (child) => isAstNode(child) ? reachesMarker(child, seen) : Array.isArray(child) && astArray(child).some((entry) => reachesMarker(entry, seen))
3236
+ );
3237
+ };
3238
+ const requested = exportName ?? "default";
3239
+ const local = exports.get(requested);
3240
+ const expression = resolve4(
3241
+ local ?? legacyExports.get(requested) ?? (exportName === null ? definitions[0] ?? null : null)
3242
+ );
3243
+ if (!expression || expression.type !== "CallExpression") {
3244
+ return {
3245
+ marker: {
3246
+ kind: local && !expression || reachesMarker(expression) ? "unknown" : "absent"
3247
+ },
3248
+ localExport: false
3249
+ };
3250
+ }
3251
+ const recognized = isDefinePlayCall(expression);
3252
+ const marker = callMarker(expression);
3253
+ if (!recognized && marker.kind === "absent" && reachesMarker(expression)) {
3254
+ return { marker: { kind: "unknown" }, localExport: false };
3255
+ }
3256
+ if (marker.kind !== "found") return { marker, localExport: Boolean(local) };
3257
+ if (!recognized) return { marker: { kind: "unknown" }, localExport: false };
3258
+ const value = resolve4(marker.value);
3259
+ return {
3260
+ marker: value?.type === "Literal" ? { kind: "value", value: value.value } : { kind: "unknown" },
3261
+ localExport: Boolean(local),
3262
+ definition: expression
3263
+ };
3264
+ }
3265
+ function resolvePlaySourceAuthoringContractEdition(marker, pinnedEdition) {
3266
+ if (marker.kind === "unknown") {
3267
+ throw new PlayAuthoringFieldValidationError(
3268
+ "compatibility.authoringContract",
3269
+ "play_authoring_binding_invalid",
3270
+ 'compatibility.authoringContract must be statically resolvable; declare "explicit-freshness" to opt into explicit freshness.'
3271
+ );
3272
+ }
3273
+ if (marker.kind === "absent")
3274
+ return pinnedEdition ?? PLAY_AUTHORING_CONTRACT_EDITION;
3275
+ validatePlayAuthoringField("compatibility.authoringContract", marker.value);
3276
+ if (pinnedEdition !== void 0 && pinnedEdition !== 10 && pinnedEdition !== PLAY_AUTHORING_CONTRACT_EDITION) {
3277
+ throw new PlayAuthoringFieldValidationError(
3278
+ "compatibility.authoringContract",
3279
+ "play_authoring_binding_invalid",
3280
+ `The source explicit-freshness contract requires authoringContractEdition ${PLAY_AUTHORING_CONTRACT_EDITION}; artifact-pinned edition 10 remains valid only for an already-published artifact.`
3281
+ );
3282
+ }
3283
+ return pinnedEdition === 10 ? 10 : PLAY_AUTHORING_CONTRACT_EDITION;
3284
+ }
3285
+
1269
3286
  // ../plays/bundling/index.ts
1270
- var PLAY_BUNDLE_CACHE_NAMESPACE = "deepline-play-artifacts-docflow-jsdoc";
3287
+ var PLAY_BUNDLE_CACHE_NAMESPACE = "deepline-play-artifacts-docflow-jsdoc-pure-contracts";
1271
3288
  var PLAY_ARTIFACT_CACHE_DIR = join(tmpdir(), PLAY_BUNDLE_CACHE_NAMESPACE);
1272
3289
  var PLAY_PROXY_NAMESPACE = "deepline-play-runtime-ref";
1273
3290
  var SOURCE_EXTENSIONS = [
@@ -1619,11 +3636,11 @@ function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Se
1619
3636
  if (!value?.trim()) return null;
1620
3637
  return trimResult ? value.trim() : value;
1621
3638
  }
1622
- const identifier = getIdentifierName3(expression);
1623
- if (!identifier || seen.has(identifier)) return null;
1624
- seen.add(identifier);
3639
+ const identifier2 = getIdentifierName3(expression);
3640
+ if (!identifier2 || seen.has(identifier2)) return null;
3641
+ seen.add(identifier2);
1625
3642
  return staticStringFromExpression(
1626
- context.declarations.get(identifier),
3643
+ context.declarations.get(identifier2),
1627
3644
  context,
1628
3645
  seen,
1629
3646
  trimResult
@@ -1647,11 +3664,11 @@ function objectExpressionFromNode(node, context, seen = /* @__PURE__ */ new Set(
1647
3664
  const expression = unwrapStaticExpression2(node);
1648
3665
  if (!expression) return null;
1649
3666
  if (expression.type === "ObjectExpression") return expression;
1650
- const identifier = getIdentifierName3(expression);
1651
- if (!identifier || seen.has(identifier)) return null;
1652
- seen.add(identifier);
3667
+ const identifier2 = getIdentifierName3(expression);
3668
+ if (!identifier2 || seen.has(identifier2)) return null;
3669
+ seen.add(identifier2);
1653
3670
  return objectExpressionFromNode(
1654
- context.declarations.get(identifier),
3671
+ context.declarations.get(identifier2),
1655
3672
  context,
1656
3673
  seen
1657
3674
  );
@@ -1719,27 +3736,42 @@ function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Se
1719
3736
  if (expression.type === "Literal" && typeof expression.value === "number") {
1720
3737
  return expression.value;
1721
3738
  }
1722
- const identifier = getIdentifierName3(expression);
1723
- if (!identifier || seen.has(identifier)) return null;
1724
- seen.add(identifier);
3739
+ const identifier2 = getIdentifierName3(expression);
3740
+ if (!identifier2 || seen.has(identifier2)) return null;
3741
+ seen.add(identifier2);
1725
3742
  return staticNumberFromExpression(
1726
- context.declarations.get(identifier),
3743
+ context.declarations.get(identifier2),
1727
3744
  context,
1728
3745
  seen
1729
3746
  );
1730
3747
  }
1731
- function toolErrorSchemaVersionFromOptions(node, context) {
1732
- const directCompatibility = resolveStaticProperty(
1733
- node,
1734
- "compatibility",
1735
- context
1736
- );
1737
- if (directCompatibility.kind === "unknown") return null;
3748
+ function compatibilityFromOptions(node, context) {
3749
+ const direct = resolveStaticProperty(node, "compatibility", context);
3750
+ if (direct.kind !== "found") {
3751
+ if (direct.kind === "unknown") return direct;
3752
+ } else {
3753
+ let value = unwrapStaticExpression2(direct.value);
3754
+ const seen = /* @__PURE__ */ new Set();
3755
+ while (value?.type === "Identifier") {
3756
+ const name = getIdentifierName3(value);
3757
+ if (name === "undefined" && !context.declarations.has(name)) {
3758
+ value = { type: "Literal", value: void 0 };
3759
+ break;
3760
+ }
3761
+ if (seen.has(name)) return { kind: "unknown" };
3762
+ seen.add(name);
3763
+ value = unwrapStaticExpression2(context.declarations.get(name));
3764
+ }
3765
+ const nullish = value?.type === "Literal" && value.value == null;
3766
+ const voidLiteral = value?.type === "UnaryExpression" && value.operator === "void" && isAstNode(value.argument) && value.argument.type === "Literal";
3767
+ if (!nullish && !voidLiteral) return direct;
3768
+ }
1738
3769
  const bindings = resolveStaticProperty(node, "bindings", context);
1739
- if (bindings.kind === "unknown") return null;
1740
- const bindingCompatibility = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "compatibility", context) : { kind: "absent" };
1741
- if (bindingCompatibility.kind === "unknown") return null;
1742
- const compatibility = directCompatibility.kind === "found" ? directCompatibility : bindingCompatibility;
3770
+ return bindings.kind === "found" ? resolveStaticProperty(bindings.value, "compatibility", context) : bindings;
3771
+ }
3772
+ function toolErrorSchemaVersionFromOptions(node, context) {
3773
+ const compatibility = compatibilityFromOptions(node, context);
3774
+ if (compatibility.kind === "unknown") return null;
1743
3775
  if (compatibility.kind === "absent") return void 0;
1744
3776
  const schema = resolveStaticProperty(
1745
3777
  compatibility.value,
@@ -1753,17 +3785,8 @@ function toolErrorSchemaVersionFromOptions(node, context) {
1753
3785
  return null;
1754
3786
  }
1755
3787
  function toolResponseReceiptRevisionFromOptions(node, context) {
1756
- const directCompatibility = resolveStaticProperty(
1757
- node,
1758
- "compatibility",
1759
- context
1760
- );
1761
- if (directCompatibility.kind === "unknown") return null;
1762
- const bindings = resolveStaticProperty(node, "bindings", context);
1763
- if (bindings.kind === "unknown") return null;
1764
- const bindingCompatibility = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "compatibility", context) : { kind: "absent" };
1765
- if (bindingCompatibility.kind === "unknown") return null;
1766
- const compatibility = directCompatibility.kind === "found" ? directCompatibility : bindingCompatibility;
3788
+ const compatibility = compatibilityFromOptions(node, context);
3789
+ if (compatibility.kind === "unknown") return null;
1767
3790
  if (compatibility.kind === "absent") return void 0;
1768
3791
  const revision = resolveStaticProperty(
1769
3792
  compatibility.value,
@@ -2559,17 +4582,32 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
2559
4582
  })).sort((left, right) => left.filePath.localeCompare(right.filePath))
2560
4583
  })
2561
4584
  );
2562
- const metadata = extractDefinedPlayMetadata(sourceCode, exportName) ?? (exportName === "default" ? extractDefinedPlayMetadata(sourceCode, null) : null);
2563
- if (metadata?.toolErrorSchemaVersionUnknown) {
4585
+ const sourceAst = parsePlaySourceAst(sourceCode);
4586
+ if (!sourceAst)
2564
4587
  throw new Error(
2565
- "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1."
2566
- );
2567
- }
2568
- if (metadata?.toolResponseReceiptRevisionUnknown) {
2569
- throw new Error(
2570
- "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string."
4588
+ "Play source syntax must be valid before selecting its authoring edition."
2571
4589
  );
4590
+ const selection = extractPlaySourceAuthoringEdition(
4591
+ sourceAst,
4592
+ exportName === "default" ? null : exportName
4593
+ );
4594
+ const metadata = (selection.marker.kind === "value" && selection.definition ? playMetadataFromDefinePlayCall(
4595
+ selection.definition,
4596
+ buildPlayMetadataContext(sourceAst)
4597
+ ) : extractDefinedPlayMetadata(sourceCode, exportName)) ?? (exportName === "default" ? extractDefinedPlayMetadata(sourceCode, null) : null);
4598
+ const compatibilityDiagnostic = metadata?.toolErrorSchemaVersionUnknown ? "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1." : metadata?.toolResponseReceiptRevisionUnknown ? "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string." : null;
4599
+ try {
4600
+ resolvePlaySourceAuthoringContractEdition(selection.marker);
4601
+ } catch (error) {
4602
+ if (compatibilityDiagnostic && selection.marker.kind === "unknown") {
4603
+ throw new Error(
4604
+ `${compatibilityDiagnostic}
4605
+ ${error instanceof Error ? error.message : String(error)}`
4606
+ );
4607
+ }
4608
+ throw error;
2572
4609
  }
4610
+ if (compatibilityDiagnostic) throw new Error(compatibilityDiagnostic);
2573
4611
  const playName = metadata?.name ?? null;
2574
4612
  const playDescription = metadata?.description ?? null;
2575
4613
  const sandboxRuntimeDeclaration = metadata?.sandboxRuntimeDeclaration ?? null;
@@ -2592,6 +4630,8 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
2592
4630
  sandboxRuntimeDeclaration,
2593
4631
  toolErrorSchemaVersion: metadata?.toolErrorSchemaVersion ?? null,
2594
4632
  toolResponseReceiptRevision: metadata?.toolResponseReceiptRevision ?? null,
4633
+ sourceAuthoringEdition: selection.marker,
4634
+ sourceHasLocalPlayExport: selection.localExport,
2595
4635
  importedPlayDependencies: [...importedPlayDependencies.values()].sort(
2596
4636
  (left, right) => left.filePath.localeCompare(right.filePath)
2597
4637
  )
@@ -2725,15 +4765,32 @@ async function bundlePlayFile(filePath, options) {
2725
4765
  const sourceIdentityRoot = adapter.sourceIdentityRoot;
2726
4766
  adapter.warnAboutNonDevelopmentBundling?.(absolutePath);
2727
4767
  try {
4768
+ const preservedCompatibility = options.compatibility === void 0 ? void 0 : {
4769
+ ...options.compatibility,
4770
+ authoringContractEdition: normalizePlayContractCompatibility(
4771
+ options.compatibility
4772
+ ).authoringContractEdition
4773
+ };
2728
4774
  const analysis = await analyzeSourceGraph(
2729
4775
  absolutePath,
2730
4776
  adapter,
2731
4777
  exportName
2732
4778
  );
4779
+ const edition = resolvePlaySourceAuthoringContractEdition(
4780
+ analysis.sourceAuthoringEdition,
4781
+ preservedCompatibility?.authoringContractEdition
4782
+ );
4783
+ const markedSource = analysis.sourceAuthoringEdition.kind === "value";
4784
+ if (markedSource && !analysis.sourceHasLocalPlayExport) {
4785
+ throw new Error(
4786
+ "Edition 10 source must select a local ESM definePlay export."
4787
+ );
4788
+ }
2733
4789
  analysis.graphHash = sha256(
2734
4790
  `${analysis.graphHash}
2735
4791
  entry-export:${exportName}
2736
- authoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`
4792
+ authoring-contract-edition:${edition}${edition >= 10 ? "\nimported-proxy-options:description" : ""}${preservedCompatibility === void 0 ? "\ndataset-row-input:current_run" : `
4793
+ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
2737
4794
  );
2738
4795
  const sourceFiles = Object.fromEntries(
2739
4796
  Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
@@ -2799,10 +4856,13 @@ authoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`
2799
4856
  success: true,
2800
4857
  artifact: {
2801
4858
  ...cachedArtifact,
4859
+ ...markedSource ? { exportName } : {},
2802
4860
  entryFile,
2803
4861
  sourceHash: analysis.sourceHash,
2804
4862
  importPolicy,
2805
- compatibility: buildPlayContractCompatibility({
4863
+ compatibility: preservedCompatibility ?? buildPlayContractCompatibility({
4864
+ authoringContractEdition: edition,
4865
+ datasetRowInput: "current_run",
2806
4866
  toolErrorSchemaVersion: analysis.toolErrorSchemaVersion ?? void 0,
2807
4867
  toolResponseReceiptRevision: analysis.toolResponseReceiptRevision ?? void 0
2808
4868
  }),
@@ -2858,6 +4918,7 @@ authoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`
2858
4918
  };
2859
4919
  }
2860
4920
  const artifact = {
4921
+ ...markedSource ? { exportName } : {},
2861
4922
  codeFormat: "cjs_module",
2862
4923
  artifactKind: target,
2863
4924
  entryFile,
@@ -2869,7 +4930,9 @@ authoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`
2869
4930
  bundledCode: executableCode,
2870
4931
  sourceMap: normalizedSourceMap,
2871
4932
  importPolicy,
2872
- compatibility: buildPlayContractCompatibility({
4933
+ compatibility: preservedCompatibility ?? buildPlayContractCompatibility({
4934
+ authoringContractEdition: edition,
4935
+ datasetRowInput: "current_run",
2873
4936
  toolErrorSchemaVersion: analysis.toolErrorSchemaVersion ?? void 0,
2874
4937
  toolResponseReceiptRevision: analysis.toolResponseReceiptRevision ?? void 0
2875
4938
  }),
@@ -3400,7 +5463,10 @@ function createSdkPlayBundlingAdapter() {
3400
5463
  return {
3401
5464
  projectRoot: PROJECT_ROOT,
3402
5465
  nodeModulesDir: HAS_PACKAGED_BUNDLING_SOURCES ? resolve3(SDK_PACKAGE_ROOT, "node_modules") : resolve3(PROJECT_ROOT, "node_modules"),
3403
- cacheDir: join3(tmpdir2(), PLAY_BUNDLE_CACHE_NAMESPACE),
5466
+ // Emit the current SDK/compiler implementation on every invocation. The
5467
+ // customer graph hash does not include SDK/compiler source bytes, so reusing an
5468
+ // artifact can silently retain an older compiler or SDK implementation.
5469
+ cacheDir: null,
3404
5470
  sdkSourceRoot: SDK_SOURCE_ROOT,
3405
5471
  sdkPackageJson: SDK_PACKAGE_JSON,
3406
5472
  sdkEntryFile: SDK_ENTRY_FILE,
@@ -3417,6 +5483,7 @@ async function bundlePlayFile2(filePath, options = {}) {
3417
5483
  const result = await bundlePlayFile(filePath, {
3418
5484
  target: options.target ?? defaultPlayBundleTarget(),
3419
5485
  exportName: options.exportName,
5486
+ compatibility: options.compatibility,
3420
5487
  adapter: {
3421
5488
  ...createSdkPlayBundlingAdapter(),
3422
5489
  sourceIdentityRoot,