@adcp/sdk 14.0.0-rc.38 → 14.0.0-rc.39

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 (600) hide show
  1. package/bin/adcp-storyboard-summary.js +286 -0
  2. package/bin/adcp.js +221 -10
  3. package/dist/lib/conformance/schemaLoader.d.mts +1 -1
  4. package/dist/lib/conformance/schemaLoader.d.ts +1 -1
  5. package/dist/lib/core/AgentClient.d.mts +6 -1
  6. package/dist/lib/core/AgentClient.d.ts +6 -1
  7. package/dist/lib/core/AgentClient.js +9 -0
  8. package/dist/lib/core/AgentClient.mjs +9 -0
  9. package/dist/lib/core/ConversationTypes.d.mts +29 -0
  10. package/dist/lib/core/ConversationTypes.d.ts +29 -0
  11. package/dist/lib/core/SingleAgentClient.d.mts +3 -1
  12. package/dist/lib/core/SingleAgentClient.d.ts +3 -1
  13. package/dist/lib/core/SingleAgentClient.js +9 -1
  14. package/dist/lib/core/SingleAgentClient.mjs +9 -1
  15. package/dist/lib/core/TaskExecutor.d.mts +13 -1
  16. package/dist/lib/core/TaskExecutor.d.ts +13 -1
  17. package/dist/lib/core/TaskExecutor.js +216 -18
  18. package/dist/lib/core/TaskExecutor.mjs +216 -19
  19. package/dist/lib/index.d.mts +5 -2
  20. package/dist/lib/index.d.ts +5 -2
  21. package/dist/lib/index.js +10 -1
  22. package/dist/lib/index.mjs +10 -1
  23. package/dist/lib/media-buy/action-assessment.d.mts +77 -0
  24. package/dist/lib/media-buy/action-assessment.d.ts +77 -0
  25. package/dist/lib/media-buy/action-assessment.js +300 -0
  26. package/dist/lib/media-buy/action-assessment.mjs +284 -0
  27. package/dist/lib/media-buy/action-constraints.d.mts +9 -0
  28. package/dist/lib/media-buy/action-constraints.d.ts +9 -0
  29. package/dist/lib/media-buy/action-constraints.js +170 -0
  30. package/dist/lib/media-buy/action-constraints.mjs +146 -0
  31. package/dist/lib/media-buy/action-contracts.d.mts +40 -0
  32. package/dist/lib/media-buy/action-contracts.d.ts +40 -0
  33. package/dist/lib/media-buy/action-contracts.js +304 -0
  34. package/dist/lib/media-buy/action-contracts.mjs +267 -0
  35. package/dist/lib/media-buy/action-metadata.generated.d.mts +37 -0
  36. package/dist/lib/media-buy/action-metadata.generated.d.ts +37 -0
  37. package/dist/lib/media-buy/action-metadata.generated.js +128 -0
  38. package/dist/lib/media-buy/action-metadata.generated.mjs +101 -0
  39. package/dist/lib/media-buy/action-types.d.mts +106 -0
  40. package/dist/lib/media-buy/action-types.d.ts +106 -0
  41. package/dist/lib/{types/v3-1-beta/tools.generated.js → media-buy/action-types.js} +2 -2
  42. package/dist/lib/media-buy/actions.d.mts +6 -0
  43. package/dist/lib/media-buy/actions.d.ts +6 -0
  44. package/dist/lib/media-buy/actions.js +38 -0
  45. package/dist/lib/media-buy/actions.mjs +9 -0
  46. package/dist/lib/media-buy/available-actions.d.mts +2 -1
  47. package/dist/lib/media-buy/available-actions.d.ts +2 -1
  48. package/dist/lib/media-buy/available-actions.js +4 -3
  49. package/dist/lib/media-buy/available-actions.mjs +4 -3
  50. package/dist/lib/media-buy/compatibility.js +3 -0
  51. package/dist/lib/media-buy/compatibility.mjs +3 -0
  52. package/dist/lib/media-buy/index.d.mts +4 -0
  53. package/dist/lib/media-buy/index.d.ts +4 -0
  54. package/dist/lib/media-buy/index.js +3 -1
  55. package/dist/lib/media-buy/index.mjs +1 -0
  56. package/dist/lib/media-buy/legacy-action-ids.d.mts +1 -0
  57. package/dist/lib/media-buy/legacy-action-ids.d.ts +1 -0
  58. package/dist/lib/media-buy/legacy-action-ids.js +50 -0
  59. package/dist/lib/media-buy/legacy-action-ids.mjs +26 -0
  60. package/dist/lib/media-buy/mutations.d.mts +70 -0
  61. package/dist/lib/media-buy/mutations.d.ts +70 -0
  62. package/dist/lib/media-buy/mutations.js +525 -0
  63. package/dist/lib/media-buy/mutations.mjs +498 -0
  64. package/dist/lib/media-buy/preflight.d.mts +20 -69
  65. package/dist/lib/media-buy/preflight.d.ts +20 -69
  66. package/dist/lib/media-buy/preflight.js +100 -336
  67. package/dist/lib/media-buy/preflight.mjs +111 -333
  68. package/dist/lib/media-buy/targeting-input.d.mts +7 -4
  69. package/dist/lib/media-buy/targeting-input.d.ts +7 -4
  70. package/dist/lib/media-buy/types.d.mts +55 -7
  71. package/dist/lib/media-buy/types.d.ts +55 -7
  72. package/dist/lib/protocols/rawResponseCapture.d.mts +12 -0
  73. package/dist/lib/protocols/rawResponseCapture.d.ts +12 -0
  74. package/dist/lib/protocols/rawResponseCapture.js +33 -3
  75. package/dist/lib/protocols/rawResponseCapture.mjs +32 -3
  76. package/dist/lib/registry/types.generated.d.mts +377 -9
  77. package/dist/lib/registry/types.generated.d.ts +377 -9
  78. package/dist/lib/reporting/evidence.d.mts +1 -0
  79. package/dist/lib/reporting/evidence.d.ts +1 -0
  80. package/dist/lib/reporting/evidence.js +32 -3
  81. package/dist/lib/reporting/evidence.mjs +31 -3
  82. package/dist/lib/reporting/ledger/handler.d.mts +51 -1
  83. package/dist/lib/reporting/ledger/handler.d.ts +51 -1
  84. package/dist/lib/reporting/ledger/handler.js +306 -38
  85. package/dist/lib/reporting/ledger/handler.mjs +304 -37
  86. package/dist/lib/reporting/ledger/health.d.mts +12 -0
  87. package/dist/lib/reporting/ledger/health.d.ts +12 -0
  88. package/dist/lib/reporting/ledger/health.js +15 -2
  89. package/dist/lib/reporting/ledger/health.mjs +13 -1
  90. package/dist/lib/reporting/ledger/index.d.mts +3 -0
  91. package/dist/lib/reporting/ledger/index.d.ts +3 -0
  92. package/dist/lib/reporting/ledger/index.js +7 -1
  93. package/dist/lib/reporting/ledger/index.mjs +3 -0
  94. package/dist/lib/reporting/ledger/lifecycle.d.mts +31 -4
  95. package/dist/lib/reporting/ledger/lifecycle.d.ts +31 -4
  96. package/dist/lib/reporting/ledger/lifecycle.js +244 -37
  97. package/dist/lib/reporting/ledger/lifecycle.mjs +244 -37
  98. package/dist/lib/reporting/ledger/managed-postgres.d.mts +231 -0
  99. package/dist/lib/reporting/ledger/managed-postgres.d.ts +231 -0
  100. package/dist/lib/reporting/ledger/managed-postgres.js +1797 -0
  101. package/dist/lib/reporting/ledger/managed-postgres.mjs +1776 -0
  102. package/dist/lib/reporting/ledger/managed.d.mts +355 -0
  103. package/dist/lib/reporting/ledger/managed.d.ts +355 -0
  104. package/dist/lib/reporting/ledger/managed.js +661 -0
  105. package/dist/lib/reporting/ledger/managed.mjs +633 -0
  106. package/dist/lib/reporting/ledger/notification-activity.d.mts +222 -0
  107. package/dist/lib/reporting/ledger/notification-activity.d.ts +222 -0
  108. package/dist/lib/reporting/ledger/notification-activity.js +1139 -0
  109. package/dist/lib/reporting/ledger/notification-activity.mjs +1110 -0
  110. package/dist/lib/reporting/ledger/postgres.d.mts +161 -1
  111. package/dist/lib/reporting/ledger/postgres.d.ts +161 -1
  112. package/dist/lib/reporting/ledger/postgres.js +1153 -21
  113. package/dist/lib/reporting/ledger/postgres.mjs +1152 -21
  114. package/dist/lib/reporting/ledger/producer.d.mts +8 -0
  115. package/dist/lib/reporting/ledger/producer.d.ts +8 -0
  116. package/dist/lib/reporting/ledger/producer.js +146 -52
  117. package/dist/lib/reporting/ledger/producer.mjs +146 -51
  118. package/dist/lib/reporting/ledger/types.d.mts +358 -1
  119. package/dist/lib/reporting/ledger/types.d.ts +358 -1
  120. package/dist/lib/reporting/ledger/types.js +3 -0
  121. package/dist/lib/reporting/ledger/types.mjs +2 -0
  122. package/dist/lib/reporting/service/conformance.d.mts +35 -0
  123. package/dist/lib/reporting/service/conformance.d.ts +35 -0
  124. package/dist/lib/reporting/service/conformance.js +89 -0
  125. package/dist/lib/reporting/service/conformance.mjs +68 -0
  126. package/dist/lib/reporting/service/index.d.mts +182 -0
  127. package/dist/lib/reporting/service/index.d.ts +182 -0
  128. package/dist/lib/reporting/service/index.js +793 -0
  129. package/dist/lib/reporting/service/index.mjs +787 -0
  130. package/dist/lib/reporting/source/index.d.mts +2 -1
  131. package/dist/lib/reporting/source/index.d.ts +2 -1
  132. package/dist/lib/reporting/source/index.js +16 -3
  133. package/dist/lib/reporting/source/index.mjs +12 -1
  134. package/dist/lib/reporting/source/inline.d.mts +88 -1
  135. package/dist/lib/reporting/source/inline.d.ts +88 -1
  136. package/dist/lib/reporting/source/inline.js +1161 -163
  137. package/dist/lib/reporting/source/inline.mjs +1166 -163
  138. package/dist/lib/reporting/source/manifest.js +12 -7
  139. package/dist/lib/reporting/source/manifest.mjs +12 -7
  140. package/dist/lib/reporting/source/source.d.mts +26 -0
  141. package/dist/lib/reporting/source/source.d.ts +26 -0
  142. package/dist/lib/reporting/source/source.js +71 -2
  143. package/dist/lib/reporting/source/source.mjs +65 -1
  144. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  145. package/dist/lib/server/create-adcp-server.d.mts +18 -0
  146. package/dist/lib/server/create-adcp-server.d.ts +18 -0
  147. package/dist/lib/server/create-adcp-server.js +52 -2
  148. package/dist/lib/server/create-adcp-server.mjs +52 -2
  149. package/dist/lib/server/decisioning/account.d.mts +1 -1
  150. package/dist/lib/server/decisioning/account.d.ts +1 -1
  151. package/dist/lib/server/decisioning/index.d.mts +1 -0
  152. package/dist/lib/server/decisioning/index.d.ts +1 -0
  153. package/dist/lib/server/decisioning/platform.d.mts +3 -0
  154. package/dist/lib/server/decisioning/platform.d.ts +3 -0
  155. package/dist/lib/server/decisioning/runtime/from-platform.js +88 -10
  156. package/dist/lib/server/decisioning/runtime/from-platform.mjs +88 -10
  157. package/dist/lib/server/decisioning/specialisms/reporting.d.mts +38 -0
  158. package/dist/lib/server/decisioning/specialisms/reporting.d.ts +38 -0
  159. package/dist/lib/{types/v3-1-beta/index.js → server/decisioning/specialisms/reporting.js} +2 -8
  160. package/dist/lib/server/decisioning/specialisms/reporting.mjs +0 -0
  161. package/dist/lib/server/index.d.mts +4 -2
  162. package/dist/lib/server/index.d.ts +4 -2
  163. package/dist/lib/server/index.js +5 -0
  164. package/dist/lib/server/index.mjs +4 -0
  165. package/dist/lib/server/media-buy-action-resolver.d.mts +63 -0
  166. package/dist/lib/server/media-buy-action-resolver.d.ts +63 -0
  167. package/dist/lib/server/media-buy-action-resolver.js +297 -0
  168. package/dist/lib/server/media-buy-action-resolver.mjs +285 -0
  169. package/dist/lib/server/media-buy-actions.d.mts +7 -8
  170. package/dist/lib/server/media-buy-actions.d.ts +7 -8
  171. package/dist/lib/server/media-buy-actions.js +57 -14
  172. package/dist/lib/server/media-buy-actions.mjs +63 -14
  173. package/dist/lib/server/notification-subscriptions/index.d.mts +2 -2
  174. package/dist/lib/server/notification-subscriptions/index.d.ts +2 -2
  175. package/dist/lib/server/notification-subscriptions/index.js +2 -0
  176. package/dist/lib/server/notification-subscriptions/index.mjs +2 -0
  177. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.mts +3 -1
  178. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.ts +3 -1
  179. package/dist/lib/server/notification-subscriptions/postgres-runtime.js +1 -0
  180. package/dist/lib/server/notification-subscriptions/postgres-runtime.mjs +1 -0
  181. package/dist/lib/server/notification-subscriptions/runtime.d.mts +12 -1
  182. package/dist/lib/server/notification-subscriptions/runtime.d.ts +12 -1
  183. package/dist/lib/server/notification-subscriptions/runtime.js +102 -16
  184. package/dist/lib/server/notification-subscriptions/runtime.mjs +101 -16
  185. package/dist/lib/server/notification-subscriptions/types.d.mts +104 -1
  186. package/dist/lib/server/notification-subscriptions/types.d.ts +104 -1
  187. package/dist/lib/server/webhook-emitter.d.mts +40 -5
  188. package/dist/lib/server/webhook-emitter.d.ts +40 -5
  189. package/dist/lib/server/webhook-emitter.js +23 -12
  190. package/dist/lib/server/webhook-emitter.mjs +23 -12
  191. package/dist/lib/storage/interfaces.d.mts +14 -2
  192. package/dist/lib/storage/interfaces.d.ts +14 -2
  193. package/dist/lib/testing/compliance/comply.d.mts +9 -3
  194. package/dist/lib/testing/compliance/comply.d.ts +9 -3
  195. package/dist/lib/testing/compliance/comply.js +158 -3
  196. package/dist/lib/testing/compliance/comply.mjs +159 -4
  197. package/dist/lib/testing/compliance/storyboard-tracks.js +7 -5
  198. package/dist/lib/testing/compliance/storyboard-tracks.mjs +7 -5
  199. package/dist/lib/testing/compliance/summary.js +10 -1
  200. package/dist/lib/testing/compliance/summary.mjs +10 -1
  201. package/dist/lib/testing/index.d.mts +1 -1
  202. package/dist/lib/testing/index.d.ts +1 -1
  203. package/dist/lib/testing/index.js +2 -0
  204. package/dist/lib/testing/index.mjs +3 -1
  205. package/dist/lib/testing/storyboard/agent-routing.d.mts +12 -43
  206. package/dist/lib/testing/storyboard/agent-routing.d.ts +12 -43
  207. package/dist/lib/testing/storyboard/agent-routing.js +75 -13
  208. package/dist/lib/testing/storyboard/agent-routing.mjs +70 -12
  209. package/dist/lib/testing/storyboard/index.d.mts +1 -0
  210. package/dist/lib/testing/storyboard/index.d.ts +1 -0
  211. package/dist/lib/testing/storyboard/index.js +3 -0
  212. package/dist/lib/testing/storyboard/index.mjs +2 -0
  213. package/dist/lib/testing/storyboard/junit.d.mts +1 -1
  214. package/dist/lib/testing/storyboard/junit.d.ts +1 -1
  215. package/dist/lib/testing/storyboard/junit.js +21 -2
  216. package/dist/lib/testing/storyboard/junit.mjs +21 -2
  217. package/dist/lib/testing/storyboard/probes.d.mts +130 -0
  218. package/dist/lib/testing/storyboard/probes.d.ts +130 -0
  219. package/dist/lib/testing/storyboard/probes.js +682 -10
  220. package/dist/lib/testing/storyboard/probes.mjs +683 -3
  221. package/dist/lib/testing/storyboard/request-signing/builder.d.mts +16 -5
  222. package/dist/lib/testing/storyboard/request-signing/builder.d.ts +16 -5
  223. package/dist/lib/testing/storyboard/request-signing/grader.d.mts +44 -1
  224. package/dist/lib/testing/storyboard/request-signing/grader.d.ts +44 -1
  225. package/dist/lib/testing/storyboard/request-signing/grader.js +46 -22
  226. package/dist/lib/testing/storyboard/request-signing/grader.mjs +43 -21
  227. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +86 -11
  228. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +86 -11
  229. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +119 -25
  230. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +117 -26
  231. package/dist/lib/testing/storyboard/request-signing/synthesize.js +22 -2
  232. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +22 -2
  233. package/dist/lib/testing/storyboard/runner.d.mts +103 -0
  234. package/dist/lib/testing/storyboard/runner.d.ts +103 -0
  235. package/dist/lib/testing/storyboard/runner.js +1090 -268
  236. package/dist/lib/testing/storyboard/runner.mjs +1096 -261
  237. package/dist/lib/testing/storyboard/seeding.d.mts +4 -1
  238. package/dist/lib/testing/storyboard/seeding.d.ts +4 -1
  239. package/dist/lib/testing/storyboard/seeding.js +55 -24
  240. package/dist/lib/testing/storyboard/seeding.mjs +55 -24
  241. package/dist/lib/testing/storyboard/test-kit.d.mts +37 -3
  242. package/dist/lib/testing/storyboard/test-kit.d.ts +37 -3
  243. package/dist/lib/testing/storyboard/test-kit.js +8 -2
  244. package/dist/lib/testing/storyboard/test-kit.mjs +7 -2
  245. package/dist/lib/testing/storyboard/types.d.mts +132 -10
  246. package/dist/lib/testing/storyboard/types.d.ts +132 -10
  247. package/dist/lib/testing/storyboard/types.js +17 -0
  248. package/dist/lib/testing/storyboard/types.mjs +16 -0
  249. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  250. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  251. package/dist/lib/testing/storyboard/validations.js +16 -0
  252. package/dist/lib/testing/storyboard/validations.mjs +16 -0
  253. package/dist/lib/testing/test-controller.d.mts +1 -1
  254. package/dist/lib/testing/test-controller.d.ts +1 -1
  255. package/dist/lib/types/buy-products.d.ts +71 -6
  256. package/dist/lib/types/control-media-buy.d.ts +25 -11
  257. package/dist/lib/types/core.generated.d.mts +69 -10
  258. package/dist/lib/types/core.generated.d.ts +69 -10
  259. package/dist/lib/types/create-media-buy.d.ts +71 -6
  260. package/dist/lib/types/forward-compat-error-codes.d.mts +7 -6
  261. package/dist/lib/types/forward-compat-error-codes.d.ts +7 -6
  262. package/dist/lib/types/index.d.mts +2 -2
  263. package/dist/lib/types/index.d.ts +2 -2
  264. package/dist/lib/types/schemas.generated.d.ts +8040 -8116
  265. package/dist/lib/types/schemas.generated.js +1074 -309
  266. package/dist/lib/types/schemas.generated.mjs +1068 -309
  267. package/dist/lib/types/tools.generated.d.mts +65 -6
  268. package/dist/lib/types/tools.generated.d.ts +65 -6
  269. package/dist/lib/types/update-media-buy.d.ts +71 -6
  270. package/dist/lib/utils/redact-secrets.d.mts +1 -1
  271. package/dist/lib/utils/redact-secrets.d.ts +1 -1
  272. package/dist/lib/utils/redact-secrets.js +1 -1
  273. package/dist/lib/utils/redact-secrets.mjs +1 -1
  274. package/dist/lib/v2/projection/cache-versions.d.mts +0 -1
  275. package/dist/lib/v2/projection/cache-versions.d.ts +0 -1
  276. package/dist/lib/v2/projection/cache-versions.js +1 -15
  277. package/dist/lib/v2/projection/cache-versions.mjs +1 -14
  278. package/dist/lib/v2/projection/canonical-properties.js +2 -2
  279. package/dist/lib/v2/projection/canonical-properties.mjs +3 -3
  280. package/dist/lib/v2/projection/registry.d.mts +1 -1
  281. package/dist/lib/v2/projection/registry.d.ts +1 -1
  282. package/dist/lib/v2/projection/registry.js +2 -2
  283. package/dist/lib/v2/projection/registry.mjs +3 -3
  284. package/dist/lib/version.d.mts +5 -5
  285. package/dist/lib/version.d.ts +5 -5
  286. package/dist/lib/version.js +3 -8
  287. package/dist/lib/version.mjs +3 -8
  288. package/dist/lib/wholesale-feed-sync/index.d.mts +1 -0
  289. package/dist/lib/wholesale-feed-sync/index.d.ts +1 -0
  290. package/dist/lib/wholesale-feed-sync/protocol-types.d.mts +42 -0
  291. package/dist/lib/wholesale-feed-sync/protocol-types.d.ts +42 -0
  292. package/dist/lib/wholesale-feed-sync/protocol-types.js +16 -0
  293. package/dist/lib/wholesale-feed-sync/protocol-types.mjs +0 -0
  294. package/dist/lib/wholesale-feed-sync/sync.d.mts +6 -6
  295. package/dist/lib/wholesale-feed-sync/sync.d.ts +6 -6
  296. package/dist/lib/wholesale-feed-sync/sync.js +3 -1
  297. package/dist/lib/wholesale-feed-sync/sync.mjs +3 -1
  298. package/dist/lib/wholesale-feed-sync/types.d.mts +15 -14
  299. package/dist/lib/wholesale-feed-sync/types.d.ts +15 -14
  300. package/dist/lib/wholesale-feed-sync/webhook-notification.d.mts +7 -5
  301. package/dist/lib/wholesale-feed-sync/webhook-notification.d.ts +7 -5
  302. package/dist/lib/wholesale-feed-sync/webhook-notification.js +45 -0
  303. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +44 -0
  304. package/docs/CLI.md +1 -1
  305. package/docs/TYPE-SUMMARY.md +118 -4
  306. package/docs/guides/ASYNC-API-REFERENCE.md +62 -1
  307. package/docs/guides/ASYNC-DEVELOPER-GUIDE.md +25 -0
  308. package/docs/guides/ASYNC-DOCUMENTATION-INDEX.md +3 -0
  309. package/docs/guides/BUYER-QUICKSTART-3.2.md +5 -0
  310. package/docs/guides/DURABLE-BUYER-WRITES.md +337 -0
  311. package/docs/guides/EXISTING-PLATFORM.md +35 -0
  312. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +7 -3
  313. package/docs/guides/MEDIA-BUY-ACTION-ASSESSMENT.md +300 -0
  314. package/docs/guides/REPORTING-LEDGER.md +654 -3
  315. package/docs/guides/REPORTING-SOURCE-EXECUTOR.md +63 -1
  316. package/docs/guides/SELLER-QUICKSTART-3.2.md +2 -0
  317. package/docs/guides/VALIDATE-YOUR-AGENT.md +35 -0
  318. package/docs/guides/idempotency-crash-recovery.md +4 -0
  319. package/docs/llms.txt +4 -2
  320. package/docs/migration-14.x-rc-worksheet.md +5 -5
  321. package/docs/migration-7.9-to-7.10.md +7 -5
  322. package/examples/README.md +17 -0
  323. package/examples/durable-buyer-writes/caller.ts +745 -0
  324. package/examples/durable-buyer-writes/worker.ts +240 -0
  325. package/examples/reliable-reporting-service/README.md +100 -0
  326. package/examples/seller-3.2-starter.ts +7 -8
  327. package/examples/targeting-input-existing-platform.ts +153 -0
  328. package/package.json +41 -29
  329. package/skills/build-seller-agent/specialisms/signed-requests.md +11 -1
  330. package/skills/cross-cutting.md +28 -11
  331. package/compliance/cache/3.1.0-beta.7/domains/brand/index.yaml +0 -160
  332. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  333. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/single_side_trust_extension.yaml +0 -454
  334. package/compliance/cache/3.1.0-beta.7/domains/creative/index.yaml +0 -339
  335. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/billing_out_of_band.yaml +0 -153
  336. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  337. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/native_in_feed.yaml +0 -543
  338. package/compliance/cache/3.1.0-beta.7/domains/governance/index.yaml +0 -682
  339. package/compliance/cache/3.1.0-beta.7/domains/media-buy/index.yaml +0 -781
  340. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  341. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/available_actions.yaml +0 -565
  342. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  343. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/canonical_formats.yaml +0 -711
  344. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  345. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  346. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  347. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  348. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_reception.yaml +0 -247
  349. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/delivery_reporting.yaml +0 -357
  350. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment.yaml +0 -633
  351. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  352. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  353. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  354. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_approved.yaml +0 -214
  355. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_conditions.yaml +0 -199
  356. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied.yaml +0 -204
  357. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  358. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/invalid_transitions.yaml +0 -289
  359. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  360. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  361. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_accountability.yaml +0 -244
  362. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  363. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  364. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  365. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  366. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  367. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  368. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize.yaml +0 -399
  369. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  370. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  371. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  372. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  373. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  374. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  375. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  376. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_products.yaml +0 -148
  377. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  378. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  379. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  380. package/compliance/cache/3.1.0-beta.7/domains/media-buy/state-machine.yaml +0 -442
  381. package/compliance/cache/3.1.0-beta.7/domains/signals/index.yaml +0 -266
  382. package/compliance/cache/3.1.0-beta.7/domains/sponsored-intelligence/index.yaml +0 -256
  383. package/compliance/cache/3.1.0-beta.7/index.json +0 -356
  384. package/compliance/cache/3.1.0-beta.7/protocols/brand/index.yaml +0 -160
  385. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  386. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/single_side_trust_extension.yaml +0 -454
  387. package/compliance/cache/3.1.0-beta.7/protocols/creative/index.yaml +0 -339
  388. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/billing_out_of_band.yaml +0 -153
  389. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  390. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/native_in_feed.yaml +0 -543
  391. package/compliance/cache/3.1.0-beta.7/protocols/governance/index.yaml +0 -682
  392. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/index.yaml +0 -781
  393. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  394. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/available_actions.yaml +0 -565
  395. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  396. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/canonical_formats.yaml +0 -711
  397. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  398. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  399. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  400. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  401. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_reception.yaml +0 -247
  402. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/delivery_reporting.yaml +0 -357
  403. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment.yaml +0 -633
  404. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  405. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  406. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  407. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_approved.yaml +0 -214
  408. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_conditions.yaml +0 -199
  409. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied.yaml +0 -204
  410. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  411. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/invalid_transitions.yaml +0 -289
  412. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  413. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  414. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_accountability.yaml +0 -244
  415. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  416. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  417. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  418. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  419. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  420. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  421. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize.yaml +0 -399
  422. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  423. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  424. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  425. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  426. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  427. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  428. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  429. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_products.yaml +0 -148
  430. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  431. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  432. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  433. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/state-machine.yaml +0 -442
  434. package/compliance/cache/3.1.0-beta.7/protocols/signals/index.yaml +0 -266
  435. package/compliance/cache/3.1.0-beta.7/protocols/sponsored-intelligence/index.yaml +0 -256
  436. package/compliance/cache/3.1.0-beta.7/specialisms/audience-sync/index.yaml +0 -313
  437. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/index.yaml +0 -350
  438. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/scenarios/governance_denied.yaml +0 -226
  439. package/compliance/cache/3.1.0-beta.7/specialisms/collection-lists/index.yaml +0 -359
  440. package/compliance/cache/3.1.0-beta.7/specialisms/content-standards/index.yaml +0 -572
  441. package/compliance/cache/3.1.0-beta.7/specialisms/creative-ad-server/index.yaml +0 -409
  442. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/generative-seller.yaml +0 -807
  443. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/index.yaml +0 -758
  444. package/compliance/cache/3.1.0-beta.7/specialisms/creative-template/index.yaml +0 -510
  445. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/index.yaml +0 -143
  446. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +0 -117
  447. package/compliance/cache/3.1.0-beta.7/specialisms/governance-delivery-monitor/index.yaml +0 -441
  448. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/denied.yaml +0 -221
  449. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/index.yaml +0 -330
  450. package/compliance/cache/3.1.0-beta.7/specialisms/property-lists/index.yaml +0 -482
  451. package/compliance/cache/3.1.0-beta.7/specialisms/sales-broadcast-tv/index.yaml +0 -738
  452. package/compliance/cache/3.1.0-beta.7/specialisms/sales-catalog-driven/index.yaml +0 -840
  453. package/compliance/cache/3.1.0-beta.7/specialisms/sales-guaranteed/index.yaml +0 -601
  454. package/compliance/cache/3.1.0-beta.7/specialisms/sales-non-guaranteed/index.yaml +0 -546
  455. package/compliance/cache/3.1.0-beta.7/specialisms/sales-proposal-mode/index.yaml +0 -586
  456. package/compliance/cache/3.1.0-beta.7/specialisms/sales-social/index.yaml +0 -919
  457. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/index.yaml +0 -424
  458. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/scenarios/governance_denied.yaml +0 -211
  459. package/compliance/cache/3.1.0-beta.7/specialisms/signal-owned/index.yaml +0 -317
  460. package/compliance/cache/3.1.0-beta.7/specialisms/sponsored-intelligence/index.yaml +0 -59
  461. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor-live.yaml +0 -78
  462. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor.yaml +0 -223
  463. package/compliance/cache/3.1.0-beta.7/test-kits/billing-gate-runner.yaml +0 -115
  464. package/compliance/cache/3.1.0-beta.7/test-kits/bistro-oranje.yaml +0 -126
  465. package/compliance/cache/3.1.0-beta.7/test-kits/distributed-brand-runner.yaml +0 -281
  466. package/compliance/cache/3.1.0-beta.7/test-kits/nova-motors.yaml +0 -262
  467. package/compliance/cache/3.1.0-beta.7/test-kits/osei-natural.yaml +0 -126
  468. package/compliance/cache/3.1.0-beta.7/test-kits/parallel-dispatch-runner.yaml +0 -196
  469. package/compliance/cache/3.1.0-beta.7/test-kits/rate-limit-trip-runner.yaml +0 -172
  470. package/compliance/cache/3.1.0-beta.7/test-kits/signed-requests-runner.yaml +0 -155
  471. package/compliance/cache/3.1.0-beta.7/test-kits/single-side-trust-runner.yaml +0 -294
  472. package/compliance/cache/3.1.0-beta.7/test-kits/substitution-observer-runner.yaml +0 -688
  473. package/compliance/cache/3.1.0-beta.7/test-kits/summit-foods.yaml +0 -125
  474. package/compliance/cache/3.1.0-beta.7/test-kits/webhook-receiver-runner.yaml +0 -265
  475. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/001-minimal-plan.json +0 -43
  476. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/002-full-plan.json +0 -217
  477. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/003-bookkeeping-stripped.json +0 -60
  478. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004a-human-review-omitted.json +0 -43
  479. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004b-human-review-explicit-null.json +0 -49
  480. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005a-policy-categories-order-1.json +0 -53
  481. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005b-policy-categories-order-2.json +0 -57
  482. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006a-ext-trace-v1.json +0 -49
  483. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006b-ext-trace-v2.json +0 -53
  484. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/007-unicode-objectives.json +0 -43
  485. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/008-numeric-canonicalization.json +0 -65
  486. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/README.md +0 -220
  487. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/canonicalization.json +0 -241
  488. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/keys.json +0 -60
  489. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/001-no-signature-header.json +0 -24
  490. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/002-wrong-tag.json +0 -26
  491. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/003-expired-signature.json +0 -26
  492. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/004-window-too-long.json +0 -26
  493. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/005-alg-not-allowed.json +0 -26
  494. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/006-missing-covered-component.json +0 -26
  495. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/007-missing-content-digest.json +0 -26
  496. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/008-unknown-keyid.json +0 -26
  497. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +0 -27
  498. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/010-content-digest-mismatch.json +0 -33
  499. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/011-malformed-header.json +0 -27
  500. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/012-missing-expires-param.json +0 -26
  501. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/013-expires-le-created.json +0 -27
  502. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/014-missing-nonce-param.json +0 -27
  503. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/015-signature-invalid.json +0 -28
  504. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/016-replayed-nonce.json +0 -35
  505. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/017-key-revoked.json +0 -38
  506. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +0 -28
  507. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/019-signature-without-signature-input.json +0 -26
  508. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/020-rate-abuse.json +0 -34
  509. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +0 -31
  510. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/022-multi-valued-content-type.json +0 -31
  511. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +0 -32
  512. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/024-unquoted-string-param.json +0 -31
  513. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +0 -43
  514. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/026-non-ascii-host.json +0 -31
  515. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +0 -25
  516. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +0 -26
  517. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/001-basic-post.json +0 -30
  518. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/002-post-with-content-digest.json +0 -31
  519. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/003-es256-post.json +0 -30
  520. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/004-multiple-signature-labels.json +0 -26
  521. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/005-default-port-stripped.json +0 -30
  522. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/006-dot-segment-path.json +0 -30
  523. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/007-query-byte-preserved.json +0 -30
  524. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/008-percent-encoded-path.json +0 -30
  525. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +0 -30
  526. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +0 -30
  527. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/011-ipv6-authority.json +0 -30
  528. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +0 -30
  529. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/README.md +0 -211
  530. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/keys.json +0 -61
  531. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/001-wrong-tag.json +0 -26
  532. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/002-expired-signature.json +0 -26
  533. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/003-window-too-long.json +0 -26
  534. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +0 -26
  535. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/005-missing-authority-component.json +0 -26
  536. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/006-missing-content-digest.json +0 -25
  537. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/007-unknown-keyid.json +0 -26
  538. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +0 -26
  539. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +0 -26
  540. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +0 -26
  541. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/011-signature-without-input.json +0 -25
  542. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/012-missing-expires-param.json +0 -26
  543. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/013-expires-le-created.json +0 -26
  544. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +0 -26
  545. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/015-signature-invalid.json +0 -26
  546. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/016-replayed-nonce.json +0 -37
  547. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/017-key-revoked.json +0 -32
  548. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/018-rate-abuse.json +0 -33
  549. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/019-revocation-stale.json +0 -32
  550. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +0 -41
  551. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +0 -26
  552. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/001-basic-post.json +0 -24
  553. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/002-es256-post.json +0 -24
  554. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +0 -24
  555. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/004-default-port-stripped.json +0 -24
  556. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +0 -24
  557. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +0 -24
  558. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +0 -25
  559. package/compliance/cache/3.1.0-beta.7/universal/billing-gate-dispatch.yaml +0 -450
  560. package/compliance/cache/3.1.0-beta.7/universal/canonical-format-validate-input.yaml +0 -640
  561. package/compliance/cache/3.1.0-beta.7/universal/capability-discovery.yaml +0 -125
  562. package/compliance/cache/3.1.0-beta.7/universal/collection-lists-pagination-integrity.yaml +0 -306
  563. package/compliance/cache/3.1.0-beta.7/universal/comply-controller-mode-gate.yaml +0 -141
  564. package/compliance/cache/3.1.0-beta.7/universal/content-standards-pagination-integrity.yaml +0 -326
  565. package/compliance/cache/3.1.0-beta.7/universal/deterministic-testing.yaml +0 -1430
  566. package/compliance/cache/3.1.0-beta.7/universal/error-compliance-signals.yaml +0 -377
  567. package/compliance/cache/3.1.0-beta.7/universal/error-compliance.yaml +0 -528
  568. package/compliance/cache/3.1.0-beta.7/universal/fictional-entities.yaml +0 -307
  569. package/compliance/cache/3.1.0-beta.7/universal/get-media-buys-pagination-integrity.yaml +0 -160
  570. package/compliance/cache/3.1.0-beta.7/universal/get-signals-pagination-integrity.yaml +0 -211
  571. package/compliance/cache/3.1.0-beta.7/universal/idempotency.yaml +0 -861
  572. package/compliance/cache/3.1.0-beta.7/universal/notification-config-event-scope.yaml +0 -119
  573. package/compliance/cache/3.1.0-beta.7/universal/notification-config-lifecycle.yaml +0 -337
  574. package/compliance/cache/3.1.0-beta.7/universal/notification-config-rejections.yaml +0 -107
  575. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-creative-formats.yaml +0 -265
  576. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-list-accounts.yaml +0 -245
  577. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity.yaml +0 -263
  578. package/compliance/cache/3.1.0-beta.7/universal/property-lists-pagination-integrity.yaml +0 -307
  579. package/compliance/cache/3.1.0-beta.7/universal/read-tool-idempotency.yaml +0 -405
  580. package/compliance/cache/3.1.0-beta.7/universal/runner-output-contract.yaml +0 -1266
  581. package/compliance/cache/3.1.0-beta.7/universal/schema-validation-signals.yaml +0 -181
  582. package/compliance/cache/3.1.0-beta.7/universal/schema-validation.yaml +0 -548
  583. package/compliance/cache/3.1.0-beta.7/universal/security.yaml +0 -539
  584. package/compliance/cache/3.1.0-beta.7/universal/signed-requests.yaml +0 -217
  585. package/compliance/cache/3.1.0-beta.7/universal/stale-response-advisory.yaml +0 -295
  586. package/compliance/cache/3.1.0-beta.7/universal/storyboard-schema.yaml +0 -2136
  587. package/compliance/cache/3.1.0-beta.7/universal/v3-envelope-integrity.yaml +0 -117
  588. package/compliance/cache/3.1.0-beta.7/universal/version-negotiation.yaml +0 -130
  589. package/compliance/cache/3.1.0-beta.7/universal/webhook-emission.yaml +0 -411
  590. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-bulk-webhooks.yaml +0 -82
  591. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-product-webhooks.yaml +0 -83
  592. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-products.yaml +0 -151
  593. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signal-webhooks.yaml +0 -83
  594. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signals.yaml +0 -149
  595. package/dist/lib/types/v3-1-beta/index.d.mts +0 -1
  596. package/dist/lib/types/v3-1-beta/index.d.ts +0 -1
  597. package/dist/lib/types/v3-1-beta/index.mjs +0 -1
  598. package/dist/lib/types/v3-1-beta/tools.generated.d.mts +0 -26788
  599. package/dist/lib/types/v3-1-beta/tools.generated.d.ts +0 -26788
  600. /package/dist/lib/{types/v3-1-beta/tools.generated.mjs → media-buy/action-types.mjs} +0 -0
@@ -32,6 +32,7 @@ function createPostgresPersistentNotificationRuntime(options) {
32
32
  store,
33
33
  proofAdapter: options.proofAdapter,
34
34
  ...options.credentialAdapter === void 0 ? {} : { credentialAdapter: options.credentialAdapter },
35
+ ...options.checkpointDeliveryAttempt === void 0 ? {} : { checkpointDeliveryAttempt: options.checkpointDeliveryAttempt },
35
36
  authorizeDelivery: options.authorizeDelivery,
36
37
  ...options.validateDestination === void 0 ? {} : { validateDestination: options.validateDestination },
37
38
  ...options.supportedCallerEventTypes === void 0 ? {} : { supportedCallerEventTypes: options.supportedCallerEventTypes },
@@ -14,6 +14,7 @@ function createPostgresPersistentNotificationRuntime(options) {
14
14
  store,
15
15
  proofAdapter: options.proofAdapter,
16
16
  ...options.credentialAdapter === void 0 ? {} : { credentialAdapter: options.credentialAdapter },
17
+ ...options.checkpointDeliveryAttempt === void 0 ? {} : { checkpointDeliveryAttempt: options.checkpointDeliveryAttempt },
17
18
  authorizeDelivery: options.authorizeDelivery,
18
19
  ...options.validateDestination === void 0 ? {} : { validateDestination: options.validateDestination },
19
20
  ...options.supportedCallerEventTypes === void 0 ? {} : { supportedCallerEventTypes: options.supportedCallerEventTypes },
@@ -1,4 +1,5 @@
1
- import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions } from './types.mjs';
1
+ import type { WebhookAttemptSuppressionReason } from '../webhook-emitter.mjs';
2
+ import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions } from './types.mjs';
2
3
  export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
3
4
  export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
4
5
  /**
@@ -10,6 +11,16 @@ export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_chan
10
11
  export declare function createPersistentNotificationRuntime(options: PersistentNotificationRuntimeOptions): PersistentNotificationRuntime;
11
12
  /** Strip SDK operational generations for generated AdCP response projections. */
12
13
  export declare function projectNotificationSubscriptionReadback(views: readonly NotificationSubscriptionView[]): NotificationSubscriptionConfigInput[];
14
+ /**
15
+ * Classifies a live-authority suppression so an emission owner can tell a
16
+ * deliberate decision not to deliver from an operational failure.
17
+ *
18
+ * Treating every suppression as terminal silently drops notifications whenever
19
+ * a store read or an authorization/credential callback has a bad minute, and
20
+ * treating every suppression as retryable poisons the queue for a subscriber
21
+ * that was legitimately revoked or denied.
22
+ */
23
+ export declare function notificationSuppressionDisposition(reason: WebhookAttemptSuppressionReason): NotificationSuppressionDisposition;
13
24
  /** Point-in-time registration validation; delivery still re-resolves and pins every attempt. */
14
25
  export declare function validatePersistentNotificationDestination(input: {
15
26
  url: string;
@@ -1,4 +1,5 @@
1
- import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions } from './types';
1
+ import type { WebhookAttemptSuppressionReason } from '../webhook-emitter';
2
+ import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions } from './types';
2
3
  export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
3
4
  export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
4
5
  /**
@@ -10,6 +11,16 @@ export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_chan
10
11
  export declare function createPersistentNotificationRuntime(options: PersistentNotificationRuntimeOptions): PersistentNotificationRuntime;
11
12
  /** Strip SDK operational generations for generated AdCP response projections. */
12
13
  export declare function projectNotificationSubscriptionReadback(views: readonly NotificationSubscriptionView[]): NotificationSubscriptionConfigInput[];
14
+ /**
15
+ * Classifies a live-authority suppression so an emission owner can tell a
16
+ * deliberate decision not to deliver from an operational failure.
17
+ *
18
+ * Treating every suppression as terminal silently drops notifications whenever
19
+ * a store read or an authorization/credential callback has a bad minute, and
20
+ * treating every suppression as retryable poisons the queue for a subscriber
21
+ * that was legitimately revoked or denied.
22
+ */
23
+ export declare function notificationSuppressionDisposition(reason: WebhookAttemptSuppressionReason): NotificationSuppressionDisposition;
13
24
  /** Point-in-time registration validation; delivery still re-resolves and pins every attempt. */
14
25
  export declare function validatePersistentNotificationDestination(input: {
15
26
  url: string;
@@ -21,6 +21,7 @@ __export(runtime_exports, {
21
21
  ACCOUNT_NOTIFICATION_TYPES: () => ACCOUNT_NOTIFICATION_TYPES,
22
22
  CALLER_NOTIFICATION_TYPES: () => CALLER_NOTIFICATION_TYPES,
23
23
  createPersistentNotificationRuntime: () => createPersistentNotificationRuntime,
24
+ notificationSuppressionDisposition: () => notificationSuppressionDisposition,
24
25
  projectNotificationSubscriptionReadback: () => projectNotificationSubscriptionReadback,
25
26
  validatePersistentNotificationDestination: () => validatePersistentNotificationDestination
26
27
  });
@@ -28,6 +29,7 @@ module.exports = __toCommonJS(runtime_exports);
28
29
  var import_node_crypto = require("node:crypto");
29
30
  var import_promises = require("node:dns/promises");
30
31
  var import_jcs = require('../../utils/jcs.js');
32
+ var import_common = require('../webhook-delivery/common.js');
31
33
  var import_ssrf = require('../../substitution/observer/ssrf.js');
32
34
  var import_pin_and_bind_fetch = require('../pin-and-bind-fetch.js');
33
35
  var import_types = require('./types.js');
@@ -96,6 +98,30 @@ function createPersistentNotificationRuntime(options) {
96
98
  ...futureCallerInvalidationEventTypes
97
99
  ]);
98
100
  const validateDestination = options.validateDestination ?? validatePersistentNotificationDestination;
101
+ const checkpointAttempt = async (context) => {
102
+ if (!options.checkpointDeliveryAttempt) return true;
103
+ const controller = new AbortController();
104
+ try {
105
+ await options.checkpointDeliveryAttempt({
106
+ scope: structuredClone(context.scope),
107
+ eventAnchor: context.eventAnchor,
108
+ ...context.accountId === void 0 ? {} : { accountId: context.accountId },
109
+ subscriberId: context.subscriberId,
110
+ destinationGeneration: context.destinationGeneration,
111
+ eventType: context.eventType,
112
+ notificationId: context.notificationId,
113
+ signal: controller.signal
114
+ });
115
+ return true;
116
+ } catch {
117
+ return false;
118
+ }
119
+ };
120
+ const suppress = (reason) => ({
121
+ decision: "suppress",
122
+ reason,
123
+ ...notificationSuppressionDisposition(reason) === "retryable" ? { retryable: true } : {}
124
+ });
99
125
  const authorizeWebhookAttempt = async (attempt) => {
100
126
  const context = parseAttemptContext(attempt.attemptAuthorizationContext);
101
127
  if (!context) return { decision: "suppress", reason: "authorization_error" };
@@ -103,22 +129,22 @@ function createPersistentNotificationRuntime(options) {
103
129
  try {
104
130
  set = await options.store.get(context.scope);
105
131
  } catch {
106
- return { decision: "suppress", reason: "authorization_error" };
132
+ return suppress("authorization_error");
107
133
  }
108
- if (!set) return { decision: "suppress", reason: "subscription_missing" };
134
+ if (!set) return suppress("subscription_missing");
109
135
  const subscription = set.subscriptions.find((item) => item.subscriberId === context.subscriberId);
110
- if (!subscription) return { decision: "suppress", reason: "subscription_missing" };
136
+ if (!subscription) return suppress("subscription_missing");
111
137
  if (subscription.destinationGeneration !== context.destinationGeneration) {
112
- return { decision: "suppress", reason: "subscription_stale" };
138
+ return attempt.recovered === true ? { decision: "suppress", reason: "subscription_stale" } : suppress("subscription_stale");
113
139
  }
114
140
  if (!subscription.active || subscription.proofGeneration !== subscription.destinationGeneration) {
115
- return { decision: "suppress", reason: "subscription_inactive" };
141
+ return suppress("subscription_inactive");
116
142
  }
117
143
  if (!subscription.eventTypes.includes(context.eventType) && !(context.futureCallerInvalidation === true && futureCallerInvalidationEventTypes.has(context.eventType) && subscription.includeFutureEventTypes)) {
118
- return { decision: "suppress", reason: "event_not_allowed" };
144
+ return suppress("event_not_allowed");
119
145
  }
120
146
  if (context.eventAnchor === "account" && !context.accountId || context.eventAnchor === "caller" && context.accountId !== void 0 || context.scope.kind === "account" && (context.eventAnchor !== "account" || context.scope.accountId !== context.accountId) || context.scope.kind === "caller" && context.eventAnchor === "account" && !subscription.allAuthorizedAccounts) {
121
- return { decision: "suppress", reason: "event_not_allowed" };
147
+ return suppress("event_not_allowed");
122
148
  }
123
149
  let decision;
124
150
  try {
@@ -137,16 +163,17 @@ function createPersistentNotificationRuntime(options) {
137
163
  })
138
164
  );
139
165
  } catch {
140
- return { decision: "suppress", reason: "authorization_error" };
166
+ return suppress("authorization_error");
141
167
  }
142
- if (decision?.authorized !== true) return { decision: "suppress", reason: "authorization_denied" };
168
+ if (decision?.authorized !== true) return suppress("authorization_denied");
143
169
  const authenticationMode = subscription.authentication.mode;
144
170
  if (authenticationMode === "rfc9421") {
171
+ if (!await checkpointAttempt(context)) return suppress("attempt_checkpoint_unavailable");
145
172
  return { decision: "allow", authentication: null };
146
173
  }
147
174
  const bindingId = subscription.authentication.bindingId;
148
175
  if (!bindingId || !options.credentialAdapter) {
149
- return { decision: "suppress", reason: "credential_unavailable" };
176
+ return suppress("credential_unavailable");
150
177
  }
151
178
  try {
152
179
  const authentication = await runAdopterCallback(
@@ -162,11 +189,12 @@ function createPersistentNotificationRuntime(options) {
162
189
  })
163
190
  );
164
191
  if (!resolvedAuthenticationMatches(authenticationMode, authentication)) {
165
- return { decision: "suppress", reason: "credential_unavailable" };
192
+ return suppress("credential_unavailable");
166
193
  }
194
+ if (!await checkpointAttempt(context)) return suppress("attempt_checkpoint_unavailable");
167
195
  return { decision: "allow", authentication };
168
196
  } catch {
169
- return { decision: "suppress", reason: "credential_unavailable" };
197
+ return suppress("credential_unavailable");
170
198
  }
171
199
  };
172
200
  const emitter = options.createEmitter(authorizeWebhookAttempt);
@@ -177,6 +205,8 @@ function createPersistentNotificationRuntime(options) {
177
205
  store: options.store,
178
206
  emitter,
179
207
  authorizeWebhookAttempt,
208
+ hasDeliveryAttemptCheckpoint: options.checkpointDeliveryAttempt !== void 0,
209
+ ...options.checkpointDeliveryAttempt === void 0 ? {} : { deliveryAttemptCheckpoint: options.checkpointDeliveryAttempt },
180
210
  async replace(scope, configs, replaceOptions = {}) {
181
211
  assertScope(scope);
182
212
  assertUniqueSubscribers(configs);
@@ -316,14 +346,15 @@ function createPersistentNotificationRuntime(options) {
316
346
  if (candidateSets.length > maxFanoutCandidates) {
317
347
  throw new Error("Persistent notification fanout exceeded maxFanoutCandidates; no deliveries were attempted");
318
348
  }
319
- const targets = candidateSets.flatMap(
349
+ const resolved = candidateSets.flatMap(
320
350
  (set) => set.subscriptions.filter(
321
351
  (subscription) => subscription.active && subscription.proofGeneration === subscription.destinationGeneration && (subscription.eventTypes.includes(event.notificationType) || futureCallerInvalidation && subscription.includeFutureEventTypes) && (set.scope.kind !== "caller" || event.anchor !== "account" || subscription.allAuthorizedAccounts)
322
352
  ).map((subscription) => ({ set, subscription }))
323
353
  );
324
- if (targets.length > maxFanoutCandidates) {
354
+ if (resolved.length > maxFanoutCandidates) {
325
355
  throw new Error("Persistent notification fanout exceeded maxFanoutCandidates; no deliveries were attempted");
326
356
  }
357
+ const targets = event.freezeRecipients ? await pinResolvedRecipients(resolved, event.freezeRecipients) : resolved;
327
358
  const deliveries = await mapConcurrent(targets, fanoutConcurrency, async ({ set, subscription }) => {
328
359
  const deliveryId = deliveryIdentity(event.emissionId, set.scope, subscription);
329
360
  const payload = notificationPayload(event, subscription.subscriberId);
@@ -353,10 +384,10 @@ function createPersistentNotificationRuntime(options) {
353
384
  attemptAuthorizationContext: context
354
385
  });
355
386
  return { ...delivery, result };
356
- } catch {
387
+ } catch (error) {
357
388
  return {
358
389
  ...delivery,
359
- failure: { reason: "delivery_runtime_error" }
390
+ failure: (0, import_common.isWebhookDeliveryTerminalError)(error) ? { reason: "delivery_binding_retired", terminal: true } : { reason: "delivery_runtime_error" }
360
391
  };
361
392
  }
362
393
  });
@@ -622,6 +653,60 @@ function assertPayloadField(payload, field, expected) {
622
653
  );
623
654
  }
624
655
  }
656
+ async function pinResolvedRecipients(resolved, freezeRecipients) {
657
+ const frozen = await freezeRecipients(
658
+ resolved.map((target) => ({
659
+ scope: structuredClone(target.set.scope),
660
+ subscriberId: target.subscription.subscriberId,
661
+ destinationGeneration: target.subscription.destinationGeneration
662
+ }))
663
+ );
664
+ if (!Array.isArray(frozen)) {
665
+ throw new TypeError("freezeRecipients must return the durably committed recipient set");
666
+ }
667
+ const committed = new Set(
668
+ frozen.map((recipient) => {
669
+ if (!recipient || typeof recipient.subscriberId !== "string" || typeof recipient.destinationGeneration !== "string" || !recipient.scope) {
670
+ throw new TypeError("freezeRecipients returned a malformed recipient reference");
671
+ }
672
+ return recipientKey(recipient);
673
+ })
674
+ );
675
+ return resolved.filter(
676
+ (target) => committed.has(
677
+ recipientKey({
678
+ scope: target.set.scope,
679
+ subscriberId: target.subscription.subscriberId,
680
+ destinationGeneration: target.subscription.destinationGeneration
681
+ })
682
+ )
683
+ );
684
+ }
685
+ function notificationSuppressionDisposition(reason) {
686
+ switch (reason) {
687
+ case "authorization_error":
688
+ case "credential_unavailable":
689
+ return "retryable";
690
+ case "subscription_stale":
691
+ return "retryable";
692
+ case "attempt_checkpoint_unavailable":
693
+ return "retryable";
694
+ case "subscription_missing":
695
+ case "subscription_inactive":
696
+ case "event_not_allowed":
697
+ case "authorization_denied":
698
+ return "terminal";
699
+ default:
700
+ return "retryable";
701
+ }
702
+ }
703
+ function recipientKey(recipient) {
704
+ return (0, import_jcs.canonicalJsonSha256)({
705
+ scope: recipient.scope,
706
+ subscriberId: recipient.subscriberId,
707
+ destinationGeneration: recipient.destinationGeneration
708
+ });
709
+ }
625
710
  function deliveryIdentity(emissionId, scope, subscription) {
626
711
  return `notification_${(0, import_jcs.canonicalJsonSha256)({
627
712
  emissionId,
@@ -844,6 +929,7 @@ function validation(message, index, field) {
844
929
  ACCOUNT_NOTIFICATION_TYPES,
845
930
  CALLER_NOTIFICATION_TYPES,
846
931
  createPersistentNotificationRuntime,
932
+ notificationSuppressionDisposition,
847
933
  projectNotificationSubscriptionReadback,
848
934
  validatePersistentNotificationDestination
849
935
  });
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { lookup } from "node:dns/promises";
3
3
  import { canonicalJsonSha256 } from "../../utils/jcs.mjs";
4
+ import { isWebhookDeliveryTerminalError } from "../webhook-delivery/common.mjs";
4
5
  import { enforceSsrfPolicy, enforceSsrfPolicyResolved } from "../../substitution/observer/ssrf.mjs";
5
6
  import { WEBHOOK_SSRF_POLICY } from "../pin-and-bind-fetch.mjs";
6
7
  import { NotificationSubscriptionValidationError } from "./types.mjs";
@@ -69,6 +70,30 @@ function createPersistentNotificationRuntime(options) {
69
70
  ...futureCallerInvalidationEventTypes
70
71
  ]);
71
72
  const validateDestination = options.validateDestination ?? validatePersistentNotificationDestination;
73
+ const checkpointAttempt = async (context) => {
74
+ if (!options.checkpointDeliveryAttempt) return true;
75
+ const controller = new AbortController();
76
+ try {
77
+ await options.checkpointDeliveryAttempt({
78
+ scope: structuredClone(context.scope),
79
+ eventAnchor: context.eventAnchor,
80
+ ...context.accountId === void 0 ? {} : { accountId: context.accountId },
81
+ subscriberId: context.subscriberId,
82
+ destinationGeneration: context.destinationGeneration,
83
+ eventType: context.eventType,
84
+ notificationId: context.notificationId,
85
+ signal: controller.signal
86
+ });
87
+ return true;
88
+ } catch {
89
+ return false;
90
+ }
91
+ };
92
+ const suppress = (reason) => ({
93
+ decision: "suppress",
94
+ reason,
95
+ ...notificationSuppressionDisposition(reason) === "retryable" ? { retryable: true } : {}
96
+ });
72
97
  const authorizeWebhookAttempt = async (attempt) => {
73
98
  const context = parseAttemptContext(attempt.attemptAuthorizationContext);
74
99
  if (!context) return { decision: "suppress", reason: "authorization_error" };
@@ -76,22 +101,22 @@ function createPersistentNotificationRuntime(options) {
76
101
  try {
77
102
  set = await options.store.get(context.scope);
78
103
  } catch {
79
- return { decision: "suppress", reason: "authorization_error" };
104
+ return suppress("authorization_error");
80
105
  }
81
- if (!set) return { decision: "suppress", reason: "subscription_missing" };
106
+ if (!set) return suppress("subscription_missing");
82
107
  const subscription = set.subscriptions.find((item) => item.subscriberId === context.subscriberId);
83
- if (!subscription) return { decision: "suppress", reason: "subscription_missing" };
108
+ if (!subscription) return suppress("subscription_missing");
84
109
  if (subscription.destinationGeneration !== context.destinationGeneration) {
85
- return { decision: "suppress", reason: "subscription_stale" };
110
+ return attempt.recovered === true ? { decision: "suppress", reason: "subscription_stale" } : suppress("subscription_stale");
86
111
  }
87
112
  if (!subscription.active || subscription.proofGeneration !== subscription.destinationGeneration) {
88
- return { decision: "suppress", reason: "subscription_inactive" };
113
+ return suppress("subscription_inactive");
89
114
  }
90
115
  if (!subscription.eventTypes.includes(context.eventType) && !(context.futureCallerInvalidation === true && futureCallerInvalidationEventTypes.has(context.eventType) && subscription.includeFutureEventTypes)) {
91
- return { decision: "suppress", reason: "event_not_allowed" };
116
+ return suppress("event_not_allowed");
92
117
  }
93
118
  if (context.eventAnchor === "account" && !context.accountId || context.eventAnchor === "caller" && context.accountId !== void 0 || context.scope.kind === "account" && (context.eventAnchor !== "account" || context.scope.accountId !== context.accountId) || context.scope.kind === "caller" && context.eventAnchor === "account" && !subscription.allAuthorizedAccounts) {
94
- return { decision: "suppress", reason: "event_not_allowed" };
119
+ return suppress("event_not_allowed");
95
120
  }
96
121
  let decision;
97
122
  try {
@@ -110,16 +135,17 @@ function createPersistentNotificationRuntime(options) {
110
135
  })
111
136
  );
112
137
  } catch {
113
- return { decision: "suppress", reason: "authorization_error" };
138
+ return suppress("authorization_error");
114
139
  }
115
- if (decision?.authorized !== true) return { decision: "suppress", reason: "authorization_denied" };
140
+ if (decision?.authorized !== true) return suppress("authorization_denied");
116
141
  const authenticationMode = subscription.authentication.mode;
117
142
  if (authenticationMode === "rfc9421") {
143
+ if (!await checkpointAttempt(context)) return suppress("attempt_checkpoint_unavailable");
118
144
  return { decision: "allow", authentication: null };
119
145
  }
120
146
  const bindingId = subscription.authentication.bindingId;
121
147
  if (!bindingId || !options.credentialAdapter) {
122
- return { decision: "suppress", reason: "credential_unavailable" };
148
+ return suppress("credential_unavailable");
123
149
  }
124
150
  try {
125
151
  const authentication = await runAdopterCallback(
@@ -135,11 +161,12 @@ function createPersistentNotificationRuntime(options) {
135
161
  })
136
162
  );
137
163
  if (!resolvedAuthenticationMatches(authenticationMode, authentication)) {
138
- return { decision: "suppress", reason: "credential_unavailable" };
164
+ return suppress("credential_unavailable");
139
165
  }
166
+ if (!await checkpointAttempt(context)) return suppress("attempt_checkpoint_unavailable");
140
167
  return { decision: "allow", authentication };
141
168
  } catch {
142
- return { decision: "suppress", reason: "credential_unavailable" };
169
+ return suppress("credential_unavailable");
143
170
  }
144
171
  };
145
172
  const emitter = options.createEmitter(authorizeWebhookAttempt);
@@ -150,6 +177,8 @@ function createPersistentNotificationRuntime(options) {
150
177
  store: options.store,
151
178
  emitter,
152
179
  authorizeWebhookAttempt,
180
+ hasDeliveryAttemptCheckpoint: options.checkpointDeliveryAttempt !== void 0,
181
+ ...options.checkpointDeliveryAttempt === void 0 ? {} : { deliveryAttemptCheckpoint: options.checkpointDeliveryAttempt },
153
182
  async replace(scope, configs, replaceOptions = {}) {
154
183
  assertScope(scope);
155
184
  assertUniqueSubscribers(configs);
@@ -289,14 +318,15 @@ function createPersistentNotificationRuntime(options) {
289
318
  if (candidateSets.length > maxFanoutCandidates) {
290
319
  throw new Error("Persistent notification fanout exceeded maxFanoutCandidates; no deliveries were attempted");
291
320
  }
292
- const targets = candidateSets.flatMap(
321
+ const resolved = candidateSets.flatMap(
293
322
  (set) => set.subscriptions.filter(
294
323
  (subscription) => subscription.active && subscription.proofGeneration === subscription.destinationGeneration && (subscription.eventTypes.includes(event.notificationType) || futureCallerInvalidation && subscription.includeFutureEventTypes) && (set.scope.kind !== "caller" || event.anchor !== "account" || subscription.allAuthorizedAccounts)
295
324
  ).map((subscription) => ({ set, subscription }))
296
325
  );
297
- if (targets.length > maxFanoutCandidates) {
326
+ if (resolved.length > maxFanoutCandidates) {
298
327
  throw new Error("Persistent notification fanout exceeded maxFanoutCandidates; no deliveries were attempted");
299
328
  }
329
+ const targets = event.freezeRecipients ? await pinResolvedRecipients(resolved, event.freezeRecipients) : resolved;
300
330
  const deliveries = await mapConcurrent(targets, fanoutConcurrency, async ({ set, subscription }) => {
301
331
  const deliveryId = deliveryIdentity(event.emissionId, set.scope, subscription);
302
332
  const payload = notificationPayload(event, subscription.subscriberId);
@@ -326,10 +356,10 @@ function createPersistentNotificationRuntime(options) {
326
356
  attemptAuthorizationContext: context
327
357
  });
328
358
  return { ...delivery, result };
329
- } catch {
359
+ } catch (error) {
330
360
  return {
331
361
  ...delivery,
332
- failure: { reason: "delivery_runtime_error" }
362
+ failure: isWebhookDeliveryTerminalError(error) ? { reason: "delivery_binding_retired", terminal: true } : { reason: "delivery_runtime_error" }
333
363
  };
334
364
  }
335
365
  });
@@ -595,6 +625,60 @@ function assertPayloadField(payload, field, expected) {
595
625
  );
596
626
  }
597
627
  }
628
+ async function pinResolvedRecipients(resolved, freezeRecipients) {
629
+ const frozen = await freezeRecipients(
630
+ resolved.map((target) => ({
631
+ scope: structuredClone(target.set.scope),
632
+ subscriberId: target.subscription.subscriberId,
633
+ destinationGeneration: target.subscription.destinationGeneration
634
+ }))
635
+ );
636
+ if (!Array.isArray(frozen)) {
637
+ throw new TypeError("freezeRecipients must return the durably committed recipient set");
638
+ }
639
+ const committed = new Set(
640
+ frozen.map((recipient) => {
641
+ if (!recipient || typeof recipient.subscriberId !== "string" || typeof recipient.destinationGeneration !== "string" || !recipient.scope) {
642
+ throw new TypeError("freezeRecipients returned a malformed recipient reference");
643
+ }
644
+ return recipientKey(recipient);
645
+ })
646
+ );
647
+ return resolved.filter(
648
+ (target) => committed.has(
649
+ recipientKey({
650
+ scope: target.set.scope,
651
+ subscriberId: target.subscription.subscriberId,
652
+ destinationGeneration: target.subscription.destinationGeneration
653
+ })
654
+ )
655
+ );
656
+ }
657
+ function notificationSuppressionDisposition(reason) {
658
+ switch (reason) {
659
+ case "authorization_error":
660
+ case "credential_unavailable":
661
+ return "retryable";
662
+ case "subscription_stale":
663
+ return "retryable";
664
+ case "attempt_checkpoint_unavailable":
665
+ return "retryable";
666
+ case "subscription_missing":
667
+ case "subscription_inactive":
668
+ case "event_not_allowed":
669
+ case "authorization_denied":
670
+ return "terminal";
671
+ default:
672
+ return "retryable";
673
+ }
674
+ }
675
+ function recipientKey(recipient) {
676
+ return canonicalJsonSha256({
677
+ scope: recipient.scope,
678
+ subscriberId: recipient.subscriberId,
679
+ destinationGeneration: recipient.destinationGeneration
680
+ });
681
+ }
598
682
  function deliveryIdentity(emissionId, scope, subscription) {
599
683
  return `notification_${canonicalJsonSha256({
600
684
  emissionId,
@@ -816,6 +900,7 @@ export {
816
900
  ACCOUNT_NOTIFICATION_TYPES,
817
901
  CALLER_NOTIFICATION_TYPES,
818
902
  createPersistentNotificationRuntime,
903
+ notificationSuppressionDisposition,
819
904
  projectNotificationSubscriptionReadback,
820
905
  validatePersistentNotificationDestination
821
906
  };
@@ -208,6 +208,16 @@ export type NotificationDeliveryAuthorizer = (input: Readonly<NotificationDelive
208
208
  } | {
209
209
  authorized: false;
210
210
  }>;
211
+ /**
212
+ * One resolved delivery target. Together with the event's `emissionId` these
213
+ * three fields are exactly the inputs to the per-subscriber delivery identity,
214
+ * so pinning them pins the idempotency key the subscriber sees.
215
+ */
216
+ export interface NotificationRecipientRef {
217
+ scope: NotificationSubscriptionScope;
218
+ subscriberId: string;
219
+ destinationGeneration: string;
220
+ }
211
221
  export interface NotificationEvent {
212
222
  /** Application-stable identity for this delivery event; reuse on crash retry, rotate on re-emission. */
213
223
  emissionId: string;
@@ -221,7 +231,69 @@ export interface NotificationEvent {
221
231
  /** Required for account-anchored events. */
222
232
  accountId?: string;
223
233
  payload: Record<string, unknown>;
234
+ /**
235
+ * Durably freezes the recipient set before any external send.
236
+ *
237
+ * The runtime resolves its candidates, hands them to this callback, and then
238
+ * delivers to exactly the intersection of those candidates and what the
239
+ * callback returns. An emitter that persists the first resolved set and
240
+ * replays it verbatim therefore keeps every `delivery_id` — and so every
241
+ * subscriber-visible idempotency key — stable across an ambiguous retry: a
242
+ * subscription replaced or revoked after the first send is skipped rather
243
+ * than addressed under a new destination generation, so a replay can never
244
+ * add a second logical delivery of the same notification.
245
+ *
246
+ * Called at most once per `emit`, before the first attempt. It is a
247
+ * durability barrier owned by the emitting subsystem, not an adopter policy
248
+ * hook, so it is deliberately not bounded by `adopterCallbackTimeoutMs`: the
249
+ * runtime cannot safely abandon a write that may still commit. Implementations
250
+ * must enforce their own transaction-level deadline. Throwing aborts the
251
+ * emission before anything is sent.
252
+ */
253
+ freezeRecipients?: (candidates: readonly NotificationRecipientRef[]) => MaybePromise<readonly NotificationRecipientRef[]>;
224
254
  }
255
+ /** Durable record that one recipient is about to receive an external POST. */
256
+ export interface NotificationDeliveryAttemptCheckpointInput {
257
+ scope: Readonly<NotificationSubscriptionScope>;
258
+ eventAnchor: NotificationEventAnchor;
259
+ accountId?: string;
260
+ subscriberId: string;
261
+ destinationGeneration: string;
262
+ eventType: string;
263
+ notificationId: string;
264
+ signal: AbortSignal;
265
+ }
266
+ /**
267
+ * Durably records that a delivery is about to be attempted, awaited on the
268
+ * allow path of live delivery authority immediately before every external POST.
269
+ *
270
+ * It is keyed on the durable attempt context rather than on a per-emission
271
+ * closure precisely so that recovered outbox attempts participate: an emission
272
+ * snapshot cannot carry a function, so a per-emission barrier would be silently
273
+ * skipped by the very path — a restarted outbox worker — where an ambiguous send
274
+ * is most likely.
275
+ *
276
+ * This is what makes a frozen recipient set safely revisable. Suppression fails
277
+ * closed before this point, so a recipient with no checkpoint provably never
278
+ * received a POST and may be replaced; a recipient with one is pinned forever,
279
+ * because a crash after it is an ambiguous send. Rejecting suppresses that
280
+ * delivery as retryable with no external attempt.
281
+ */
282
+ export type NotificationDeliveryAttemptCheckpoint = (input: Readonly<NotificationDeliveryAttemptCheckpointInput>) => MaybePromise<void>;
283
+ /**
284
+ * Whether a live-authority suppression is a deliberate decision not to deliver
285
+ * or an operational failure that says nothing about the subscriber.
286
+ *
287
+ * `terminal` — the subscriber must not receive this event: it is gone, inactive,
288
+ * not subscribed to the type, or the adopter denied it. Settle the emission.
289
+ *
290
+ * `retryable` — the runtime could not establish authority: a store read failed,
291
+ * an authorization or credential callback threw or timed out, or the
292
+ * subscription generation moved while the emission was in flight. Nothing was
293
+ * sent (`attempts: 0`), so the owner must release and retry rather than record
294
+ * the notification as delivered.
295
+ */
296
+ export type NotificationSuppressionDisposition = 'terminal' | 'retryable';
225
297
  export interface NotificationSubscriptionView {
226
298
  subscriber_id: string;
227
299
  url: string;
@@ -264,8 +336,14 @@ export type NotificationFanoutDelivery = NotificationFanoutDeliveryBase & ({
264
336
  failure?: never;
265
337
  } | {
266
338
  result?: never;
339
+ /**
340
+ * `delivery_binding_retired` is terminal: the delivery identity is
341
+ * retired or past its retry horizon and can never succeed. Anything
342
+ * else is an operational failure worth retrying.
343
+ */
267
344
  failure: {
268
- reason: 'delivery_runtime_error';
345
+ reason: 'delivery_runtime_error' | 'delivery_binding_retired';
346
+ terminal?: boolean;
269
347
  };
270
348
  });
271
349
  export interface NotificationFanoutResult {
@@ -279,6 +357,14 @@ export interface PersistentNotificationRuntimeOptions {
279
357
  proofAdapter: NotificationProofAdapter;
280
358
  credentialAdapter?: NotificationCredentialBindingAdapter;
281
359
  authorizeDelivery: NotificationDeliveryAuthorizer;
360
+ /**
361
+ * Durable pre-POST checkpoint. Required by any emission owner that freezes a
362
+ * recipient set and needs to know whether a recipient was ever addressed;
363
+ * `PersistentNotificationRuntime.hasDeliveryAttemptCheckpoint` reports whether
364
+ * it is wired so such an owner can fail closed at startup instead of silently
365
+ * losing the guarantee.
366
+ */
367
+ checkpointDeliveryAttempt?: NotificationDeliveryAttemptCheckpoint;
282
368
  /** Defaults to DNS resolution plus the SDK's strict webhook SSRF policy. */
283
369
  validateDestination?: NotificationDestinationValidator;
284
370
  /** Build the emitter with the supplied mandatory per-attempt authorizer. */
@@ -317,6 +403,23 @@ export interface PersistentNotificationRuntime {
317
403
  readonly store: NotificationSubscriptionStore;
318
404
  readonly emitter: RecoverableWebhookEmitter;
319
405
  readonly authorizeWebhookAttempt: WebhookAttemptAuthorizer;
406
+ /**
407
+ * True when a durable pre-POST attempt checkpoint is wired.
408
+ *
409
+ * Optional so a custom implementation written against an earlier release
410
+ * still satisfies this interface structurally. An emission owner that needs
411
+ * the checkpoint treats an absent flag as "not proven" and fails closed.
412
+ */
413
+ readonly hasDeliveryAttemptCheckpoint?: boolean;
414
+ /**
415
+ * The checkpoint this runtime actually invokes, exposed so an emission owner
416
+ * can verify by identity that its own checkpoint is the one that runs.
417
+ * Declaring the capability is not the same as wiring the right function:
418
+ * two correctly-built checkpoints pointing at different stores each look
419
+ * valid in isolation, and the mismatch only shows up as deliveries that
420
+ * checkpoint nothing.
421
+ */
422
+ readonly deliveryAttemptCheckpoint?: NotificationDeliveryAttemptCheckpoint;
320
423
  replace(scope: Readonly<NotificationSubscriptionScope>, configs: readonly NotificationSubscriptionConfigInput[], options?: {
321
424
  expectedGeneration?: string;
322
425
  dryRun?: boolean;