@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.
- package/bin/adcp-identity.js +74 -0
- package/bin/adcp.js +2 -0
- package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
- package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
- package/dist/lib/adapters/keyed-account-backend.js +121 -0
- package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
- package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
- package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
- package/dist/lib/adapters/keyed-account-store.js +227 -0
- package/dist/lib/adapters/keyed-account-store.mjs +203 -0
- package/dist/lib/core/SingleAgentClient.d.mts +16 -2
- package/dist/lib/core/SingleAgentClient.d.ts +16 -2
- package/dist/lib/core/SingleAgentClient.js +259 -62
- package/dist/lib/core/SingleAgentClient.mjs +261 -57
- package/dist/lib/core/TaskExecutor.d.mts +6 -0
- package/dist/lib/core/TaskExecutor.d.ts +6 -0
- package/dist/lib/core/TaskExecutor.js +66 -5
- package/dist/lib/core/TaskExecutor.mjs +71 -5
- package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
- package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
- package/dist/lib/core/redis-webhook-registration-store.js +23 -1
- package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
- package/dist/lib/core/webhook-registration.d.mts +7 -1
- package/dist/lib/core/webhook-registration.d.ts +7 -1
- package/dist/lib/core/webhook-registration.js +24 -2
- package/dist/lib/core/webhook-registration.mjs +23 -2
- package/dist/lib/identity-3.3/index.d.mts +10 -0
- package/dist/lib/identity-3.3/index.d.ts +10 -0
- package/dist/lib/identity-3.3/index.js +75 -0
- package/dist/lib/identity-3.3/index.mjs +46 -0
- package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
- package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
- package/dist/lib/identity-3.3/lifecycle.js +267 -0
- package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
- package/dist/lib/identity-3.3/revocation.d.mts +50 -0
- package/dist/lib/identity-3.3/revocation.d.ts +50 -0
- package/dist/lib/identity-3.3/revocation.js +238 -0
- package/dist/lib/identity-3.3/revocation.mjs +216 -0
- package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
- package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
- package/dist/lib/identity-3.3/server.d.mts +34 -0
- package/dist/lib/identity-3.3/server.d.ts +34 -0
- package/dist/lib/identity-3.3/server.js +219 -0
- package/dist/lib/identity-3.3/server.mjs +194 -0
- package/dist/lib/identity-3.3/store.d.mts +24 -0
- package/dist/lib/identity-3.3/store.d.ts +24 -0
- package/dist/lib/identity-3.3/store.js +191 -0
- package/dist/lib/identity-3.3/store.mjs +169 -0
- package/dist/lib/identity-3.3/trust.d.mts +94 -0
- package/dist/lib/identity-3.3/trust.d.ts +94 -0
- package/dist/lib/identity-3.3/trust.js +278 -0
- package/dist/lib/identity-3.3/trust.mjs +239 -0
- package/dist/lib/identity-3.3/types.d.mts +127 -0
- package/dist/lib/identity-3.3/types.d.ts +127 -0
- package/dist/lib/identity-3.3/types.js +16 -0
- package/dist/lib/identity-3.3/types.mjs +0 -0
- package/dist/lib/identity-3.3/validation.d.mts +2 -0
- package/dist/lib/identity-3.3/validation.d.ts +2 -0
- package/dist/lib/identity-3.3/validation.js +125 -0
- package/dist/lib/identity-3.3/validation.mjs +91 -0
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/reporting/azure/index.d.mts +5 -0
- package/dist/lib/reporting/azure/index.d.ts +5 -0
- package/dist/lib/reporting/azure/index.js +26 -7
- package/dist/lib/reporting/azure/index.mjs +26 -7
- package/dist/lib/reporting/bigquery/index.d.mts +80 -25
- package/dist/lib/reporting/bigquery/index.d.ts +80 -25
- package/dist/lib/reporting/bigquery/index.js +184 -81
- package/dist/lib/reporting/bigquery/index.mjs +182 -80
- package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
- package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
- package/dist/lib/reporting/gcs/errors.d.mts +6 -0
- package/dist/lib/reporting/gcs/errors.d.ts +6 -0
- package/dist/lib/reporting/gcs/fence.d.mts +5 -0
- package/dist/lib/reporting/gcs/fence.d.ts +5 -0
- package/dist/lib/reporting/gcs/index.d.mts +9 -0
- package/dist/lib/reporting/gcs/index.d.ts +9 -0
- package/dist/lib/reporting/gcs/reader.d.mts +27 -3
- package/dist/lib/reporting/gcs/reader.d.ts +27 -3
- package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
- package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
- package/dist/lib/reporting/gcs/row-provider.js +34 -14
- package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
- package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
- package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
- package/dist/lib/reporting/ledger/index.d.mts +11 -0
- package/dist/lib/reporting/ledger/index.d.ts +11 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
- package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
- package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
- package/dist/lib/reporting/ledger/managed.d.mts +86 -6
- package/dist/lib/reporting/ledger/managed.d.ts +86 -6
- package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
- package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
- package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
- package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
- package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
- package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
- package/dist/lib/reporting/ledger/postgres.js +43 -27
- package/dist/lib/reporting/ledger/postgres.mjs +43 -27
- package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.js +8 -4
- package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
- package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
- package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
- package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
- package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
- package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
- package/dist/lib/reporting/ledger/row-storage.js +126 -66
- package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
- package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
- package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
- package/dist/lib/reporting/ledger/schedule.js +24 -0
- package/dist/lib/reporting/ledger/schedule.mjs +23 -0
- package/dist/lib/reporting/ledger/types.d.mts +23 -1
- package/dist/lib/reporting/ledger/types.d.ts +23 -1
- package/dist/lib/reporting/s3/index.d.mts +5 -0
- package/dist/lib/reporting/s3/index.d.ts +5 -0
- package/dist/lib/reporting/s3/index.js +37 -14
- package/dist/lib/reporting/s3/index.mjs +37 -14
- package/dist/lib/reporting/service/index.d.mts +10 -0
- package/dist/lib/reporting/service/index.d.ts +10 -0
- package/dist/lib/reporting/service/maintenance.d.mts +28 -2
- package/dist/lib/reporting/service/maintenance.d.ts +28 -2
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-sync-contract.d.mts +14 -0
- package/dist/lib/server/account-sync-contract.d.ts +14 -0
- package/dist/lib/server/account-sync-contract.js +225 -0
- package/dist/lib/server/account-sync-contract.mjs +197 -0
- package/dist/lib/server/adcp-server.js +5 -0
- package/dist/lib/server/adcp-server.mjs +10 -0
- package/dist/lib/server/auth-signature.d.mts +10 -0
- package/dist/lib/server/auth-signature.d.ts +10 -0
- package/dist/lib/server/auth-signature.js +61 -2
- package/dist/lib/server/auth-signature.mjs +65 -2
- package/dist/lib/server/auth.d.mts +6 -0
- package/dist/lib/server/auth.d.ts +6 -0
- package/dist/lib/server/auth.js +6 -0
- package/dist/lib/server/auth.mjs +6 -0
- package/dist/lib/server/create-adcp-server.d.mts +19 -5
- package/dist/lib/server/create-adcp-server.d.ts +19 -5
- package/dist/lib/server/create-adcp-server.js +238 -19
- package/dist/lib/server/create-adcp-server.mjs +240 -10
- package/dist/lib/server/decisioning/account.d.mts +24 -1
- package/dist/lib/server/decisioning/account.d.ts +24 -1
- package/dist/lib/server/decisioning/index.d.mts +1 -1
- package/dist/lib/server/decisioning/index.d.ts +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
- package/dist/lib/server/index.d.mts +2 -0
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.js +12 -0
- package/dist/lib/server/index.mjs +12 -0
- package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
- package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
- package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
- package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
- package/dist/lib/server/principal/types.d.mts +1 -1
- package/dist/lib/server/principal/types.d.ts +1 -1
- package/dist/lib/server/serve.js +5 -0
- package/dist/lib/server/serve.mjs +5 -0
- package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.js +4 -0
- package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
- package/dist/lib/server/webhook-emitter.d.mts +10 -0
- package/dist/lib/server/webhook-emitter.d.ts +10 -0
- package/dist/lib/server/webhook-emitter.js +22 -0
- package/dist/lib/server/webhook-emitter.mjs +22 -0
- package/dist/lib/signing/agent-context.d.mts +0 -5
- package/dist/lib/signing/agent-context.d.ts +0 -5
- package/dist/lib/signing/agent-context.js +9 -1
- package/dist/lib/signing/agent-context.mjs +9 -1
- package/dist/lib/signing/agent-fetch.js +27 -2
- package/dist/lib/signing/agent-fetch.mjs +32 -2
- package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
- package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
- package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
- package/dist/lib/signing/agent-resolver/index.js +5 -0
- package/dist/lib/signing/agent-resolver/index.mjs +3 -0
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
- package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
- package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
- package/dist/lib/signing/brand-jwks.d.mts +2 -2
- package/dist/lib/signing/brand-jwks.d.ts +2 -2
- package/dist/lib/signing/brand-jwks.js +4 -4
- package/dist/lib/signing/brand-jwks.mjs +4 -4
- package/dist/lib/signing/client.d.mts +1 -0
- package/dist/lib/signing/client.d.ts +1 -0
- package/dist/lib/signing/client.js +5 -0
- package/dist/lib/signing/client.mjs +3 -0
- package/dist/lib/signing/jwks-https.d.mts +1 -1
- package/dist/lib/signing/jwks-https.d.ts +1 -1
- package/dist/lib/signing/jwks-https.js +1 -1
- package/dist/lib/signing/jwks-https.mjs +1 -1
- package/dist/lib/signing/jwks.d.mts +11 -3
- package/dist/lib/signing/jwks.d.ts +11 -3
- package/dist/lib/signing/jwks.js +1 -1
- package/dist/lib/signing/jwks.mjs +1 -1
- package/dist/lib/signing/parser.d.mts +1 -1
- package/dist/lib/signing/parser.d.ts +1 -1
- package/dist/lib/signing/parser.js +5 -3
- package/dist/lib/signing/parser.mjs +6 -4
- package/dist/lib/signing/revocation.d.mts +4 -1
- package/dist/lib/signing/revocation.d.ts +4 -1
- package/dist/lib/signing/revocation.js +33 -3
- package/dist/lib/signing/revocation.mjs +31 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +4 -0
- package/dist/lib/signing/server.mjs +4 -0
- package/dist/lib/signing/types.d.mts +3 -0
- package/dist/lib/signing/types.d.ts +3 -0
- package/dist/lib/signing/web-bot-auth.d.mts +117 -0
- package/dist/lib/signing/web-bot-auth.d.ts +117 -0
- package/dist/lib/signing/web-bot-auth.js +660 -0
- package/dist/lib/signing/web-bot-auth.mjs +624 -0
- package/dist/lib/testing/client.d.mts +1 -4
- package/dist/lib/testing/client.d.ts +1 -4
- package/dist/lib/testing/client.js +141 -20
- package/dist/lib/testing/client.mjs +137 -19
- package/dist/lib/testing/compliance/comply.js +29 -10
- package/dist/lib/testing/compliance/comply.mjs +37 -11
- package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
- package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
- package/dist/lib/testing/storyboard/default-invariants.js +2 -0
- package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
- package/dist/lib/testing/storyboard/runner.js +23 -8
- package/dist/lib/testing/storyboard/runner.mjs +24 -8
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/adcp.d.mts +4 -0
- package/dist/lib/types/adcp.d.ts +4 -0
- package/dist/lib/types/schemas.generated.d.ts +6 -6
- package/dist/lib/utils/capabilities.d.mts +1 -0
- package/dist/lib/utils/capabilities.d.ts +1 -0
- package/dist/lib/utils/capabilities.js +5 -0
- package/dist/lib/utils/capabilities.mjs +5 -0
- package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
- package/dist/lib/v2/projection/creative-delivery.js +26 -10
- package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
- package/dist/lib/v2/projection/index.d.mts +1 -1
- package/dist/lib/v2/projection/index.d.ts +1 -1
- package/dist/lib/v2/projection/legacy-routes.d.mts +24 -2
- package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
- package/dist/lib/v2/projection/legacy-routes.js +28 -2
- package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
- package/dist/lib/validation/schema-loader.d.mts +2 -0
- package/dist/lib/validation/schema-loader.d.ts +2 -0
- package/dist/lib/validation/schema-loader.js +43 -4
- package/dist/lib/validation/schema-loader.mjs +39 -3
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
- package/docs/guides/REPORTING-LEDGER.md +132 -46
- package/docs/guides/REPORTING-OPERATIONS.md +25 -4
- package/docs/guides/REPORTING-STABILITY.md +76 -0
- package/docs/guides/account-resolution.md +101 -0
- package/docs/llms.txt +3 -2
- package/docs/migration-12-to-13.md +7 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +355 -0
- package/docs/migration-agent-resolution-3.3.md +5 -0
- package/docs/migration-reporting-row-storage-alignment.md +137 -0
- package/examples/storyboards/account-sync-contract.yaml +57 -0
- 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-
|
|
4
|
-
> Library: @adcp/sdk
|
|
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
|
-
| npm integrity | registry-derived after publication; run `npm view @adcp/sdk@
|
|
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@
|
|
25
|
-
npm view '@adcp/sdk@
|
|
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
|