@adcp/sdk 15.9.0 → 16.0.0-beta.1

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 (295) hide show
  1. package/bin/adcp-identity.js +74 -0
  2. package/bin/adcp.js +2 -0
  3. package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
  4. package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
  5. package/dist/lib/adapters/keyed-account-backend.js +121 -0
  6. package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
  7. package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
  8. package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
  9. package/dist/lib/adapters/keyed-account-store.js +227 -0
  10. package/dist/lib/adapters/keyed-account-store.mjs +203 -0
  11. package/dist/lib/core/SingleAgentClient.d.mts +16 -2
  12. package/dist/lib/core/SingleAgentClient.d.ts +16 -2
  13. package/dist/lib/core/SingleAgentClient.js +259 -62
  14. package/dist/lib/core/SingleAgentClient.mjs +261 -57
  15. package/dist/lib/core/TaskExecutor.d.mts +6 -0
  16. package/dist/lib/core/TaskExecutor.d.ts +6 -0
  17. package/dist/lib/core/TaskExecutor.js +66 -5
  18. package/dist/lib/core/TaskExecutor.mjs +71 -5
  19. package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
  20. package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
  21. package/dist/lib/core/redis-webhook-registration-store.js +23 -1
  22. package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
  23. package/dist/lib/core/webhook-registration.d.mts +7 -1
  24. package/dist/lib/core/webhook-registration.d.ts +7 -1
  25. package/dist/lib/core/webhook-registration.js +24 -2
  26. package/dist/lib/core/webhook-registration.mjs +23 -2
  27. package/dist/lib/identity-3.3/index.d.mts +10 -0
  28. package/dist/lib/identity-3.3/index.d.ts +10 -0
  29. package/dist/lib/identity-3.3/index.js +75 -0
  30. package/dist/lib/identity-3.3/index.mjs +46 -0
  31. package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
  32. package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
  33. package/dist/lib/identity-3.3/lifecycle.js +267 -0
  34. package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
  35. package/dist/lib/identity-3.3/revocation.d.mts +50 -0
  36. package/dist/lib/identity-3.3/revocation.d.ts +50 -0
  37. package/dist/lib/identity-3.3/revocation.js +238 -0
  38. package/dist/lib/identity-3.3/revocation.mjs +216 -0
  39. package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
  40. package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
  41. package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
  42. package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
  43. package/dist/lib/identity-3.3/server.d.mts +34 -0
  44. package/dist/lib/identity-3.3/server.d.ts +34 -0
  45. package/dist/lib/identity-3.3/server.js +219 -0
  46. package/dist/lib/identity-3.3/server.mjs +194 -0
  47. package/dist/lib/identity-3.3/store.d.mts +24 -0
  48. package/dist/lib/identity-3.3/store.d.ts +24 -0
  49. package/dist/lib/identity-3.3/store.js +191 -0
  50. package/dist/lib/identity-3.3/store.mjs +169 -0
  51. package/dist/lib/identity-3.3/trust.d.mts +94 -0
  52. package/dist/lib/identity-3.3/trust.d.ts +94 -0
  53. package/dist/lib/identity-3.3/trust.js +278 -0
  54. package/dist/lib/identity-3.3/trust.mjs +239 -0
  55. package/dist/lib/identity-3.3/types.d.mts +127 -0
  56. package/dist/lib/identity-3.3/types.d.ts +127 -0
  57. package/dist/lib/identity-3.3/types.js +16 -0
  58. package/dist/lib/identity-3.3/types.mjs +0 -0
  59. package/dist/lib/identity-3.3/validation.d.mts +2 -0
  60. package/dist/lib/identity-3.3/validation.d.ts +2 -0
  61. package/dist/lib/identity-3.3/validation.js +125 -0
  62. package/dist/lib/identity-3.3/validation.mjs +91 -0
  63. package/dist/lib/index.d.mts +1 -1
  64. package/dist/lib/index.d.ts +1 -1
  65. package/dist/lib/reporting/azure/index.d.mts +5 -0
  66. package/dist/lib/reporting/azure/index.d.ts +5 -0
  67. package/dist/lib/reporting/azure/index.js +26 -7
  68. package/dist/lib/reporting/azure/index.mjs +26 -7
  69. package/dist/lib/reporting/bigquery/index.d.mts +80 -25
  70. package/dist/lib/reporting/bigquery/index.d.ts +80 -25
  71. package/dist/lib/reporting/bigquery/index.js +184 -81
  72. package/dist/lib/reporting/bigquery/index.mjs +182 -80
  73. package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
  74. package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
  75. package/dist/lib/reporting/gcs/errors.d.mts +6 -0
  76. package/dist/lib/reporting/gcs/errors.d.ts +6 -0
  77. package/dist/lib/reporting/gcs/fence.d.mts +5 -0
  78. package/dist/lib/reporting/gcs/fence.d.ts +5 -0
  79. package/dist/lib/reporting/gcs/index.d.mts +9 -0
  80. package/dist/lib/reporting/gcs/index.d.ts +9 -0
  81. package/dist/lib/reporting/gcs/reader.d.mts +27 -3
  82. package/dist/lib/reporting/gcs/reader.d.ts +27 -3
  83. package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
  84. package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
  85. package/dist/lib/reporting/gcs/row-provider.js +34 -14
  86. package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
  87. package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
  88. package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
  89. package/dist/lib/reporting/ledger/index.d.mts +11 -0
  90. package/dist/lib/reporting/ledger/index.d.ts +11 -0
  91. package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
  92. package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
  93. package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
  94. package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
  95. package/dist/lib/reporting/ledger/managed.d.mts +86 -6
  96. package/dist/lib/reporting/ledger/managed.d.ts +86 -6
  97. package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
  98. package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
  99. package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
  100. package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
  101. package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
  102. package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
  103. package/dist/lib/reporting/ledger/postgres.js +43 -27
  104. package/dist/lib/reporting/ledger/postgres.mjs +43 -27
  105. package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
  106. package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
  107. package/dist/lib/reporting/ledger/row-encoding.js +8 -4
  108. package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
  109. package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
  110. package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
  111. package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
  112. package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
  113. package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
  114. package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
  115. package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
  116. package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
  117. package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
  118. package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
  119. package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
  120. package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
  121. package/dist/lib/reporting/ledger/row-storage.js +126 -66
  122. package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
  123. package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
  124. package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
  125. package/dist/lib/reporting/ledger/schedule.js +24 -0
  126. package/dist/lib/reporting/ledger/schedule.mjs +23 -0
  127. package/dist/lib/reporting/ledger/types.d.mts +23 -1
  128. package/dist/lib/reporting/ledger/types.d.ts +23 -1
  129. package/dist/lib/reporting/s3/index.d.mts +5 -0
  130. package/dist/lib/reporting/s3/index.d.ts +5 -0
  131. package/dist/lib/reporting/s3/index.js +37 -14
  132. package/dist/lib/reporting/s3/index.mjs +37 -14
  133. package/dist/lib/reporting/service/index.d.mts +10 -0
  134. package/dist/lib/reporting/service/index.d.ts +10 -0
  135. package/dist/lib/reporting/service/maintenance.d.mts +28 -2
  136. package/dist/lib/reporting/service/maintenance.d.ts +28 -2
  137. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  138. package/dist/lib/server/account-sync-contract.d.mts +14 -0
  139. package/dist/lib/server/account-sync-contract.d.ts +14 -0
  140. package/dist/lib/server/account-sync-contract.js +225 -0
  141. package/dist/lib/server/account-sync-contract.mjs +197 -0
  142. package/dist/lib/server/adcp-server.js +5 -0
  143. package/dist/lib/server/adcp-server.mjs +10 -0
  144. package/dist/lib/server/auth-signature.d.mts +10 -0
  145. package/dist/lib/server/auth-signature.d.ts +10 -0
  146. package/dist/lib/server/auth-signature.js +61 -2
  147. package/dist/lib/server/auth-signature.mjs +65 -2
  148. package/dist/lib/server/auth.d.mts +6 -0
  149. package/dist/lib/server/auth.d.ts +6 -0
  150. package/dist/lib/server/auth.js +6 -0
  151. package/dist/lib/server/auth.mjs +6 -0
  152. package/dist/lib/server/create-adcp-server.d.mts +19 -5
  153. package/dist/lib/server/create-adcp-server.d.ts +19 -5
  154. package/dist/lib/server/create-adcp-server.js +238 -19
  155. package/dist/lib/server/create-adcp-server.mjs +240 -10
  156. package/dist/lib/server/decisioning/account.d.mts +24 -1
  157. package/dist/lib/server/decisioning/account.d.ts +24 -1
  158. package/dist/lib/server/decisioning/index.d.mts +1 -1
  159. package/dist/lib/server/decisioning/index.d.ts +1 -1
  160. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
  161. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
  162. package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
  163. package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
  164. package/dist/lib/server/index.d.mts +2 -0
  165. package/dist/lib/server/index.d.ts +2 -0
  166. package/dist/lib/server/index.js +12 -0
  167. package/dist/lib/server/index.mjs +12 -0
  168. package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
  169. package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
  170. package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
  171. package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
  172. package/dist/lib/server/principal/types.d.mts +1 -1
  173. package/dist/lib/server/principal/types.d.ts +1 -1
  174. package/dist/lib/server/serve.js +5 -0
  175. package/dist/lib/server/serve.mjs +5 -0
  176. package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
  177. package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
  178. package/dist/lib/server/webhook-delivery/recovery.js +4 -0
  179. package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
  180. package/dist/lib/server/webhook-emitter.d.mts +10 -0
  181. package/dist/lib/server/webhook-emitter.d.ts +10 -0
  182. package/dist/lib/server/webhook-emitter.js +22 -0
  183. package/dist/lib/server/webhook-emitter.mjs +22 -0
  184. package/dist/lib/signing/agent-context.d.mts +0 -5
  185. package/dist/lib/signing/agent-context.d.ts +0 -5
  186. package/dist/lib/signing/agent-context.js +9 -1
  187. package/dist/lib/signing/agent-context.mjs +9 -1
  188. package/dist/lib/signing/agent-fetch.js +27 -2
  189. package/dist/lib/signing/agent-fetch.mjs +32 -2
  190. package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
  191. package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
  192. package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
  193. package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
  194. package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
  195. package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
  196. package/dist/lib/signing/agent-resolver/index.js +5 -0
  197. package/dist/lib/signing/agent-resolver/index.mjs +3 -0
  198. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
  199. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
  200. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
  201. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
  202. package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
  203. package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
  204. package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
  205. package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
  206. package/dist/lib/signing/brand-jwks.d.mts +2 -2
  207. package/dist/lib/signing/brand-jwks.d.ts +2 -2
  208. package/dist/lib/signing/brand-jwks.js +4 -4
  209. package/dist/lib/signing/brand-jwks.mjs +4 -4
  210. package/dist/lib/signing/client.d.mts +1 -0
  211. package/dist/lib/signing/client.d.ts +1 -0
  212. package/dist/lib/signing/client.js +5 -0
  213. package/dist/lib/signing/client.mjs +3 -0
  214. package/dist/lib/signing/jwks-https.d.mts +1 -1
  215. package/dist/lib/signing/jwks-https.d.ts +1 -1
  216. package/dist/lib/signing/jwks-https.js +1 -1
  217. package/dist/lib/signing/jwks-https.mjs +1 -1
  218. package/dist/lib/signing/jwks.d.mts +11 -3
  219. package/dist/lib/signing/jwks.d.ts +11 -3
  220. package/dist/lib/signing/jwks.js +1 -1
  221. package/dist/lib/signing/jwks.mjs +1 -1
  222. package/dist/lib/signing/parser.d.mts +1 -1
  223. package/dist/lib/signing/parser.d.ts +1 -1
  224. package/dist/lib/signing/parser.js +5 -3
  225. package/dist/lib/signing/parser.mjs +6 -4
  226. package/dist/lib/signing/revocation.d.mts +4 -1
  227. package/dist/lib/signing/revocation.d.ts +4 -1
  228. package/dist/lib/signing/revocation.js +33 -3
  229. package/dist/lib/signing/revocation.mjs +31 -2
  230. package/dist/lib/signing/server.d.mts +1 -1
  231. package/dist/lib/signing/server.d.ts +1 -1
  232. package/dist/lib/signing/server.js +4 -0
  233. package/dist/lib/signing/server.mjs +4 -0
  234. package/dist/lib/signing/types.d.mts +3 -0
  235. package/dist/lib/signing/types.d.ts +3 -0
  236. package/dist/lib/signing/web-bot-auth.d.mts +117 -0
  237. package/dist/lib/signing/web-bot-auth.d.ts +117 -0
  238. package/dist/lib/signing/web-bot-auth.js +660 -0
  239. package/dist/lib/signing/web-bot-auth.mjs +624 -0
  240. package/dist/lib/testing/client.d.mts +1 -4
  241. package/dist/lib/testing/client.d.ts +1 -4
  242. package/dist/lib/testing/client.js +141 -20
  243. package/dist/lib/testing/client.mjs +137 -19
  244. package/dist/lib/testing/compliance/comply.js +29 -10
  245. package/dist/lib/testing/compliance/comply.mjs +37 -11
  246. package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
  247. package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
  248. package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
  249. package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
  250. package/dist/lib/testing/storyboard/default-invariants.js +2 -0
  251. package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
  252. package/dist/lib/testing/storyboard/runner.js +23 -8
  253. package/dist/lib/testing/storyboard/runner.mjs +24 -8
  254. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  255. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  256. package/dist/lib/types/adcp.d.mts +4 -0
  257. package/dist/lib/types/adcp.d.ts +4 -0
  258. package/dist/lib/types/schemas.generated.d.ts +6 -6
  259. package/dist/lib/utils/capabilities.d.mts +1 -0
  260. package/dist/lib/utils/capabilities.d.ts +1 -0
  261. package/dist/lib/utils/capabilities.js +5 -0
  262. package/dist/lib/utils/capabilities.mjs +5 -0
  263. package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
  264. package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
  265. package/dist/lib/v2/projection/creative-delivery.js +26 -10
  266. package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
  267. package/dist/lib/v2/projection/index.d.mts +1 -1
  268. package/dist/lib/v2/projection/index.d.ts +1 -1
  269. package/dist/lib/v2/projection/legacy-routes.d.mts +24 -2
  270. package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
  271. package/dist/lib/v2/projection/legacy-routes.js +28 -2
  272. package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
  273. package/dist/lib/validation/schema-loader.d.mts +2 -0
  274. package/dist/lib/validation/schema-loader.d.ts +2 -0
  275. package/dist/lib/validation/schema-loader.js +43 -4
  276. package/dist/lib/validation/schema-loader.mjs +39 -3
  277. package/dist/lib/version.d.mts +3 -3
  278. package/dist/lib/version.d.ts +3 -3
  279. package/dist/lib/version.js +3 -3
  280. package/dist/lib/version.mjs +3 -3
  281. package/docs/TYPE-SUMMARY.md +2 -2
  282. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
  283. package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
  284. package/docs/guides/REPORTING-LEDGER.md +132 -46
  285. package/docs/guides/REPORTING-OPERATIONS.md +25 -4
  286. package/docs/guides/REPORTING-STABILITY.md +76 -0
  287. package/docs/guides/account-resolution.md +101 -0
  288. package/docs/llms.txt +3 -2
  289. package/docs/migration-12-to-13.md +7 -0
  290. package/docs/migration-14.x-rc-worksheet.md +4 -4
  291. package/docs/migration-agent-identity-3.3.md +355 -0
  292. package/docs/migration-agent-resolution-3.3.md +5 -0
  293. package/docs/migration-reporting-row-storage-alignment.md +137 -0
  294. package/examples/storyboards/account-sync-contract.yaml +57 -0
  295. package/package.json +15 -1
@@ -38,6 +38,9 @@ __export(TaskExecutor_exports, {
38
38
  transferDeferredSettlementAcknowledgement: () => transferDeferredSettlementAcknowledgement
39
39
  });
40
40
  module.exports = __toCommonJS(TaskExecutor_exports);
41
+ var import_webhook_registration = require('./webhook-registration.js');
42
+ var import_adcp_version_config = require('../utils/adcp-version-config.js');
43
+ var import_schema_errors = require('../validation/schema-errors.js');
41
44
  var import_crypto = require("crypto");
42
45
  var import_protocols = require('../protocols/index.js');
43
46
  var import_mcp_tasks = require('../protocols/mcp-tasks.js');
@@ -67,6 +70,9 @@ var import_match = require('./match.js');
67
70
  var import_webhook_url = require('./webhook-url.js');
68
71
  var import_task_deadline = require('./task-deadline.js');
69
72
  var import_errors2 = require('../errors/index.js');
73
+ function validateIdentity33Payload(...args) {
74
+ return require('../identity-3.3/validation.js').validateIdentity33Payload(...args);
75
+ }
70
76
  class MaxClarificationError extends Error {
71
77
  constructor(taskId, maxAttempts) {
72
78
  super(`Task ${taskId} exceeded maximum clarification attempts: ${maxAttempts}`);
@@ -191,8 +197,15 @@ function webhookRegistrationFromPreparedCall(_agent, preparedCall) {
191
197
  if (typeof candidate.url !== "string") {
192
198
  throw new import_errors.ConfigurationError("push_notification_config.url must be a string.", "push_notification_config.url");
193
199
  }
200
+ const profile = candidate.signing_profile;
194
201
  if (!Object.prototype.hasOwnProperty.call(candidate, "authentication")) {
195
- return { callbackUrl: candidate.url, mode: "rfc9421" };
202
+ if (profile !== void 0 && !["adcp/webhook-signing/v1", "web-bot-auth"].includes(profile))
203
+ throw new import_errors.ConfigurationError("Unsupported webhook signing profile", "signing_profile");
204
+ return {
205
+ callbackUrl: candidate.url,
206
+ mode: "rfc9421",
207
+ ...profile !== void 0 && { signingProfile: profile }
208
+ };
196
209
  }
197
210
  const authentication = candidate.authentication;
198
211
  if (!authentication || typeof authentication !== "object" || Array.isArray(authentication)) {
@@ -670,6 +683,15 @@ class TaskExecutor {
670
683
  * Throws in strict, logs to `debugLogs` in warn, no-ops in off.
671
684
  */
672
685
  validateRequest(taskName, params, debugLogs) {
686
+ if (this.config.experimentalIdentity33?.() && this.requestValidationMode !== "off") {
687
+ const outcome = validateIdentity33Payload(taskName, "request", params, this.config.adcpVersion);
688
+ if (!outcome.valid) {
689
+ if (this.requestValidationMode === "strict") throw (0, import_schema_errors.buildValidationError)(taskName, "request", outcome.issues);
690
+ if (debugLogs)
691
+ this.logDebug(debugLogs, "warning", `Request validation failed for ${taskName}`, { issues: outcome.issues });
692
+ }
693
+ return;
694
+ }
673
695
  (0, import_client_hooks.validateOutgoingRequest)(taskName, params, this.requestValidationMode, debugLogs, this.config.adcpVersion);
674
696
  }
675
697
  /**
@@ -861,19 +883,29 @@ class TaskExecutor {
861
883
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
862
884
  });
863
885
  (0, import_abort.throwIfAborted)(options.signal);
886
+ const callbackProfile = this.config.signedIdentity33Webhooks?.() && (webhookUrl || params?.reporting_webhook || params?.artifact_webhook || params?.push_notification_config) ? this.config.webhookSigningProfile?.() : void 0;
887
+ const applyCallbackProfiles = (args) => {
888
+ if (!callbackProfile || options.preserveGovernedPayload) return;
889
+ for (const field of ["push_notification_config", "reporting_webhook", "artifact_webhook"]) {
890
+ const callback = args[field];
891
+ if (callback && typeof callback === "object" && callback.authentication === void 0 && callback.signing_profile === void 0)
892
+ callback.signing_profile = callbackProfile;
893
+ }
894
+ };
864
895
  const governanceMiddleware = this.governanceMiddleware;
865
896
  if (governanceMiddleware) {
866
897
  const modernGovernance = targetCapabilities !== void 0 && (0, import_governance.targetDeclaresGovernanceEnforcement)(targetCapabilities, taskName);
867
898
  const governableParams = modernGovernance ? (0, import_protocols.prepareProtocolToolCall)(agent, params, {
868
899
  toolName: taskName,
869
900
  webhookUrl,
870
- webhookSecret: this.config.webhookSecret,
901
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
871
902
  operationId: taskId,
872
903
  serverVersion: effectiveServerVersion,
873
904
  adcpVersion: this.config.adcpVersion,
874
905
  wireAdcpVersion,
875
906
  versionEnvelope
876
907
  }).args : params;
908
+ if (modernGovernance) applyCallbackProfiles(governableParams);
877
909
  if (await governanceMiddleware.shouldCheck(taskName, governableParams, targetCapabilities)) {
878
910
  const sdkInjectedPushConfig = modernGovernance && webhookUrl !== void 0 && this.config.webhookSecret !== void 0;
879
911
  assertGovernedPayloadHasNoCallbackCredentials(taskName, governableParams, { sdkInjectedPushConfig });
@@ -918,13 +950,42 @@ class TaskExecutor {
918
950
  const preparedCall = (0, import_protocols.prepareProtocolToolCall)(agent, dispatchParams, {
919
951
  toolName: taskName,
920
952
  webhookUrl,
921
- webhookSecret: this.config.webhookSecret,
953
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
922
954
  operationId: taskId,
923
955
  serverVersion: effectiveServerVersion,
924
956
  adcpVersion: this.config.adcpVersion,
925
957
  wireAdcpVersion,
926
958
  versionEnvelope
927
959
  });
960
+ applyCallbackProfiles(preparedCall.args);
961
+ const signingProfile = options.preserveGovernedPayload ? void 0 : callbackProfile;
962
+ if (signingProfile && preparedCall.args.push_notification_config && typeof preparedCall.args.push_notification_config === "object") {
963
+ const registration = preparedCall.args.push_notification_config;
964
+ if (registration.authentication === void 0 && registration.signing_profile === void 0)
965
+ registration.signing_profile = signingProfile;
966
+ }
967
+ if (this.config.signedIdentity33Webhooks?.()) {
968
+ for (const [field, deliveryKind, taskType] of [
969
+ ["reporting_webhook", "reporting", "media_buy_delivery"],
970
+ ["artifact_webhook", "artifact", "artifact_delivery"]
971
+ ]) {
972
+ const delivery = preparedCall.args[field];
973
+ if (!delivery || typeof delivery.url !== "string" || delivery.authentication !== void 0) continue;
974
+ const selected = delivery.signing_profile ?? (options.preserveGovernedPayload ? "adcp/webhook-signing/v1" : callbackProfile);
975
+ if (selected !== "adcp/webhook-signing/v1" && selected !== "web-bot-auth")
976
+ throw new Error("Invalid delivery signing profile");
977
+ if (!options.preserveGovernedPayload) delivery.signing_profile = selected;
978
+ await this.config.onWebhookRegistration?.({
979
+ agent,
980
+ taskType,
981
+ operationId: (0, import_webhook_registration.deliveryWebhookRegistrationId)(deliveryKind, delivery.url),
982
+ callbackUrl: delivery.url,
983
+ mode: "rfc9421",
984
+ signingProfile: selected,
985
+ deliveryKind
986
+ });
987
+ }
988
+ }
928
989
  let webhookRegistrationPersisted = false;
929
990
  if (webhookUrl && this.config.onWebhookRegistration) {
930
991
  const registration = webhookRegistrationFromPreparedCall(agent, preparedCall);
@@ -997,7 +1058,7 @@ class TaskExecutor {
997
1058
  const callOptions = {
998
1059
  debugLogs,
999
1060
  webhookUrl,
1000
- webhookSecret: this.config.webhookSecret,
1061
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
1001
1062
  operationId: taskId,
1002
1063
  serverVersion: effectiveServerVersion,
1003
1064
  session: { contextId: options.contextId, taskId: options.taskId },
@@ -4399,7 +4460,7 @@ class TaskExecutor {
4399
4460
  try {
4400
4461
  const validationVersion = (serverVersion ?? this.lastKnownServerVersion) === "v2" ? "v2.5" : this.responseAdcpVersionForValidation() ?? this.config.adcpVersion ?? import_version.ADCP_VERSION;
4401
4462
  const normalizedResponse = this.normalizeResponseForValidation(response, taskName, validationVersion === "v2.5");
4402
- const outcome = (0, import_client_hooks.validateIncomingResponse)(taskName, normalizedResponse, mode, void 0, validationVersion);
4463
+ const outcome = (this.config.experimentalIdentity33?.() || this.config.identity33SchemaExperiment && normalizedResponse && typeof normalizedResponse === "object" && (0, import_adcp_version_config.isAdcpVersionAtLeast)(normalizedResponse.adcp_version, "3.3")) && mode !== "off" ? validateIdentity33Payload(taskName, "response", normalizedResponse, validationVersion) : (0, import_client_hooks.validateIncomingResponse)(taskName, normalizedResponse, mode, void 0, validationVersion);
4403
4464
  if (outcome.valid) return { valid: true, errors: [] };
4404
4465
  const errorStrings = outcome.issues.map((i) => `${i.pointer}: ${i.message}`);
4405
4466
  if (logViolations) {
@@ -1,3 +1,14 @@
1
+ import { fileURLToPath as __adcpFileURLToPath } from "node:url";
2
+ import { dirname as __adcpDirname } from "node:path";
3
+ import { createRequire as __adcpCreateRequire } from "node:module";
4
+ const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
5
+ const require2 = __adcpCreateRequire(import.meta.url);
6
+ import { deliveryWebhookRegistrationId } from "./webhook-registration.mjs";
7
+ import { isAdcpVersionAtLeast } from "../utils/adcp-version-config.mjs";
8
+ function validateIdentity33Payload(...args) {
9
+ return require2("../identity-3.3/validation").validateIdentity33Payload(...args);
10
+ }
11
+ import { buildValidationError } from "../validation/schema-errors.mjs";
1
12
  import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "crypto";
2
13
  import {
3
14
  ProtocolClient,
@@ -164,8 +175,15 @@ function webhookRegistrationFromPreparedCall(_agent, preparedCall) {
164
175
  if (typeof candidate.url !== "string") {
165
176
  throw new ConfigurationError("push_notification_config.url must be a string.", "push_notification_config.url");
166
177
  }
178
+ const profile = candidate.signing_profile;
167
179
  if (!Object.prototype.hasOwnProperty.call(candidate, "authentication")) {
168
- return { callbackUrl: candidate.url, mode: "rfc9421" };
180
+ if (profile !== void 0 && !["adcp/webhook-signing/v1", "web-bot-auth"].includes(profile))
181
+ throw new ConfigurationError("Unsupported webhook signing profile", "signing_profile");
182
+ return {
183
+ callbackUrl: candidate.url,
184
+ mode: "rfc9421",
185
+ ...profile !== void 0 && { signingProfile: profile }
186
+ };
169
187
  }
170
188
  const authentication = candidate.authentication;
171
189
  if (!authentication || typeof authentication !== "object" || Array.isArray(authentication)) {
@@ -643,6 +661,15 @@ class TaskExecutor {
643
661
  * Throws in strict, logs to `debugLogs` in warn, no-ops in off.
644
662
  */
645
663
  validateRequest(taskName, params, debugLogs) {
664
+ if (this.config.experimentalIdentity33?.() && this.requestValidationMode !== "off") {
665
+ const outcome = validateIdentity33Payload(taskName, "request", params, this.config.adcpVersion);
666
+ if (!outcome.valid) {
667
+ if (this.requestValidationMode === "strict") throw buildValidationError(taskName, "request", outcome.issues);
668
+ if (debugLogs)
669
+ this.logDebug(debugLogs, "warning", `Request validation failed for ${taskName}`, { issues: outcome.issues });
670
+ }
671
+ return;
672
+ }
646
673
  validateOutgoingRequest(taskName, params, this.requestValidationMode, debugLogs, this.config.adcpVersion);
647
674
  }
648
675
  /**
@@ -834,19 +861,29 @@ class TaskExecutor {
834
861
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
835
862
  });
836
863
  throwIfAborted(options.signal);
864
+ const callbackProfile = this.config.signedIdentity33Webhooks?.() && (webhookUrl || params?.reporting_webhook || params?.artifact_webhook || params?.push_notification_config) ? this.config.webhookSigningProfile?.() : void 0;
865
+ const applyCallbackProfiles = (args) => {
866
+ if (!callbackProfile || options.preserveGovernedPayload) return;
867
+ for (const field of ["push_notification_config", "reporting_webhook", "artifact_webhook"]) {
868
+ const callback = args[field];
869
+ if (callback && typeof callback === "object" && callback.authentication === void 0 && callback.signing_profile === void 0)
870
+ callback.signing_profile = callbackProfile;
871
+ }
872
+ };
837
873
  const governanceMiddleware = this.governanceMiddleware;
838
874
  if (governanceMiddleware) {
839
875
  const modernGovernance = targetCapabilities !== void 0 && targetDeclaresGovernanceEnforcement(targetCapabilities, taskName);
840
876
  const governableParams = modernGovernance ? prepareProtocolToolCall(agent, params, {
841
877
  toolName: taskName,
842
878
  webhookUrl,
843
- webhookSecret: this.config.webhookSecret,
879
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
844
880
  operationId: taskId,
845
881
  serverVersion: effectiveServerVersion,
846
882
  adcpVersion: this.config.adcpVersion,
847
883
  wireAdcpVersion,
848
884
  versionEnvelope
849
885
  }).args : params;
886
+ if (modernGovernance) applyCallbackProfiles(governableParams);
850
887
  if (await governanceMiddleware.shouldCheck(taskName, governableParams, targetCapabilities)) {
851
888
  const sdkInjectedPushConfig = modernGovernance && webhookUrl !== void 0 && this.config.webhookSecret !== void 0;
852
889
  assertGovernedPayloadHasNoCallbackCredentials(taskName, governableParams, { sdkInjectedPushConfig });
@@ -891,13 +928,42 @@ class TaskExecutor {
891
928
  const preparedCall = prepareProtocolToolCall(agent, dispatchParams, {
892
929
  toolName: taskName,
893
930
  webhookUrl,
894
- webhookSecret: this.config.webhookSecret,
931
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
895
932
  operationId: taskId,
896
933
  serverVersion: effectiveServerVersion,
897
934
  adcpVersion: this.config.adcpVersion,
898
935
  wireAdcpVersion,
899
936
  versionEnvelope
900
937
  });
938
+ applyCallbackProfiles(preparedCall.args);
939
+ const signingProfile = options.preserveGovernedPayload ? void 0 : callbackProfile;
940
+ if (signingProfile && preparedCall.args.push_notification_config && typeof preparedCall.args.push_notification_config === "object") {
941
+ const registration = preparedCall.args.push_notification_config;
942
+ if (registration.authentication === void 0 && registration.signing_profile === void 0)
943
+ registration.signing_profile = signingProfile;
944
+ }
945
+ if (this.config.signedIdentity33Webhooks?.()) {
946
+ for (const [field, deliveryKind, taskType] of [
947
+ ["reporting_webhook", "reporting", "media_buy_delivery"],
948
+ ["artifact_webhook", "artifact", "artifact_delivery"]
949
+ ]) {
950
+ const delivery = preparedCall.args[field];
951
+ if (!delivery || typeof delivery.url !== "string" || delivery.authentication !== void 0) continue;
952
+ const selected = delivery.signing_profile ?? (options.preserveGovernedPayload ? "adcp/webhook-signing/v1" : callbackProfile);
953
+ if (selected !== "adcp/webhook-signing/v1" && selected !== "web-bot-auth")
954
+ throw new Error("Invalid delivery signing profile");
955
+ if (!options.preserveGovernedPayload) delivery.signing_profile = selected;
956
+ await this.config.onWebhookRegistration?.({
957
+ agent,
958
+ taskType,
959
+ operationId: deliveryWebhookRegistrationId(deliveryKind, delivery.url),
960
+ callbackUrl: delivery.url,
961
+ mode: "rfc9421",
962
+ signingProfile: selected,
963
+ deliveryKind
964
+ });
965
+ }
966
+ }
901
967
  let webhookRegistrationPersisted = false;
902
968
  if (webhookUrl && this.config.onWebhookRegistration) {
903
969
  const registration = webhookRegistrationFromPreparedCall(agent, preparedCall);
@@ -970,7 +1036,7 @@ class TaskExecutor {
970
1036
  const callOptions = {
971
1037
  debugLogs,
972
1038
  webhookUrl,
973
- webhookSecret: this.config.webhookSecret,
1039
+ webhookSecret: this.config.signedIdentity33Webhooks?.() ? void 0 : this.config.webhookSecret,
974
1040
  operationId: taskId,
975
1041
  serverVersion: effectiveServerVersion,
976
1042
  session: { contextId: options.contextId, taskId: options.taskId },
@@ -4372,7 +4438,7 @@ class TaskExecutor {
4372
4438
  try {
4373
4439
  const validationVersion = (serverVersion ?? this.lastKnownServerVersion) === "v2" ? "v2.5" : this.responseAdcpVersionForValidation() ?? this.config.adcpVersion ?? ADCP_VERSION;
4374
4440
  const normalizedResponse = this.normalizeResponseForValidation(response, taskName, validationVersion === "v2.5");
4375
- const outcome = validateIncomingResponse(taskName, normalizedResponse, mode, void 0, validationVersion);
4441
+ const outcome = (this.config.experimentalIdentity33?.() || this.config.identity33SchemaExperiment && normalizedResponse && typeof normalizedResponse === "object" && isAdcpVersionAtLeast(normalizedResponse.adcp_version, "3.3")) && mode !== "off" ? validateIdentity33Payload(taskName, "response", normalizedResponse, validationVersion) : validateIncomingResponse(taskName, normalizedResponse, mode, void 0, validationVersion);
4376
4442
  if (outcome.valid) return { valid: true, errors: [] };
4377
4443
  const errorStrings = outcome.issues.map((i) => `${i.pointer}: ${i.message}`);
4378
4444
  if (logViolations) {
@@ -59,6 +59,8 @@ CREATE TABLE IF NOT EXISTS ${table} (
59
59
  callback_url TEXT NOT NULL,
60
60
  method TEXT NOT NULL,
61
61
  mode TEXT NOT NULL,
62
+ delivery_kind TEXT CHECK (delivery_kind IS NULL OR (mode = 'rfc9421' AND delivery_kind IN ('reporting', 'artifact'))),
63
+ signing_profile TEXT CHECK (signing_profile IS NULL OR (mode = 'rfc9421' AND signing_profile IN ('adcp/webhook-signing/v1', 'web-bot-auth'))),
62
64
  authorization_context_version SMALLINT,
63
65
  delegated_operator_authorization JSONB,
64
66
  preview_mode TEXT,
@@ -80,6 +82,12 @@ CREATE TABLE IF NOT EXISTS ${table} (
80
82
  CONSTRAINT ${tableName}_valid_expiry CHECK (expires_at > created_at)
81
83
  );
82
84
 
85
+ ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS signing_profile TEXT
86
+ CHECK (signing_profile IS NULL OR (mode = 'rfc9421' AND signing_profile IN ('adcp/webhook-signing/v1', 'web-bot-auth')));
87
+
88
+ ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS delivery_kind TEXT
89
+ CHECK (delivery_kind IS NULL OR (mode = 'rfc9421' AND delivery_kind IN ('reporting', 'artifact')));
90
+
83
91
  CREATE INDEX IF NOT EXISTS idx_${tableName}_expires_at
84
92
  ON ${table}(expires_at);
85
93
  `.trim();
@@ -94,6 +102,8 @@ const RETURNING_REGISTRATION = `
94
102
  callback_url,
95
103
  method,
96
104
  mode,
105
+ signing_profile,
106
+ delivery_kind,
97
107
  authorization_context_version,
98
108
  delegated_operator_authorization,
99
109
  preview_mode,
@@ -148,6 +158,8 @@ function registrationFromRow(row, expectedKey) {
148
158
  callbackUrl: requiredString(row, "callback_url"),
149
159
  method: requiredString(row, "method"),
150
160
  mode: requiredString(row, "mode"),
161
+ ...row.signing_profile != null && { signingProfile: optionalString(row, "signing_profile") },
162
+ ...row.delivery_kind != null && { deliveryKind: optionalString(row, "delivery_kind") },
151
163
  ...authorizationContextVersion === 1 && { authorizationContextVersion },
152
164
  ...delegatedOperatorAuthorization !== null && { delegatedOperatorAuthorization },
153
165
  ...previewMode !== void 0 && { previewMode },
@@ -203,18 +215,18 @@ function pgWebhookRegistrationStore(db, options = {}) {
203
215
  INSERT INTO ${table} AS existing (
204
216
  agent_id, operation_id, agent_url, protocol, task_type, callback_url,
205
217
  method, mode, authorization_context_version, delegated_operator_authorization,
206
- preview_mode, requires_durable_settlement, created_at, expires_at
218
+ preview_mode, requires_durable_settlement, created_at, expires_at, signing_profile, delivery_kind
207
219
  )
208
220
  SELECT
209
221
  $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, $11, $12,
210
222
  to_timestamp($13::double precision / 1000.0),
211
- to_timestamp($14::double precision / 1000.0)
223
+ to_timestamp($14::double precision / 1000.0), $15, $16
212
224
  FROM backend_clock
213
225
  WHERE to_timestamp($14::double precision / 1000.0) > backend_clock.now
214
226
  ON CONFLICT (agent_id, operation_id) DO UPDATE SET (
215
227
  agent_url, protocol, task_type, callback_url, method, mode,
216
228
  authorization_context_version, delegated_operator_authorization,
217
- preview_mode, requires_durable_settlement, created_at, expires_at
229
+ preview_mode, requires_durable_settlement, created_at, expires_at, signing_profile, delivery_kind
218
230
  ) = (
219
231
  SELECT
220
232
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.agent_url
@@ -240,7 +252,20 @@ function pgWebhookRegistrationStore(db, options = {}) {
240
252
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.created_at
241
253
  ELSE existing.created_at END,
242
254
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.expires_at
243
- ELSE existing.expires_at END
255
+ WHEN existing.delivery_kind IS NOT NULL AND
256
+ ROW(existing.agent_url, existing.protocol, existing.task_type, existing.callback_url, existing.method, existing.mode,
257
+ existing.authorization_context_version, existing.delegated_operator_authorization, existing.preview_mode,
258
+ COALESCE(existing.signing_profile, 'adcp/webhook-signing/v1'), existing.delivery_kind)
259
+ IS NOT DISTINCT FROM
260
+ ROW(EXCLUDED.agent_url, EXCLUDED.protocol, EXCLUDED.task_type, EXCLUDED.callback_url, EXCLUDED.method, EXCLUDED.mode,
261
+ EXCLUDED.authorization_context_version, EXCLUDED.delegated_operator_authorization, EXCLUDED.preview_mode,
262
+ COALESCE(EXCLUDED.signing_profile, 'adcp/webhook-signing/v1'), EXCLUDED.delivery_kind)
263
+ THEN GREATEST(existing.expires_at, EXCLUDED.expires_at)
264
+ ELSE existing.expires_at END,
265
+ CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.signing_profile
266
+ ELSE existing.signing_profile END,
267
+ CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.delivery_kind
268
+ ELSE existing.delivery_kind END
244
269
  FROM backend_clock
245
270
  )
246
271
  RETURNING ${RETURNING_REGISTRATION},
@@ -259,7 +284,9 @@ function pgWebhookRegistrationStore(db, options = {}) {
259
284
  proposed.previewMode ?? null,
260
285
  proposed.requiresDurableSettlement ?? null,
261
286
  proposed.createdAt,
262
- proposed.expiresAt
287
+ proposed.expiresAt,
288
+ proposed.signingProfile ?? null,
289
+ proposed.deliveryKind ?? null
263
290
  ]
264
291
  );
265
292
  const row = result.rows[0];
@@ -39,6 +39,8 @@ CREATE TABLE IF NOT EXISTS ${table} (
39
39
  callback_url TEXT NOT NULL,
40
40
  method TEXT NOT NULL,
41
41
  mode TEXT NOT NULL,
42
+ delivery_kind TEXT CHECK (delivery_kind IS NULL OR (mode = 'rfc9421' AND delivery_kind IN ('reporting', 'artifact'))),
43
+ signing_profile TEXT CHECK (signing_profile IS NULL OR (mode = 'rfc9421' AND signing_profile IN ('adcp/webhook-signing/v1', 'web-bot-auth'))),
42
44
  authorization_context_version SMALLINT,
43
45
  delegated_operator_authorization JSONB,
44
46
  preview_mode TEXT,
@@ -60,6 +62,12 @@ CREATE TABLE IF NOT EXISTS ${table} (
60
62
  CONSTRAINT ${tableName}_valid_expiry CHECK (expires_at > created_at)
61
63
  );
62
64
 
65
+ ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS signing_profile TEXT
66
+ CHECK (signing_profile IS NULL OR (mode = 'rfc9421' AND signing_profile IN ('adcp/webhook-signing/v1', 'web-bot-auth')));
67
+
68
+ ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS delivery_kind TEXT
69
+ CHECK (delivery_kind IS NULL OR (mode = 'rfc9421' AND delivery_kind IN ('reporting', 'artifact')));
70
+
63
71
  CREATE INDEX IF NOT EXISTS idx_${tableName}_expires_at
64
72
  ON ${table}(expires_at);
65
73
  `.trim();
@@ -74,6 +82,8 @@ const RETURNING_REGISTRATION = `
74
82
  callback_url,
75
83
  method,
76
84
  mode,
85
+ signing_profile,
86
+ delivery_kind,
77
87
  authorization_context_version,
78
88
  delegated_operator_authorization,
79
89
  preview_mode,
@@ -128,6 +138,8 @@ function registrationFromRow(row, expectedKey) {
128
138
  callbackUrl: requiredString(row, "callback_url"),
129
139
  method: requiredString(row, "method"),
130
140
  mode: requiredString(row, "mode"),
141
+ ...row.signing_profile != null && { signingProfile: optionalString(row, "signing_profile") },
142
+ ...row.delivery_kind != null && { deliveryKind: optionalString(row, "delivery_kind") },
131
143
  ...authorizationContextVersion === 1 && { authorizationContextVersion },
132
144
  ...delegatedOperatorAuthorization !== null && { delegatedOperatorAuthorization },
133
145
  ...previewMode !== void 0 && { previewMode },
@@ -183,18 +195,18 @@ function pgWebhookRegistrationStore(db, options = {}) {
183
195
  INSERT INTO ${table} AS existing (
184
196
  agent_id, operation_id, agent_url, protocol, task_type, callback_url,
185
197
  method, mode, authorization_context_version, delegated_operator_authorization,
186
- preview_mode, requires_durable_settlement, created_at, expires_at
198
+ preview_mode, requires_durable_settlement, created_at, expires_at, signing_profile, delivery_kind
187
199
  )
188
200
  SELECT
189
201
  $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, $11, $12,
190
202
  to_timestamp($13::double precision / 1000.0),
191
- to_timestamp($14::double precision / 1000.0)
203
+ to_timestamp($14::double precision / 1000.0), $15, $16
192
204
  FROM backend_clock
193
205
  WHERE to_timestamp($14::double precision / 1000.0) > backend_clock.now
194
206
  ON CONFLICT (agent_id, operation_id) DO UPDATE SET (
195
207
  agent_url, protocol, task_type, callback_url, method, mode,
196
208
  authorization_context_version, delegated_operator_authorization,
197
- preview_mode, requires_durable_settlement, created_at, expires_at
209
+ preview_mode, requires_durable_settlement, created_at, expires_at, signing_profile, delivery_kind
198
210
  ) = (
199
211
  SELECT
200
212
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.agent_url
@@ -220,7 +232,20 @@ function pgWebhookRegistrationStore(db, options = {}) {
220
232
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.created_at
221
233
  ELSE existing.created_at END,
222
234
  CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.expires_at
223
- ELSE existing.expires_at END
235
+ WHEN existing.delivery_kind IS NOT NULL AND
236
+ ROW(existing.agent_url, existing.protocol, existing.task_type, existing.callback_url, existing.method, existing.mode,
237
+ existing.authorization_context_version, existing.delegated_operator_authorization, existing.preview_mode,
238
+ COALESCE(existing.signing_profile, 'adcp/webhook-signing/v1'), existing.delivery_kind)
239
+ IS NOT DISTINCT FROM
240
+ ROW(EXCLUDED.agent_url, EXCLUDED.protocol, EXCLUDED.task_type, EXCLUDED.callback_url, EXCLUDED.method, EXCLUDED.mode,
241
+ EXCLUDED.authorization_context_version, EXCLUDED.delegated_operator_authorization, EXCLUDED.preview_mode,
242
+ COALESCE(EXCLUDED.signing_profile, 'adcp/webhook-signing/v1'), EXCLUDED.delivery_kind)
243
+ THEN GREATEST(existing.expires_at, EXCLUDED.expires_at)
244
+ ELSE existing.expires_at END,
245
+ CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.signing_profile
246
+ ELSE existing.signing_profile END,
247
+ CASE WHEN existing.expires_at <= backend_clock.now THEN EXCLUDED.delivery_kind
248
+ ELSE existing.delivery_kind END
224
249
  FROM backend_clock
225
250
  )
226
251
  RETURNING ${RETURNING_REGISTRATION},
@@ -239,7 +264,9 @@ function pgWebhookRegistrationStore(db, options = {}) {
239
264
  proposed.previewMode ?? null,
240
265
  proposed.requiresDurableSettlement ?? null,
241
266
  proposed.createdAt,
242
- proposed.expiresAt
267
+ proposed.expiresAt,
268
+ proposed.signingProfile ?? null,
269
+ proposed.deliveryKind ?? null
243
270
  ]
244
271
  );
245
272
  const row = result.rows[0];
@@ -77,6 +77,21 @@ if raw then
77
77
  if current_expires_at > now_ms then
78
78
  if redis.call('PTTL', KEYS[1]) < 0 then return cjson.encode({status = 'corrupt'}) end
79
79
  if stored.fingerprint == ARGV[3] then
80
+ if ARGV[6] == 'delivery' and proposed_expires_at > current_expires_at then
81
+ local registration_ok, registration = pcall(cjson.decode, stored.registration)
82
+ if not registration_ok or type(registration) ~= 'table' or not registration.deliveryKind then
83
+ return cjson.encode({status = 'corrupt'})
84
+ end
85
+ if registration.expiresAt ~= current_expires_at then return cjson.encode({status = 'corrupt'}) end
86
+ local replacements
87
+ stored.registration, replacements = string.gsub(stored.registration, '("expiresAt"%s*:%s*)%d+', function(prefix)
88
+ return prefix .. ARGV[4]
89
+ end)
90
+ if replacements ~= 1 then return cjson.encode({status = 'corrupt'}) end
91
+ stored.expiresAt = ARGV[4]
92
+ raw = cjson.encode(stored)
93
+ redis.call('SET', KEYS[1], raw, 'PXAT', ARGV[4])
94
+ end
80
95
  return cjson.encode({status = 'existing', record = raw})
81
96
  end
82
97
  return cjson.encode({status = 'conflict'})
@@ -283,7 +298,14 @@ function redisWebhookRegistrationStore(client, options = {}) {
283
298
  "putIfAbsent",
284
299
  PUT_IF_ABSENT_SCRIPT,
285
300
  [key],
286
- [expectedKey.agentId, expectedKey.operationId, fingerprint, String(proposed.expiresAt), serialized]
301
+ [
302
+ expectedKey.agentId,
303
+ expectedKey.operationId,
304
+ fingerprint,
305
+ String(proposed.expiresAt),
306
+ serialized,
307
+ proposed.deliveryKind ? "delivery" : "operation"
308
+ ]
287
309
  );
288
310
  if (outcome.status === "conflict") {
289
311
  throw new import_errors.ConfigurationError(
@@ -61,6 +61,21 @@ if raw then
61
61
  if current_expires_at > now_ms then
62
62
  if redis.call('PTTL', KEYS[1]) < 0 then return cjson.encode({status = 'corrupt'}) end
63
63
  if stored.fingerprint == ARGV[3] then
64
+ if ARGV[6] == 'delivery' and proposed_expires_at > current_expires_at then
65
+ local registration_ok, registration = pcall(cjson.decode, stored.registration)
66
+ if not registration_ok or type(registration) ~= 'table' or not registration.deliveryKind then
67
+ return cjson.encode({status = 'corrupt'})
68
+ end
69
+ if registration.expiresAt ~= current_expires_at then return cjson.encode({status = 'corrupt'}) end
70
+ local replacements
71
+ stored.registration, replacements = string.gsub(stored.registration, '("expiresAt"%s*:%s*)%d+', function(prefix)
72
+ return prefix .. ARGV[4]
73
+ end)
74
+ if replacements ~= 1 then return cjson.encode({status = 'corrupt'}) end
75
+ stored.expiresAt = ARGV[4]
76
+ raw = cjson.encode(stored)
77
+ redis.call('SET', KEYS[1], raw, 'PXAT', ARGV[4])
78
+ end
64
79
  return cjson.encode({status = 'existing', record = raw})
65
80
  end
66
81
  return cjson.encode({status = 'conflict'})
@@ -267,7 +282,14 @@ function redisWebhookRegistrationStore(client, options = {}) {
267
282
  "putIfAbsent",
268
283
  PUT_IF_ABSENT_SCRIPT,
269
284
  [key],
270
- [expectedKey.agentId, expectedKey.operationId, fingerprint, String(proposed.expiresAt), serialized]
285
+ [
286
+ expectedKey.agentId,
287
+ expectedKey.operationId,
288
+ fingerprint,
289
+ String(proposed.expiresAt),
290
+ serialized,
291
+ proposed.deliveryKind ? "delivery" : "operation"
292
+ ]
271
293
  );
272
294
  if (outcome.status === "conflict") {
273
295
  throw new ConfigurationError(
@@ -16,6 +16,9 @@ export interface WebhookRegistration {
16
16
  callbackUrl: string;
17
17
  method: 'POST';
18
18
  mode: WebhookAuthenticationMode;
19
+ signingProfile?: 'adcp/webhook-signing/v1' | 'web-bot-auth';
20
+ /** Out-of-band reports/artifacts bind to the destination, not a task operation. */
21
+ deliveryKind?: 'reporting' | 'artifact';
19
22
  /** Versioned marker distinguishing tuple-aware registrations from legacy rows. */
20
23
  authorizationContextVersion?: 1;
21
24
  /** Trusted local tuple used to re-authorize delegated seller keys after restart. */
@@ -33,7 +36,8 @@ export interface WebhookRegistrationStore {
33
36
  /** Return no record when `expiresAt` is at or before the current time. */
34
37
  get(agentId: string, operationId: string): Promise<Readonly<WebhookRegistration> | undefined>;
35
38
  /**
36
- * Atomically create a registration. An identical retry is idempotent; a
39
+ * Atomically create a registration. An identical retry is idempotent; matching
40
+ * destination delivery routes also extend expiry to the later value. A
37
41
  * conflicting live registration for the same key MUST reject. A successful
38
42
  * return MUST provide immediate read-your-writes consistency through `get()`
39
43
  * so the SDK can verify trusted authorization provenance before dispatch.
@@ -68,3 +72,5 @@ export declare class InMemoryWebhookRegistrationStore implements WebhookRegistra
68
72
  markRequiresDurableSettlement(agentId: string, operationId: string): Promise<void>;
69
73
  private pruneExpired;
70
74
  }
75
+ /** Stable, non-secret local route key. It is never sent as an authentication credential. */
76
+ export declare function deliveryWebhookRegistrationId(kind: 'reporting' | 'artifact', url: string): string;
@@ -16,6 +16,9 @@ export interface WebhookRegistration {
16
16
  callbackUrl: string;
17
17
  method: 'POST';
18
18
  mode: WebhookAuthenticationMode;
19
+ signingProfile?: 'adcp/webhook-signing/v1' | 'web-bot-auth';
20
+ /** Out-of-band reports/artifacts bind to the destination, not a task operation. */
21
+ deliveryKind?: 'reporting' | 'artifact';
19
22
  /** Versioned marker distinguishing tuple-aware registrations from legacy rows. */
20
23
  authorizationContextVersion?: 1;
21
24
  /** Trusted local tuple used to re-authorize delegated seller keys after restart. */
@@ -33,7 +36,8 @@ export interface WebhookRegistrationStore {
33
36
  /** Return no record when `expiresAt` is at or before the current time. */
34
37
  get(agentId: string, operationId: string): Promise<Readonly<WebhookRegistration> | undefined>;
35
38
  /**
36
- * Atomically create a registration. An identical retry is idempotent; a
39
+ * Atomically create a registration. An identical retry is idempotent; matching
40
+ * destination delivery routes also extend expiry to the later value. A
37
41
  * conflicting live registration for the same key MUST reject. A successful
38
42
  * return MUST provide immediate read-your-writes consistency through `get()`
39
43
  * so the SDK can verify trusted authorization provenance before dispatch.
@@ -68,3 +72,5 @@ export declare class InMemoryWebhookRegistrationStore implements WebhookRegistra
68
72
  markRequiresDurableSettlement(agentId: string, operationId: string): Promise<void>;
69
73
  private pruneExpired;
70
74
  }
75
+ /** Stable, non-secret local route key. It is never sent as an authentication credential. */
76
+ export declare function deliveryWebhookRegistrationId(kind: 'reporting' | 'artifact', url: string): string;