@adcp/sdk 14.0.0-rc.37 → 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 (622) 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/content-mismatch.d.mts +126 -0
  79. package/dist/lib/reporting/content-mismatch.d.ts +126 -0
  80. package/dist/lib/reporting/content-mismatch.js +90 -0
  81. package/dist/lib/reporting/content-mismatch.mjs +66 -0
  82. package/dist/lib/reporting/evidence.d.mts +1 -0
  83. package/dist/lib/reporting/evidence.d.ts +1 -0
  84. package/dist/lib/reporting/evidence.js +32 -3
  85. package/dist/lib/reporting/evidence.mjs +31 -3
  86. package/dist/lib/reporting/index.d.mts +3 -1
  87. package/dist/lib/reporting/index.d.ts +3 -1
  88. package/dist/lib/reporting/index.js +3 -0
  89. package/dist/lib/reporting/index.mjs +2 -0
  90. package/dist/lib/reporting/ledger/handler.d.mts +51 -1
  91. package/dist/lib/reporting/ledger/handler.d.ts +51 -1
  92. package/dist/lib/reporting/ledger/handler.js +306 -38
  93. package/dist/lib/reporting/ledger/handler.mjs +304 -37
  94. package/dist/lib/reporting/ledger/health.d.mts +12 -0
  95. package/dist/lib/reporting/ledger/health.d.ts +12 -0
  96. package/dist/lib/reporting/ledger/health.js +15 -2
  97. package/dist/lib/reporting/ledger/health.mjs +13 -1
  98. package/dist/lib/reporting/ledger/index.d.mts +3 -0
  99. package/dist/lib/reporting/ledger/index.d.ts +3 -0
  100. package/dist/lib/reporting/ledger/index.js +7 -1
  101. package/dist/lib/reporting/ledger/index.mjs +3 -0
  102. package/dist/lib/reporting/ledger/lifecycle.d.mts +31 -4
  103. package/dist/lib/reporting/ledger/lifecycle.d.ts +31 -4
  104. package/dist/lib/reporting/ledger/lifecycle.js +244 -37
  105. package/dist/lib/reporting/ledger/lifecycle.mjs +244 -37
  106. package/dist/lib/reporting/ledger/managed-postgres.d.mts +231 -0
  107. package/dist/lib/reporting/ledger/managed-postgres.d.ts +231 -0
  108. package/dist/lib/reporting/ledger/managed-postgres.js +1797 -0
  109. package/dist/lib/reporting/ledger/managed-postgres.mjs +1776 -0
  110. package/dist/lib/reporting/ledger/managed.d.mts +355 -0
  111. package/dist/lib/reporting/ledger/managed.d.ts +355 -0
  112. package/dist/lib/reporting/ledger/managed.js +661 -0
  113. package/dist/lib/reporting/ledger/managed.mjs +633 -0
  114. package/dist/lib/reporting/ledger/notification-activity.d.mts +222 -0
  115. package/dist/lib/reporting/ledger/notification-activity.d.ts +222 -0
  116. package/dist/lib/reporting/ledger/notification-activity.js +1139 -0
  117. package/dist/lib/reporting/ledger/notification-activity.mjs +1110 -0
  118. package/dist/lib/reporting/ledger/postgres.d.mts +161 -1
  119. package/dist/lib/reporting/ledger/postgres.d.ts +161 -1
  120. package/dist/lib/reporting/ledger/postgres.js +1153 -21
  121. package/dist/lib/reporting/ledger/postgres.mjs +1152 -21
  122. package/dist/lib/reporting/ledger/producer.d.mts +8 -0
  123. package/dist/lib/reporting/ledger/producer.d.ts +8 -0
  124. package/dist/lib/reporting/ledger/producer.js +146 -52
  125. package/dist/lib/reporting/ledger/producer.mjs +146 -51
  126. package/dist/lib/reporting/ledger/types.d.mts +358 -1
  127. package/dist/lib/reporting/ledger/types.d.ts +358 -1
  128. package/dist/lib/reporting/ledger/types.js +3 -0
  129. package/dist/lib/reporting/ledger/types.mjs +2 -0
  130. package/dist/lib/reporting/reconciliation.d.mts +362 -2
  131. package/dist/lib/reporting/reconciliation.d.ts +362 -2
  132. package/dist/lib/reporting/reconciliation.js +1051 -7
  133. package/dist/lib/reporting/reconciliation.mjs +1053 -7
  134. package/dist/lib/reporting/service/conformance.d.mts +35 -0
  135. package/dist/lib/reporting/service/conformance.d.ts +35 -0
  136. package/dist/lib/reporting/service/conformance.js +89 -0
  137. package/dist/lib/reporting/service/conformance.mjs +68 -0
  138. package/dist/lib/reporting/service/index.d.mts +182 -0
  139. package/dist/lib/reporting/service/index.d.ts +182 -0
  140. package/dist/lib/reporting/service/index.js +793 -0
  141. package/dist/lib/reporting/service/index.mjs +787 -0
  142. package/dist/lib/reporting/source/index.d.mts +2 -1
  143. package/dist/lib/reporting/source/index.d.ts +2 -1
  144. package/dist/lib/reporting/source/index.js +16 -3
  145. package/dist/lib/reporting/source/index.mjs +12 -1
  146. package/dist/lib/reporting/source/inline.d.mts +88 -1
  147. package/dist/lib/reporting/source/inline.d.ts +88 -1
  148. package/dist/lib/reporting/source/inline.js +1161 -163
  149. package/dist/lib/reporting/source/inline.mjs +1166 -163
  150. package/dist/lib/reporting/source/manifest.js +12 -7
  151. package/dist/lib/reporting/source/manifest.mjs +12 -7
  152. package/dist/lib/reporting/source/source.d.mts +26 -0
  153. package/dist/lib/reporting/source/source.d.ts +26 -0
  154. package/dist/lib/reporting/source/source.js +71 -2
  155. package/dist/lib/reporting/source/source.mjs +65 -1
  156. package/dist/lib/schemas/index.d.mts +22 -1
  157. package/dist/lib/schemas/index.d.ts +22 -1
  158. package/dist/lib/schemas/index.js +7 -0
  159. package/dist/lib/schemas/index.mjs +7 -0
  160. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  161. package/dist/lib/server/create-adcp-server.d.mts +18 -0
  162. package/dist/lib/server/create-adcp-server.d.ts +18 -0
  163. package/dist/lib/server/create-adcp-server.js +52 -2
  164. package/dist/lib/server/create-adcp-server.mjs +52 -2
  165. package/dist/lib/server/decisioning/account.d.mts +1 -1
  166. package/dist/lib/server/decisioning/account.d.ts +1 -1
  167. package/dist/lib/server/decisioning/index.d.mts +1 -0
  168. package/dist/lib/server/decisioning/index.d.ts +1 -0
  169. package/dist/lib/server/decisioning/platform.d.mts +3 -0
  170. package/dist/lib/server/decisioning/platform.d.ts +3 -0
  171. package/dist/lib/server/decisioning/runtime/from-platform.js +88 -10
  172. package/dist/lib/server/decisioning/runtime/from-platform.mjs +88 -10
  173. package/dist/lib/server/decisioning/specialisms/reporting.d.mts +38 -0
  174. package/dist/lib/server/decisioning/specialisms/reporting.d.ts +38 -0
  175. package/dist/lib/{types/v3-1-beta/index.js → server/decisioning/specialisms/reporting.js} +2 -8
  176. package/dist/lib/server/decisioning/specialisms/reporting.mjs +0 -0
  177. package/dist/lib/server/index.d.mts +4 -2
  178. package/dist/lib/server/index.d.ts +4 -2
  179. package/dist/lib/server/index.js +5 -0
  180. package/dist/lib/server/index.mjs +4 -0
  181. package/dist/lib/server/media-buy-action-resolver.d.mts +63 -0
  182. package/dist/lib/server/media-buy-action-resolver.d.ts +63 -0
  183. package/dist/lib/server/media-buy-action-resolver.js +297 -0
  184. package/dist/lib/server/media-buy-action-resolver.mjs +285 -0
  185. package/dist/lib/server/media-buy-actions.d.mts +7 -8
  186. package/dist/lib/server/media-buy-actions.d.ts +7 -8
  187. package/dist/lib/server/media-buy-actions.js +57 -14
  188. package/dist/lib/server/media-buy-actions.mjs +63 -14
  189. package/dist/lib/server/notification-subscriptions/index.d.mts +2 -2
  190. package/dist/lib/server/notification-subscriptions/index.d.ts +2 -2
  191. package/dist/lib/server/notification-subscriptions/index.js +2 -0
  192. package/dist/lib/server/notification-subscriptions/index.mjs +2 -0
  193. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.mts +3 -1
  194. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.ts +3 -1
  195. package/dist/lib/server/notification-subscriptions/postgres-runtime.js +1 -0
  196. package/dist/lib/server/notification-subscriptions/postgres-runtime.mjs +1 -0
  197. package/dist/lib/server/notification-subscriptions/runtime.d.mts +12 -1
  198. package/dist/lib/server/notification-subscriptions/runtime.d.ts +12 -1
  199. package/dist/lib/server/notification-subscriptions/runtime.js +102 -16
  200. package/dist/lib/server/notification-subscriptions/runtime.mjs +101 -16
  201. package/dist/lib/server/notification-subscriptions/types.d.mts +104 -1
  202. package/dist/lib/server/notification-subscriptions/types.d.ts +104 -1
  203. package/dist/lib/server/webhook-emitter.d.mts +40 -5
  204. package/dist/lib/server/webhook-emitter.d.ts +40 -5
  205. package/dist/lib/server/webhook-emitter.js +23 -12
  206. package/dist/lib/server/webhook-emitter.mjs +23 -12
  207. package/dist/lib/storage/interfaces.d.mts +14 -2
  208. package/dist/lib/storage/interfaces.d.ts +14 -2
  209. package/dist/lib/testing/compliance/comply.d.mts +9 -3
  210. package/dist/lib/testing/compliance/comply.d.ts +9 -3
  211. package/dist/lib/testing/compliance/comply.js +158 -3
  212. package/dist/lib/testing/compliance/comply.mjs +159 -4
  213. package/dist/lib/testing/compliance/storyboard-tracks.js +7 -5
  214. package/dist/lib/testing/compliance/storyboard-tracks.mjs +7 -5
  215. package/dist/lib/testing/compliance/summary.js +10 -1
  216. package/dist/lib/testing/compliance/summary.mjs +10 -1
  217. package/dist/lib/testing/index.d.mts +1 -1
  218. package/dist/lib/testing/index.d.ts +1 -1
  219. package/dist/lib/testing/index.js +2 -0
  220. package/dist/lib/testing/index.mjs +3 -1
  221. package/dist/lib/testing/storyboard/agent-routing.d.mts +12 -43
  222. package/dist/lib/testing/storyboard/agent-routing.d.ts +12 -43
  223. package/dist/lib/testing/storyboard/agent-routing.js +75 -13
  224. package/dist/lib/testing/storyboard/agent-routing.mjs +70 -12
  225. package/dist/lib/testing/storyboard/index.d.mts +1 -0
  226. package/dist/lib/testing/storyboard/index.d.ts +1 -0
  227. package/dist/lib/testing/storyboard/index.js +3 -0
  228. package/dist/lib/testing/storyboard/index.mjs +2 -0
  229. package/dist/lib/testing/storyboard/junit.d.mts +1 -1
  230. package/dist/lib/testing/storyboard/junit.d.ts +1 -1
  231. package/dist/lib/testing/storyboard/junit.js +21 -2
  232. package/dist/lib/testing/storyboard/junit.mjs +21 -2
  233. package/dist/lib/testing/storyboard/probes.d.mts +130 -0
  234. package/dist/lib/testing/storyboard/probes.d.ts +130 -0
  235. package/dist/lib/testing/storyboard/probes.js +682 -10
  236. package/dist/lib/testing/storyboard/probes.mjs +683 -3
  237. package/dist/lib/testing/storyboard/request-signing/builder.d.mts +16 -5
  238. package/dist/lib/testing/storyboard/request-signing/builder.d.ts +16 -5
  239. package/dist/lib/testing/storyboard/request-signing/grader.d.mts +44 -1
  240. package/dist/lib/testing/storyboard/request-signing/grader.d.ts +44 -1
  241. package/dist/lib/testing/storyboard/request-signing/grader.js +46 -22
  242. package/dist/lib/testing/storyboard/request-signing/grader.mjs +43 -21
  243. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +86 -11
  244. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +86 -11
  245. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +119 -25
  246. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +117 -26
  247. package/dist/lib/testing/storyboard/request-signing/synthesize.js +22 -2
  248. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +22 -2
  249. package/dist/lib/testing/storyboard/runner.d.mts +103 -0
  250. package/dist/lib/testing/storyboard/runner.d.ts +103 -0
  251. package/dist/lib/testing/storyboard/runner.js +1090 -268
  252. package/dist/lib/testing/storyboard/runner.mjs +1096 -261
  253. package/dist/lib/testing/storyboard/seeding.d.mts +4 -1
  254. package/dist/lib/testing/storyboard/seeding.d.ts +4 -1
  255. package/dist/lib/testing/storyboard/seeding.js +55 -24
  256. package/dist/lib/testing/storyboard/seeding.mjs +55 -24
  257. package/dist/lib/testing/storyboard/test-kit.d.mts +37 -3
  258. package/dist/lib/testing/storyboard/test-kit.d.ts +37 -3
  259. package/dist/lib/testing/storyboard/test-kit.js +8 -2
  260. package/dist/lib/testing/storyboard/test-kit.mjs +7 -2
  261. package/dist/lib/testing/storyboard/types.d.mts +132 -10
  262. package/dist/lib/testing/storyboard/types.d.ts +132 -10
  263. package/dist/lib/testing/storyboard/types.js +17 -0
  264. package/dist/lib/testing/storyboard/types.mjs +16 -0
  265. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  266. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  267. package/dist/lib/testing/storyboard/validations.js +16 -0
  268. package/dist/lib/testing/storyboard/validations.mjs +16 -0
  269. package/dist/lib/testing/test-controller.d.mts +1 -1
  270. package/dist/lib/testing/test-controller.d.ts +1 -1
  271. package/dist/lib/types/buy-products.d.ts +71 -6
  272. package/dist/lib/types/control-media-buy.d.ts +25 -11
  273. package/dist/lib/types/core.generated.d.mts +69 -10
  274. package/dist/lib/types/core.generated.d.ts +69 -10
  275. package/dist/lib/types/create-media-buy.d.ts +71 -6
  276. package/dist/lib/types/forward-compat-error-codes.d.mts +7 -6
  277. package/dist/lib/types/forward-compat-error-codes.d.ts +7 -6
  278. package/dist/lib/types/index.d.mts +2 -2
  279. package/dist/lib/types/index.d.ts +2 -2
  280. package/dist/lib/types/schemas.generated.d.ts +8040 -8116
  281. package/dist/lib/types/schemas.generated.js +1074 -309
  282. package/dist/lib/types/schemas.generated.mjs +1068 -309
  283. package/dist/lib/types/tools.generated.d.mts +65 -6
  284. package/dist/lib/types/tools.generated.d.ts +65 -6
  285. package/dist/lib/types/update-media-buy.d.ts +71 -6
  286. package/dist/lib/utils/redact-secrets.d.mts +1 -1
  287. package/dist/lib/utils/redact-secrets.d.ts +1 -1
  288. package/dist/lib/utils/redact-secrets.js +1 -1
  289. package/dist/lib/utils/redact-secrets.mjs +1 -1
  290. package/dist/lib/v2/projection/cache-versions.d.mts +0 -1
  291. package/dist/lib/v2/projection/cache-versions.d.ts +0 -1
  292. package/dist/lib/v2/projection/cache-versions.js +1 -15
  293. package/dist/lib/v2/projection/cache-versions.mjs +1 -14
  294. package/dist/lib/v2/projection/canonical-properties.js +2 -2
  295. package/dist/lib/v2/projection/canonical-properties.mjs +3 -3
  296. package/dist/lib/v2/projection/registry.d.mts +1 -1
  297. package/dist/lib/v2/projection/registry.d.ts +1 -1
  298. package/dist/lib/v2/projection/registry.js +2 -2
  299. package/dist/lib/v2/projection/registry.mjs +3 -3
  300. package/dist/lib/validation/schema-loader.d.mts +9 -1
  301. package/dist/lib/validation/schema-loader.d.ts +9 -1
  302. package/dist/lib/validation/schema-loader.js +65 -8
  303. package/dist/lib/validation/schema-loader.mjs +64 -8
  304. package/dist/lib/version.d.mts +5 -5
  305. package/dist/lib/version.d.ts +5 -5
  306. package/dist/lib/version.js +3 -8
  307. package/dist/lib/version.mjs +3 -8
  308. package/dist/lib/wholesale-feed-sync/index.d.mts +1 -0
  309. package/dist/lib/wholesale-feed-sync/index.d.ts +1 -0
  310. package/dist/lib/wholesale-feed-sync/protocol-types.d.mts +42 -0
  311. package/dist/lib/wholesale-feed-sync/protocol-types.d.ts +42 -0
  312. package/dist/lib/wholesale-feed-sync/protocol-types.js +16 -0
  313. package/dist/lib/wholesale-feed-sync/protocol-types.mjs +0 -0
  314. package/dist/lib/wholesale-feed-sync/sync.d.mts +6 -6
  315. package/dist/lib/wholesale-feed-sync/sync.d.ts +6 -6
  316. package/dist/lib/wholesale-feed-sync/sync.js +3 -1
  317. package/dist/lib/wholesale-feed-sync/sync.mjs +3 -1
  318. package/dist/lib/wholesale-feed-sync/types.d.mts +15 -14
  319. package/dist/lib/wholesale-feed-sync/types.d.ts +15 -14
  320. package/dist/lib/wholesale-feed-sync/webhook-notification.d.mts +7 -5
  321. package/dist/lib/wholesale-feed-sync/webhook-notification.d.ts +7 -5
  322. package/dist/lib/wholesale-feed-sync/webhook-notification.js +45 -0
  323. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +44 -0
  324. package/docs/CLI.md +1 -1
  325. package/docs/TYPE-SUMMARY.md +118 -4
  326. package/docs/guides/ASYNC-API-REFERENCE.md +62 -1
  327. package/docs/guides/ASYNC-DEVELOPER-GUIDE.md +25 -0
  328. package/docs/guides/ASYNC-DOCUMENTATION-INDEX.md +3 -0
  329. package/docs/guides/BUYER-QUICKSTART-3.2.md +5 -0
  330. package/docs/guides/DURABLE-BUYER-WRITES.md +337 -0
  331. package/docs/guides/EXISTING-PLATFORM.md +80 -1
  332. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +57 -0
  333. package/docs/guides/MEDIA-BUY-ACTION-ASSESSMENT.md +300 -0
  334. package/docs/guides/REPORTING-LEDGER.md +654 -3
  335. package/docs/guides/REPORTING-RECONCILIATION.md +50 -0
  336. package/docs/guides/REPORTING-SOURCE-EXECUTOR.md +63 -1
  337. package/docs/guides/SELLER-QUICKSTART-3.2.md +2 -0
  338. package/docs/guides/VALIDATE-YOUR-AGENT.md +35 -0
  339. package/docs/guides/idempotency-crash-recovery.md +4 -0
  340. package/docs/llms.txt +4 -2
  341. package/docs/migration-14.x-rc-worksheet.md +60 -5
  342. package/docs/migration-7.9-to-7.10.md +7 -5
  343. package/examples/README.md +17 -0
  344. package/examples/durable-buyer-writes/caller.ts +745 -0
  345. package/examples/durable-buyer-writes/worker.ts +240 -0
  346. package/examples/reliable-reporting-service/README.md +100 -0
  347. package/examples/seller-3.2-starter.ts +7 -8
  348. package/examples/targeting-input-existing-platform.ts +153 -0
  349. package/package.json +41 -29
  350. package/skills/build-seller-agent/SKILL.md +2 -0
  351. package/skills/build-seller-agent/specialisms/signed-requests.md +11 -1
  352. package/skills/cross-cutting.md +28 -11
  353. package/compliance/cache/3.1.0-beta.7/domains/brand/index.yaml +0 -160
  354. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  355. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/single_side_trust_extension.yaml +0 -454
  356. package/compliance/cache/3.1.0-beta.7/domains/creative/index.yaml +0 -339
  357. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/billing_out_of_band.yaml +0 -153
  358. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  359. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/native_in_feed.yaml +0 -543
  360. package/compliance/cache/3.1.0-beta.7/domains/governance/index.yaml +0 -682
  361. package/compliance/cache/3.1.0-beta.7/domains/media-buy/index.yaml +0 -781
  362. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  363. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/available_actions.yaml +0 -565
  364. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  365. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/canonical_formats.yaml +0 -711
  366. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  367. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  368. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  369. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  370. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_reception.yaml +0 -247
  371. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/delivery_reporting.yaml +0 -357
  372. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment.yaml +0 -633
  373. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  374. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  375. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  376. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_approved.yaml +0 -214
  377. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_conditions.yaml +0 -199
  378. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied.yaml +0 -204
  379. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  380. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/invalid_transitions.yaml +0 -289
  381. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  382. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  383. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_accountability.yaml +0 -244
  384. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  385. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  386. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  387. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  388. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  389. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  390. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize.yaml +0 -399
  391. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  392. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  393. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  394. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  395. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  396. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  397. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  398. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_products.yaml +0 -148
  399. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  400. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  401. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  402. package/compliance/cache/3.1.0-beta.7/domains/media-buy/state-machine.yaml +0 -442
  403. package/compliance/cache/3.1.0-beta.7/domains/signals/index.yaml +0 -266
  404. package/compliance/cache/3.1.0-beta.7/domains/sponsored-intelligence/index.yaml +0 -256
  405. package/compliance/cache/3.1.0-beta.7/index.json +0 -356
  406. package/compliance/cache/3.1.0-beta.7/protocols/brand/index.yaml +0 -160
  407. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  408. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/single_side_trust_extension.yaml +0 -454
  409. package/compliance/cache/3.1.0-beta.7/protocols/creative/index.yaml +0 -339
  410. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/billing_out_of_band.yaml +0 -153
  411. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  412. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/native_in_feed.yaml +0 -543
  413. package/compliance/cache/3.1.0-beta.7/protocols/governance/index.yaml +0 -682
  414. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/index.yaml +0 -781
  415. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  416. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/available_actions.yaml +0 -565
  417. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  418. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/canonical_formats.yaml +0 -711
  419. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  420. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  421. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  422. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  423. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_reception.yaml +0 -247
  424. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/delivery_reporting.yaml +0 -357
  425. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment.yaml +0 -633
  426. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  427. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  428. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  429. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_approved.yaml +0 -214
  430. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_conditions.yaml +0 -199
  431. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied.yaml +0 -204
  432. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  433. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/invalid_transitions.yaml +0 -289
  434. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  435. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  436. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_accountability.yaml +0 -244
  437. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  438. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  439. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  440. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  441. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  442. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  443. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize.yaml +0 -399
  444. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  445. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  446. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  447. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  448. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  449. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  450. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  451. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_products.yaml +0 -148
  452. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  453. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  454. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  455. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/state-machine.yaml +0 -442
  456. package/compliance/cache/3.1.0-beta.7/protocols/signals/index.yaml +0 -266
  457. package/compliance/cache/3.1.0-beta.7/protocols/sponsored-intelligence/index.yaml +0 -256
  458. package/compliance/cache/3.1.0-beta.7/specialisms/audience-sync/index.yaml +0 -313
  459. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/index.yaml +0 -350
  460. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/scenarios/governance_denied.yaml +0 -226
  461. package/compliance/cache/3.1.0-beta.7/specialisms/collection-lists/index.yaml +0 -359
  462. package/compliance/cache/3.1.0-beta.7/specialisms/content-standards/index.yaml +0 -572
  463. package/compliance/cache/3.1.0-beta.7/specialisms/creative-ad-server/index.yaml +0 -409
  464. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/generative-seller.yaml +0 -807
  465. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/index.yaml +0 -758
  466. package/compliance/cache/3.1.0-beta.7/specialisms/creative-template/index.yaml +0 -510
  467. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/index.yaml +0 -143
  468. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +0 -117
  469. package/compliance/cache/3.1.0-beta.7/specialisms/governance-delivery-monitor/index.yaml +0 -441
  470. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/denied.yaml +0 -221
  471. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/index.yaml +0 -330
  472. package/compliance/cache/3.1.0-beta.7/specialisms/property-lists/index.yaml +0 -482
  473. package/compliance/cache/3.1.0-beta.7/specialisms/sales-broadcast-tv/index.yaml +0 -738
  474. package/compliance/cache/3.1.0-beta.7/specialisms/sales-catalog-driven/index.yaml +0 -840
  475. package/compliance/cache/3.1.0-beta.7/specialisms/sales-guaranteed/index.yaml +0 -601
  476. package/compliance/cache/3.1.0-beta.7/specialisms/sales-non-guaranteed/index.yaml +0 -546
  477. package/compliance/cache/3.1.0-beta.7/specialisms/sales-proposal-mode/index.yaml +0 -586
  478. package/compliance/cache/3.1.0-beta.7/specialisms/sales-social/index.yaml +0 -919
  479. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/index.yaml +0 -424
  480. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/scenarios/governance_denied.yaml +0 -211
  481. package/compliance/cache/3.1.0-beta.7/specialisms/signal-owned/index.yaml +0 -317
  482. package/compliance/cache/3.1.0-beta.7/specialisms/sponsored-intelligence/index.yaml +0 -59
  483. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor-live.yaml +0 -78
  484. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor.yaml +0 -223
  485. package/compliance/cache/3.1.0-beta.7/test-kits/billing-gate-runner.yaml +0 -115
  486. package/compliance/cache/3.1.0-beta.7/test-kits/bistro-oranje.yaml +0 -126
  487. package/compliance/cache/3.1.0-beta.7/test-kits/distributed-brand-runner.yaml +0 -281
  488. package/compliance/cache/3.1.0-beta.7/test-kits/nova-motors.yaml +0 -262
  489. package/compliance/cache/3.1.0-beta.7/test-kits/osei-natural.yaml +0 -126
  490. package/compliance/cache/3.1.0-beta.7/test-kits/parallel-dispatch-runner.yaml +0 -196
  491. package/compliance/cache/3.1.0-beta.7/test-kits/rate-limit-trip-runner.yaml +0 -172
  492. package/compliance/cache/3.1.0-beta.7/test-kits/signed-requests-runner.yaml +0 -155
  493. package/compliance/cache/3.1.0-beta.7/test-kits/single-side-trust-runner.yaml +0 -294
  494. package/compliance/cache/3.1.0-beta.7/test-kits/substitution-observer-runner.yaml +0 -688
  495. package/compliance/cache/3.1.0-beta.7/test-kits/summit-foods.yaml +0 -125
  496. package/compliance/cache/3.1.0-beta.7/test-kits/webhook-receiver-runner.yaml +0 -265
  497. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/001-minimal-plan.json +0 -43
  498. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/002-full-plan.json +0 -217
  499. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/003-bookkeeping-stripped.json +0 -60
  500. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004a-human-review-omitted.json +0 -43
  501. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004b-human-review-explicit-null.json +0 -49
  502. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005a-policy-categories-order-1.json +0 -53
  503. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005b-policy-categories-order-2.json +0 -57
  504. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006a-ext-trace-v1.json +0 -49
  505. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006b-ext-trace-v2.json +0 -53
  506. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/007-unicode-objectives.json +0 -43
  507. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/008-numeric-canonicalization.json +0 -65
  508. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/README.md +0 -220
  509. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/canonicalization.json +0 -241
  510. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/keys.json +0 -60
  511. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/001-no-signature-header.json +0 -24
  512. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/002-wrong-tag.json +0 -26
  513. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/003-expired-signature.json +0 -26
  514. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/004-window-too-long.json +0 -26
  515. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/005-alg-not-allowed.json +0 -26
  516. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/006-missing-covered-component.json +0 -26
  517. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/007-missing-content-digest.json +0 -26
  518. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/008-unknown-keyid.json +0 -26
  519. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +0 -27
  520. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/010-content-digest-mismatch.json +0 -33
  521. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/011-malformed-header.json +0 -27
  522. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/012-missing-expires-param.json +0 -26
  523. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/013-expires-le-created.json +0 -27
  524. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/014-missing-nonce-param.json +0 -27
  525. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/015-signature-invalid.json +0 -28
  526. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/016-replayed-nonce.json +0 -35
  527. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/017-key-revoked.json +0 -38
  528. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +0 -28
  529. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/019-signature-without-signature-input.json +0 -26
  530. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/020-rate-abuse.json +0 -34
  531. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +0 -31
  532. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/022-multi-valued-content-type.json +0 -31
  533. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +0 -32
  534. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/024-unquoted-string-param.json +0 -31
  535. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +0 -43
  536. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/026-non-ascii-host.json +0 -31
  537. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +0 -25
  538. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +0 -26
  539. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/001-basic-post.json +0 -30
  540. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/002-post-with-content-digest.json +0 -31
  541. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/003-es256-post.json +0 -30
  542. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/004-multiple-signature-labels.json +0 -26
  543. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/005-default-port-stripped.json +0 -30
  544. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/006-dot-segment-path.json +0 -30
  545. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/007-query-byte-preserved.json +0 -30
  546. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/008-percent-encoded-path.json +0 -30
  547. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +0 -30
  548. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +0 -30
  549. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/011-ipv6-authority.json +0 -30
  550. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +0 -30
  551. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/README.md +0 -211
  552. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/keys.json +0 -61
  553. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/001-wrong-tag.json +0 -26
  554. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/002-expired-signature.json +0 -26
  555. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/003-window-too-long.json +0 -26
  556. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +0 -26
  557. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/005-missing-authority-component.json +0 -26
  558. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/006-missing-content-digest.json +0 -25
  559. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/007-unknown-keyid.json +0 -26
  560. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +0 -26
  561. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +0 -26
  562. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +0 -26
  563. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/011-signature-without-input.json +0 -25
  564. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/012-missing-expires-param.json +0 -26
  565. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/013-expires-le-created.json +0 -26
  566. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +0 -26
  567. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/015-signature-invalid.json +0 -26
  568. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/016-replayed-nonce.json +0 -37
  569. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/017-key-revoked.json +0 -32
  570. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/018-rate-abuse.json +0 -33
  571. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/019-revocation-stale.json +0 -32
  572. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +0 -41
  573. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +0 -26
  574. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/001-basic-post.json +0 -24
  575. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/002-es256-post.json +0 -24
  576. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +0 -24
  577. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/004-default-port-stripped.json +0 -24
  578. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +0 -24
  579. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +0 -24
  580. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +0 -25
  581. package/compliance/cache/3.1.0-beta.7/universal/billing-gate-dispatch.yaml +0 -450
  582. package/compliance/cache/3.1.0-beta.7/universal/canonical-format-validate-input.yaml +0 -640
  583. package/compliance/cache/3.1.0-beta.7/universal/capability-discovery.yaml +0 -125
  584. package/compliance/cache/3.1.0-beta.7/universal/collection-lists-pagination-integrity.yaml +0 -306
  585. package/compliance/cache/3.1.0-beta.7/universal/comply-controller-mode-gate.yaml +0 -141
  586. package/compliance/cache/3.1.0-beta.7/universal/content-standards-pagination-integrity.yaml +0 -326
  587. package/compliance/cache/3.1.0-beta.7/universal/deterministic-testing.yaml +0 -1430
  588. package/compliance/cache/3.1.0-beta.7/universal/error-compliance-signals.yaml +0 -377
  589. package/compliance/cache/3.1.0-beta.7/universal/error-compliance.yaml +0 -528
  590. package/compliance/cache/3.1.0-beta.7/universal/fictional-entities.yaml +0 -307
  591. package/compliance/cache/3.1.0-beta.7/universal/get-media-buys-pagination-integrity.yaml +0 -160
  592. package/compliance/cache/3.1.0-beta.7/universal/get-signals-pagination-integrity.yaml +0 -211
  593. package/compliance/cache/3.1.0-beta.7/universal/idempotency.yaml +0 -861
  594. package/compliance/cache/3.1.0-beta.7/universal/notification-config-event-scope.yaml +0 -119
  595. package/compliance/cache/3.1.0-beta.7/universal/notification-config-lifecycle.yaml +0 -337
  596. package/compliance/cache/3.1.0-beta.7/universal/notification-config-rejections.yaml +0 -107
  597. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-creative-formats.yaml +0 -265
  598. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-list-accounts.yaml +0 -245
  599. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity.yaml +0 -263
  600. package/compliance/cache/3.1.0-beta.7/universal/property-lists-pagination-integrity.yaml +0 -307
  601. package/compliance/cache/3.1.0-beta.7/universal/read-tool-idempotency.yaml +0 -405
  602. package/compliance/cache/3.1.0-beta.7/universal/runner-output-contract.yaml +0 -1266
  603. package/compliance/cache/3.1.0-beta.7/universal/schema-validation-signals.yaml +0 -181
  604. package/compliance/cache/3.1.0-beta.7/universal/schema-validation.yaml +0 -548
  605. package/compliance/cache/3.1.0-beta.7/universal/security.yaml +0 -539
  606. package/compliance/cache/3.1.0-beta.7/universal/signed-requests.yaml +0 -217
  607. package/compliance/cache/3.1.0-beta.7/universal/stale-response-advisory.yaml +0 -295
  608. package/compliance/cache/3.1.0-beta.7/universal/storyboard-schema.yaml +0 -2136
  609. package/compliance/cache/3.1.0-beta.7/universal/v3-envelope-integrity.yaml +0 -117
  610. package/compliance/cache/3.1.0-beta.7/universal/version-negotiation.yaml +0 -130
  611. package/compliance/cache/3.1.0-beta.7/universal/webhook-emission.yaml +0 -411
  612. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-bulk-webhooks.yaml +0 -82
  613. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-product-webhooks.yaml +0 -83
  614. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-products.yaml +0 -151
  615. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signal-webhooks.yaml +0 -83
  616. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signals.yaml +0 -149
  617. package/dist/lib/types/v3-1-beta/index.d.mts +0 -1
  618. package/dist/lib/types/v3-1-beta/index.d.ts +0 -1
  619. package/dist/lib/types/v3-1-beta/index.mjs +0 -1
  620. package/dist/lib/types/v3-1-beta/tools.generated.d.mts +0 -26788
  621. package/dist/lib/types/v3-1-beta/tools.generated.d.ts +0 -26788
  622. /package/dist/lib/{types/v3-1-beta/tools.generated.mjs → media-buy/action-types.mjs} +0 -0
@@ -251,6 +251,11 @@ interface TaskOptions {
251
251
  contextId?: string;
252
252
  /** Enable debug logging for this task */
253
253
  debug?: boolean;
254
+ /** Operation-routed crash recovery for direct A2A mutations */
255
+ durableContinuationRecovery?: {
256
+ /** Stable host authorization scope for the authenticated principal + account */
257
+ ownerScope: string;
258
+ };
254
259
  /** Additional metadata to include */
255
260
  metadata?: Record<string, any>;
256
261
  }
@@ -571,6 +576,11 @@ interface DeferredContinuation<T> {
571
576
  question?: string;
572
577
  /** Resume the task with user input */
573
578
  resume: (input: any) => Promise<TaskResult<T>>;
579
+ /** Host-only route capability; present for opted-in direct mutations */
580
+ recovery?: {
581
+ operationId: string;
582
+ recoveryKey: string;
583
+ };
574
584
  }
575
585
  ```
576
586
 
@@ -878,6 +888,9 @@ interface DeferredTaskState {
878
888
  clientContext?: unknown; // Opaque SDK context; round-trip unchanged
879
889
  settlementOperationId?: string; // Trusted committed-mutation recovery route
880
890
  settlementOperationRouteRequired?: true; // New-format routed record; preserve on every successor
891
+ directContinuationRecovery?: true; // Routed direct pause, not committed settlement
892
+ directContinuationRecoveryKeyDigest?: string; // SHA-256; raw capability is never stored
893
+ directContinuationOwnerBindingDigest?: string; // Authenticated owner/account + trusted seller binding
881
894
  settlementResumeAuthorizationRequired?: boolean; // Owning coordinator must authorize seller-input dispatch
882
895
  settlementServerTaskId?: string; // Durably bound seller work handle
883
896
  settlementPendingTaskId?: string; // Nonterminal seller work retained for restart polling
@@ -919,6 +932,12 @@ interface DeferredTaskStorage extends Storage<DeferredTaskState> {
919
932
  ```
920
933
 
921
934
  `putIfAbsent()` must atomically reject an existing unexpired key.
935
+ Custom adapters MUST round-trip every `DeferredTaskState` field opaquely,
936
+ including fields introduced by newer SDK versions. When A→B moves an
937
+ operation route but retains A as a dispatch fence, later deletion or expiry of
938
+ A MUST clear the route only if it still points at A; it must never delete the
939
+ route that now points at B. Deploy readers that preserve new fields before
940
+ enabling new routed writers in a shared store.
922
941
  For ordinary and marker-absent legacy records, `replaceIfVersion()` is the
923
942
  exclusive seller-dispatch claim: it must replace only the exact generation and
924
943
  keep the key present under the SDK-supplied internal safety TTL. New
@@ -939,7 +958,7 @@ dispatch, the SDK generation-conditionally restores the original state with
939
958
  its remaining human-input TTL.
940
959
 
941
960
  The three settlement-operation methods form a second atomic index over
942
- committed continuations. Initial pause creation writes the opaque token and
961
+ committed continuations and opted-in direct mutation pauses. Initial pause creation writes the opaque token and
943
962
  operation route together. A nested pause writes B and moves the route from the
944
963
  exact dispatch-committed generation A in one transaction while retaining A as
945
964
  a dispatch fence. `getBySettlementOperationId()` returns that exact current
@@ -959,6 +978,48 @@ trusted settlement operation identity. A terminal restart resume is returned
959
978
  only after a reconstructed durable coordinator settles it; without a matching
960
979
  recoverer, the resume fails closed.
961
980
 
981
+ Direct A2A mutations opt in per call with an authenticated owner/account scope:
982
+
983
+ ```typescript
984
+ const paused = await agent.buyProducts(request, undefined, {
985
+ durableContinuationRecovery: {
986
+ ownerScope: `principal:${principalId}/account:${accountId}`,
987
+ },
988
+ });
989
+
990
+ // Persist this pair once in host-only storage. The recovery key is distinct
991
+ // from the human-facing resume token and must never be sent to the seller.
992
+ const route = paused.deferred?.recovery;
993
+ if (!route) throw new Error('Seller did not return a recoverable A2A pause');
994
+
995
+ const recovered = await restartedAgent.recoverDirectPauseContinuation({
996
+ operationId: route.operationId,
997
+ recoveryKey: route.recoveryKey,
998
+ ownerScope: `principal:${principalId}/account:${accountId}`,
999
+ });
1000
+ ```
1001
+
1002
+ The SDK stores only the recovery-key digest, binds it to the supplied stable
1003
+ principal/account owner scope and trusted seller ID/origin, and validates the route
1004
+ store before seller dispatch. Unknown routes, wrong capabilities, owner drift,
1005
+ and seller drift fail without revealing a token. The host must authenticate
1006
+ the caller before constructing `ownerScope`; request fields are not an
1007
+ authentication source. Keep the scope byte-stable for the operation lifetime;
1008
+ do not use a mutable display name, seller-supplied value, seller task ID, or
1009
+ request idempotency key. Custom stores must round-trip all three
1010
+ `directContinuation*` fields and implement the operation-route methods as one
1011
+ linearizable index. Direct routes do not enter committed-settlement recovery,
1012
+ so the existing callback and terminal settlement fences remain unchanged.
1013
+ The operation route covers resumable pause generations. If resume instead
1014
+ reaches `submitted` or a terminal result, persist the returned seller task ID
1015
+ and result through the normal host operation record; terminal uncertainty is
1016
+ reconciled by polling that seller task ID, never by redispatching the mutation.
1017
+ Persist the first returned recovery pair before considering the initial pause
1018
+ restart-safe. After any possible continuation dispatch, an absent pause route
1019
+ does not authorize redispatch.
1020
+
1021
+ ### Committed coordinator checkpoints
1022
+
962
1023
  If seller continuation reaches a terminal result, the SDK replaces the human
963
1024
  input record with an opaque terminal checkpoint using the same independent
964
1025
  safety horizon. Recovery and application completion handlers retry from that
@@ -412,6 +412,31 @@ async function manageTaskLifecycle() {
412
412
  }
413
413
  ```
414
414
 
415
+ For a direct A2A mutation that may pause more than once, opt into an atomic
416
+ operation route and persist the returned host-only capability once:
417
+
418
+ ```typescript
419
+ const paused = await agent.buyProducts(request, undefined, {
420
+ durableContinuationRecovery: {
421
+ ownerScope: `principal:${principalId}/account:${accountId}`,
422
+ },
423
+ });
424
+
425
+ const savedRecovery = paused.deferred?.recovery;
426
+ if (!savedRecovery) throw new Error('Seller did not return a recoverable A2A pause');
427
+ await saveHostOnly(savedRecovery);
428
+
429
+ const current = await restartedAgent.recoverDirectPauseContinuation({
430
+ ...savedRecovery,
431
+ ownerScope: `principal:${principalId}/account:${accountId}`,
432
+ });
433
+ ```
434
+
435
+ `ownerScope` must come from authenticated host context. The recovery key is
436
+ separate from the resume token and must not be placed in approval links or
437
+ sent to the seller. Recovery returns the current nested pause without a seller
438
+ call; its `deferred.resume()` remains generation-fenced.
439
+
415
440
  Durable snapshots redact entire secret-shaped containers and truncate
416
441
  over-depth subtrees. `SingleAgentClient.getProducts()` rejects an authenticated
417
442
  request `property_list` before seller dispatch when durable storage also needs
@@ -4,6 +4,9 @@
4
4
 
5
5
  Complete documentation for the ADCP TypeScript client library's new async execution model introduced in PR #78. This documentation covers migration from old patterns, comprehensive developer guidance, and production-ready implementation strategies.
6
6
 
7
+ Deploying request-scoped callers across multiple processes? Start with
8
+ [Durable buyer writes across processes](./DURABLE-BUYER-WRITES.md).
9
+
7
10
  ## 📚 Documentation Structure
8
11
 
9
12
  ### 1. [Migration Guide](./ASYNC-MIGRATION-GUIDE.md)
@@ -1,8 +1,13 @@
1
1
  # Call a seller with AdCP 3.2
2
2
 
3
+ For product possibility, accepted change rights, and current execution routes, use the [MediaBuy action assessment helpers](./MEDIA-BUY-ACTION-ASSESSMENT.md).
4
+
3
5
  Requires Node.js `^20.19.0 || >=22.12.0`. Install the SDK 14 prerelease
4
6
  and create one client:
5
7
 
8
+ For request-scoped callers whose callback or poll may run on another process,
9
+ use the [durable buyer writes recipe](./DURABLE-BUYER-WRITES.md).
10
+
6
11
  ```bash
7
12
  npm install '@adcp/sdk@^14.0.0-0'
8
13
  ```
@@ -0,0 +1,337 @@
1
+ # Durable buyer writes across processes
2
+
3
+ This recipe preserves one outbound AdCP 3.2 mutation when the HTTP caller,
4
+ callback receiver, poller, and publisher are different processes. It is
5
+ validated against `@adcp/sdk@14.0.0-rc.38` and the SDK's pinned
6
+ `3.2.0-rc.3` protocol bundle. Earlier SDK 14 prereleases are not the supported
7
+ baseline for this recipe.
8
+
9
+ The compiling two-process example is:
10
+
11
+ - [`caller.ts`](../../examples/durable-buyer-writes/caller.ts) — stages an
12
+ immutable `buy_products` request, binds the SDK callback operation to it in
13
+ the registration transaction, and dispatches with a request-scoped client.
14
+ - [`worker.ts`](../../examples/durable-buyer-writes/worker.ts) — reconstructs a
15
+ fresh authorized client for callback verification, polling, A2A continuation
16
+ resume, and host-outbox publication.
17
+
18
+ The example uses PostgreSQL, but the SDK also ships
19
+ `redisWebhookRegistrationStore` and Redis replay/idempotency backends. Do not
20
+ mix volatile and durable implementations in one receiver fleet.
21
+
22
+ ## Four identities, four columns
23
+
24
+ Never substitute one of these values for another:
25
+
26
+ | Identity | Issuer and purpose | Example column |
27
+ | --- | --- | --- |
28
+ | Logical operation ID | Host application; one business intent and its recovery record | `logical_operation_id` |
29
+ | Request `idempotency_key` | Buyer; immutable replay identity for one canonical mutating request | `request_idempotency_key` |
30
+ | Seller `task_id` | Seller; polling handle for accepted asynchronous work | `seller_task_id` |
31
+ | Webhook `idempotency_key` | Seller webhook infrastructure; delivery-key binding for retries of one payload | SDK webhook-dedup backend |
32
+
33
+ The webhook delivery key is an infrastructure-layer convention carried in the
34
+ AdCP webhook envelope, not the original request key. The SDK's client-minted
35
+ `operation_id` is a fifth correlation/routing value: the example stores it as
36
+ `sdk_operation_id` in an insert-only route table and binds every retry attempt
37
+ to the host operation before network dispatch. Late callbacks from an earlier
38
+ attempt therefore remain verifiable and routable.
39
+ An A2A `Task.id`, A2A `contextId`, and a deferred continuation token remain
40
+ separate again.
41
+
42
+ A retry after an uncertain response reloads the stored canonical payload and
43
+ request key. It does not regenerate either. A later A→B→A business sequence is
44
+ three operations with three keys even though the final business state resembles
45
+ the first. A timeout is not evidence that the seller rejected the request and
46
+ is never an automatic reason to rotate the key. Reconcile by the operation's
47
+ natural key before deciding that a new intent exists.
48
+
49
+ ## Production wiring
50
+
51
+ The published example is source rather than a package export, so applications
52
+ normally copy it. Import its migration/readiness functions locally and run
53
+ them from deployment/startup tooling before accepting traffic:
54
+
55
+ ```ts
56
+ import { Pool } from 'pg';
57
+ import { migrateDurableBuyer, probeDurableBuyerStores } from './durable-buyer-writes/caller.js';
58
+
59
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL });
60
+ await migrateDurableBuyer(pool);
61
+ await probeDurableBuyerStores(pool); // startup/readiness, not once per request
62
+ ```
63
+
64
+ Its named tables are deployment-specific:
65
+
66
+ | State | Example namespace/table | Retention |
67
+ | --- | --- | --- |
68
+ | Host operation, natural key, and terminal winner | `buyer_prod_v1` in `buyer_adcp_operations` | Through business reconciliation and audit policy |
69
+ | SDK attempt-to-operation routes | `buyer_adcp_operation_routes` | At least as long as the matching callback registrations |
70
+ | Host publication outbox | `buyer_prod_v1` in `buyer_adcp_publications` | Until published, then through the host's duplicate-proof horizon |
71
+ | Trusted callback registration | `buyer_adcp_webhook_registrations` | At least the seller webhook retry horizon; seven days in the example |
72
+ | RFC 9421 nonce replay fence | `buyer_adcp_webhook_replays` | SDK signature window; sweep only expired rows |
73
+ | Webhook delivery and terminal dedup | `buyer_adcp_webhook_dedup` | At least `max(24h, advertised delivery retry horizon)`; seven days in the example |
74
+ | Deferred continuation | Host `DeferredTaskStorage` | At least the permitted human-input/recovery interval; seven days in the example |
75
+
76
+ Use deployment-unique PostgreSQL table names or Redis prefixes. Run the
77
+ root-exported `cleanupExpiredWebhookRegistrations()` and the
78
+ `@adcp/sdk/signing/server` export `sweepExpiredReplays()` as bounded
79
+ maintenance. Remove an attempt route only after its registration is gone;
80
+ idempotency-backend cleanup is likewise operational maintenance, not a
81
+ correctness prerequisite. The pinned 3.2 schema caps the advertised webhook
82
+ retry horizon at the example's seven-day value. Backend clocks, not process
83
+ clocks, decide expiry.
84
+
85
+ `DeferredTaskStorage` is deliberately an application adapter because paused
86
+ state can contain application-owned projection context. Supply the same atomic
87
+ implementation to every caller and worker. It must implement generation CAS,
88
+ atomic operation routing, encrypted-at-rest storage, expiry, and the full
89
+ contract in [Async API reference](./ASYNC-API-REFERENCE.md#deferredtaskstorage).
90
+ Do not replace it with `MemoryStorage` in a restart-sensitive deployment.
91
+
92
+ ### Stage, then dispatch
93
+
94
+ ```ts
95
+ const ledger = new PostgresOperationLedger(pool);
96
+ await ledger.stage(logicalOperationId, orderId, authorizedSession, {
97
+ account: { account_id: authorizedSession.sellerAccountId },
98
+ brand: { domain: advertiserDomain },
99
+ feed_version: selectedFeedVersion,
100
+ pricing_version: selectedPricingVersion, // when list_products supplied one
101
+ purchases: selectedRealProducts,
102
+ purchase_order_ref: orderId,
103
+ start_time: 'asap',
104
+ end_time: campaignEnd,
105
+ });
106
+
107
+ await dispatchStagedBuy(dependencies, logicalOperationId);
108
+ ```
109
+
110
+ `stage()` commits the logical ID, separately supplied natural key, request key,
111
+ complete canonical payload, seller/account binding, tenant, and principal before
112
+ the SDK call. Mirror the natural key into a seller-supported field such as
113
+ `purchase_order_ref` or namespaced `context` so seller readback can reconcile an
114
+ expired or ambiguous request. During SDK pre-dispatch registration,
115
+ the example's `OperationBoundRegistrationStore` atomically writes the supported
116
+ PostgreSQL registration and binds the new SDK `operation_id` to that row. A
117
+ crash before that transaction returns sends nothing; a crash after it remains
118
+ recoverable by a different process. A retry creates another operation route
119
+ but reuses the original canonical payload and request key. A seller response
120
+ without result data remains `dispatch-uncertain`; malformed result data becomes
121
+ `terminal-result-pending`. Neither can win terminal settlement merely because a
122
+ transport adapter reported `failed`. Treat `staged`, `dispatch-uncertain`, and
123
+ `terminal-result-pending` as reconciliation queues, not terminal outcomes.
124
+ Abort and deadline errors are thrown rather than returned by the SDK; the
125
+ example catches that path, marks the stored row `dispatch-uncertain`, and
126
+ rethrows the original error with its SDK-attached request key intact.
127
+
128
+ The host's `resolveSellerSession()` rechecks current tenant, principal, seller,
129
+ and account authorization and re-derives the request-local bearer. It returns
130
+ `undefined` for an authorization denial and throws for an infrastructure
131
+ failure, so callback workers can return static 404 versus retryable 5xx without
132
+ leaking details. No token is stored in the operation, deferred state, callback
133
+ URL, or `ctx_metadata`.
134
+
135
+ ### Receive on a fresh process
136
+
137
+ Mount a raw-body route matching the configured server-owned template:
138
+
139
+ ```ts
140
+ app.post(
141
+ '/adcp/webhook/:task_type/:agent_id/:operation_id',
142
+ express.raw({ type: 'application/json' }),
143
+ async (req, res, next) => {
144
+ try {
145
+ await receiveTaskWebhook(dependencies, req, res);
146
+ } catch (error) {
147
+ next(error); // static application 500/503 handler; never reflect error.message
148
+ }
149
+ },
150
+ );
151
+ ```
152
+
153
+ `receiveTaskWebhook()` resolves the operation from `(seller,
154
+ operation_id)`, reauthorizes it, constructs a new `AgentClient`, and invokes the
155
+ SDK HTTP helper. The helper reads the shared registration, verifies RFC 9421
156
+ and its replay fence, validates the route/envelope/task identities, and applies
157
+ the shared webhook-dedup claim before the host handler runs. Its public URL is
158
+ constructed from server-owned configuration, never `Host` or forwarding
159
+ headers. Preserve the helper's 2xx/409/429/503 mapping.
160
+ The example rejects seller IDs outside the RFC 3986 unreserved set because the
161
+ SDK substitutes callback macros without percent-encoding them. Missing or
162
+ unauthorized pre-verification routes receive a static 400/404; database or
163
+ readiness failures flow to the application's static error middleware.
164
+
165
+ ### Poll or resume after restart
166
+
167
+ Persist `metadata.serverTaskId`, never `metadata.taskId`, as the seller polling
168
+ handle. When no callback arrives:
169
+
170
+ ```ts
171
+ await recoverByPolling(dependencies, logicalOperationId, AbortSignal.timeout(15_000));
172
+ ```
173
+
174
+ `recoverByPolling()` intentionally uses the public `TaskExecutor` because the
175
+ similarly named `AgentClient.getTaskStatus()` method is internal. Its third
176
+ positional argument is optional transport configuration; the example passes
177
+ `undefined` before the abort signal. A terminal poll without the canonical
178
+ `result` is evidence of status, but not enough to fingerprint or publish the
179
+ business result; keep reconciling until result readback or a callback supplies
180
+ it.
181
+
182
+ For an A2A pause with a verified native continuation, persist the SDK deferred
183
+ token and reconstruct the client with the same `DeferredTaskStorage` before:
184
+
185
+ ```ts
186
+ await resumePendingInput(dependencies, logicalOperationId, approvedInput);
187
+ ```
188
+
189
+ Reauthorization happens immediately before resume. MCP pauses and A2A pauses
190
+ without native `Task.id` plus `contextId` are intentionally nonresumable; the
191
+ status label or seller work ID cannot be promoted into a continuation
192
+ capability. For a committed legacy-purchase compatibility continuation,
193
+ negotiate `MediaBuyLifecycleCoordinator` on the fresh `AgentClient` with the
194
+ same durable continuation store, `principalScope`, and stable non-secret
195
+ `legacyPurchaseSellerSessionScope` before `resumeDeferredTask()`. That installs
196
+ the SDK settlement recoverer; a bare replacement client correctly fails closed.
197
+ For the direct `buy_products` path, the example also takes a leased host
198
+ continuation claim immediately before resume. Terminal callbacks return a
199
+ retryable in-progress response while that claim is live; a callback that wins
200
+ before the claim prevents resume. The example enforces a five-minute minimum
201
+ and renews the claim while the resume call is active. If renewal is lost, it
202
+ refuses to commit that worker's observation and lets callback or polling
203
+ reconciliation choose the terminal winner.
204
+
205
+ Direct A2A mutations can close the nested-pause handoff window with
206
+ `TaskOptions.durableContinuationRecovery`. Supply an `ownerScope` derived from
207
+ the authenticated principal and seller account, then persist the initial
208
+ `result.deferred.recovery` operation ID and host-only recovery key. If a worker
209
+ dies after atomically moving the SDK route from token A to token B but before
210
+ the host observes B, a fresh `AgentClient` calls
211
+ `recoverDirectPauseContinuation({ operationId, recoveryKey, ownerScope })` to
212
+ reconstruct B without seller I/O. The SDK stores only a key digest, also binds
213
+ the route to the supplied owner scope and trusted seller identity, and keeps this
214
+ direct route separate from the legacy compatibility coordinator's committed
215
+ settlement path. A claimed uncertain-dispatch fence fails with an explicit
216
+ "do not redispatch" error. Persist the initial recovery pair before treating
217
+ the first pause as restart-safe. The route ends when continuation leaves a
218
+ resumable pause; a missing route after possible dispatch is never evidence
219
+ that redispatch is safe. Reconcile terminal uncertainty by polling the saved
220
+ seller task ID.
221
+
222
+ ## Terminal settlement and host publication
223
+
224
+ Direct responses, verified callbacks, polls, and continuation results compete
225
+ to update one locked operation row. The first authoritative terminal
226
+ fingerprint wins. An exact duplicate sees the same fingerprint and one existing
227
+ outbox row. A different canonical terminal payload rolls back with a conflict
228
+ and cannot replace the winner. Task-envelope labels that carry the same
229
+ canonical commitment payload intentionally converge; the first observed label
230
+ remains in the operational status column.
231
+
232
+ Only schema-valid terminal seller result payloads are fingerprinted. The
233
+ fingerprint projects immutable commitment identity (`media_buy_id`, `revision`,
234
+ `accepted_proposal`, and `purchase_bindings`) and excludes delivery-only or
235
+ time-varying fields such as `replayed`, `context`, `ext`, `available_actions`,
236
+ `media_buy_status`, `confirmed_at`, and `warnings`, so direct, poll, and
237
+ callback delivery of the same business result converge. The first full
238
+ validated payload remains the publication value. The ledger's `status` column records task-envelope
239
+ status independently from the commitment payload's own `completed`/`failed`
240
+ discriminant. SDK-local transport failures and terminal polls that
241
+ omit `result` remain nonterminal host observations. An incomplete terminal
242
+ callback is rejected with a retryable 503 before the SDK publishes its dedup
243
+ claim, so a corrected retry can still settle the operation.
244
+
245
+ The same database transaction records the terminal winner and inserts the
246
+ publication outbox row. `publishOne()` establishes a leased publication owner
247
+ before calling application code. Because PostgreSQL and an external event bus
248
+ do not share a transaction, the downstream publisher must atomically
249
+ deduplicate `logicalOperationId`. A crash after the external send but before
250
+ the database ACK then causes an idempotent retry, not a duplicate business
251
+ effect. Keep each send below the example's 60-second lease or renew the claim
252
+ effect. Keep each send below the example's 60-second lease; this compact helper
253
+ does not expose publication-lease renewal. If the destination cannot offer that
254
+ contract, publish into a database table consumed transactionally with the
255
+ destination's own state instead.
256
+
257
+ The SDK owns transport/protocol validation, callback authentication, replay
258
+ protection, registration persistence, delivery claims, status normalization,
259
+ and continuation fencing. The host still owns:
260
+
261
+ - authenticated tenant/principal/seller/account resolution and credential
262
+ re-derivation;
263
+ - durable logical-operation, canonical-request, natural-key, and task-handle
264
+ storage;
265
+ - an atomic `DeferredTaskStorage` implementation for restart-safe A2A pauses;
266
+ - terminal winner plus publication-outbox transaction;
267
+ - idempotent downstream publication, leases, monitoring, dead letters, and
268
+ retention/cleanup scheduling;
269
+ - campaign approvals, budgets, per-seller orchestration, and ongoing delivery
270
+ reconciliation.
271
+
272
+ ## Evidence matrix
273
+
274
+ | Boundary | Expected convergence | Existing SDK evidence / host proof |
275
+ | --- | --- | --- |
276
+ | Seller accepts, response is lost | Retry the same canonical payload and request key; reconcile before any new intent | Exact pinned-key transport retry is covered by [`media-buy-lifecycle-coordinator.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/media-buy-lifecycle-coordinator.test.js#L12478); typed replay, conflict, and expiry surfaces are covered by [`idempotency-client.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/idempotency-client.test.js#L114), [line 288](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/idempotency-client.test.js#L288), and [line 307](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/idempotency-client.test.js#L307). The example stages the canonical request value and key first. |
277
+ | Callback before submitted response | Callback winner is retained; later nonterminal response is stale | [`task-executor-pre-dispatch-boundary.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/task-executor-pre-dispatch-boundary.test.js#L351). |
278
+ | Callback reaches another process after caller exit | Fresh receiver reads the shared trusted registration and operation binding | PostgreSQL and Redis reconstruction are covered by [`webhook-registration-durability.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/webhook-registration-durability.test.js#L239) and [line 359](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/webhook-registration-durability.test.js#L359); restarted durable callback settlement is covered by [`task-executor-pre-dispatch-boundary.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/task-executor-pre-dispatch-boundary.test.js#L2096). |
279
+ | Restart after observation, before host publication | Terminal winner and one outbox row commit together; a publisher lease is recoverable | The example's PostgreSQL rollback and expired-lease recovery are exercised in [`durable-buyer-writes.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/examples/durable-buyer-writes.test.js#L91) and [line 128](https://github.com/adcontextprotocol/adcp-client/blob/main/test/examples/durable-buyer-writes.test.js#L128). Downstream idempotency on `logicalOperationId` closes the post-send/pre-ACK window. |
280
+ | Repeated identical terminal observations | Acknowledge without another handler/publication | Host transaction race: [`durable-buyer-writes.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/examples/durable-buyer-writes.test.js#L59). SDK delivery-key and cross-key terminal dedup: [`async-handler-webhook-dedup.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/async-handler-webhook-dedup.test.js#L194) and [`task-executor-pre-dispatch-boundary.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/task-executor-pre-dispatch-boundary.test.js#L2505). |
281
+ | Conflicting terminal observations | Preserve first winner and return conflict | Host winner preservation: [`durable-buyer-writes.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/examples/durable-buyer-writes.test.js#L59). SDK dedup and deferred winner protection: [`async-handler-webhook-dedup.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/async-handler-webhook-dedup.test.js#L288) and [`single-agent-deferred-recovery.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/single-agent-deferred-recovery.test.js#L3006). |
282
+ | Pending input or authorization | A fresh authorized process resumes the persisted current A2A token once; callbacks and the host lease fence competing settlement | SDK generation fencing and restart settlement are covered by [`single-agent-deferred-recovery.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/single-agent-deferred-recovery.test.js#L155), [line 411](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/single-agent-deferred-recovery.test.js#L411), and [line 2136](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/single-agent-deferred-recovery.test.js#L2136). The host reauthorization/lease is in `resumePendingInput()`. Direct A→B route recovery at the store-B/host-observation crash boundary is covered by [`direct-pause-recovery.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/direct-pause-recovery.test.js). |
283
+ | No callback; polling recovery | Poll exact seller `task_id`; callback and poll race to the same terminal winner | Poll-first closure and competing callback fencing: [`task-executor-pre-dispatch-boundary.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/task-executor-pre-dispatch-boundary.test.js#L1104). Restarted pending polling without redispatch: [`single-agent-deferred-recovery.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/lib/single-agent-deferred-recovery.test.js#L2524). |
284
+
285
+ ## Task completion is not delivery completion
286
+
287
+ A completed `buy_products`, `accept_proposal`, or `create_media_buy` task says
288
+ that mutation finished and yields a MediaBuy identity. It does not say the buy
289
+ finished delivering. Move that `media_buy_id` into a separate, durable delivery
290
+ reconciliation loop using `get_media_buys`, `get_media_buy_delivery`, reporting
291
+ materializations, and their own notification receipts. Deleting the task
292
+ operation must never delete the campaign/delivery watch.
293
+
294
+ Task-status push is eligible only after the seller returns `submitted` or
295
+ otherwise creates durable asynchronous work. AdCP 3.2 synchronous terminal
296
+ responses are authoritative inline and must not produce a task-completion
297
+ webhook. The server-side silence contract is tested in
298
+ [`server-decisioning-auto-emit-completion.test.js`](https://github.com/adcontextprotocol/adcp-client/blob/main/test/server-decisioning-auto-emit-completion.test.js#L94).
299
+ `reporting_webhook` is a distinct ongoing-delivery channel and remains in the
300
+ task parameters; it is not a substitute for `push_notification_config`.
301
+
302
+ ## Helper boundaries
303
+
304
+ `attachTaskDeadlineIdempotencyKey` is an internal SDK helper, not a package-root
305
+ API. After the SDK already selected the request key, it copies that key onto a
306
+ pending `TaskTimeoutError` so callers can recover the exact request. It does not
307
+ derive a logical operation ID, canonicalize business intent, persist a request,
308
+ or authorize rotation. Application code should inspect the timeout's exposed
309
+ idempotency-key field and return to its own durable operation row.
310
+
311
+ Media-buy action helpers have a different boundary. `assessMediaBuyAction` and
312
+ the legacy `preflightUpdateMediaBuy` assess whether a proposed update/control
313
+ is legal against accepted terms, current state, and advertised actions. They do
314
+ not prove creative validity, account authorization, product availability,
315
+ budget approval, or final seller acceptance. Product/capability discovery,
316
+ `validate_input` or `sync_creatives({ dry_run: true })`, authenticated account
317
+ resolution, and the actual mutation retain those responsibilities.
318
+ `preflightUpdateMediaBuy` is root-exported; import `assessMediaBuyAction` from
319
+ `@adcp/sdk/media-buy/actions`.
320
+
321
+ ## Adoption checklist
322
+
323
+ - [ ] Pin and test `@adcp/sdk@14.0.0-rc.38` with AdCP `3.2.0-rc.3`; reassess this guide when upgrading either pin.
324
+ - [ ] Apply every current migration helper and the host operation/outbox migration before traffic; configure unique tables/prefixes and readiness probes.
325
+ - [ ] Persist one logical operation, natural key, request key, and canonical request before dispatch; refuse same-operation payload drift.
326
+ - [ ] Keep every SDK attempt route through the matching callback-registration retention window; retries add routes but preserve the request key.
327
+ - [ ] Use one stable seller ID and the same registration, RFC 9421 replay, webhook-dedup, deferred, operation, and publication stores on every replica.
328
+ - [ ] Retain callback/dedup/proof state for at least `max(24h, seller advertised webhook horizon)` and request keys through the seller replay horizon.
329
+ - [ ] Re-resolve tenant, principal, seller credential, and seller account before dispatch, callback handling, polling, and continuation resume.
330
+ - [ ] Capture exact raw callback bytes and build the public URL from trusted configuration; keep the SDK's failure status mapping.
331
+ - [ ] Persist `metadata.serverTaskId` for polling. Never poll with SDK `operation_id`, request key, A2A `Task.id`, or continuation token.
332
+ - [ ] Make terminal settlement first-writer-wins, fingerprint canonical task value, insert the host outbox in the same transaction, and make the downstream consumer idempotent by logical operation ID.
333
+ - [ ] Configure and contract-test a durable `DeferredTaskStorage` before accepting restart-sensitive A2A pauses; never fabricate MCP continuation identity.
334
+ - [ ] For direct A2A mutations, enable `durableContinuationRecovery`, persist the first `deferred.recovery` pair before treating the pause as restart-safe, and recover the current pause route after a crash; a missing route after possible dispatch never authorizes redispatch.
335
+ - [ ] Alert on aged reconciliation rows, unpublished outbox rows, and repeated publisher failures; apply a host-owned retry/dead-letter policy.
336
+ - [ ] Keep MediaBuy/delivery reconciliation alive after create-task completion.
337
+ - [ ] Run `npm run ci:doc-links` and `npm run ci:quick`; the linked focused suites are the acceptance evidence for the SDK-owned boundaries.
@@ -14,6 +14,41 @@ This is the thin integration path for an application that already owns authentic
14
14
 
15
15
  The example accepts an already authenticated request context, rechecks tenant/account authorization before starting a submitted-task poll, calls `list_products`, records the initial mixed-status result in the application's transaction, and records terminal settlement after polling. Its store also implements `WebhookRegistrationStore` and idempotent `recordWebhookSettlement`, so verified callbacks can resolve the persisted operation to its tenant, re-authorize, and save completion after a restart. It imports only from `@adcp/sdk`, uses no private `dist/` path, and does not enable the optional schema subpath.
16
16
 
17
+ ## Migrate targeting adapters without casts
18
+
19
+ AdCP 3.2 mutation targeting is a command shape, while accepted provider state
20
+ and response readback are strict state shapes. The packed, compile-gated
21
+ [`targeting-input-existing-platform.ts`](../../examples/targeting-input-existing-platform.ts)
22
+ example derives its input types from the public `BuyProductsRequest` and
23
+ `ControlMediaBuyRequest` exports and uses only public projection helpers.
24
+
25
+ | Request state | Adapter action | Accepted/readback state |
26
+ | --- | --- | --- |
27
+ | Dimension omitted | Create: preserve the product/provider default. Update: make no provider call and retain stored state. | Existing strict value remains; no command is stored. |
28
+ | Dimension `null` | Verify that the product and provider support clearing, then send the provider's explicit clear/replacement operation. | The dimension is absent. Never echo `null`. |
29
+ | Dimension has a value | Translate and replace the complete provider dimension. | Persist and return the validated value. |
30
+
31
+ Translate the original request into provider set/clear operations first; do not
32
+ drop `null` before the provider executes the clear. On create, start from the
33
+ selected product's strict configured/default targeting and call
34
+ `applyTargetingInput()` so omitted dimensions are materialized, cleared defaults
35
+ are removed, and supplied dimensions replace them. On update, load the prior
36
+ strict state and apply the same helper. Commit only that complete strict result.
37
+ `resolveTargetingInput()` removes request commands but cannot materialize create
38
+ defaults on its own. If the provider succeeds but the local commit fails,
39
+ reconcile through the application's existing transaction or outbox boundary.
40
+ The outer `control_media_buy` handler must also serialize or CAS the whole
41
+ read-provider-save block using the request revision so concurrent patches cannot
42
+ lose an accepted dimension. The example's provider seam assumes exact, atomic
43
+ application: an adapter whose provider normalizes values should return its
44
+ canonical post-mutation readback and persist that instead of the request value.
45
+
46
+ The example deliberately throws `UnsupportedTargetingClearError` before any
47
+ provider call or durable write. Do not cast the request to a strict overlay,
48
+ drop `null` keys before the provider has executed the clear, or persist the
49
+ request object unchanged. Provider adapters should also reject targeting
50
+ dimensions they do not translate instead of silently discarding them.
51
+
17
52
  Configure the callback as an absolute template containing both trusted route macros, for example `https://buyer.example/adcp/webhook/{task_type}/{operation_id}`. Supply a framework adapter that derives the public URL only from server-owned configuration, and mount raw-body parsing on the matching route:
18
53
 
19
54
  ```ts
@@ -37,10 +72,22 @@ The submitted continuation's `waitForCompletion` function is deliberately proces
37
72
  | Client task | `TaskOptions.timeout` is one absolute task deadline; `signal` is caller cancellation | Throws the abort/timeout error | Returns `TaskResult` with `success: false` and structured `adcpError` |
38
73
  | `validateAdAgents` | `signal` spans the whole discovery; `timeoutMs` bounds each fetch | Throws the signal's abort reason and starts no later fallback | Returns `valid: false` with discovery errors |
39
74
  | Submitted wait | `waitForCompletion(interval, signal)` | Stops polling; A2A cancellation is a best-effort protocol courtesy | Returns the latest/terminal `TaskResult` |
40
- | Transport observer | Body preview is bounded to 1 s; async observer flush is bounded to 5 s | Never becomes an unbounded request dependency | Observer rejection is isolated from protocol behavior |
75
+ | Transport observer | Response delivery waits up to 1 s for a cloned body preview; task completion then waits up to 5 s for pending async observers | Never becomes an unbounded request dependency | Observer rejection is isolated from protocol behavior |
41
76
 
42
77
  Do not catch every outcome into a string. Switch on `result.status`; use `result.adcpError` for failed results, and catch thrown cancellation/configuration errors separately. Internal transport retries reuse an idempotency key. A new application intent must receive a new key; after an ambiguous timeout, reconcile by the persisted natural key before deciding to retry.
43
78
 
79
+ Transport diagnostics are bounded, but they remain on the critical path when
80
+ `onTransportActivity` is enabled. The SDK may spend up to
81
+ `BODY_SNIPPET_TIMEOUT_MS` (currently 1 second) capturing a redacted preview from
82
+ a clone before returning the original `Response`, then up to
83
+ `OBSERVER_FLUSH_TIMEOUT_MS` (currently 5 seconds) waiting for observer promises
84
+ before the enclosing task settles. The original response stream remains owned
85
+ by the protocol client, previews stay size-bounded, and SSE bodies are not
86
+ captured. There is no detached-observer or explicit-flush mode. A
87
+ latency-sensitive application should synchronously enqueue each event into its
88
+ own bounded in-memory or durable queue and return promptly; flushing that queue
89
+ is then an application lifecycle concern rather than part of request latency.
90
+
44
91
  ## Reuse scoped capability evidence
45
92
 
46
93
  An application that already performs a bounded seller preflight can prime the specific client instance instead of triggering another probe:
@@ -61,4 +108,36 @@ if (!reused) await agent.getCapabilities({ signal }); // rejected evidence clear
61
108
 
62
109
  The compiling example's `reuseCapabilityEvidence` method contains this flow without an undefined helper. The scope binds evidence to the normalized endpoint, configured AdCP release, and this immutable client's authorization/transport instance; preserve the seller's normalized `capabilities.servedVersion` when the preflight supplies it. Use one client per authorization context. Expired, malformed, endpoint-mismatched, release-mismatched, or differently scoped evidence is refused, clears older cached state, and leaves discovery cold; `refreshCapabilities()` rotates the scope so older snapshots cannot be reinstalled. Include `toolSchemas` when the preflight observed MCP `tools/list`; compatibility projection augments and uses the same tool evidence. A constructor-level scoped fetch refuses priming, and a per-call `trustedFetchFn` bypasses primed state, because either fetch defines a narrower transport scope.
63
110
 
111
+ This is same-instance preflight reuse, not a durable cache identity. The opaque
112
+ `scopeKey` is created per client instance and is intentionally not reconstructable
113
+ from endpoint, credentials, or version. After a process restart, a snapshot
114
+ persisted by the old client is refused by the new client even when its timestamps
115
+ are still fresh. Do not attach the new scope to that old observation. Construct
116
+ the replacement client first, obtain its scope, and either perform a fresh
117
+ tenant-scoped preflight for that scope or let `getCapabilities()` discover cold:
118
+
119
+ ```ts
120
+ const replacement = new AgentClient(
121
+ {
122
+ id: 'seller',
123
+ name: 'Seller',
124
+ agent_uri: sellerUrl,
125
+ protocol: 'mcp',
126
+ auth_token: requestScopedAuthToken,
127
+ },
128
+ clientOptions
129
+ );
130
+ const replacementScope = replacement.getCapabilityEvidenceScope();
131
+ const fresh = await tenantScopedCapabilityPreflight(replacementScope, signal);
132
+
133
+ if (!replacement.primeCapabilities({ ...fresh, scope: replacementScope })) {
134
+ await replacement.getCapabilities({ signal });
135
+ }
136
+ ```
137
+
138
+ An application-owned persisted discovery cache may still accelerate the
139
+ application's own preflight logic, but it cannot currently be installed across
140
+ SDK client instances. Retain a process-local client when same-instance reuse is
141
+ required; otherwise budget for fresh discovery after reconstruction.
142
+
64
143
  For durable webhook and reporting flows, continue with [Push notification configuration](./PUSH-NOTIFICATION-CONFIG.md) and the [Reporting ledger](./REPORTING-LEDGER.md).