deepline 0.3.461 → 0.3.462

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/dist/bundling-sources/sdk/src/client-core.ts +7593 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +8 -7366
  3. package/dist/bundling-sources/sdk/src/http-core.ts +1239 -0
  4. package/dist/bundling-sources/sdk/src/http.ts +6 -1231
  5. package/dist/bundling-sources/sdk/src/index.ts +4 -1
  6. package/dist/bundling-sources/sdk/src/play.ts +5 -5
  7. package/dist/bundling-sources/sdk/src/plays/client-core.ts +437 -0
  8. package/dist/bundling-sources/sdk/src/plays/client.ts +4 -421
  9. package/dist/bundling-sources/sdk/src/plays/input-example.ts +3 -4
  10. package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
  11. package/dist/bundling-sources/sdk/src/plays/run-request.ts +1 -1
  12. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  13. package/dist/bundling-sources/sdk/src/server.ts +43 -0
  14. package/dist/bundling-sources/sdk/src/types.ts +15 -5
  15. package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +15 -0
  16. package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +0 -307
  17. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
  18. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +3 -2
  19. package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
  20. package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +34 -0
  21. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +59 -0
  22. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +94 -1
  23. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +11 -1
  24. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-failure-codes.ts +24 -0
  25. package/dist/bundling-sources/shared_libs/observability/dlq.ts +32 -0
  26. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +57 -3
  27. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +1 -0
  28. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +66 -1
  29. package/dist/bundling-sources/shared_libs/play-data-plane/sheet-column-storage.ts +36 -7
  30. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +250 -11
  31. package/dist/bundling-sources/shared_libs/play-runtime/array-input-store.ts +319 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +991 -359
  33. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +17 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +13 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +110 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +155 -6
  37. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +110 -6
  38. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -13
  39. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +14 -1
  40. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +57 -1
  41. package/dist/bundling-sources/shared_libs/play-runtime/free-company-lookup-batching.ts +218 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +42 -5
  43. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts +6 -1
  44. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +92 -31
  45. package/dist/bundling-sources/shared_libs/play-runtime/governor/block-reserving-budget-state-backend.ts +69 -14
  46. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +93 -23
  47. package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +15 -4
  48. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +22 -18
  49. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +5 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +2 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +190 -14
  52. package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +131 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +77 -2
  54. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +271 -2
  55. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +51 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +2 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +27 -1
  58. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/provider-text-for-log.ts +63 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +19 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +112 -16
  63. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +104 -2
  64. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +265 -151
  65. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +17 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +35 -14
  67. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +12 -1
  68. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +4 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts +36 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +136 -70
  71. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +237 -36
  72. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +148 -4
  73. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +6 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +285 -32
  75. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +251 -56
  76. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +29 -4
  77. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts +27 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +22 -1
  79. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1397 -382
  80. package/dist/bundling-sources/shared_libs/play-runtime/runtime-array-input-receipts.ts +920 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +16 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +38 -0
  83. package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +6 -0
  84. package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -1
  85. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +30 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +14 -3
  87. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +31 -4
  88. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -0
  89. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +20 -7
  90. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +12 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/index.ts +9 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +10 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +4 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1496 -320
  95. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +31 -1
  96. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1389 -129
  97. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +36 -0
  98. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +162 -23
  100. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +499 -115
  101. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +377 -9
  102. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +117 -8
  103. package/dist/bundling-sources/shared_libs/play-runtime/secret-resolution-retry-policy.ts +25 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/terminal-runtime-performance.ts +391 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +40 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +6 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/mapped-calls.ts +171 -0
  108. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +16 -1
  109. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +26 -3
  110. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +16 -2
  111. package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +28 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +55 -5
  113. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +41 -1
  114. package/dist/bundling-sources/shared_libs/plays/contracts.ts +4 -0
  115. package/dist/bundling-sources/shared_libs/plays/dataset.ts +9 -3
  116. package/dist/bundling-sources/shared_libs/plays/deploy/manifest-contract.ts +2 -0
  117. package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +3 -2
  118. package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +2 -2
  119. package/dist/bundling-sources/shared_libs/plays/run-output-summary.ts +66 -0
  120. package/dist/bundling-sources/shared_libs/plays/script-entry.ts +1 -1
  121. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +43 -1
  122. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +9 -0
  123. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +91 -13
  124. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +3 -0
  125. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +41 -24
  126. package/dist/bundling-sources/shared_libs/security/attested-client-ip.ts +91 -0
  127. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +0 -11
  128. package/dist/cli/{auth-6HJXNWUG.mjs → auth-JDLEY7VU.mjs} +5 -4
  129. package/dist/cli/auth-UXKY6TCC.js +41 -0
  130. package/dist/cli/{billing-6P5HO6QG.js → billing-HXAXB3XZ.js} +152 -78
  131. package/dist/cli/{billing-MJ42N7YF.mjs → billing-SDHLBLMV.mjs} +84 -10
  132. package/dist/cli/{chunk-5MDIZX7M.js → chunk-3ACMRZRV.js} +8 -6
  133. package/dist/cli/{chunk-FGLKOWSC.mjs → chunk-3KZCFOZ6.mjs} +1 -1
  134. package/dist/cli/chunk-4KQ6SIBC.mjs +1038 -0
  135. package/dist/cli/{chunk-Z2GUFYT6.js → chunk-5LEAXRHV.js} +11 -11
  136. package/dist/cli/{chunk-MEAIOXJL.mjs → chunk-6NNVJDVR.mjs} +7 -5
  137. package/dist/cli/{chunk-NMJ4D2WO.js → chunk-6PMCRYDA.js} +216 -91
  138. package/dist/cli/{chunk-RY4IVOU3.mjs → chunk-6RNQGWFD.mjs} +16 -806
  139. package/dist/cli/{chunk-EBU7LQ64.js → chunk-6V7KVRR5.js} +3 -3
  140. package/dist/cli/{chunk-OZBWRICM.js → chunk-7LFIMWMW.js} +2 -2
  141. package/dist/cli/chunk-7MJ6VI2T.mjs +19 -0
  142. package/dist/cli/chunk-7SWNPNML.js +1039 -0
  143. package/dist/cli/{chunk-IHHLTHE7.mjs → chunk-7U3XNPOA.mjs} +267 -38
  144. package/dist/cli/{chunk-5FDKJQZE.js → chunk-7VZHXVOQ.js} +1 -1
  145. package/dist/cli/{chunk-R64BGGRQ.mjs → chunk-AT636LLU.mjs} +2 -2
  146. package/dist/cli/{chunk-MDJPEGVN.js → chunk-BGTPIMSM.js} +392 -261
  147. package/dist/cli/{chunk-KVJ5VHW5.mjs → chunk-CKSOY47X.mjs} +2 -2
  148. package/dist/cli/{chunk-7DH2FD7Y.mjs → chunk-D464JW3N.mjs} +5 -85
  149. package/dist/cli/chunk-D6DXOUTO.mjs +827 -0
  150. package/dist/cli/{describe-2WQY7ZCY.js → chunk-EM4TXCCI.js} +27 -44
  151. package/dist/cli/chunk-F6QV42MC.mjs +91 -0
  152. package/dist/cli/chunk-FKVYR3QA.mjs +1039 -0
  153. package/dist/cli/{chunk-FGMX4HUZ.js → chunk-GEGW5HPZ.js} +29 -27
  154. package/dist/cli/{chunk-TNMBPMMC.js → chunk-HUB3CCM2.js} +13 -4
  155. package/dist/cli/{chunk-ACCR7POB.js → chunk-I6VHOU5O.js} +27 -27
  156. package/dist/cli/{chunk-Z2XUZC34.js → chunk-IAYSWZDJ.js} +188 -76
  157. package/dist/cli/chunk-JF3TLIMQ.js +19 -0
  158. package/dist/cli/{chunk-HDFRJ4IT.mjs → chunk-JVHOS3K3.mjs} +177 -65
  159. package/dist/cli/{chunk-V7REJRDZ.mjs → chunk-LFXLQEZN.mjs} +1 -1
  160. package/dist/cli/{chunk-CRYOUPEB.js → chunk-LROWFPGN.js} +16 -16
  161. package/dist/cli/{chunk-SLEUWLJE.mjs → chunk-MSY22NQW.mjs} +5 -5
  162. package/dist/cli/{chunk-BGY2PLP7.mjs → chunk-MUUQZIOF.mjs} +23 -49
  163. package/dist/cli/{chunk-FCAZQ7WV.js → chunk-NBLSCHKK.js} +52 -50
  164. package/dist/cli/{chunk-QAJAJPKK.mjs → chunk-NHRWZPWZ.mjs} +4 -2
  165. package/dist/cli/{chunk-KXMNM4AQ.js → chunk-NMU3VR5U.js} +4 -5
  166. package/dist/cli/{chunk-QIW7TVV6.mjs → chunk-O2RX5A66.mjs} +14 -12
  167. package/dist/cli/{chunk-SAZFZQRI.js → chunk-OMQ23IXL.js} +2 -2
  168. package/dist/cli/{chunk-5IYOUBFZ.js → chunk-OPJAJBD4.js} +28 -54
  169. package/dist/cli/{chunk-FJZILBL7.mjs → chunk-PHSEINNH.mjs} +5 -5
  170. package/dist/cli/{chunk-3DNKFH2G.mjs → chunk-PKHVSIJG.mjs} +19 -1
  171. package/dist/cli/{chunk-WIYWSYDS.mjs → chunk-Q2EIZKVX.mjs} +3 -3
  172. package/dist/cli/{chunk-5FY72YOV.js → chunk-QJZ6WNWD.js} +8 -8
  173. package/dist/cli/{chunk-EIMG75BT.mjs → chunk-S3A4IXBQ.mjs} +4 -5
  174. package/dist/cli/{chunk-3BMLICF7.mjs → chunk-S42YIQNE.mjs} +13 -8
  175. package/dist/cli/{chunk-RFONC4WJ.mjs → chunk-S6UAJR6V.mjs} +3 -3
  176. package/dist/cli/{chunk-G7L27KZB.mjs → chunk-TKAQR3IB.mjs} +31 -21
  177. package/dist/cli/{chunk-QWRHGGUH.js → chunk-UAJFWWZE.js} +20 -2
  178. package/dist/cli/{chunk-VZBCEA5S.mjs → chunk-UDRPEZ5F.mjs} +223 -92
  179. package/dist/cli/{chunk-KCCOQ5G5.js → chunk-ULK7JGGI.js} +511 -282
  180. package/dist/cli/chunk-V335HGX5.js +1038 -0
  181. package/dist/cli/{chunk-MGXEUZHL.mjs → chunk-V3MEA7NB.mjs} +7 -5
  182. package/dist/cli/{chunk-O6QOMHCH.js → chunk-VFGVXXZP.js} +37 -35
  183. package/dist/cli/chunk-VLEVVDWG.js +91 -0
  184. package/dist/cli/{chunk-R2GLGLDR.mjs → chunk-VPHN2HAL.mjs} +216 -91
  185. package/dist/cli/{chunk-CFUTOWE4.js → chunk-WG3KGAII.js} +8 -88
  186. package/dist/cli/{describe-FRAVCY5F.mjs → chunk-WIY6U6GD.mjs} +19 -36
  187. package/dist/cli/{chunk-PNATXKLP.js → chunk-XANRM3QA.js} +6 -6
  188. package/dist/cli/{chunk-KGQNIA37.js → chunk-XQCTG5OO.js} +44 -34
  189. package/dist/cli/{chunk-T3MVIPHG.mjs → chunk-XZAFIOUQ.mjs} +1 -1
  190. package/dist/cli/chunk-Y4DPU4OM.js +827 -0
  191. package/dist/cli/chunk-YT5EODJO.js +920 -0
  192. package/dist/cli/{chunk-SCIR5JXW.js → chunk-ZGQSFYD2.js} +56 -51
  193. package/dist/cli/{chunk-QEYHTIV4.mjs → chunk-ZUK6LIJB.mjs} +10 -1
  194. package/dist/cli/command-docs.d.mts +5 -0
  195. package/dist/cli/command-docs.d.ts +5 -0
  196. package/dist/cli/command-docs.js +2 -2
  197. package/dist/cli/command-docs.mjs +1 -1
  198. package/dist/cli/{csv-NX7NO3O6.js → csv-C56GSCEU.js} +13 -12
  199. package/dist/cli/{csv-DQ6GW5B5.mjs → csv-L54JS7TF.mjs} +4 -3
  200. package/dist/cli/{db-R72DFMP6.js → db-MOGRMZTA.js} +30 -27
  201. package/dist/cli/{db-2YP33M4K.mjs → db-YVBUW2DX.mjs} +10 -7
  202. package/dist/cli/describe-KYEULWPG.js +48 -0
  203. package/dist/cli/describe-NLZKKT7C.mjs +48 -0
  204. package/dist/cli/describe-core.d.mts +153 -5
  205. package/dist/cli/describe-core.d.ts +153 -5
  206. package/dist/cli/describe-core.js +9 -5
  207. package/dist/cli/describe-core.mjs +10 -6
  208. package/dist/cli/{executions-ZLHD4QIT.js → executions-A7L4ULPP.js} +9 -7
  209. package/dist/cli/{executions-WFBU7L2Q.mjs → executions-ZBGSTT37.mjs} +7 -5
  210. package/dist/cli/{feedback-CN3HJFVF.mjs → feedback-G6GU37FD.mjs} +6 -5
  211. package/dist/cli/{feedback-NDV6TPHG.js → feedback-OHLY7RYD.js} +10 -9
  212. package/dist/cli/getting-started.d.mts +6 -6
  213. package/dist/cli/getting-started.d.ts +6 -6
  214. package/dist/cli/getting-started.js +2 -2
  215. package/dist/cli/getting-started.mjs +1 -1
  216. package/dist/cli/git-P76N4NDQ.js +25 -0
  217. package/dist/cli/{git-QAD6E3HW.mjs → git-PKZW3QD5.mjs} +5 -4
  218. package/dist/cli/index.js +152 -142
  219. package/dist/cli/index.mjs +56 -46
  220. package/dist/cli/{legacy-noops-KVC5QJ74.js → legacy-noops-5LM3D724.js} +8 -7
  221. package/dist/cli/{legacy-noops-TPTKNBI2.mjs → legacy-noops-LJJYG6YA.mjs} +5 -4
  222. package/dist/cli/{monitors-SV57JFLO.mjs → monitors-72QV4ALO.mjs} +19 -6
  223. package/dist/cli/{monitors-KCROV6PJ.js → monitors-UX3H5DC2.js} +103 -90
  224. package/dist/cli/{org-KX6QIR7A.mjs → org-6RRRKOCP.mjs} +9 -6
  225. package/dist/cli/{org-NJYX5743.js → org-IF7ISUVB.js} +70 -67
  226. package/dist/cli/pages-3SU3HKL7.js +252 -0
  227. package/dist/cli/pages-DXDYYKEK.mjs +252 -0
  228. package/dist/cli/{play-IQQ57L7Z.mjs → play-AHASKRLA.mjs} +512 -1508
  229. package/dist/cli/{play-32L7EQN4.js → play-EUIUVLUH.js} +1090 -2086
  230. package/dist/cli/{providers-4WEC2EQN.mjs → providers-GWGE3WY3.mjs} +7 -5
  231. package/dist/cli/{providers-ZQV6QLVQ.js → providers-V5WU4VXJ.js} +10 -8
  232. package/dist/cli/{quickstart-RQ76RIUE.mjs → quickstart-OXKQ5ZST.mjs} +5 -4
  233. package/dist/cli/{quickstart-HKUSFADF.js → quickstart-QP65I5PF.js} +13 -12
  234. package/dist/cli/run-6MM72IGL.mjs +443 -0
  235. package/dist/cli/run-F3FTYS56.js +443 -0
  236. package/dist/cli/search-OYKOOI7A.js +32 -0
  237. package/dist/cli/{search-ZRAVFBZC.mjs → search-ZMEBVJZB.mjs} +8 -6
  238. package/dist/cli/{secrets-J3G5Y43U.js → secrets-ACND5N6A.js} +16 -14
  239. package/dist/cli/{secrets-CMJOVNVH.mjs → secrets-XRCJFF3L.mjs} +7 -5
  240. package/dist/cli/{sessions-MDQYY5CB.mjs → sessions-RTK3CEW6.mjs} +5 -4
  241. package/dist/cli/{sessions-WY7VN4AE.js → sessions-ZGRJPCFF.js} +6 -5
  242. package/dist/cli/{settings-HTNTFKCE.js → settings-PD5KWQQZ.js} +80 -77
  243. package/dist/cli/{settings-4RWZPCT5.mjs → settings-XDRBPRDE.mjs} +14 -11
  244. package/dist/cli/{setup-P3GYYZWG.mjs → setup-3HPYAOCC.mjs} +12 -10
  245. package/dist/cli/{setup-QGCAP62X.js → setup-E2Q6PXHC.js} +53 -51
  246. package/dist/cli/{skills-7NAE4ICL.mjs → skills-OOQFMPOV.mjs} +7 -6
  247. package/dist/cli/skills-XYWV52KB.js +31 -0
  248. package/dist/cli/tools-ASCDZJCK.js +55 -0
  249. package/dist/cli/tools-C5ZT3UIC.mjs +55 -0
  250. package/dist/cli/update-5RQSEIFM.js +33 -0
  251. package/dist/cli/{update-GODLRKNB.mjs → update-ZWJTADIW.mjs} +9 -8
  252. package/dist/cli/{workflow-4BXOUVEO.mjs → workflow-23NMPAJ7.mjs} +10 -8
  253. package/dist/cli/{workflow-AO3A6LXN.js → workflow-TCXU5YJV.js} +20 -18
  254. package/dist/client-DS2IWYZF.d.ts +10 -0
  255. package/dist/client-DTwnz_AW.d.mts +10 -0
  256. package/dist/{client-CYqG23K1.d.ts → client-core-B_6HAIBy.d.ts} +385 -12
  257. package/dist/{client-BbU5_j7n.d.mts → client-core-DzBSlY1U.d.mts} +385 -12
  258. package/dist/{compiler-manifest-CWz_sNOQ.d.ts → compiler-manifest-Dcyd3-Zd.d.mts} +43 -1
  259. package/dist/{compiler-manifest-CWz_sNOQ.d.mts → compiler-manifest-Dcyd3-Zd.d.ts} +43 -1
  260. package/dist/errors-d-sTrZhe.d.mts +142 -0
  261. package/dist/errors-yQwfgrcX.d.ts +142 -0
  262. package/dist/{index-BF2JB_Ug.d.mts → index-C6oXchjN.d.mts} +1 -1
  263. package/dist/{index-4NPXDzlD.d.ts → index-P56zy_z5.d.ts} +1 -1
  264. package/dist/index.d.mts +11 -147
  265. package/dist/index.d.ts +11 -147
  266. package/dist/index.js +15 -11
  267. package/dist/index.mjs +14 -10
  268. package/dist/install-integrity.json +141 -104
  269. package/dist/plays/bundle-play-file.d.mts +3 -3
  270. package/dist/plays/bundle-play-file.d.ts +3 -3
  271. package/dist/plays/bundle-play-file.mjs +2 -1
  272. package/dist/plays/play-description.d.mts +2 -2
  273. package/dist/plays/play-description.d.ts +2 -2
  274. package/dist/plays/play-description.js +2 -2
  275. package/dist/plays/play-description.mjs +1 -1
  276. package/dist/plays/run-request.d.mts +2 -2
  277. package/dist/plays/run-request.d.ts +2 -2
  278. package/dist/release.d.mts +1 -1
  279. package/dist/release.d.ts +1 -1
  280. package/dist/release.js +2 -2
  281. package/dist/release.mjs +1 -1
  282. package/dist/server.d.mts +17 -0
  283. package/dist/server.d.ts +17 -0
  284. package/dist/server.js +76 -0
  285. package/dist/server.mjs +76 -0
  286. package/package.json +6 -1
  287. package/dist/cli/auth-IACERYQH.js +0 -40
  288. package/dist/cli/chunk-PQUUWFXY.js +0 -95
  289. package/dist/cli/chunk-YBWAG72P.mjs +0 -95
  290. package/dist/cli/chunk-YQDUODZW.js +0 -1710
  291. package/dist/cli/git-JVI36ZFV.js +0 -24
  292. package/dist/cli/search-75X5LTDE.js +0 -30
  293. package/dist/cli/skills-BKJ53JOQ.js +0 -30
  294. package/dist/cli/tools-COWMIEJ6.mjs +0 -45
  295. package/dist/cli/tools-TASOCE7I.js +0 -45
  296. package/dist/cli/update-SJIKVME6.js +0 -32
@@ -1,40 +1,3 @@
1
- import { createHmac, timingSafeEqual } from 'node:crypto';
2
-
3
- const PARALLEL_WEBHOOK_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
4
- const STANDARD_WEBHOOK_SECRET_PREFIX = 'whsec_';
5
-
6
- type WebhookVerificationOk = {
7
- ok: true;
8
- mode: 'verified' | 'unsigned_non_prod';
9
- };
10
-
11
- type WebhookVerificationFailure = {
12
- ok: false;
13
- status: 401 | 500;
14
- code: string;
15
- message: string;
16
- };
17
-
18
- export type WebhookVerificationResult =
19
- | WebhookVerificationOk
20
- | WebhookVerificationFailure;
21
-
22
- export type ProviderCallbackBindingValidationFailure = {
23
- ok: false;
24
- status: 409;
25
- code: 'provider_callback_binding_mismatch';
26
- message: string;
27
- fields: string[];
28
- };
29
-
30
- export type ProviderCallbackBindingValidationResult =
31
- | { ok: true }
32
- | ProviderCallbackBindingValidationFailure;
33
-
34
- function normalizedEnvFlag(value: string | undefined) {
35
- return value?.trim().toLowerCase();
36
- }
37
-
38
1
  function readRecord(value: unknown): Record<string, unknown> {
39
2
  return value && typeof value === 'object' && !Array.isArray(value)
40
3
  ? (value as Record<string, unknown>)
@@ -48,94 +11,6 @@ function readString(value: unknown) {
48
11
  return trimmed || null;
49
12
  }
50
13
 
51
- function readStringAtPath(record: Record<string, unknown>, path: string) {
52
- const value = path.split('.').reduce<unknown>((current, part) => {
53
- if (!current || typeof current !== 'object' || Array.isArray(current)) {
54
- return undefined;
55
- }
56
- return (current as Record<string, unknown>)[part];
57
- }, record);
58
- return readString(value);
59
- }
60
-
61
- function addString(
62
- values: Set<string>,
63
- value: string | number | null | undefined,
64
- ) {
65
- const string = readString(value);
66
- if (string) values.add(string);
67
- }
68
-
69
- function genericWebhookIdsFromPayload(payload: Record<string, unknown>) {
70
- const values = new Set<string>();
71
- for (const path of [
72
- 'webhook_id',
73
- 'webhookId',
74
- 'hook_id',
75
- 'hookId',
76
- 'webhook.id',
77
- 'data.webhook_id',
78
- 'data.webhookId',
79
- 'data.hook_id',
80
- 'data.hookId',
81
- 'result.webhook_id',
82
- 'result.webhookId',
83
- 'result.data.webhook_id',
84
- 'result.data.webhookId',
85
- ]) {
86
- addString(values, readStringAtPath(payload, path));
87
- }
88
-
89
- const events = Array.isArray(payload.events) ? payload.events : [];
90
- for (const item of events) {
91
- const event = readRecord(item);
92
- addString(values, readStringAtPath(event, 'webhook_id'));
93
- addString(values, readStringAtPath(event, 'webhookId'));
94
- }
95
-
96
- return values;
97
- }
98
-
99
- function isTheirstackWebhookBindingPayload(payload: Record<string, unknown>) {
100
- return Boolean(
101
- readString(payload.id) &&
102
- readString(payload.search_id) &&
103
- readString(payload.event_type) &&
104
- readString(payload.url),
105
- );
106
- }
107
-
108
- function theirstackWebhookIdsFromPayload(payload: Record<string, unknown>) {
109
- const values = new Set<string>();
110
- addString(values, payload.webhook_id as string | number | null | undefined);
111
- addString(values, payload.webhookId as string | number | null | undefined);
112
- if (isTheirstackWebhookBindingPayload(payload)) {
113
- addString(values, payload.id as string | number | null | undefined);
114
- }
115
- return values;
116
- }
117
-
118
- function theirstackSavedSearchIdsFromPayload(payload: Record<string, unknown>) {
119
- const values = new Set<string>();
120
- addString(values, payload.search_id as string | number | null | undefined);
121
- addString(
122
- values,
123
- payload.saved_search_id as string | number | null | undefined,
124
- );
125
- return values;
126
- }
127
-
128
- function mismatchedFields(input: {
129
- expected: string | null;
130
- actual: Set<string>;
131
- field: string;
132
- }) {
133
- if (!input.expected || input.actual.size === 0) return [];
134
- return [...input.actual].some((value) => value !== input.expected)
135
- ? [input.field]
136
- : [];
137
- }
138
-
139
14
  export function theirstackSavedSearchIdFromProviderBinding(
140
15
  providerBinding: Record<string, unknown>,
141
16
  ) {
@@ -149,185 +24,3 @@ export function theirstackSavedSearchIdFromProviderBinding(
149
24
  readString(readRecord(webhook.data).search_id)
150
25
  );
151
26
  }
152
-
153
- export function validateProviderCallbackBinding(input: {
154
- provider: string;
155
- payload: Record<string, unknown>;
156
- providerBinding: Record<string, unknown>;
157
- upstreamWebhookId?: string | null;
158
- }): ProviderCallbackBindingValidationResult {
159
- const fields =
160
- input.provider === 'theirstack'
161
- ? [
162
- ...mismatchedFields({
163
- expected: input.upstreamWebhookId ?? null,
164
- actual: theirstackWebhookIdsFromPayload(input.payload),
165
- field: 'webhook_id',
166
- }),
167
- ...mismatchedFields({
168
- expected: theirstackSavedSearchIdFromProviderBinding(
169
- input.providerBinding,
170
- ),
171
- actual: theirstackSavedSearchIdsFromPayload(input.payload),
172
- field: 'search_id',
173
- }),
174
- ]
175
- : mismatchedFields({
176
- expected: input.upstreamWebhookId ?? null,
177
- actual: genericWebhookIdsFromPayload(input.payload),
178
- field: 'webhook_id',
179
- });
180
-
181
- if (fields.length === 0) {
182
- return { ok: true };
183
- }
184
-
185
- return {
186
- ok: false,
187
- status: 409,
188
- code: 'provider_callback_binding_mismatch',
189
- message:
190
- 'Callback payload provider identifiers do not match the authenticated Deepline monitor binding.',
191
- fields: Array.from(new Set(fields)),
192
- };
193
- }
194
-
195
- function shouldRequireParallelWebhookSignature() {
196
- const explicit = normalizedEnvFlag(
197
- process.env.DEEPLINE_REQUIRE_PARALLEL_WEBHOOK_SIGNATURE,
198
- );
199
- if (explicit === 'true' || explicit === '1' || explicit === 'yes') {
200
- return true;
201
- }
202
- if (explicit === 'false' || explicit === '0' || explicit === 'no') {
203
- return false;
204
- }
205
- return process.env.NODE_ENV === 'production';
206
- }
207
-
208
- function parallelWebhookSigningSecret() {
209
- return (
210
- process.env.DEEPLINE_PARALLEL_WEBHOOK_SECRET?.trim() ||
211
- process.env.PARALLEL_WEBHOOK_SECRET?.trim() ||
212
- null
213
- );
214
- }
215
-
216
- function signingKey(secret: string) {
217
- if (secret.startsWith(STANDARD_WEBHOOK_SECRET_PREFIX)) {
218
- return Buffer.from(
219
- secret.slice(STANDARD_WEBHOOK_SECRET_PREFIX.length),
220
- 'base64',
221
- );
222
- }
223
- return secret;
224
- }
225
-
226
- function readStandardWebhookHeader(headers: Headers, name: string) {
227
- return (
228
- headers.get(name) ?? headers.get(`svix-${name.replace('webhook-', '')}`)
229
- );
230
- }
231
-
232
- function parseTimestampMs(value: string) {
233
- const trimmed = value.trim();
234
- if (/^\d+$/.test(trimmed)) {
235
- const numeric = Number(trimmed);
236
- if (!Number.isFinite(numeric)) return null;
237
- return numeric > 10_000_000_000 ? numeric : numeric * 1000;
238
- }
239
- const parsed = Date.parse(trimmed);
240
- return Number.isFinite(parsed) ? parsed : null;
241
- }
242
-
243
- function readSignatures(header: string) {
244
- return header
245
- .split(/\s+/)
246
- .map((part) => part.trim())
247
- .filter(Boolean)
248
- .flatMap((part) => {
249
- const [version, signature] = part.split(',', 2);
250
- return version === 'v1' && signature ? [signature] : [];
251
- });
252
- }
253
-
254
- function signaturesEqual(expectedBase64: string, actualBase64: string) {
255
- const expected = Buffer.from(expectedBase64, 'base64');
256
- const actual = Buffer.from(actualBase64, 'base64');
257
- if (expected.length === 0 || actual.length === 0) return false;
258
- if (expected.length !== actual.length) return false;
259
- return timingSafeEqual(expected, actual);
260
- }
261
-
262
- export function verifyParallelWebhookRequest(input: {
263
- headers: Headers;
264
- rawBody: string;
265
- nowMs?: number;
266
- }): WebhookVerificationResult {
267
- const secret = parallelWebhookSigningSecret();
268
- if (!secret) {
269
- if (shouldRequireParallelWebhookSignature()) {
270
- return {
271
- ok: false,
272
- status: 500,
273
- code: 'parallel_webhook_secret_missing',
274
- message: 'Parallel webhook signing secret is not configured.',
275
- };
276
- }
277
- return { ok: true, mode: 'unsigned_non_prod' };
278
- }
279
-
280
- const webhookId = readStandardWebhookHeader(input.headers, 'webhook-id');
281
- const webhookTimestamp = readStandardWebhookHeader(
282
- input.headers,
283
- 'webhook-timestamp',
284
- );
285
- const webhookSignature = readStandardWebhookHeader(
286
- input.headers,
287
- 'webhook-signature',
288
- );
289
-
290
- if (!webhookId || !webhookTimestamp || !webhookSignature) {
291
- return {
292
- ok: false,
293
- status: 401,
294
- code: 'parallel_webhook_signature_missing',
295
- message: 'Parallel webhook signature headers are missing.',
296
- };
297
- }
298
-
299
- const timestampMs = parseTimestampMs(webhookTimestamp);
300
- const nowMs = input.nowMs ?? Date.now();
301
- if (
302
- timestampMs === null ||
303
- Math.abs(nowMs - timestampMs) > PARALLEL_WEBHOOK_SIGNATURE_TOLERANCE_MS
304
- ) {
305
- return {
306
- ok: false,
307
- status: 401,
308
- code: 'parallel_webhook_timestamp_invalid',
309
- message: 'Parallel webhook timestamp is outside the accepted window.',
310
- };
311
- }
312
-
313
- const signedPayload = `${webhookId}.${webhookTimestamp}.${input.rawBody}`;
314
- const expectedSignature = createHmac('sha256', signingKey(secret))
315
- .update(signedPayload)
316
- .digest('base64');
317
- const signatures = readSignatures(webhookSignature);
318
- if (
319
- signatures.length === 0 ||
320
- !signatures.some((signature) =>
321
- signaturesEqual(expectedSignature, signature),
322
- )
323
- ) {
324
- return {
325
- ok: false,
326
- status: 401,
327
- code: 'parallel_webhook_signature_invalid',
328
- message: 'Parallel webhook signature is invalid.',
329
- };
330
- }
331
-
332
- return { ok: true, mode: 'verified' };
333
- }
@@ -143,6 +143,9 @@ export function monitorErrorNextAction(payload: MonitorErrorPayload): string {
143
143
  if (code === 'monitor_control_plane_unavailable') {
144
144
  return 'Wait briefly, then rerun the same monitor read. No monitor state was changed.';
145
145
  }
146
+ if (code === 'monitor_job_control_plane_unavailable') {
147
+ return 'Wait briefly, then retry the same request once, reusing its Idempotency-Key if it sent one. Deepline could not confirm whether it was applied.';
148
+ }
146
149
  if (code === 'provider_monitor_identity_backfill_in_progress') {
147
150
  return typeof retryAfterSeconds === 'number'
148
151
  ? `Wait ${retryAfterSeconds} seconds, then retry the same monitor lifecycle request once. No upstream monitor was created.`
@@ -18,8 +18,9 @@
18
18
  // dev-bootstrap test orgs are always suppressed (see
19
19
  // `shouldSuppressMonitorActor` + the transport-level guard in
20
20
  // the shared Slack delivery contract).
21
- // - Environments: ALL (dev + preview + prod). The two channels declare
22
- // `requiredEnv: 'all'` in the delivery contract, so they post in local dev too.
21
+ // - Environments: Production only (KAR-77). Gauntlet and local tests trigger
22
+ // monitor errors on purpose, and these channels resolve to the production
23
+ // channel IDs wherever the reporting bot token is set.
23
24
  // - Spend: NEVER include provider spend. These payloads carry only keys,
24
25
  // counts, and trigger metadata — no provider-cost fields.
25
26
 
@@ -95,6 +95,8 @@
95
95
  "./quickstart-prompts.js": "./quickstart-prompts.ts",
96
96
  "./signal-radars/inbound-dead-letter": "./signal-radars/inbound-dead-letter.ts",
97
97
  "./signal-radars/inbound-dead-letter.js": "./signal-radars/inbound-dead-letter.ts",
98
+ "./signal-radars/inbound-failure-codes": "./signal-radars/inbound-failure-codes.ts",
99
+ "./signal-radars/inbound-failure-codes.js": "./signal-radars/inbound-failure-codes.ts",
98
100
  "./signal-radars/inbound-message": "./signal-radars/inbound-message.ts",
99
101
  "./signal-radars/inbound-message.js": "./signal-radars/inbound-message.ts",
100
102
  "./signal-radars/inbound-queue": "./signal-radars/inbound-queue.ts",
@@ -519,6 +519,40 @@ export function tamradarCallbackRadarId(payload: Record<string, unknown>) {
519
519
  );
520
520
  }
521
521
 
522
+ export type TamradarBatchNotice = {
523
+ updateType: 'bulk_completed' | 'radar_failure';
524
+ bulkId: string;
525
+ itemIndex: number | null;
526
+ code: number | null;
527
+ };
528
+
529
+ /**
530
+ * A shared bulk callback also carries messages about the batch itself: the
531
+ * final `bulk_completed` summary, and a `radar_failure` for an item TamRadar
532
+ * refused, which never became a radar. Neither has a radar ID to route by, and
533
+ * neither is a finding. A message with no `bulk_id` is not one of these.
534
+ */
535
+ export function tamradarBatchNotice(
536
+ payload: Record<string, unknown>,
537
+ ): TamradarBatchNotice | null {
538
+ const unwrapped = unwrapTamradarPayload(payload);
539
+ const bulkId = readString(unwrapped.bulk_id);
540
+ const updateType = readString(unwrapped.update_type);
541
+ if (
542
+ !bulkId ||
543
+ (updateType !== 'bulk_completed' && updateType !== 'radar_failure')
544
+ ) {
545
+ return null;
546
+ }
547
+ return {
548
+ updateType,
549
+ bulkId,
550
+ itemIndex:
551
+ typeof unwrapped.item_index === 'number' ? unwrapped.item_index : null,
552
+ code: typeof unwrapped.code === 'number' ? unwrapped.code : null,
553
+ };
554
+ }
555
+
522
556
  function genericWebhookIds(payload: Record<string, unknown>) {
523
557
  return [
524
558
  'webhook_id',
@@ -499,3 +499,62 @@ export function providerMonitorBatchOperationRequestFingerprint(
499
499
  }
500
500
  return canonicalJson(normalized);
501
501
  }
502
+
503
+ export type ProviderMonitorBatchChangeBucket =
504
+ | 'created'
505
+ | 'updated'
506
+ | 'removed';
507
+
508
+ /**
509
+ * What a changed result did to the provider resource, by its code. Every
510
+ * code a runner records with `changed: true` belongs here; the
511
+ * provider-monitor-batch-change-buckets test reads the runner sources and
512
+ * fails on one that is missing. A missing code would otherwise count as
513
+ * changed with no bucket, so `created + updated + removed` falls short of
514
+ * `changed` rather than reporting a close as a create (KAR-115).
515
+ */
516
+ export const PROVIDER_MONITOR_BATCH_CHANGE_BUCKETS: Readonly<
517
+ Record<string, ProviderMonitorBatchChangeBucket>
518
+ > = {
519
+ // A new provider resource.
520
+ provider_batch_created: 'created',
521
+ provider_create_adjudicated: 'created',
522
+ provider_create_adopted_by_operator: 'created',
523
+ named_batch_create: 'created',
524
+ named_batch_start: 'created',
525
+ provider_repaired: 'created',
526
+ fleet_converged: 'created',
527
+ // An existing provider resource replaced or reconciled.
528
+ existing_monitor_replaced: 'updated',
529
+ existing_monitor_reconciled_by_identity: 'updated',
530
+ named_batch_update: 'updated',
531
+ provider_configuration_repaired: 'updated',
532
+ // A provider resource closed, or proven absent. A create stopped or deleted
533
+ // by the customer's intent before it settled ends removed.
534
+ upstream_deactivated: 'removed',
535
+ upstream_inactive_verified: 'removed',
536
+ already_absent_upstream: 'removed',
537
+ deleted_monitor_resource_closed: 'removed',
538
+ deleted_monitor_intent_closed: 'removed',
539
+ fleet_member_removed: 'removed',
540
+ fleet_converged_inactive: 'removed',
541
+ provider_batch_created_then_stopped: 'removed',
542
+ provider_batch_created_then_deleted: 'removed',
543
+ pending_create_intent_satisfied: 'removed',
544
+ };
545
+
546
+ export function providerMonitorBatchChangeBucket(input: {
547
+ operationKind: ProviderMonitorBatchOperationKind | undefined;
548
+ state: ProviderMonitorBatchResultState | undefined;
549
+ changed: boolean;
550
+ code?: string;
551
+ }): ProviderMonitorBatchChangeBucket | null {
552
+ if (input.state !== 'done' || !input.changed) return null;
553
+ // A runner that predates a code split still records the old code, so a
554
+ // deactivation stays removed whatever it reports.
555
+ if (input.operationKind === 'deactivate') return 'removed';
556
+ if (input.code === undefined) return null;
557
+ return Object.hasOwn(PROVIDER_MONITOR_BATCH_CHANGE_BUCKETS, input.code)
558
+ ? PROVIDER_MONITOR_BATCH_CHANGE_BUCKETS[input.code]!
559
+ : null;
560
+ }
@@ -31,16 +31,26 @@ type ProviderMonitorUpstreamIdentityDefinition = {
31
31
  * treating different authored filters as an exact duplicate.
32
32
  */
33
33
  allowDistinctConfigurations?: boolean;
34
+ /**
35
+ * Payload fields that never change which findings the provider resource
36
+ * delivers. `updates_since` only sets how far back the first delivery
37
+ * replays, so two monitors that differ only there watch the same feed.
38
+ * Claim keys written before this list existed still carry these fields;
39
+ * readers resolve them through `canonicalProviderMonitorIdentityClaimKey`.
40
+ */
41
+ nonConfigurationFields?: readonly string[];
34
42
  };
35
43
 
36
44
  const PROVIDER_MONITOR_UPSTREAM_IDENTITY_FIELDS = {
37
45
  'deepline_native.company_radar': {
38
46
  fields: [{ name: 'radar_type' }, { name: 'domain' }],
39
47
  allowDistinctConfigurations: true,
48
+ nonConfigurationFields: ['updates_since'],
40
49
  },
41
50
  'deepline_native.contact_radar': {
42
51
  fields: [{ name: 'radar_type' }, { name: 'profile_url' }],
43
52
  allowDistinctConfigurations: true,
53
+ nonConfigurationFields: ['updates_since'],
44
54
  },
45
55
  'deepline_native.industry_radar': {
46
56
  fields: [
@@ -48,6 +58,7 @@ const PROVIDER_MONITOR_UPSTREAM_IDENTITY_FIELDS = {
48
58
  { name: 'industry', runtimePayloadAliases: ['keyword'] },
49
59
  ],
50
60
  allowDistinctConfigurations: true,
61
+ nonConfigurationFields: ['updates_since'],
51
62
  },
52
63
  } as const satisfies Record<string, ProviderMonitorUpstreamIdentityDefinition>;
53
64
 
@@ -59,6 +70,8 @@ function canonicalMonitorTool(tool: string) {
59
70
  : tool;
60
71
  }
61
72
 
73
+ const CONFIGURATION_SEPARATOR = '#configuration=';
74
+
62
75
  function stableJson(value: unknown): string {
63
76
  if (Array.isArray(value)) return `[${value.map(stableJson).join(',')}]`;
64
77
  if (value && typeof value === 'object') {
@@ -172,5 +185,85 @@ export function providerMonitorUpstreamIdentityClaimKey(
172
185
  ),
173
186
  );
174
187
  if (Object.keys(configuration).length === 0) return scopeKey;
175
- return `${scopeKey}#configuration=${stableJson(configuration)}`;
188
+ return `${scopeKey}${CONFIGURATION_SEPARATOR}${stableJson(configuration)}`;
189
+ }
190
+
191
+ function parseJsonObject(text: string): Record<string, unknown> | null {
192
+ try {
193
+ const parsed: unknown = JSON.parse(text);
194
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
195
+ ? (parsed as Record<string, unknown>)
196
+ : null;
197
+ } catch {
198
+ return null;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Splits a stored claim key into its scope JSON and configuration JSON. A
204
+ * scope value may itself contain the separator text, so the split is the one
205
+ * where both halves parse as JSON objects. Scope-only keys return null.
206
+ */
207
+ function splitClaimKey(identityKey: string) {
208
+ let separator = identityKey.indexOf(CONFIGURATION_SEPARATOR);
209
+ while (separator !== -1) {
210
+ const scopeKey = identityKey.slice(0, separator);
211
+ const configuration = parseJsonObject(
212
+ identityKey.slice(separator + CONFIGURATION_SEPARATOR.length),
213
+ );
214
+ if (configuration && parseJsonObject(scopeKey)) {
215
+ return { scopeKey, configuration };
216
+ }
217
+ separator = identityKey.indexOf(CONFIGURATION_SEPARATOR, separator + 1);
218
+ }
219
+ return null;
220
+ }
221
+
222
+ /**
223
+ * The claim key with every `nonConfigurationFields` entry removed. Two claim
224
+ * keys with the same canonical form occupy the same provider feed. A key that
225
+ * is already canonical, scope-only, or for a tool without such fields is
226
+ * returned unchanged, so this is idempotent and safe on any stored key.
227
+ */
228
+ export function canonicalProviderMonitorIdentityClaimKey(
229
+ tool: string,
230
+ identityKey: string,
231
+ ) {
232
+ const definition: ProviderMonitorUpstreamIdentityDefinition | undefined =
233
+ PROVIDER_MONITOR_UPSTREAM_IDENTITY_FIELDS[
234
+ canonicalMonitorTool(
235
+ tool,
236
+ ) as keyof typeof PROVIDER_MONITOR_UPSTREAM_IDENTITY_FIELDS
237
+ ];
238
+ const ignored = definition?.nonConfigurationFields;
239
+ if (!ignored?.length) return identityKey;
240
+ const parts = splitClaimKey(identityKey);
241
+ if (!parts) return identityKey;
242
+ const configuration = Object.fromEntries(
243
+ Object.entries(parts.configuration).filter(
244
+ ([field]) => !ignored.includes(field),
245
+ ),
246
+ );
247
+ if (Object.keys(configuration).length === 0) return parts.scopeKey;
248
+ return `${parts.scopeKey}${CONFIGURATION_SEPARATOR}${stableJson(configuration)}`;
249
+ }
250
+
251
+ /** Whether a claim key carries configuration beyond its scope. */
252
+ export function providerMonitorIdentityClaimKeyHasConfiguration(
253
+ identityKey: string,
254
+ ) {
255
+ return splitClaimKey(identityKey) !== null;
256
+ }
257
+
258
+ /** True when the stored claim key and the identity key name the same feed. */
259
+ export function providerMonitorIdentityClaimKeysMatch(
260
+ tool: string,
261
+ left: string,
262
+ right: string,
263
+ ) {
264
+ return (
265
+ left === right ||
266
+ canonicalProviderMonitorIdentityClaimKey(tool, left) ===
267
+ canonicalProviderMonitorIdentityClaimKey(tool, right)
268
+ );
176
269
  }
@@ -1,5 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { isRepairableTenantDataPlaneError } from '@deepline/ingestion-v2/tenant-data-plane-errors';
3
+ import {
4
+ MONITOR_REFUND_SETTLEMENT_PENDING_CODE,
5
+ PROVIDER_MONITOR_CONTROL_STATE_PENDING_CODE,
6
+ } from '@deepline/monitors/signal-radars/inbound-failure-codes';
3
7
  import type { SignalRadarInboundMessage } from '@deepline/monitors/signal-radars/inbound-message';
4
8
  import {
5
9
  hasMonitorSdkValidationIssues,
@@ -42,7 +46,10 @@ export function classifyInboundFailure(error: unknown): InboundFailureClass {
42
46
  : '';
43
47
  const transientCodes = new Set([
44
48
  'tenant_data_plane_repair_required',
45
- 'provider_monitor_convex_sync_pending',
49
+ // An admission-backed callback whose Convex binding has not landed yet.
50
+ PROVIDER_MONITOR_CONTROL_STATE_PENDING_CODE,
51
+ // A refund waits for its lifecycle charge, which settles on its own clock.
52
+ MONITOR_REFUND_SETTLEMENT_PENDING_CODE,
46
53
  // The worker emits this after capture-first receipt persistence cannot be
47
54
  // completed. The event has not entered durable storage, so it must remain
48
55
  // retryable even after the ordinary poison-message delivery budget.
@@ -63,6 +70,9 @@ export function classifyInboundFailure(error: unknown): InboundFailureClass {
63
70
  'EPIPE',
64
71
  'ENOTFOUND',
65
72
  'EAI_AGAIN',
73
+ // `snitcher_ip2company_quota_exceeded` is left out on purpose: a spent
74
+ // quota will not recover inside the retry budget, so that event dead-letters
75
+ // with its payload retained and waits for a redrive.
66
76
  'snitcher_ip2company_retryable',
67
77
  '57P01', // admin shutdown
68
78
  '57P02', // crash shutdown
@@ -0,0 +1,24 @@
1
+ // Failure codes shared by whoever raises an inbound failure and whoever decides
2
+ // what to do about it. A literal on each side drifted once (KAR-74), so a
3
+ // retryable failure read as poison and dead-lettered. Convex imports this file,
4
+ // so it holds constants only.
5
+
6
+ /** An admission-backed callback whose Convex monitor binding has not landed. */
7
+ export const PROVIDER_MONITOR_CONTROL_STATE_PENDING_CODE =
8
+ 'provider_monitor_control_state_pending';
9
+
10
+ /**
11
+ * A callback for a retired binding of a monitor that still exists: a replaced
12
+ * radar, a finished rotation or a suspension. Permanent on purpose. It can never
13
+ * resolve, so it dead-letters on its budget and the row keeps the payload.
14
+ */
15
+ export const PROVIDER_CALLBACK_BINDING_RETIRED_CODE =
16
+ 'provider_callback_binding_retired';
17
+
18
+ /** A refund waiting for its lifecycle charge to settle. */
19
+ export const MONITOR_REFUND_SETTLEMENT_PENDING_CODE =
20
+ 'monitor_refund_settlement_pending';
21
+
22
+ /** Storage has no blob for this receipt. No retry can bring it back. */
23
+ export const SIGNAL_RADAR_INBOUND_PAYLOAD_MISSING_CODE =
24
+ 'signal_radar_inbound_payload_missing';