@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
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
- > Generated at: 2026-10-13
4
- > Library: @adcp/sdk v15.9.0
3
+ > Generated at: 2026-10-14
4
+ > Library: @adcp/sdk v16.0.0-beta.1
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
  > Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
@@ -2143,6 +2143,7 @@ These docs are available locally in the repo and hosted at https://adcontextprot
2143
2143
  | Reporting ledger cutover from custom tables | docs/guides/REPORTING-LEDGER-CUTOVER.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-LEDGER-CUTOVER.md) |
2144
2144
  | Buyer reporting reconciliation | docs/guides/REPORTING-RECONCILIATION.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-RECONCILIATION.md) |
2145
2145
  | Reliable Reporting production operations | docs/guides/REPORTING-OPERATIONS.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-OPERATIONS.md) |
2146
+ | Reliable Reporting stability policy (experimental storage subpaths) | docs/guides/REPORTING-STABILITY.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-STABILITY.md) |
2146
2147
  | Validate your agent (5-command checklist) | docs/guides/VALIDATE-YOUR-AGENT.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/VALIDATE-YOUR-AGENT.md) |
2147
2148
  | Async patterns (polling, webhooks, deferred) | docs/guides/ASYNC-DEVELOPER-GUIDE.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/ASYNC-DEVELOPER-GUIDE.md) |
2148
2149
  | Async API reference | docs/guides/ASYNC-API-REFERENCE.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/ASYNC-API-REFERENCE.md) |
@@ -400,6 +400,13 @@ resolve. An `AgentClient` given a resolver rebuilt from these routes applies
400
400
  that rewrite in another process, as it does after its own discovery. Routes
401
401
  without `seller_declared` leave canonical writes unchanged.
402
402
 
403
+ A buyer that stored the seller's raw `get_products` product, and projects it
404
+ again in a process that never ran discovery, can record the same origin by
405
+ passing that stored product: `legacyRoutesForProduct(productId,
406
+ projected.format_options, { sellerProduct: storedProduct })`. An option is then
407
+ seller-declared exactly when the stored product's own `format_options[]` names
408
+ it, which is the rule the SDK applies after its own discovery.
409
+
403
410
  Compatibility consumers that must retain top-level `format_ids[]` while
404
411
  publishing URL-free canonical declarations can use the additive projection:
405
412
 
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
11
11
 
12
12
  | Fact | Value |
13
13
  | --- | --- |
14
- | Exact npm package | `@adcp/sdk@15.9.0` |
15
- | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@15.9.0 dist.integrity` |
14
+ | Exact npm package | `@adcp/sdk@16.0.0-beta.1` |
15
+ | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@16.0.0-beta.1 dist.integrity` |
16
16
  | Node.js runtime | `^20.19.0 || >=22.12.0` |
17
17
  | Default AdCP wire release | `3.2.4` |
18
18
  | Maintained wire releases | `v2.5`, `v2.6`, `v3`, `3.0.0`, `3.0`, `3.0.1`, `3.0.2`, `3.0.3`, `3.0.4`, `3.0.5`, `3.0.6`, `3.0.7`, `3.0.8`, `3.0.9`, `3.0.10`, `3.0.11`, `3.0.12`, `3.0.13`, `3.0.14`, `3.0.15`, `3.0.16`, `3.0.17`, `3.0.18`, `3.0.19`, `3.0.20`, `3.0.21`, `3.0.22`, `3.0.23`, `3.0.24`, `3.0.25`, `3.1.0`, `3.1`, `3.1.1`, `3.1.2`, `3.1.3`, `3.1.4`, `3.1.5`, `3.1.6`, `3.1.7`, `3.1.8`, `3.1.9`, `3.1.10`, `3.1.11`, `3.1.12`, `3.1.13`, `3.1.14`, `3.1.15`, `3.1.16`, `3.1.17`, `3.1.18`, `3.1.19`, `3.1.20`, `3.1.21`, `3.1.22`, `3.1.23`, `3.1.24`, `3.2.1`, `3.2`, `3.2.2`, `3.2.3`, `3.2.4` |
@@ -21,8 +21,8 @@ below as the publication/deployment gate.
21
21
  Install exact production inputs rather than a moving range or dist-tag:
22
22
 
23
23
  ```bash
24
- npm install --save-exact '@adcp/sdk@15.9.0'
25
- npm view '@adcp/sdk@15.9.0' dist.integrity
24
+ npm install --save-exact '@adcp/sdk@16.0.0-beta.1'
25
+ npm view '@adcp/sdk@16.0.0-beta.1' dist.integrity
26
26
  ```
27
27
 
28
28
  ### Required and optional peers
@@ -0,0 +1,355 @@
1
+ # Experimental AdCP 3.3 agent identity
2
+
3
+ The experimental identity rollout is tracked in
4
+ [adcp-client#3233](https://github.com/adcontextprotocol/adcp-client/issues/3233).
5
+ This release implements the rollout behind explicit experimental configuration.
6
+ The SDK's default `ADCP_VERSION` remains **3.2.4**. Experimental client/server
7
+ instances select the 3.3 carrier and apply the pinned draft overlays to the
8
+ released bundle; they do not regenerate or replace the public 3.2 types.
9
+ Upstream PRs remain open, so the experiment can change before graduation.
10
+
11
+ The dedicated API is `@adcp/sdk/identity-3.3`. Existing RFC configuration remains
12
+ supported through 3.x and emits a one-time deprecation warning when used.
13
+
14
+ ## Canonical agent origins
15
+
16
+ ```ts
17
+ import { canonicalAgentOrigin } from '@adcp/sdk/signing/client';
18
+
19
+ const origin = canonicalAgentOrigin('HTTPS://User@Buyer.Example.COM.:443/mcp?x=1');
20
+ // https://buyer.example.com
21
+ ```
22
+
23
+ The helper is also exported from `@adcp/sdk/signing/server` and
24
+ `@adcp/sdk/signing`. It reuses the existing authority canonicalization rules:
25
+ scheme and host case normalization, one trailing DNS root dot removed,
26
+ userinfo and default ports stripped, and non-default ports preserved. Path,
27
+ query, and fragment do not participate in origin comparison. Malformed
28
+ authorities, raw authority backslashes or control characters, and IPv6 zone
29
+ identifiers are rejected. Producer inputs with IDN
30
+ U-labels normalize to Punycode A-labels. Wire comparers must separately reject
31
+ raw non-ASCII hostnames before comparing, as the existing `canonicalAgentUrl`
32
+ helper does.
33
+
34
+ The existing `canonicalizeOrigin` / `originsEqual` primitives and
35
+ `identity.key_origins` comparisons use this same authority validation. A
36
+ single trailing DNS root dot now compares equal to its dotless form;
37
+ malformed authorities that the URL parser previously repaired are rejected.
38
+ `CanonicalizeError` is exported from the same signing entry points. Origin
39
+ errors use fixed messages and redact the input in `meta.input`, including
40
+ userinfo, path, and query values.
41
+
42
+ Origin normalization does not verify a signature or grant authority. Continue
43
+ to use full canonical agent URLs for existing RFC 9421 identities, governance
44
+ JWS issuers, and path-mounted agents. The WBA profile permits one agent
45
+ per origin; origin equality alone must not merge existing principals.
46
+
47
+ ## Resolver request context
48
+
49
+ Both `JwksResolver.resolve(keyid, signerOrigin?)` and the optional
50
+ `resolveWithMetadata(keyid, signerOrigin?)` accept an origin locator. Existing
51
+ one-argument implementations and calls remain compatible. Static and HTTPS
52
+ resolvers remain pinned to their configured keys or URL; the additional
53
+ argument does not turn them into identity-discovery resolvers.
54
+
55
+ `ResolvedAgentJwksResolver` checks a supplied origin against the origin of its
56
+ configured agent URL before discovery or cached-key access. A mismatch or
57
+ malformed locator is rejected with `request_signature_key_unknown`; raw
58
+ non-ASCII context hostnames are rejected before origin comparison. Matching
59
+ origins retain the full capability-confirmed `agentUrl` in discovery metadata.
60
+ Percent-encoded context hostnames are also rejected so escaped U-labels
61
+ cannot bypass wire validation; percent escapes in stripped userinfo remain
62
+ accepted. Producer origin normalization retains its existing behavior.
63
+ `BrandJsonJwksResolver` forwards the context through both lookup methods,
64
+ including after legacy onboarding has selected and pinned an agent URL.
65
+ When legacy brand configuration omits `agentUrl`, initial onboarding must
66
+ complete the configured operator, capability, and JWKS discovery chain to
67
+ confirm and pin an agent URL before it compares origin context. Subsequent
68
+ lookups check the pinned origin before fetching keys. The
69
+ context never changes the onboarding fetch target.
70
+
71
+ Custom wrappers must forward both the argument and discovery metadata:
72
+
73
+ ```ts
74
+ import type { JwksResolver } from '@adcp/sdk/signing/server';
75
+
76
+ function wrapResolver(inner: JwksResolver): JwksResolver {
77
+ return {
78
+ resolve: (keyid, signerOrigin) => inner.resolve(keyid, signerOrigin),
79
+ ...(inner.resolveWithMetadata && {
80
+ resolveWithMetadata: (keyid: string, signerOrigin?: string) =>
81
+ inner.resolveWithMetadata!(keyid, signerOrigin),
82
+ }),
83
+ };
84
+ }
85
+ ```
86
+
87
+ Origin-aware caches and concurrent-lookup coalescing must use
88
+ `(canonicalAgentOrigin(signerOrigin), keyid)` as their key. A shared `kid`
89
+ must never select another origin's key or metadata. Keep context-free lookups
90
+ separate. Use a structured key, such as nested maps or `JSON.stringify([origin, keyid])`,
91
+ to prevent delimiter collisions. Treat the origin as an unverified locator until signature
92
+ verification succeeds. Validate request-derived locators against the wire
93
+ rules before forming a cache key; producer normalization alone does not
94
+ reject raw IDN U-labels. On request verification, metadata remains necessary
95
+ to reject webhook-only fallback keys and expired operator delegations.
96
+
97
+ ## Buyer signing and webhook registration
98
+
99
+ ```ts
100
+ import { SingleAgentClient } from '@adcp/sdk';
101
+ import { jwkThumbprint } from '@adcp/sdk/identity-3.3';
102
+
103
+ const client = new SingleAgentClient({
104
+ ...seller,
105
+ request_signing: {
106
+ profile: 'web-bot-auth',
107
+ agent_url: 'https://buyer.example.com',
108
+ kid: jwkThumbprint(privateJwk),
109
+ alg: 'ed25519',
110
+ private_key: privateJwk,
111
+ },
112
+ }, {
113
+ experimentalIdentity33: true,
114
+ webhookSigningProfile: 'web-bot-auth',
115
+ webhookVerification: {
116
+ webBotAuth: { directory, isRevoked: (origin, kid) => revocations.isRevoked(origin, kid) },
117
+ },
118
+ });
119
+ ```
120
+
121
+ The official MCP/A2A transports receive the SDK's signed fetch wrapper. The
122
+ seller must advertise `request_signing.profiles` containing `web-bot-auth`.
123
+ Provider configurations additionally supply `public_key`; the provider's
124
+ thumbprint kid and algorithm must match that public key. The wrapper signs the
125
+ final UTF-8 body, covers the selected `Signature-Agent` member and digest,
126
+ uses a fresh nonce, and refuses automatic HTTP redirects. `signWebBotAuth`
127
+ also supports `relay: true` with a new label; the verifier validates every
128
+ layer regardless of dictionary ordering.
129
+
130
+ `SignatureDirectoryResolver` derives the directory from the covered canonical
131
+ origin. It validates a possession signature for every key and the exact body
132
+ digest before caching keys. Its audit proof retains the signed body and
133
+ headers. Verification requires this resolver so context-free JWKS adapters cannot
134
+ attribute a key to an arbitrary origin. Discovery uses HTTPS, DNS pinning, no redirects, a 256 KiB cap, a
135
+ 5-second connect bound and 10-second total bound, at most 64 keys, and bounded
136
+ single-flight/negative caches. Successful refresh replaces the key set;
137
+ failed refresh cannot prove removal, and never extends possession-proof
138
+ expiry. Published vector keys are rejected in production.
139
+
140
+ Publish an origin revocation list even when no keys are revoked. For example:
141
+
142
+ ```sh
143
+ adcp identity revocations --origin https://buyer.example.com --keys private-jwks.json --output revocations.jws
144
+ ```
145
+
146
+ Serve the exact JWS at `/.well-known/governance-revocations.json` and refresh it
147
+ before `next_update` (the command defaults to five minutes). Pass `--snapshot`
148
+ to sign a list of revoked key thumbprints and optional reasons/dates.
149
+ `createSignedOriginRevocationList` provides the same authoring API. The SDK
150
+ supports Ed25519 and P-256 identity keys. Observed key revocations are permanent;
151
+ refresh failures use the last verified list only within the published grace
152
+ window. First-contact identity reads may proceed when no list is available;
153
+ mutating operations fail closed without a current or grace-valid signed list.
154
+
155
+ For positively negotiated 3.3 sellers advertising signed webhooks, experimental
156
+ clients omit injected reporting/task webhook HMAC authentication even when a
157
+ client secret exists. Explicit caller authentication preserves the legacy
158
+ choice. Older, unknown-version, and unsigned-webhook sellers preserve existing
159
+ behavior. `update_media_buy` and artifact registrations are validated with the
160
+ same negotiated draft rules. The selected asymmetric profile is persisted in
161
+ the trusted callback registration and survives Redis/Postgres storage and
162
+ restart. An incoming header cannot change that selection. Reporting routes
163
+ use the configured registration lifetime; keep it long enough for delivery.
164
+ Sellers must persist `reporting_webhook.signing_profile` with their media-buy
165
+ record and pass it to later `emitWebhook` calls; the request context forwards
166
+ it automatically only for deliveries emitted during that request.
167
+
168
+ WBA webhook verification pins the signer to the registered seller origin.
169
+ Registrations requiring legacy delegated-operator resolution or publisher JWS
170
+ pins must select the RFC webhook profile; the SDK rejects that combination
171
+ under WBA. Configure a shared replay store across replicas.
172
+
173
+ ## Seller authorization and durable state
174
+
175
+ Signature verification establishes an origin, never a principal or spend
176
+ permission. Trust evaluation runs at binding, grants, and open onboarding,
177
+ never during cryptographic verification. Wire `signedRequests.webBotAuth` (or
178
+ `verifySignatureAsAuthenticator.webBotAuth`) with a signed directory,
179
+ origin-revocation resolver, and `createIdentity33PrincipalResolver`.
180
+
181
+ ```ts
182
+ import {
183
+ createIdentity33StateStores, TrustEvaluator, OriginIdentityLifecycle,
184
+ SignatureDirectoryResolver, OriginRevocationResolver,
185
+ createIdentity33PrincipalResolver, createIdentity33PrincipalScopeResolver, createIdentity33Authorization,
186
+ withIdentity33PrincipalHandlers,
187
+ } from '@adcp/sdk/identity-3.3';
188
+
189
+ const stores = createIdentity33StateStores({ store: sharedStateStore, tenantId });
190
+ const trust = new TrustEvaluator({ authorityHistory: stores.authorityHistory });
191
+ const lifecycle = new OriginIdentityLifecycle({
192
+ store: stores.identity,
193
+ trust,
194
+ onboarding,
195
+ lookupLegacyPrincipals: app.lookupLegacyPrincipals,
196
+ checkRequirement: app.checkOnboardingRequirement,
197
+ hasBillingRelationship: app.hasBillingRelationship,
198
+ notify: app.publishPrincipalInvalidation,
199
+ });
200
+ // Configure principalRuntime's resolvePrincipal with this mapping. Both its
201
+ // authorization scope and public record id must use the audited binding.
202
+ const resolvePrincipalScope = createIdentity33PrincipalScopeResolver({
203
+ lifecycle, tenantId, legacy: app.resolveLegacyPrincipal,
204
+ });
205
+
206
+ const directory = new SignatureDirectoryResolver();
207
+ const revocations = new OriginRevocationResolver({ directory, store: stores.revocations });
208
+ const authorize = createIdentity33Authorization({
209
+ lifecycle,
210
+ grants: { evaluator: trust, resolveBrandHouse: app.resolveVerifiedBrandHouse },
211
+ resolveClaims: app.resolveAuthorizedAccountClaims, // Read-only account lookup; never provision here.
212
+ });
213
+
214
+ const server = createAdcpServerFromPlatform(platform, {
215
+ ...serverOptions,
216
+ identity33: { authorize },
217
+ protocol: withIdentity33PrincipalHandlers(principalRuntime.protocol, lifecycle),
218
+ signedRequests: {
219
+ ...legacyVerifierOptions,
220
+ assertLegacyOriginAllowed: url => lifecycle.assertLegacyAllowed(url),
221
+ webBotAuth: {
222
+ directory,
223
+ isRevoked: (origin, kid) => revocations.isRevoked(origin, kid),
224
+ resolvePrincipal: createIdentity33PrincipalResolver({ lifecycle }),
225
+ },
226
+ },
227
+ });
228
+ ```
229
+
230
+ `sharedStateStore` must implement atomic `getWithVersion`/`putIfMatch`; the SDK's
231
+ Postgres store supplies these. Hoist stores outside request factories and bind
232
+ `tenantId` to trusted routing. The adapters retain bindings/audits, operator
233
+ quotas, authoritative trust history, applications/outbox notifications, and
234
+ monotonic revocation facts across restarts. In-memory stores are for development.
235
+ `resolveClaims` runs before account resolution and receives the authenticated server context: for `sync_accounts`,
236
+ return every proposed claim before provisioning; for spend, use the existing
237
+ seller-resolved account's brand/operator/billing/sandbox, never request
238
+ reassignment. Authorization runs before idempotency lookup and handler effects.
239
+ Keep the normal buyer registry's suspension, blocking, sandbox and billing
240
+ gates enabled; grants do not replace them.
241
+
242
+ `bindPrincipal` requires seller audit evidence. Existing RFC mappings require
243
+ explicit migration approval and an unambiguous origin. `sync_principal` may
244
+ create only a new principal under declared open tiers; legacy-ledger lookup is
245
+ mandatory. Quotas apply to the operator domain. PRIVATE PSL origins can open
246
+ sandbox access only. Open agent billing is never automatic; production operator
247
+ or advertiser billing additionally requires the seller's existing billing
248
+ relationship with that billed domain. Unknown requirements remain unsatisfied;
249
+ wrong-direction requirements are ignored, with message/URL fallback for humans.
250
+
251
+ Set the seller's `platform.capabilities.account.agentOnboarding`, supported
252
+ billing and sandbox fields, and declare `account.agent_onboarding` in
253
+ `platform.capabilities.overrides.experimental_features`. Declare request
254
+ profiles through `overrides.request_signing`. Server construction validates
255
+ posture semantics; unbound `get_principal` reads remain `unconfigured` and
256
+ never run the durable principal runtime. Caller-only relationships may exist
257
+ before binding. Notification reasons are `relationship_changed` and
258
+ `relationship_expiring`. Queue state is committed before publish; reuse the
259
+ provided notification ID as the emitter's delivery ID. Call
260
+ `flushRelationshipNotifications` after restart and schedule
261
+ `notifyRelationshipExpiring` with your seller-declared lead time.
262
+
263
+ ## Trust, grants, and revocation
264
+
265
+ The operator is derived using the pinned ICANN+PRIVATE PSL, never a document
266
+ field or authoritative hop host. Trust reads allow one document hop, zero HTTP
267
+ redirects, 2 MiB, depth 32, and no duplicate JSON keys. Exactly one canonical
268
+ origin must carry the required role. Cache lifetime is the configured revocation
269
+ poll interval (60–1800 seconds), negatives at most 60 seconds. Failures are not
270
+ absence. Share authoritative-history state when retaining legacy fallback.
271
+
272
+ Demand grants come from the verified brand or house record. Implicit authority
273
+ requires brand, account operator, and signer operator to share a registrable
274
+ domain. Otherwise only a direct grant with the account operator equal to the
275
+ signer, or a two-link chain through the account operator, is accepted. The
276
+ intersection must cover the actual brand IDs, countries, scope, signer-origin
277
+ narrowing and temporal window. A restrictive published grant cannot be
278
+ superseded by seller fallback. A trust 200 disables brand.json authority;
279
+ authoritative absence alone permits explicit legacy policy. An established
280
+ identity lacking a grant gets `PERMISSION_DENIED` with
281
+ `{ scope: 'agent', reason: 'grant_absent' }`. No account or live buy is changed.
282
+
283
+ Origin key revocations use `/.well-known/governance-revocations.json`, signed
284
+ with `typ: adcp-gov-revocation+jws`, as ratified R3 specifies. This origin key
285
+ list does not migrate governance-context, designated-task response or rights
286
+ JWS discovery: those retain the RFC chain in 3.3. Polling fails closed, revoked
287
+ keys remain revoked forever, `keyCompromise` cannot be weakened, and the earliest
288
+ `invalidity_date` is retained. Revocation never pauses or cancels committed buys.
289
+
290
+ Permanent revocation storage reserves separate bounded capacity for audited bound
291
+ origins and anonymous/self-service origins, so first-contact traffic cannot exhaust the bound
292
+ pool. Storage failures deny reads and mutations without outage grace; inspect the
293
+ non-enumerable error cause and raise `createIdentity33StateStores.revocationLimits`
294
+ when capacity is exhausted. Existing facts must remain stored. Outage grace is
295
+ available only after that origin's fetch fails, never merely because the global
296
+ fetch limiter is full.
297
+
298
+ ## Authoring and pinned sources
299
+
300
+ ```sh
301
+ adcp identity trust-validate trust.json
302
+ adcp identity directory --origin https://buyer.example.com \
303
+ --keys private-jwks.json --output directory-response.json
304
+ ```
305
+
306
+ Serve the output's exact body and headers at the directory well-known path.
307
+ Re-run after rotation and before proof expiry. The helper publishes public
308
+ thumbprint keys only; keep the input private key file private. The SDK also
309
+ exports `createSignedSignatureDirectory`, `createTrustRecord`, and
310
+ `validateTrustRecord` for applications. Trust records contain no key discovery.
311
+
312
+ The implementation pins these upstream heads, rather than claiming they are
313
+ released schemas:
314
+
315
+ | PR | Pinned head | Surface |
316
+ | --- | --- | --- |
317
+ | [7894](https://github.com/adcontextprotocol/adcp/pull/7894) | `656bd080f01cc2fca4a1e623af44e96cfd827ba5` | WBA wire profile, profile selectors, directory and request/relay vectors |
318
+ | [8121](https://github.com/adcontextprotocol/adcp/pull/8121) | `f5973ac0267b1b94d714c55fc4e3ad8fc2511350` | Origin identity and key-free trust v1 |
319
+ | [8162](https://github.com/adcontextprotocol/adcp/pull/8162) | `5c9914c5c382cc32f3d2ad7842942e548c414705` | Ratified identity, coexistence, revocation |
320
+ | [8168](https://github.com/adcontextprotocol/adcp/pull/8168) | `45540941dfd61e80ab8a463f780cb147c82a32f0` | Relationship and principal response arms |
321
+ | [8169](https://github.com/adcontextprotocol/adcp/pull/8169) | `3ce6a14d7afaa71fa78ddf2223ed0421e01205ae` | Grants, trust schema, grant_absent |
322
+ | [8170](https://github.com/adcontextprotocol/adcp/pull/8170) | `8d3591e70e9a717c7fdfb513360a796fba24ca9a` | Onboarding additions only; its old trust key fields are excluded |
323
+ | [8177](https://github.com/adcontextprotocol/adcp/pull/8177) | `b663f8e4235fe4276c73fb9bac6db491b2252bbf` | Reporting authentication omission |
324
+
325
+ Ratified R2 defaults replay to 429. Older vector negative/002 expects 403;
326
+ `replayStatus: 403` is an explicit compatibility test option, not the default.
327
+ Older #7894 governance vectors propose a superseded migration and are retained
328
+ with their non-applicability recorded in `test/fixtures/wba-profile/PINNED.json`.
329
+ The buyer default onboarding field is `profiles.adcp.onboarding`, matching the
330
+ schema; the design's `record_profiles` wording names the schema definition.
331
+
332
+ The process-local trust evaluator bounds authority history and conservatively disables legacy fallback after history eviction. Production sellers should supply `authorityHistory` from the shared state stores so history survives restarts and cache eviction.
333
+
334
+ Open `sync_principal` commits the newly approved origin binding before the caller notification-configuration handler runs. A later configuration failure does not undo that binding; retry applies configuration to the same principal. This allocation never grants spend authority: every mutating request still passes tier, relationship and grant checks before provisioning or idempotency.
335
+
336
+ `resolveClaims` must perform its own read-only lookup of the existing seller account; `ctx.account` is unset because authorization precedes account resolution and provisioning. Always use `createIdentity33PrincipalResolver` with this authorization hook so verified WBA requests carry the protected identity claim.
337
+
338
+ Before enabling persisted webhook profile selection, rerun `getWebhookRegistrationMigration()` against existing PostgreSQL registration tables. It adds the optional `signing_profile` and `delivery_kind` columns; existing NULL rows retain the RFC verifier and their existing provenance. Redis and memory records preserve the optional fields directly.
339
+
340
+ Reusing a reporting or artifact URL extends its matching registration's expiry.
341
+ Use a new callback URL when changing its signing profile while old deliveries are
342
+ still outstanding. A live URL's verifier remains immutable; changing it requires
343
+ explicitly deleting the old registration, which also stops accepting old deliveries.
344
+
345
+ Compute the deletion key with `deliveryWebhookRegistrationId` from
346
+ `@adcp/sdk/identity-3.3`, then call
347
+ `store.delete(agentId, deliveryWebhookRegistrationId('reporting', callbackUrl))`.
348
+
349
+ The standard principal resolver automatically fences RFC signatures for already-bound origins. Custom resolvers must supply `assertLegacyOriginAllowed`; legacy keys must resolve an unambiguous agent origin. Preserve an existing operator principal during approved migration by passing `principalKind: "operator"` to `bindPrincipal`. WBA authenticators enforce signature presence and must use `requireSignatureWhenPresent` for bearer coexistence.
350
+
351
+ Signing capabilities include the experimental `wba_draft_revision` field next to `profiles`, identifying `draft-ietf-webbotauth-httpsig-protocol-00` as required by ratified R2. Reporting and artifact callback choices are persisted by destination before dispatch, including update calls; their receivers pass the trusted request URL and `taskType` (`media_buy_delivery` or `artifact_delivery`) to `verifyAndParseWebhook`. These deliveries preserve the original payload in `result` after authentication and schema validation; `envelope` adds SDK routing/status metadata. PostgreSQL migrations also add optional `delivery_kind`.
352
+
353
+ Revocation stores allocate no permanent row for an empty list. Each audited/unbound pool reserves a tenant-wide CAS budget (10,000 origins and 100,000 keys; each operator is limited to 256 origins and 16,384 keys per pool). Audited bindings promote existing facts without deleting them; self-service `openAccess` bindings stay in the unbound pool. Failed writes may conservatively reserve capacity; facts are never evicted to regain it. Store/quota failures return `SERVICE_UNAVAILABLE` for every operation. In-memory revocation storage is for development/tests; production sellers use shared persistent stores.
354
+
355
+ Unbound callers use an internal per-origin anonymous scope to isolate task/proposal state; this is not a durable principal and is never returned by `get_principal`. Only the explicit anonymous tool policy is allowed.
@@ -40,6 +40,11 @@ disable it. Set `legacyWebhookFallback: false` on a standalone brand resolver to
40
40
  `ResolvedAgentJwksResolver` requires explicitly enabling the fallback for webhook use.
41
41
  Wrappers shared with request verification must forward `resolveWithMetadata`
42
42
  so the verifier can refuse webhook-only fallback keys.
43
+ The [agent identity foundations note](./migration-agent-identity-3.3.md)
44
+ describes canonical origins and the optional signer-origin lookup argument;
45
+ wrappers must forward that argument on both resolver methods as well.
46
+ Origin consistency comparisons now remove one trailing DNS root dot and
47
+ reject malformed authorities instead of accepting URL-parser repairs.
43
48
 
44
49
  Capabilities discovery defaults to MCP. A2A integrations using
45
50
  `BrandJsonJwksResolver` must set `protocol: 'a2a'`; the onboarding record does
@@ -0,0 +1,137 @@
1
+ # Breaking: reporting row storage field alignment
2
+
3
+ Reliable Reporting row storage now stores every value in the format AdCP
4
+ already defines for it, and `{period_date}` is the period's calendar date in its
5
+ `source_timezone` instead of UTC. This is one deliberate breaking change, made
6
+ before any deployment activated row storage in production. It ships in the
7
+ 15.9.0 release.
8
+
9
+ Affected: anyone who applied `REPORTING_ROW_STORAGE_MIGRATION`, configured
10
+ `rowStorage`, or wrote a custom `ReportingRowObjectProviderV1`. Not affected:
11
+ the wire (`revision_content_sha256` and every other buyer-visible value is
12
+ unchanged), PostgreSQL-kind row storage behavior, and anyone who never installed
13
+ the row-storage tables.
14
+
15
+ ## Upgrading
16
+
17
+ Apply the new `REPORTING_ROW_STORAGE_MIGRATION` before starting any binary that
18
+ contains this change, and stop older writers first: they read the old column
19
+ names and fail against the renamed tables. A new binary refuses to start row
20
+ storage against an un-migrated database (`probeReportingRowStorageSchemaV1`
21
+ names the missing columns). The migration takes a brief exclusive lock on the
22
+ row-storage tables, so apply it in a maintenance window. It is idempotent,
23
+ serialized by an advisory lock so concurrent appliers cannot race, runs on a
24
+ fresh install, and on an installed database it:
25
+
26
+ - renames the columns listed below in place, keeping every recorded location;
27
+ - replaces `encoding` with `format` and `algorithm`, backfilled to `jsonl` and
28
+ `adcp_jcs_rows_v1` (the old column admitted exactly one value);
29
+ - adds the AdCP length checks (a database that already holds an out-of-bounds
30
+ key fails the migration with a message naming the count, and rolls back);
31
+ - rewrites open write intents' `created_objects` from `objectKey` /
32
+ `nativeVersion` to `object_ref` / `native_version_ref`.
33
+
34
+ If you installed the row-storage tables but never activated them, the in-place
35
+ migration is enough: there is nothing to preserve. Dropping the tables to start
36
+ clean also works, but it discards `adcp_persistence_installation`, so the new
37
+ installation ID changes every binding's `namespace_key` and with it the object
38
+ key prefix. Do not drop tables that contain row sets.
39
+
40
+ The migration does not rewrite object keys. Objects written before the upgrade
41
+ keep the key recorded in `object_ref`, rendered under the old UTC rule with a
42
+ `yyyy/MM/dd` layout. Reads, retention and deletes use the recorded key, so they
43
+ keep working. New writes render the new key, so a period re-written after the
44
+ upgrade may sit at a different key than its earlier objects, and an upload that
45
+ was in flight across the upgrade can leave its old-key object behind. Re-sync
46
+ instead of upgrading in place if you want every object under the new layout.
47
+
48
+ ## Object key templates require `{revision_key}`
49
+
50
+ Every writable object binding's `keyTemplate` must now include
51
+ `{revision_key}`, not only when snapshot compaction is on, so no two row sets
52
+ can ever name the same object key. The default template already includes it.
53
+ The store throws `INVALID_INPUT` when a binding is configured and again in
54
+ `readyRowStorage` if a template omits it. A custom template without it must
55
+ add it, under a new binding ID (a binding's identity digest includes its
56
+ template).
57
+
58
+ Objects already written stay readable: reads use each chunk's recorded
59
+ `object_ref`, not a re-rendered key. Keep the old binding definition
60
+ configured while revisions reference it, and mark it `readOnly: true`; a
61
+ read-only binding is exempt from the requirement, is never chosen for new
62
+ writes, and is still used for reads and retirement (`readyRowStorage` still
63
+ probes it, so keep its location reachable). Compaction ignores read-only
64
+ bindings, because nothing can adopt through them. The
65
+ reference-checked deletes and the per-object lock are unchanged, because
66
+ header-only revisions still share chunks within an obligation.
67
+
68
+ ## Renamed fields
69
+
70
+ | Before | After | AdCP definition |
71
+ | ----------------------------------------------- | ------------------------------------------- | --------------------------------------------------------- |
72
+ | `adcp_reporting_row_chunks.object_key` | `object_ref` (1 to 1024 characters) | `reporting-file-object-ref.json` |
73
+ | `adcp_reporting_row_chunks.native_version` | `native_version_ref` (1 to 1024 characters) | `reporting-native-version-ref.json` |
74
+ | `adcp_reporting_row_chunks.physical_byte_count` | `size_bytes` | `reporting-file-entry.json` `size_bytes`: stored size |
75
+ | `adcp_reporting_row_chunks.byte_count` | `canonical_size_bytes` | uncompressed canonical bytes; the digest-pinned manifest |
76
+ | `adcp_reporting_row_sets.canonical_byte_count` | `content_size_bytes` | size of the content `content_sha256` covers (the binding's byte count) |
77
+ | `adcp_reporting_row_sets.encoding` | `format` = `jsonl`, `algorithm` = `adcp_jcs_rows_v1` | `reporting-file-manifest.json` `format`, `reporting-canonicalization-contract.json` `algorithm` |
78
+
79
+ `size_bytes` means what it means in the AdCP file manifest: the size of the
80
+ stored object, after compression. The uncompressed canonical size is a separate
81
+ value because chunk and segment digests, byte ranges and the binding verify
82
+ against it. A row set's `content_size_bytes` is a third quantity: the byte count of
83
+ the content `content_sha256` digests, which for a revision includes the
84
+ envelope, so it is not the sum of its chunks' `canonical_size_bytes`. Manifest JSON field names (`byte_count`, `byte_offset`) are
85
+ digest-pinned and did not change.
86
+
87
+ TypeScript and provider API:
88
+
89
+ - `ReportingRowChunkLocatorV1`: `objectKey` is `objectRef`, `nativeVersion` is
90
+ `nativeVersionRef`, `physicalByteCount` is `sizeBytes`.
91
+ - `ReportingRowObjectProviderV1`: inputs take `objectRef` (was `key`) and
92
+ `nativeVersionRef` (was `nativeVersion`); `putIfAbsent` returns
93
+ `{ created, nativeVersionRef }`. Add the optional
94
+ `stat({ objectRef, nativeVersionRef })` returning
95
+ `{ nativeVersionRef, sizeBytes }` (the version it resolved, which must equal the
96
+ one asked for, and the stored size) or `null`.
97
+ The commit transaction uses it to prove an adopted object unchanged without
98
+ re-downloading it under the account lock; a provider without `stat` falls back
99
+ to the full read. Every bundled provider implements it, and
100
+ `runReportingRowObjectProviderConformanceV1` checks it (new
101
+ `version-pinned-stat` entry).
102
+ - `ReportingRowBindingSelectionInputV1.canonical_byte_count` is
103
+ `content_size_bytes`; `ReportingRowSetHandleV1.canonicalByteCount` is
104
+ `contentSizeBytes`.
105
+ - `ReportingRowSetPrepareInputV1` takes `sourceTimezone` next to `periodStart`;
106
+ a `periodStart` without a usable `sourceTimezone` fails with `INVALID_INPUT`.
107
+ - `REPORTING_ROW_ENCODING_V1` is replaced by `REPORTING_ROW_FORMAT_V1`
108
+ (`jsonl`) and `REPORTING_ROW_ALGORITHM_V1` (`adcp_jcs_rows_v1`);
109
+ `encodeReportingRowsV1` returns `format` and `algorithm` instead of `encoding`.
110
+
111
+ ## `{period_date}`
112
+
113
+ The placeholder name is unchanged. It now renders AdCP's `YYYY-MM-DD`: the
114
+ calendar date of the period start in the period's `source_timezone`, as one path
115
+ segment. A period starting `2026-10-02T07:00:00Z` in `America/Los_Angeles` is
116
+ `2026-10-02`; one starting `2026-10-01T15:00:00Z` in `Asia/Tokyo` is also
117
+ `2026-10-02`. The old rendering used the UTC date and split it into
118
+ `yyyy/MM/dd` directories. A missing, unknown or non-IANA timezone fails the
119
+ write rather than guessing a date. The default key template string did not
120
+ change, so existing binding identities remain valid.
121
+
122
+ If you built tooling that lists objects by `yyyy/MM/dd` directory, list by the
123
+ single `YYYY-MM-DD` segment, or read the recorded `object_ref` from
124
+ `adcp_reporting_row_chunks`.
125
+
126
+ ## Digests
127
+
128
+ `adcp_jcs_rows_v1` names the per-row RFC 8785 canonicalization the stored rows
129
+ use. A revision's `content_sha256` is still the envelope digest
130
+ (`revision_envelope_v1`), not AdCP's array-shaped content digest; only an
131
+ adjustment's `rows_v1` digest has that shape. The format and algorithm tokens
132
+ label the encoding; they are not an input to any
133
+ chunk, segment, manifest or protocol digest. No digest changed. The shared
134
+ golden fixture `test/fixtures/reporting-row-storage-v1.json` replaced its
135
+ top-level `encoding` label with `format` and `algorithm`; every expected digest
136
+ and byte count is identical. Other SDKs sharing the fixture must adopt the new
137
+ labels and storage names but reproduce the same bytes.
@@ -0,0 +1,57 @@
1
+ id: account_sync_contract
2
+ version: "1.0.0"
3
+ title: "Account identity and payment terms"
4
+ category: schema_validation
5
+ summary: "Repeat provisioning with fresh request keys preserves the account; requested terms are accepted or rejected."
6
+ narrative: |
7
+ Run with one authenticated sandbox principal permitted to use agent billing.
8
+ The seller must accept net_60 or reject it. If the seller rejects the first
9
+ request, provision and repeat checks require an accepted-terms fixture instead.
10
+ agent:
11
+ interaction_model: any
12
+ capabilities: []
13
+ caller:
14
+ role: buyer_agent
15
+ required_tools: [sync_accounts, list_accounts]
16
+ invariants: [account.sync_contract]
17
+ phases:
18
+ - id: sync
19
+ title: "Sync twice with different request keys, then read the roster"
20
+ steps:
21
+ - id: first_sync
22
+ task: sync_accounts
23
+ sample_request:
24
+ idempotency_key: "$generate:uuid_v4#account_first_sync"
25
+ accounts:
26
+ - brand: { domain: "acmeoutdoor.example" }
27
+ operator: "pinnacle-agency.example"
28
+ sandbox: true
29
+ billing: agent
30
+ payment_terms: net_60
31
+ validations:
32
+ - check: field_present
33
+ path: accounts
34
+ - id: repeat_sync
35
+ task: sync_accounts
36
+ sample_request:
37
+ idempotency_key: "$generate:uuid_v4#account_repeat_sync"
38
+ accounts:
39
+ - brand: { domain: "acmeoutdoor.example" }
40
+ operator: "pinnacle-agency.example"
41
+ sandbox: true
42
+ billing: agent
43
+ payment_terms: net_60
44
+ validations:
45
+ - check: field_present
46
+ path: accounts
47
+ - id: read_accounts
48
+ task: list_accounts
49
+ sample_request:
50
+ account:
51
+ brand: { domain: "acmeoutdoor.example" }
52
+ operator: "pinnacle-agency.example"
53
+ sandbox: true
54
+ sandbox: true
55
+ validations:
56
+ - check: field_present
57
+ path: accounts