@adcp/sdk 14.1.0 → 14.2.0

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 (106) hide show
  1. package/dist/lib/core/SingleAgentClient.d.mts +4 -1
  2. package/dist/lib/core/SingleAgentClient.d.ts +4 -1
  3. package/dist/lib/core/SingleAgentClient.js +25 -4
  4. package/dist/lib/core/SingleAgentClient.mjs +25 -4
  5. package/dist/lib/core/TaskExecutor.d.mts +3 -1
  6. package/dist/lib/core/TaskExecutor.d.ts +3 -1
  7. package/dist/lib/core/TaskExecutor.js +15 -11
  8. package/dist/lib/core/TaskExecutor.mjs +15 -11
  9. package/dist/lib/core/buyer-account-registry.d.mts +30 -2
  10. package/dist/lib/core/buyer-account-registry.d.ts +30 -2
  11. package/dist/lib/core/buyer-account-registry.js +126 -42
  12. package/dist/lib/core/buyer-account-registry.mjs +127 -43
  13. package/dist/lib/index.d.mts +3 -2
  14. package/dist/lib/index.d.ts +3 -2
  15. package/dist/lib/index.js +9 -0
  16. package/dist/lib/index.mjs +12 -1
  17. package/dist/lib/net/agent-transport-fetch.d.mts +4 -0
  18. package/dist/lib/net/agent-transport-fetch.d.ts +4 -0
  19. package/dist/lib/net/agent-transport-fetch.js +18 -5
  20. package/dist/lib/net/agent-transport-fetch.mjs +17 -5
  21. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  22. package/dist/lib/signing/agent-resolver/errors.d.mts +2 -0
  23. package/dist/lib/signing/agent-resolver/errors.d.ts +2 -0
  24. package/dist/lib/signing/agent-resolver/errors.js +6 -0
  25. package/dist/lib/signing/agent-resolver/errors.mjs +6 -0
  26. package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +9 -0
  27. package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +9 -0
  28. package/dist/lib/signing/agent-resolver/fetch-helpers.js +35 -1
  29. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +38 -2
  30. package/dist/lib/signing/agent-resolver/legacy-brand.js +1 -1
  31. package/dist/lib/signing/agent-resolver/legacy-brand.mjs +2 -2
  32. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +1 -1
  33. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +1 -1
  34. package/dist/lib/signing/agent-resolver/resolve-agent.js +47 -5
  35. package/dist/lib/signing/agent-resolver/resolve-agent.mjs +55 -6
  36. package/dist/lib/signing/brand-jwks.d.mts +2 -0
  37. package/dist/lib/signing/brand-jwks.d.ts +2 -0
  38. package/dist/lib/signing/brand-jwks.js +10 -2
  39. package/dist/lib/signing/brand-jwks.mjs +10 -2
  40. package/dist/lib/signing/errors.d.mts +4 -2
  41. package/dist/lib/signing/errors.d.ts +4 -2
  42. package/dist/lib/signing/errors.js +3 -1
  43. package/dist/lib/signing/errors.mjs +3 -1
  44. package/dist/lib/signing/verifier.js +1 -1
  45. package/dist/lib/signing/verifier.mjs +1 -1
  46. package/dist/lib/signing/webhook-verifier.js +2 -2
  47. package/dist/lib/signing/webhook-verifier.mjs +3 -3
  48. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  49. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  50. package/dist/lib/types/accept-proposal.d.ts +19 -1
  51. package/dist/lib/types/buy-products.d.ts +19 -1
  52. package/dist/lib/types/check-governance.d.ts +19 -1
  53. package/dist/lib/types/comply-test-controller.d.ts +19 -1
  54. package/dist/lib/types/control-media-buy.d.ts +19 -1
  55. package/dist/lib/types/core.generated.d.mts +14 -1
  56. package/dist/lib/types/core.generated.d.ts +14 -1
  57. package/dist/lib/types/create-media-buy.d.ts +14 -1
  58. package/dist/lib/types/get-media-buys.d.ts +14 -1
  59. package/dist/lib/types/get-products.d.ts +19 -1
  60. package/dist/lib/types/list-products.d.ts +19 -1
  61. package/dist/lib/types/refine-proposals.d.ts +19 -1
  62. package/dist/lib/types/request-proposals.d.ts +19 -1
  63. package/dist/lib/types/schemas.generated.d.ts +12 -3
  64. package/dist/lib/types/schemas.generated.js +4 -1
  65. package/dist/lib/types/schemas.generated.mjs +4 -1
  66. package/dist/lib/types/tools.generated.d.mts +14 -1
  67. package/dist/lib/types/tools.generated.d.ts +14 -1
  68. package/dist/lib/types/update-media-buy.d.ts +14 -1
  69. package/dist/lib/version.d.mts +3 -3
  70. package/dist/lib/version.d.ts +3 -3
  71. package/dist/lib/version.js +3 -3
  72. package/dist/lib/version.mjs +3 -3
  73. package/dist/lib/webhooks/index.d.mts +24 -0
  74. package/dist/lib/webhooks/index.d.ts +24 -0
  75. package/dist/lib/webhooks/index.js +50 -24
  76. package/dist/lib/webhooks/index.mjs +49 -24
  77. package/dist/lib/wholesale-feed-sync/index.d.mts +2 -0
  78. package/dist/lib/wholesale-feed-sync/index.d.ts +2 -0
  79. package/dist/lib/wholesale-feed-sync/index.js +7 -0
  80. package/dist/lib/wholesale-feed-sync/index.mjs +4 -0
  81. package/dist/lib/wholesale-feed-sync/mirror.d.mts +97 -0
  82. package/dist/lib/wholesale-feed-sync/mirror.d.ts +97 -0
  83. package/dist/lib/wholesale-feed-sync/mirror.js +350 -0
  84. package/dist/lib/wholesale-feed-sync/mirror.mjs +322 -0
  85. package/dist/lib/wholesale-feed-sync/sync.d.mts +12 -29
  86. package/dist/lib/wholesale-feed-sync/sync.d.ts +12 -29
  87. package/dist/lib/wholesale-feed-sync/sync.js +153 -297
  88. package/dist/lib/wholesale-feed-sync/sync.mjs +158 -297
  89. package/docs/README.md +6 -0
  90. package/docs/TYPE-SUMMARY.md +2 -2
  91. package/docs/guides/BUYER-STORAGE.md +3 -0
  92. package/docs/guides/FIRST-CALL-TO-A-SELLER.md +3 -1
  93. package/docs/guides/account-resolution.md +46 -10
  94. package/docs/llms.txt +2 -2
  95. package/docs/migration-14.0-to-14.1.md +85 -0
  96. package/docs/migration-14.x-rc-worksheet.md +4 -4
  97. package/docs/migration-agent-resolution-3.3.md +5 -3
  98. package/docs/recipes/verifying-inbound-webhooks.md +4 -0
  99. package/package.json +2 -1
  100. package/skills/adcp-brand.previous/SKILL.md +0 -200
  101. package/skills/adcp-creative.previous/SKILL.md +0 -305
  102. package/skills/adcp-governance.previous/SKILL.md +0 -566
  103. package/skills/adcp-measurement.previous/SKILL.md +0 -136
  104. package/skills/adcp-media-buy.previous/SKILL.md +0 -556
  105. package/skills/adcp-si.previous/SKILL.md +0 -206
  106. package/skills/adcp-signals.previous/SKILL.md +0 -204
@@ -26,6 +26,8 @@ accounts: {
26
26
 
27
27
  For buyer setup and opt-in lifecycle management, see
28
28
  [First call to a seller](./FIRST-CALL-TO-A-SELLER.md).
29
+ For upgrading an existing integration, use the
30
+ [14.0-to-14.1 checklist](../migration-14.0-to-14.1.md).
29
31
 
30
32
  Account resolvers receive `ctx.provisioning`. It is false on discovery and
31
33
  negotiation (`get_products`, `list_products`, `get_signals`, and proposal
@@ -133,29 +135,53 @@ construction, not a silent fallback.
133
135
 
134
136
  ### 1 · How it works
135
137
 
136
- 1. Buyer calls `sync_accounts` with `AccountReference[]`.
138
+ 1. Buyer calls `sync_accounts` with natural-key provisioning entries.
137
139
  2. Framework calls your `accounts.upsert()` — you create/find accounts and
138
140
  store the `authPrincipal → accounts` mapping.
139
- 3. Buyer calls any tool (e.g. `create_media_buy`) without `ext.account_ref`.
140
- 4. Framework calls `accounts.resolve(undefined, ctx)` — you look up the
141
- account by `ctx.authInfo`.
141
+ 3. On subsequent account-scoped calls, the buyer supplies top-level
142
+ `account: { brand, operator, ... }`. The framework calls
143
+ `accounts.resolve(ref, ctx)` with that natural key. Look it up within the
144
+ authenticated caller's synced roster; do not substitute another account.
145
+ 4. When a request omits `account`, the framework instead calls
146
+ `accounts.resolve(undefined, ctx)`. This is a separate auth-derived lookup
147
+ path. A null result is allowed for account-optional tools and yields
148
+ `ACCOUNT_REQUIRED` for account-required operations.
149
+
150
+ Implicit sellers refuse the `{ account_id }` reference arm. A seller handle
151
+ returned by `sync_accounts` does not replace the natural key on later calls.
142
152
 
143
153
  ### 2 · Key derivation
144
154
 
145
155
  Extract the principal key from `ctx.authInfo.credential`:
146
156
 
147
157
  ```ts
148
- resolve: async (_ref, ctx) => {
158
+ resolve: async (ref, ctx) => {
149
159
  const cred = ctx?.authInfo?.credential;
150
160
  const key = cred?.kind === 'oauth' ? `oauth:${cred.client_id}`
151
161
  : cred?.kind === 'api_key' ? `api_key:${cred.key_id}`
152
162
  : cred?.kind === 'http_sig' ? `http_sig:${cred.agent_url}`
153
163
  : undefined;
154
164
  if (!key) return null;
165
+ if (ref !== undefined) {
166
+ // Match the full natural key within THIS principal's synced roster.
167
+ // An unknown or unauthorized ref returns null, without a fallback.
168
+ return await db.findSyncedAccountByNaturalKey(key, ref);
169
+ }
170
+ // Account omitted: use your existing auth-derived selection policy.
155
171
  return await db.findAccountByPrincipalKey(key);
156
172
  },
157
173
  ```
158
174
 
175
+ The `db` methods above are operations you implement in your own store.
176
+ `findSyncedAccountByNaturalKey` must compare the complete brand identity
177
+ (domain, optional brand ID and countries), operator, operator-unit ID,
178
+ currency, timezone, and sandbox within the principal's roster. Use consistent
179
+ normalization at sync and lookup, including country ordering and omitted/false
180
+ sandbox. It must not create an account or match on brand/operator alone.
181
+ `findAccountByPrincipalKey` handles only the omitted-reference path according
182
+ to your documented selection policy. The built-in `InMemoryImplicitAccountStore`
183
+ keeps its historical first-account selection for that path.
184
+
159
185
  **Why `credential.client_id`, not `authInfo.sub`?**
160
186
 
161
187
  `credential.client_id` is the OAuth *client* identity — stable across token
@@ -187,14 +213,24 @@ receiving auth errors will refresh credentials or escalate, not call
187
213
 
188
214
  ```ts
189
215
  // ✓ Correct
190
- resolve: async (_ref, ctx) => {
191
- const account = await db.findByPrincipal(extractKey(ctx?.authInfo));
192
- return account ?? null; // omitted account → ACCOUNT_REQUIRED
216
+ resolve: async (ref, ctx) => {
217
+ const key = extractKey(ctx?.authInfo);
218
+ if (!key) return null;
219
+ const account = ref === undefined
220
+ ? await db.findAccountByPrincipalKey(key)
221
+ : await db.findSyncedAccountByNaturalKey(key, ref);
222
+ // Missing: supplied account → ACCOUNT_NOT_FOUND;
223
+ // omitted account on an account-required operation → ACCOUNT_REQUIRED.
224
+ return account ?? null;
193
225
  },
194
226
 
195
227
  // ✗ Wrong — misleads buyers about how to recover
196
- resolve: async (_ref, ctx) => {
197
- const account = await db.findByPrincipal(extractKey(ctx?.authInfo));
228
+ resolve: async (ref, ctx) => {
229
+ const key = extractKey(ctx?.authInfo);
230
+ if (!key) return null;
231
+ const account = ref === undefined
232
+ ? await db.findAccountByPrincipalKey(key)
233
+ : await db.findSyncedAccountByNaturalKey(key, ref);
198
234
  if (!account) throw new AdcpError('AUTH_MISSING', { message: 'call sync_accounts first' });
199
235
  return account;
200
236
  },
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
- > Generated at: 2026-10-04
4
- > Library: @adcp/sdk v14.1.0
3
+ > Generated at: 2026-10-05
4
+ > Library: @adcp/sdk v14.2.0
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.
@@ -0,0 +1,85 @@
1
+ # Migrating from SDK 14.0 to 14.1
2
+
3
+ SDK **14.1.0** still uses AdCP **3.2.1** on the wire. Its signature verification
4
+ adopts the AdCP 3.3 agent-resolution algorithm; this does not upgrade your wire
5
+ protocol or require enabling a new media-buy lifecycle.
6
+
7
+ ```sh
8
+ npm install @adcp/sdk@14.1.0
9
+ ```
10
+
11
+ Account policies and strict account references keep their 14.0 defaults. Check
12
+ the applicable rows below before rolling out: some TypeScript types change,
13
+ and signature verification rejects identities or keys it cannot confirm.
14
+
15
+ ## Required changes when applicable
16
+
17
+ | If your integration… | Change for 14.1 |
18
+ |---|---|
19
+ | Exhaustively switches over `WholesaleFeedSyncState` | Add a `degraded` case. A failed refresh preserves an existing mirror and marks it degraded; an initial failure still sets `error`. |
20
+ | Reads registry refresh fence fields as required values | Handle `undefined` on the deprecated fields in `AgentComplianceDetail.refresh_availability` and the `refreshAgent` 503 response. For example, use `refresh_availability.code ?? 'unknown'` for a local display label. The live registry no longer returns these fields; removal from SDK types is planned for the next major release. |
21
+ | Uses a standalone `BrandJsonJwksResolver` with A2A | Set `protocol: 'a2a'`. Capability discovery defaults to MCP; the onboarding record does not select the transport. |
22
+ | Supplies a natural-key account reference to an implicit seller | Resolve the complete key within the authenticated caller's synced roster. Include brand identity, operator, operator unit, currency, timezone, and sandbox. An unknown supplied reference must return `null`, never fall back to another account. See [account resolution](./guides/account-resolution.md#implicit-deep-dive). |
23
+ | Stores non-canonical issuer URLs in governance principal, replay, or revocation indexes | Migrate those keys to the canonical issuer identity before switching verification. Preserve replay and revocation history; use the [signature migration guide](./migration-agent-resolution-3.3.md) to check normalization rules. |
24
+ | Configures JWKS or operator discovery cache limits | Review the bounds in the [signature migration guide](./migration-agent-resolution-3.3.md). Brand discovery requires positive `maxAgeSeconds`; non-finite or negative cache options fail configuration validation. Expired mappings and keys are refused rather than reused. |
25
+ | Repairs wholesale mirrors from webhook deliveries | Acknowledge only after `refresh()` or repair succeeds. Failed catalog reads now reject, preserving the mirror and leaving the delivery eligible for retry. |
26
+
27
+ For the complete list of newly optional registry fields, see the
28
+ [14.1.0 changelog](https://github.com/adcontextprotocol/adcp-client/blob/main/CHANGELOG.md#1410).
29
+
30
+ ## Security behavior to verify
31
+
32
+ Existing resolver constructor signatures remain supported, but accepting a key
33
+ now requires a confirmed canonical agent identity and the capabilities-selected
34
+ operator record. Ambiguous onboarding and unconfirmed cross-domain mappings
35
+ fail closed. Prefer supplying the expected `agentUrl` already recorded by your
36
+ integration.
37
+
38
+ Publisher-pinned webhook keys must also appear in the agent JWKS as the same
39
+ public key. Resolve pins from your persisted registration and media-buy record
40
+ for every affected publisher, rather than selecting publishers from the webhook
41
+ payload. Refresh callbacks must throw on fetch failure; `null` confirms removal
42
+ of a pin. Follow the [publisher-pin migration guidance](./migration-agent-resolution-3.3.md#publisher-pin-context).
43
+
44
+ `SingleAgentClient` and `BrandJsonJwksResolver` retain legacy 3.x webhook
45
+ fallback by default. A standalone `ResolvedAgentJwksResolver` requires explicit
46
+ opt-in. That fallback does not authorize request signatures.
47
+
48
+ Signed MCP and A2A HTTP 401 errors now retain signature diagnostics and repair
49
+ guidance. Explicit Signature-challenge rejections skip unsigned authentication
50
+ probes and credential refresh retries. Bare signed 401s retain the existing
51
+ single client-credentials refresh attempt.
52
+
53
+ ## Optional adoption
54
+
55
+ | Feature | Default and adoption path |
56
+ |---|---|
57
+ | Buyer account registry | `accountPolicy` remains `'off'`. Set `'auto'` or `'strict'` to enforce setup, or configure registry storage/scope/capacity to opt into memoized `resolveAccount()`. Without opt-in, that helper still sends `sync_accounts` on each call. See [first call to a seller](./guides/FIRST-CALL-TO-A-SELLER.md). |
58
+ | Product cache | Opt in with `createProductCache`. Public and account-scoped responses stay separate; missing `cache_scope` prevents caching. See [buyer setup and caching](./guides/FIRST-CALL-TO-A-SELLER.md). |
59
+ | Strict seller account references | `strictAccountReferences` remains false; compatibility paths warn. Move reference authorization into `resolveAccount`, then set it to true. It becomes the default in the next major release. See [strict account references](./guides/account-resolution.md#strict-account-references-strictaccountreferences). |
60
+ | Additive implicit account sync | `InMemoryImplicitAccountStore` keeps replacement sync semantics and its 24-hour TTL. Set `mergeOnUpsert: true` for additive batches; `delete_missing: true` still requests replacement. Use `remove(ref, ctx)` for individual revocation. |
61
+
62
+ Account resolvers now receive `ctx.provisioning`. Discovery and negotiation
63
+ must remain lookup-only; gate any lazy account creation on this flag. The
64
+ [seller account guide](./guides/account-resolution.md) includes an example.
65
+
66
+ ## Check your rollout
67
+
68
+ - Compile your application to catch the new state and optional registry fields.
69
+ - Exercise signed requests and webhooks against your actual agent/operator
70
+ records, including key rotation and any publisher pins.
71
+ - Check that supplied unknown or unauthorized account references are refused,
72
+ and that discovery does not create accounts.
73
+ - If you handle `sync_accounts` results, handle per-account notification
74
+ event-type failures. In strict request validation, valid siblings can proceed;
75
+ with `delete_missing: true`, the invalid batch is refused before writes.
76
+ Warn-mode validation remains advisory, as in 14.0.
77
+ - Exercise failed feed refreshes and webhook redelivery without losing the last
78
+ good mirror.
79
+
80
+ The published 14.1.0 artifact passed reporting core **4/4** and full lifecycle
81
+ **4/4** qualification, with integrity and provenance verified. This covers
82
+ Python producers and TypeScript consumers. It does not establish reverse-direction
83
+ parity or Python version-skew coverage; broader work remains in
84
+ [#3027](https://github.com/adcontextprotocol/adcp-client/issues/3027).
85
+ See the [published release and qualification evidence](https://github.com/adcontextprotocol/adcp-client/releases/tag/%40adcp/sdk%4014.1.0).
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
11
11
 
12
12
  | Fact | Value |
13
13
  | --- | --- |
14
- | Exact npm package | `@adcp/sdk@14.1.0` |
15
- | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@14.1.0 dist.integrity` |
14
+ | Exact npm package | `@adcp/sdk@14.2.0` |
15
+ | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@14.2.0 dist.integrity` |
16
16
  | Node.js runtime | `^20.19.0 || >=22.12.0` |
17
17
  | Default AdCP wire release | `3.2.1` |
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` |
@@ -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@14.1.0'
25
- npm view '@adcp/sdk@14.1.0' dist.integrity
24
+ npm install --save-exact '@adcp/sdk@14.2.0'
25
+ npm view '@adcp/sdk@14.2.0' dist.integrity
26
26
  ```
27
27
 
28
28
  ### Required and optional peers
@@ -1,8 +1,10 @@
1
1
  # Agent resolution and publisher pins
2
2
 
3
- The SDK follows the shared AdCP 3.3 agent-resolution algorithm for request,
4
- webhook and governance signatures. The protocol alignment changes key discovery
5
- and verification; it does not change the SDK's configured wire protocol version.
3
+ SDK 14.1 follows the shared AdCP 3.3 agent-resolution algorithm for request,
4
+ webhook and governance signatures. SDK 14.1.0 still uses **AdCP 3.2.1 on the
5
+ wire**: this alignment changes key discovery and verification, not the configured
6
+ wire protocol version. Start with the [14.0-to-14.1 upgrade checklist](./migration-14.0-to-14.1.md)
7
+ for required changes and opt-in features outside signature verification.
6
8
 
7
9
  ## Expected agent URLs
8
10
 
@@ -387,3 +387,7 @@ debug sink with redaction.
387
387
  - [ ] Multi-replica deployments use Redis or Postgres replay storage.
388
388
  - [ ] Signature failure never falls back to another auth scheme.
389
389
  - [ ] JSON parsing and side effects happen only after verification succeeds.
390
+
391
+ Legacy HMAC receivers can call `preflightWebhookRequest({ headers }, { maxSkewSeconds: 300 })`
392
+ from `@adcp/sdk/webhooks` before secret lookup. Success checks syntax/freshness;
393
+ then authenticate with `verifyWebhookRequest` using the secret and exact raw body.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "14.1.0",
3
+ "version": "14.2.0",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",
@@ -541,6 +541,7 @@
541
541
  "!dist/lib/schemas-data/*/bundled/**/*",
542
542
  "bin/**/*.js",
543
543
  "skills/**/*",
544
+ "!skills/*.previous/**/*",
544
545
  ".claude-plugin/**/*",
545
546
  "compliance/cache/3.0.25/**/*",
546
547
  "compliance/cache/3.1.24/**/*",
@@ -1,200 +0,0 @@
1
- ---
2
- name: adcp-brand
3
- description: Execute AdCP Brand Protocol operations with brand agents - get brand identity data, search for licensable rights, acquire rights for campaigns, and manage existing grants. Use when users want to look up brand identities, find talent or IP for licensing, or manage rights grants.
4
- ---
5
-
6
- # AdCP Brand Protocol
7
-
8
- This skill enables you to execute the AdCP Brand Protocol with brand agents. The Brand Protocol provides access to brand identity, creative guidelines, and licensable rights (talent, IP, content).
9
-
10
- > **Buyer-side basics** — idempotency replay, `oneOf` variants, async `status:'submitted'` polling, error recovery from `adcp_error.issues[]` — live in `skills/call-adcp-agent/SKILL.md`. This skill covers per-task semantics only.
11
-
12
- ## Overview
13
-
14
- The Brand Protocol provides 4 standardized tasks:
15
-
16
- | Task | Purpose | Response Time |
17
- |------|---------|---------------|
18
- | `get_brand_identity` | Get brand identity and guidelines | ~1-3s |
19
- | `get_rights` | Search licensable rights | ~1-5s |
20
- | `acquire_rights` | Acquire rights for a campaign | ~1-10s |
21
- | `update_rights` | Modify an existing grant | ~1-5s |
22
-
23
- ## Typical Workflow
24
-
25
- ### Brand Identity Lookup
26
- 1. **Get identity**: `get_brand_identity` with brand domain and optional field filter
27
- 2. **Use data**: Apply colors, logos, tone, guidelines to creative generation
28
-
29
- ### Rights Licensing
30
- 1. **Search rights**: `get_rights` with natural language query and use types
31
- 2. **Review options**: Evaluate matches by pricing, availability, compatibility
32
- 3. **Acquire**: `acquire_rights` with selected pricing option and campaign details
33
- 4. **Manage**: `update_rights` to extend, adjust caps, or pause/resume
34
-
35
- ---
36
-
37
- ## Task Reference
38
-
39
- ### get_brand_identity
40
-
41
- Get brand identity data from a brand agent.
42
-
43
- **Request:**
44
- ```json
45
- {
46
- "brand_id": "athlete-jane-doe",
47
- "fields": ["description", "logos", "colors", "tone"],
48
- "use_case": "creative_production",
49
- "authorized": true
50
- }
51
- ```
52
-
53
- **Key fields:**
54
- - `brand_id` (string, required): Brand identifier within the agent's roster
55
- - `fields` (array, optional): Sections to include — `description`, `industry`, `keller_type`, `logos`, `colors`, `fonts`, `visual_guidelines`, `tone`, `tagline`, `voice_synthesis`, `assets`, `rights`. Omit for all.
56
- - `use_case` (string, optional): Intended use — `endorsement`, `voice_synthesis`, `likeness`, `creative_production`, `media_planning`
57
- - `authorized` (boolean, optional): Sandbox only — simulate authorized access to see protected fields. Real agents use OAuth. Default false.
58
-
59
- **Response contains:**
60
- - `brand`: Brand identity object with requested fields
61
- - Public fields (always available): `description`, `industry`, `logos` (public subset)
62
- - Protected fields (require authorization): `colors`, `fonts`, `tone`, `voice_synthesis`, `visual_guidelines`, full `assets`
63
-
64
- ---
65
-
66
- ### get_rights
67
-
68
- Search for licensable rights (talent, IP, content) from a brand agent.
69
-
70
- **Request:**
71
- ```json
72
- {
73
- "query": "Dutch athlete for restaurant brand in Amsterdam, budget 400 EUR/month",
74
- "uses": ["likeness", "endorsement"],
75
- "buyer_brand": {
76
- "domain": "restaurant.nl"
77
- },
78
- "countries": ["NL"],
79
- "include_excluded": false
80
- }
81
- ```
82
-
83
- **Key fields:**
84
- - `query` (string, required): Natural language description of desired rights
85
- - `uses` (array, required): Rights uses — `likeness`, `voice`, `name`, `endorsement`
86
- - `buyer_brand` (object, optional): Buyer brand for compatibility filtering — `{ domain, brand_id }`
87
- - `countries` (array, optional): Countries where rights are needed (ISO 3166-1 alpha-2)
88
- - `brand_id` (string, optional): Search within a specific brand only
89
- - `include_excluded` (boolean, optional): Include filtered-out results with reasons. Default false.
90
-
91
- **Response contains:**
92
- - `rights`: Array of matching rights offerings with:
93
- - `rights_id`: Use in `acquire_rights`
94
- - `brand_id`, `name`, `description`: Who/what the rights cover
95
- - `uses`: Available use types
96
- - `pricing_options`: Array with `pricing_option_id`, `price`, `currency`, `period`
97
- - `availability`: Geographic and temporal restrictions
98
- - `exclusions`: Any brand/category conflicts
99
-
100
- ---
101
-
102
- ### acquire_rights
103
-
104
- Acquire rights from a brand agent for a campaign.
105
-
106
- **Request:**
107
- ```json
108
- {
109
- "rights_id": "rights_jane_doe_endorsement",
110
- "pricing_option_id": "monthly_standard",
111
- "buyer": {
112
- "domain": "restaurant.nl"
113
- },
114
- "campaign": {
115
- "description": "Social media campaign featuring athlete endorsement for Amsterdam restaurant launch",
116
- "uses": ["likeness", "endorsement"],
117
- "countries": ["NL"],
118
- "estimated_impressions": 500000,
119
- "start_date": "2025-03-01",
120
- "end_date": "2025-06-30"
121
- }
122
- }
123
- ```
124
-
125
- **Key fields:**
126
- - `rights_id` (string, required): From `get_rights` response
127
- - `pricing_option_id` (string, required): Selected pricing option
128
- - `buyer` (object, required): Buyer brand identity — `{ domain, brand_id }`
129
- - `campaign` (object, required): Campaign details for rights clearance
130
- - `description` (string, required): How the rights will be used
131
- - `uses` (array, required): Rights uses for this campaign
132
- - `countries` (array, optional): Campaign countries
133
- - `estimated_impressions` (integer, optional): Estimated total impressions
134
- - `start_date`, `end_date` (string, optional): Campaign dates (YYYY-MM-DD)
135
-
136
- **Response contains:**
137
- - `status`: `acquired`, `pending_approval`, or `rejected`
138
- - `rights_grant_id`: Grant identifier (if acquired)
139
- - `generation_credentials`: Credentials for AI generation (voice synthesis, likeness, etc.)
140
- - `rejection_reason`: Why the request was rejected (category conflict, exclusivity, etc.)
141
-
142
- ---
143
-
144
- ### update_rights
145
-
146
- Update an existing rights grant — extend dates, adjust impression caps, or pause/resume.
147
-
148
- **Request:**
149
- ```json
150
- {
151
- "rights_id": "grant_abc123",
152
- "end_date": "2025-09-30",
153
- "impression_cap": 1000000,
154
- "paused": false
155
- }
156
- ```
157
-
158
- **Key fields:**
159
- - `rights_id` (string, required): Rights grant identifier from `acquire_rights`
160
- - `end_date` (string, optional): New end date (must be >= current end date)
161
- - `impression_cap` (number, optional): New impression cap (must be >= current)
162
- - `paused` (boolean, optional): Pause or resume the grant
163
-
164
- ---
165
-
166
- ## Key Concepts
167
-
168
- ### Public vs Protected Fields
169
-
170
- Brand agents distinguish between public and protected data:
171
- - **Public**: Available without authorization — basic description, industry, public logos
172
- - **Protected**: Requires OAuth or authorized flag — colors, fonts, tone, voice synthesis credentials, full asset library
173
-
174
- ### Rights Use Types
175
-
176
- - `likeness`: Use of a person's visual likeness (photos, AI-generated images)
177
- - `voice`: Voice synthesis or audio recording rights
178
- - `name`: Use of a person's name in advertising
179
- - `endorsement`: Endorsement/testimonial rights
180
-
181
- ### Rights Clearance
182
-
183
- `acquire_rights` checks:
184
- 1. Brand/category compatibility (no competitor conflicts)
185
- 2. Geographic availability
186
- 3. Temporal availability
187
- 4. Existing exclusivity agreements
188
-
189
- Results: `acquired` (immediate), `pending_approval` (human review), or `rejected` (with reason).
190
-
191
- ---
192
-
193
- ## Error Handling
194
-
195
- Common error codes:
196
-
197
- - `REFERENCE_NOT_FOUND`: Invalid brand_id, rights_id, or pricing_option_id (brand-protocol resources use the universal not-found fallback per `error-handling.mdx`; brands lack a dedicated `*_NOT_FOUND` code)
198
- - `CATEGORY_CONFLICT`: Buyer brand conflicts with existing agreements
199
- - `GEOGRAPHIC_RESTRICTION`: Rights not available in requested countries
200
- - `AUTHORIZATION_REQUIRED`: Protected fields require OAuth