@adcp/sdk 14.1.0 → 14.3.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 (139) 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/reporting/inspection.d.mts +3 -3
  22. package/dist/lib/reporting/inspection.d.ts +3 -3
  23. package/dist/lib/reporting/inspection.js +229 -84
  24. package/dist/lib/reporting/inspection.mjs +229 -84
  25. package/dist/lib/reporting/ledger/status-ingest.js +3 -19
  26. package/dist/lib/reporting/ledger/status-ingest.mjs +2 -18
  27. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  28. package/dist/lib/server/create-adcp-server.js +5 -2
  29. package/dist/lib/server/create-adcp-server.mjs +5 -2
  30. package/dist/lib/signing/agent-resolver/errors.d.mts +2 -0
  31. package/dist/lib/signing/agent-resolver/errors.d.ts +2 -0
  32. package/dist/lib/signing/agent-resolver/errors.js +6 -0
  33. package/dist/lib/signing/agent-resolver/errors.mjs +6 -0
  34. package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +9 -0
  35. package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +9 -0
  36. package/dist/lib/signing/agent-resolver/fetch-helpers.js +35 -1
  37. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +38 -2
  38. package/dist/lib/signing/agent-resolver/legacy-brand.js +1 -1
  39. package/dist/lib/signing/agent-resolver/legacy-brand.mjs +2 -2
  40. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +1 -1
  41. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +1 -1
  42. package/dist/lib/signing/agent-resolver/resolve-agent.js +47 -5
  43. package/dist/lib/signing/agent-resolver/resolve-agent.mjs +55 -6
  44. package/dist/lib/signing/brand-jwks.d.mts +2 -0
  45. package/dist/lib/signing/brand-jwks.d.ts +2 -0
  46. package/dist/lib/signing/brand-jwks.js +10 -2
  47. package/dist/lib/signing/brand-jwks.mjs +10 -2
  48. package/dist/lib/signing/canonicalize.d.mts +2 -0
  49. package/dist/lib/signing/canonicalize.d.ts +2 -0
  50. package/dist/lib/signing/canonicalize.js +1 -1
  51. package/dist/lib/signing/canonicalize.mjs +1 -1
  52. package/dist/lib/signing/errors.d.mts +4 -2
  53. package/dist/lib/signing/errors.d.ts +4 -2
  54. package/dist/lib/signing/errors.js +3 -1
  55. package/dist/lib/signing/errors.mjs +3 -1
  56. package/dist/lib/signing/verifier.js +2 -2
  57. package/dist/lib/signing/verifier.mjs +2 -2
  58. package/dist/lib/signing/webhook-verifier.js +2 -2
  59. package/dist/lib/signing/webhook-verifier.mjs +3 -3
  60. package/dist/lib/testing/storyboard/request-signing/builder.js +13 -1
  61. package/dist/lib/testing/storyboard/request-signing/builder.mjs +13 -1
  62. package/dist/lib/testing/storyboard/request-signing/grader.js +1 -0
  63. package/dist/lib/testing/storyboard/request-signing/grader.mjs +1 -0
  64. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +1 -1
  65. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +1 -1
  66. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  67. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  68. package/dist/lib/types/accept-proposal.d.ts +19 -1
  69. package/dist/lib/types/buy-products.d.ts +19 -1
  70. package/dist/lib/types/check-governance.d.ts +19 -1
  71. package/dist/lib/types/comply-test-controller.d.ts +19 -1
  72. package/dist/lib/types/control-media-buy.d.ts +19 -1
  73. package/dist/lib/types/core.generated.d.mts +14 -1
  74. package/dist/lib/types/core.generated.d.ts +14 -1
  75. package/dist/lib/types/create-media-buy.d.ts +14 -1
  76. package/dist/lib/types/get-media-buys.d.ts +14 -1
  77. package/dist/lib/types/get-products.d.ts +19 -1
  78. package/dist/lib/types/list-products.d.ts +19 -1
  79. package/dist/lib/types/refine-proposals.d.ts +19 -1
  80. package/dist/lib/types/request-proposals.d.ts +19 -1
  81. package/dist/lib/types/schemas.generated.d.ts +12 -3
  82. package/dist/lib/types/schemas.generated.js +4 -1
  83. package/dist/lib/types/schemas.generated.mjs +4 -1
  84. package/dist/lib/types/tools.generated.d.mts +14 -1
  85. package/dist/lib/types/tools.generated.d.ts +14 -1
  86. package/dist/lib/types/update-media-buy.d.ts +14 -1
  87. package/dist/lib/utils/pointer-utils.d.mts +2 -0
  88. package/dist/lib/utils/pointer-utils.d.ts +2 -0
  89. package/dist/lib/utils/pointer-utils.js +43 -0
  90. package/dist/lib/utils/pointer-utils.mjs +19 -0
  91. package/dist/lib/validation/diagnostic-limits.d.mts +4 -0
  92. package/dist/lib/validation/diagnostic-limits.d.ts +4 -0
  93. package/dist/lib/validation/diagnostic-limits.js +57 -0
  94. package/dist/lib/validation/diagnostic-limits.mjs +32 -0
  95. package/dist/lib/validation/schema-errors.d.mts +3 -1
  96. package/dist/lib/validation/schema-errors.d.ts +3 -1
  97. package/dist/lib/validation/schema-errors.js +18 -3
  98. package/dist/lib/validation/schema-errors.mjs +18 -3
  99. package/dist/lib/validation/schema-validator.js +56 -4
  100. package/dist/lib/validation/schema-validator.mjs +56 -4
  101. package/dist/lib/version.d.mts +3 -3
  102. package/dist/lib/version.d.ts +3 -3
  103. package/dist/lib/version.js +3 -3
  104. package/dist/lib/version.mjs +3 -3
  105. package/dist/lib/webhooks/index.d.mts +24 -0
  106. package/dist/lib/webhooks/index.d.ts +24 -0
  107. package/dist/lib/webhooks/index.js +50 -24
  108. package/dist/lib/webhooks/index.mjs +49 -24
  109. package/dist/lib/wholesale-feed-sync/index.d.mts +2 -0
  110. package/dist/lib/wholesale-feed-sync/index.d.ts +2 -0
  111. package/dist/lib/wholesale-feed-sync/index.js +7 -0
  112. package/dist/lib/wholesale-feed-sync/index.mjs +4 -0
  113. package/dist/lib/wholesale-feed-sync/mirror.d.mts +97 -0
  114. package/dist/lib/wholesale-feed-sync/mirror.d.ts +97 -0
  115. package/dist/lib/wholesale-feed-sync/mirror.js +350 -0
  116. package/dist/lib/wholesale-feed-sync/mirror.mjs +322 -0
  117. package/dist/lib/wholesale-feed-sync/sync.d.mts +12 -29
  118. package/dist/lib/wholesale-feed-sync/sync.d.ts +12 -29
  119. package/dist/lib/wholesale-feed-sync/sync.js +153 -297
  120. package/dist/lib/wholesale-feed-sync/sync.mjs +158 -297
  121. package/docs/README.md +6 -0
  122. package/docs/TYPE-SUMMARY.md +2 -2
  123. package/docs/guides/BUYER-STORAGE.md +3 -0
  124. package/docs/guides/FIRST-CALL-TO-A-SELLER.md +3 -1
  125. package/docs/guides/account-resolution.md +46 -10
  126. package/docs/llms.txt +2 -2
  127. package/docs/migration-14.0-to-14.1.md +85 -0
  128. package/docs/migration-14.x-rc-worksheet.md +4 -4
  129. package/docs/migration-agent-resolution-3.3.md +5 -3
  130. package/docs/recipes/verifying-inbound-webhooks.md +4 -0
  131. package/package.json +3 -2
  132. package/skills/call-adcp-agent/SKILL.md +4 -1
  133. package/skills/adcp-brand.previous/SKILL.md +0 -200
  134. package/skills/adcp-creative.previous/SKILL.md +0 -305
  135. package/skills/adcp-governance.previous/SKILL.md +0 -566
  136. package/skills/adcp-measurement.previous/SKILL.md +0 -136
  137. package/skills/adcp-media-buy.previous/SKILL.md +0 -556
  138. package/skills/adcp-si.previous/SKILL.md +0 -206
  139. package/skills/adcp-signals.previous/SKILL.md +0 -204
@@ -68,5 +68,7 @@ export declare function formatSignatureParams(components: ReadonlyArray<string>,
68
68
  * non-transitional produce different A-labels for the same input, which
69
69
  * would open a signer/verifier canonicalization differential. Accepts
70
70
  * both absolute (`scheme://…`) and scheme-relative (`//…`) URL shapes.
71
+ * The transport taxonomy classifies the received URI as malformed. Diagnostic
72
+ * step 1 is SDK-local parsing, not the checklist's signature-header parser.
71
73
  */
72
74
  export declare function rejectNonAsciiHost(rawUrl: string): void;
@@ -68,5 +68,7 @@ export declare function formatSignatureParams(components: ReadonlyArray<string>,
68
68
  * non-transitional produce different A-labels for the same input, which
69
69
  * would open a signer/verifier canonicalization differential. Accepts
70
70
  * both absolute (`scheme://…`) and scheme-relative (`//…`) URL shapes.
71
+ * The transport taxonomy classifies the received URI as malformed. Diagnostic
72
+ * step 1 is SDK-local parsing, not the checklist's signature-header parser.
71
73
  */
72
74
  export declare function rejectNonAsciiHost(rawUrl: string): void;
@@ -269,7 +269,7 @@ function rejectNonAsciiHost(rawUrl) {
269
269
  for (let i = 0; i < authority.length; i++) {
270
270
  if (authority.charCodeAt(i) > 127) {
271
271
  throw new import_errors.RequestSignatureError(
272
- "request_signature_header_malformed",
272
+ "request_target_uri_malformed",
273
273
  1,
274
274
  "URL authority contains non-ASCII bytes; use the A-label (Punycode) form"
275
275
  );
@@ -239,7 +239,7 @@ function rejectNonAsciiHost(rawUrl) {
239
239
  for (let i = 0; i < authority.length; i++) {
240
240
  if (authority.charCodeAt(i) > 127) {
241
241
  throw new RequestSignatureError(
242
- "request_signature_header_malformed",
242
+ "request_target_uri_malformed",
243
243
  1,
244
244
  "URL authority contains non-ASCII bytes; use the A-label (Punycode) form"
245
245
  );
@@ -1,12 +1,14 @@
1
1
  import { ADCPError } from '../errors/index.mjs';
2
2
  import type { RequestSigningErrorCode } from '../types/core.generated.mjs';
3
- export { RequestSigningErrorCodeMetadata } from '../types/enums.generated.mjs';
3
+ import { RequestSigningErrorCodeMetadata } from '../types/enums.generated.mjs';
4
+ export { RequestSigningErrorCodeMetadata };
4
5
  /** Canonical rc.6 request-signing transport vocabulary. */
5
6
  export type RequestSignatureErrorCode = RequestSigningErrorCode;
6
7
  export declare class RequestSignatureError extends ADCPError {
7
8
  readonly code: RequestSignatureErrorCode;
8
9
  readonly failedStep: number;
9
- constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown);
10
+ readonly recovery: 'transient' | 'correctable' | 'terminal';
11
+ constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown, recovery?: 'transient' | 'correctable' | 'terminal');
10
12
  }
11
13
  /**
12
14
  * Error codes surfaced by the RFC 9421 webhook-signing verifier. Maps onto
@@ -1,12 +1,14 @@
1
1
  import { ADCPError } from '../errors';
2
2
  import type { RequestSigningErrorCode } from '../types/core.generated';
3
- export { RequestSigningErrorCodeMetadata } from '../types/enums.generated';
3
+ import { RequestSigningErrorCodeMetadata } from '../types/enums.generated';
4
+ export { RequestSigningErrorCodeMetadata };
4
5
  /** Canonical rc.6 request-signing transport vocabulary. */
5
6
  export type RequestSignatureErrorCode = RequestSigningErrorCode;
6
7
  export declare class RequestSignatureError extends ADCPError {
7
8
  readonly code: RequestSignatureErrorCode;
8
9
  readonly failedStep: number;
9
- constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown);
10
+ readonly recovery: 'transient' | 'correctable' | 'terminal';
11
+ constructor(code: RequestSignatureErrorCode, failedStep: number, message: string, details?: unknown, recovery?: 'transient' | 'correctable' | 'terminal');
10
12
  }
11
13
  /**
12
14
  * Error codes surfaced by the RFC 9421 webhook-signing verifier. Maps onto
@@ -30,10 +30,12 @@ var import_enums = require('../types/enums.generated.js');
30
30
  class RequestSignatureError extends import_errors.ADCPError {
31
31
  code;
32
32
  failedStep;
33
- constructor(code, failedStep, message, details) {
33
+ recovery;
34
+ constructor(code, failedStep, message, details, recovery) {
34
35
  super(message, details);
35
36
  this.code = code;
36
37
  this.failedStep = failedStep;
38
+ this.recovery = recovery ?? import_enums.RequestSigningErrorCodeMetadata[code].recovery;
37
39
  }
38
40
  }
39
41
  class WebhookSignatureError extends import_errors.ADCPError {
@@ -3,10 +3,12 @@ import { RequestSigningErrorCodeMetadata } from "../types/enums.generated.mjs";
3
3
  class RequestSignatureError extends ADCPError {
4
4
  code;
5
5
  failedStep;
6
- constructor(code, failedStep, message, details) {
6
+ recovery;
7
+ constructor(code, failedStep, message, details, recovery) {
7
8
  super(message, details);
8
9
  this.code = code;
9
10
  this.failedStep = failedStep;
11
+ this.recovery = recovery ?? RequestSigningErrorCodeMetadata[code].recovery;
10
12
  }
11
13
  }
12
14
  class WebhookSignatureError extends ADCPError {
@@ -99,7 +99,7 @@ async function verifyRequestSignature(request, options) {
99
99
  if (!parsedSig) throw parseError;
100
100
  const effectiveEncoding = pinnedBinaryEncoding ?? parsedEncoding;
101
101
  const canonicalizationProfile = effectiveEncoding === "rfc8941-base64" ? "3.2" : "legacy";
102
- if (canonicalizationProfile === "legacy") (0, import_canonicalize.rejectNonAsciiHost)(request.url);
102
+ (0, import_canonicalize.rejectNonAsciiHost)(request.url);
103
103
  validateSingleValuedCoveredHeaders(parsedInput.components, request);
104
104
  requireParams(parsedInput);
105
105
  if (parsedInput.params.tag !== import_types.REQUEST_SIGNING_TAG) {
@@ -141,7 +141,7 @@ async function verifyRequestSignature(request, options) {
141
141
  }
142
142
  } catch (err) {
143
143
  if (err instanceof import_errors2.AgentResolverError) {
144
- throw new import_errors.RequestSignatureError(err.code, 7, err.message, err.detail);
144
+ throw new import_errors.RequestSignatureError(err.code, 7, err.message, err.detail, err.recovery);
145
145
  }
146
146
  throw err;
147
147
  }
@@ -92,7 +92,7 @@ async function verifyRequestSignature(request, options) {
92
92
  if (!parsedSig) throw parseError;
93
93
  const effectiveEncoding = pinnedBinaryEncoding ?? parsedEncoding;
94
94
  const canonicalizationProfile = effectiveEncoding === "rfc8941-base64" ? "3.2" : "legacy";
95
- if (canonicalizationProfile === "legacy") rejectNonAsciiHost(request.url);
95
+ rejectNonAsciiHost(request.url);
96
96
  validateSingleValuedCoveredHeaders(parsedInput.components, request);
97
97
  requireParams(parsedInput);
98
98
  if (parsedInput.params.tag !== REQUEST_SIGNING_TAG) {
@@ -134,7 +134,7 @@ async function verifyRequestSignature(request, options) {
134
134
  }
135
135
  } catch (err) {
136
136
  if (err instanceof AgentResolverError) {
137
- throw new RequestSignatureError(err.code, 7, err.message, err.detail);
137
+ throw new RequestSignatureError(err.code, 7, err.message, err.detail, err.recovery);
138
138
  }
139
139
  throw err;
140
140
  }
@@ -37,8 +37,8 @@ var import_replay = require('./replay.js');
37
37
  var import_revocation = require('./revocation.js');
38
38
  var import_types = require('./types.js');
39
39
  function keyDiscoveryRetryable(error) {
40
- if (error instanceof import_errors2.AgentResolverError) return import_errors.RequestSigningErrorCodeMetadata[error.code].recovery === "transient";
41
- if (error instanceof import_brand_jwks.BrandJsonResolverError) return error.code === "fetch_failed";
40
+ if (error instanceof import_errors2.AgentResolverError) return error.recovery === "transient";
41
+ if (error instanceof import_brand_jwks.BrandJsonResolverError) return error.recovery === "transient";
42
42
  return true;
43
43
  }
44
44
  const WEBHOOK_SIGNING_TAG = "adcp/webhook-signing/v1";
@@ -1,6 +1,6 @@
1
1
  import { buildSignatureBase, canonicalTargetUri, getHeaderValue } from "./canonicalize.mjs";
2
2
  import { contentDigestMatches } from "./content-digest.mjs";
3
- import { RequestSignatureError, WebhookSignatureError, RequestSigningErrorCodeMetadata } from "./errors.mjs";
3
+ import { RequestSignatureError, WebhookSignatureError } from "./errors.mjs";
4
4
  import { AgentResolverError } from "./agent-resolver/errors.mjs";
5
5
  import { BrandJsonResolverError } from "./brand-jwks.mjs";
6
6
  import { parseSignature, parseSignatureInput } from "./parser.mjs";
@@ -10,8 +10,8 @@ import { InMemoryReplayStore } from "./replay.mjs";
10
10
  import { InMemoryRevocationStore } from "./revocation.mjs";
11
11
  import { ALLOWED_ALGS, CLOCK_SKEW_TOLERANCE_SECONDS, MAX_SIGNATURE_WINDOW_SECONDS } from "./types.mjs";
12
12
  function keyDiscoveryRetryable(error) {
13
- if (error instanceof AgentResolverError) return RequestSigningErrorCodeMetadata[error.code].recovery === "transient";
14
- if (error instanceof BrandJsonResolverError) return error.code === "fetch_failed";
13
+ if (error instanceof AgentResolverError) return error.recovery === "transient";
14
+ if (error instanceof BrandJsonResolverError) return error.recovery === "transient";
15
15
  return true;
16
16
  }
17
17
  const WEBHOOK_SIGNING_TAG = "adcp/webhook-signing/v1";
@@ -192,6 +192,7 @@ const MUTATIONS = {
192
192
  // transport-ungradable by the live probe because no HTTP client can route
193
193
  // to that intentionally invalid host spelling.
194
194
  "profile-3.2/negative/001-base64url-sf-binary": (vector, _keys, options) => passthrough(vector, options),
195
+ "profile-3.2/negative/001-no-signature-header": delegateToRoot("001-no-signature-header"),
195
196
  "profile-3.2/negative/002-multiple-trailing-dots": (vector, _keys, options) => passthrough(vector, options),
196
197
  "profile-3.2/negative/002-wrong-tag": delegateToRoot("002-wrong-tag"),
197
198
  "profile-3.2/negative/003-expired-signature": delegateToRoot("003-expired-signature"),
@@ -208,6 +209,7 @@ const MUTATIONS = {
208
209
  "profile-3.2/negative/008-unknown-keyid": delegateToRoot("008-unknown-keyid"),
209
210
  "profile-3.2/negative/009-key-ops-missing-verify": delegateToRoot("009-key-ops-missing-verify"),
210
211
  "profile-3.2/negative/010-content-digest-mismatch": delegateToRoot("010-content-digest-mismatch"),
212
+ "profile-3.2/negative/011-malformed-header": delegateToRoot("011-malformed-header"),
211
213
  "profile-3.2/negative/012-missing-expires-param": delegateToRoot("012-missing-expires-param"),
212
214
  "profile-3.2/negative/013-expires-le-created": delegateToRoot("013-expires-le-created"),
213
215
  "profile-3.2/negative/014-missing-nonce-param": delegateToRoot("014-missing-nonce-param"),
@@ -220,8 +222,18 @@ const MUTATIONS = {
220
222
  },
221
223
  "profile-3.2/negative/016-replayed-nonce": delegateToRoot("016-replayed-nonce"),
222
224
  "profile-3.2/negative/017-key-revoked": delegateToRoot("017-key-revoked"),
225
+ "profile-3.2/negative/019-signature-without-signature-input": delegateToRoot("019-signature-without-signature-input"),
223
226
  "profile-3.2/negative/020-rate-abuse": delegateToRoot("020-rate-abuse"),
224
- "profile-3.2/negative/025-jwk-alg-crv-mismatch": delegateToRoot("025-jwk-alg-crv-mismatch")
227
+ "profile-3.2/negative/021-duplicate-signature-input-label": delegateToRoot("021-duplicate-signature-input-label"),
228
+ "profile-3.2/negative/022-multi-valued-content-type": delegateToRoot("022-multi-valued-content-type"),
229
+ "profile-3.2/negative/023-multi-valued-content-digest": delegateToRoot("023-multi-valued-content-digest"),
230
+ "profile-3.2/negative/024-unquoted-string-param": delegateToRoot("024-unquoted-string-param"),
231
+ "profile-3.2/negative/025-jwk-alg-crv-mismatch": delegateToRoot("025-jwk-alg-crv-mismatch"),
232
+ "profile-3.2/negative/026-non-ascii-host": delegateToRoot("026-non-ascii-host"),
233
+ "profile-3.2/negative/027-webhook-registration-authentication-unsigned": delegateToRoot(
234
+ "027-webhook-registration-authentication-unsigned"
235
+ ),
236
+ "profile-3.2/negative/028-unsigned-protocol-method-required": delegateToRoot("028-unsigned-protocol-method-required")
225
237
  };
226
238
  function delegateToRoot(rootId) {
227
239
  return (vector, keys, options) => {
@@ -175,6 +175,7 @@ const MUTATIONS = {
175
175
  // transport-ungradable by the live probe because no HTTP client can route
176
176
  // to that intentionally invalid host spelling.
177
177
  "profile-3.2/negative/001-base64url-sf-binary": (vector, _keys, options) => passthrough(vector, options),
178
+ "profile-3.2/negative/001-no-signature-header": delegateToRoot("001-no-signature-header"),
178
179
  "profile-3.2/negative/002-multiple-trailing-dots": (vector, _keys, options) => passthrough(vector, options),
179
180
  "profile-3.2/negative/002-wrong-tag": delegateToRoot("002-wrong-tag"),
180
181
  "profile-3.2/negative/003-expired-signature": delegateToRoot("003-expired-signature"),
@@ -191,6 +192,7 @@ const MUTATIONS = {
191
192
  "profile-3.2/negative/008-unknown-keyid": delegateToRoot("008-unknown-keyid"),
192
193
  "profile-3.2/negative/009-key-ops-missing-verify": delegateToRoot("009-key-ops-missing-verify"),
193
194
  "profile-3.2/negative/010-content-digest-mismatch": delegateToRoot("010-content-digest-mismatch"),
195
+ "profile-3.2/negative/011-malformed-header": delegateToRoot("011-malformed-header"),
194
196
  "profile-3.2/negative/012-missing-expires-param": delegateToRoot("012-missing-expires-param"),
195
197
  "profile-3.2/negative/013-expires-le-created": delegateToRoot("013-expires-le-created"),
196
198
  "profile-3.2/negative/014-missing-nonce-param": delegateToRoot("014-missing-nonce-param"),
@@ -203,8 +205,18 @@ const MUTATIONS = {
203
205
  },
204
206
  "profile-3.2/negative/016-replayed-nonce": delegateToRoot("016-replayed-nonce"),
205
207
  "profile-3.2/negative/017-key-revoked": delegateToRoot("017-key-revoked"),
208
+ "profile-3.2/negative/019-signature-without-signature-input": delegateToRoot("019-signature-without-signature-input"),
206
209
  "profile-3.2/negative/020-rate-abuse": delegateToRoot("020-rate-abuse"),
207
- "profile-3.2/negative/025-jwk-alg-crv-mismatch": delegateToRoot("025-jwk-alg-crv-mismatch")
210
+ "profile-3.2/negative/021-duplicate-signature-input-label": delegateToRoot("021-duplicate-signature-input-label"),
211
+ "profile-3.2/negative/022-multi-valued-content-type": delegateToRoot("022-multi-valued-content-type"),
212
+ "profile-3.2/negative/023-multi-valued-content-digest": delegateToRoot("023-multi-valued-content-digest"),
213
+ "profile-3.2/negative/024-unquoted-string-param": delegateToRoot("024-unquoted-string-param"),
214
+ "profile-3.2/negative/025-jwk-alg-crv-mismatch": delegateToRoot("025-jwk-alg-crv-mismatch"),
215
+ "profile-3.2/negative/026-non-ascii-host": delegateToRoot("026-non-ascii-host"),
216
+ "profile-3.2/negative/027-webhook-registration-authentication-unsigned": delegateToRoot(
217
+ "027-webhook-registration-authentication-unsigned"
218
+ ),
219
+ "profile-3.2/negative/028-unsigned-protocol-method-required": delegateToRoot("028-unsigned-protocol-method-required")
208
220
  };
209
221
  function delegateToRoot(rootId) {
210
222
  return (vector, keys, options) => {
@@ -134,6 +134,7 @@ const TRANSPORT_UNGRADABLE = {
134
134
  // agent as Punycode, defeating the parse-time check. Direct verifier
135
135
  // tests exercise this edge.
136
136
  "026-non-ascii-host": "HTTP transport punycodes U-labels before the request leaves the client; verified at the library level.",
137
+ "profile-3.2/negative/026-non-ascii-host": "HTTP transport punycodes U-labels before the request leaves the client; verified at the library level.",
137
138
  "profile-3.2/negative/002-multiple-trailing-dots": "HTTP transport cannot route to an intentionally malformed DNS authority; verified at the library level."
138
139
  };
139
140
  function semanticVectorExclusion(vector, declaredCapability) {
@@ -113,6 +113,7 @@ const TRANSPORT_UNGRADABLE = {
113
113
  // agent as Punycode, defeating the parse-time check. Direct verifier
114
114
  // tests exercise this edge.
115
115
  "026-non-ascii-host": "HTTP transport punycodes U-labels before the request leaves the client; verified at the library level.",
116
+ "profile-3.2/negative/026-non-ascii-host": "HTTP transport punycodes U-labels before the request leaves the client; verified at the library level.",
116
117
  "profile-3.2/negative/002-multiple-trailing-dots": "HTTP transport cannot route to an intentionally malformed DNS authority; verified at the library level."
117
118
  };
118
119
  function semanticVectorExclusion(vector, declaredCapability) {
@@ -39,7 +39,7 @@ function selectRequestSigningVectors(loaded, signingProfileVersion) {
39
39
  }
40
40
  function signingProfileForAdcpVersion(version) {
41
41
  const match = /^(\d+)\.(\d+)/.exec(version ?? "");
42
- return match && Number(match[1]) === 3 && Number(match[2]) === 2 ? "3.2" : void 0;
42
+ return match && (Number(match[1]) > 3 || Number(match[1]) === 3 && Number(match[2]) >= 2) ? "3.2" : void 0;
43
43
  }
44
44
  const ERROR_CODES = /* @__PURE__ */ new Set([
45
45
  "request_signature_required",
@@ -11,7 +11,7 @@ function selectRequestSigningVectors(loaded, signingProfileVersion) {
11
11
  }
12
12
  function signingProfileForAdcpVersion(version) {
13
13
  const match = /^(\d+)\.(\d+)/.exec(version ?? "");
14
- return match && Number(match[1]) === 3 && Number(match[2]) === 2 ? "3.2" : void 0;
14
+ return match && (Number(match[1]) > 3 || Number(match[1]) === 3 && Number(match[2]) >= 2) ? "3.2" : void 0;
15
15
  }
16
16
  const ERROR_CODES = /* @__PURE__ */ new Set([
17
17
  "request_signature_required",
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "14.1.0";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "14.3.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "14.1.0";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "14.3.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -145,6 +145,11 @@ export type ActivationKey = {
145
145
  */
146
146
  export type AdvertiserIndustry = 'automotive' | 'automotive.electric_vehicles' | 'automotive.parts_accessories' | 'automotive.luxury' | 'beauty_cosmetics' | 'beauty_cosmetics.skincare' | 'beauty_cosmetics.fragrance' | 'beauty_cosmetics.haircare' | 'cannabis' | 'cpg' | 'cpg.personal_care' | 'cpg.household' | 'dating' | 'education' | 'education.higher_education' | 'education.online_learning' | 'education.k12' | 'energy_utilities' | 'energy_utilities.renewable' | 'fashion_apparel' | 'fashion_apparel.luxury' | 'fashion_apparel.sportswear' | 'finance' | 'finance.banking' | 'finance.insurance' | 'finance.investment' | 'finance.cryptocurrency' | 'food_beverage' | 'food_beverage.alcohol' | 'food_beverage.restaurants' | 'food_beverage.packaged_goods' | 'gambling_betting' | 'gambling_betting.sports_betting' | 'gambling_betting.casino' | 'gaming' | 'gaming.mobile' | 'gaming.console_pc' | 'gaming.esports' | 'government_nonprofit' | 'government_nonprofit.political' | 'government_nonprofit.charity' | 'healthcare' | 'healthcare.pharmaceutical' | 'healthcare.medical_devices' | 'healthcare.wellness' | 'home_garden' | 'home_garden.furniture' | 'home_garden.home_improvement' | 'media_entertainment' | 'media_entertainment.podcasts' | 'media_entertainment.music' | 'media_entertainment.film_tv' | 'media_entertainment.publishing' | 'media_entertainment.live_events' | 'pets' | 'professional_services' | 'professional_services.legal' | 'professional_services.consulting' | 'real_estate' | 'real_estate.residential' | 'real_estate.commercial' | 'recruitment_hr' | 'retail' | 'retail.ecommerce' | 'retail.department_stores' | 'sports_fitness' | 'sports_fitness.equipment' | 'sports_fitness.teams_leagues' | 'technology' | 'technology.software' | 'technology.hardware' | 'technology.ai_ml' | 'telecom' | 'telecom.mobile_carriers' | 'telecom.internet_providers' | 'transportation_logistics' | 'travel_hospitality' | 'travel_hospitality.airlines' | 'travel_hospitality.hotels' | 'travel_hospitality.cruise' | 'travel_hospitality.tourism';
147
147
 
148
+ /**
149
+ * User-level bases that may resolve age for demographic targeting execution. Population estimates are deliberately absent because aggregate composition cannot establish an individual impression's age.
150
+ */
151
+ export type AgeDeterminationBasis = 'verified' | 'declared' | 'inferred';
152
+
148
153
  /**
149
154
  * Methods for verifying user age for compliance. Does not include 'inferred' as it is not accepted for regulatory compliance.
150
155
  */
@@ -1083,7 +1088,20 @@ export type DemographicSystem = 'nielsen' | 'nielsen_audio' | 'barb' | 'agf' | '
1083
1088
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
1084
1089
  */
1085
1090
  export interface DemographicTargetingIntent {
1086
- age: DemographicAgeRange & {};
1091
+ age: DemographicAgeRange & {
1092
+ /**
1093
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
1094
+ *
1095
+ * @minItems 1
1096
+ */
1097
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
1098
+ /**
1099
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
1100
+ *
1101
+ * @minItems 1
1102
+ */
1103
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
1104
+ };
1087
1105
  }
1088
1106
 
1089
1107
  /**
@@ -145,6 +145,11 @@ export type ActivationKey = {
145
145
  */
146
146
  export type AdvertiserIndustry = 'automotive' | 'automotive.electric_vehicles' | 'automotive.parts_accessories' | 'automotive.luxury' | 'beauty_cosmetics' | 'beauty_cosmetics.skincare' | 'beauty_cosmetics.fragrance' | 'beauty_cosmetics.haircare' | 'cannabis' | 'cpg' | 'cpg.personal_care' | 'cpg.household' | 'dating' | 'education' | 'education.higher_education' | 'education.online_learning' | 'education.k12' | 'energy_utilities' | 'energy_utilities.renewable' | 'fashion_apparel' | 'fashion_apparel.luxury' | 'fashion_apparel.sportswear' | 'finance' | 'finance.banking' | 'finance.insurance' | 'finance.investment' | 'finance.cryptocurrency' | 'food_beverage' | 'food_beverage.alcohol' | 'food_beverage.restaurants' | 'food_beverage.packaged_goods' | 'gambling_betting' | 'gambling_betting.sports_betting' | 'gambling_betting.casino' | 'gaming' | 'gaming.mobile' | 'gaming.console_pc' | 'gaming.esports' | 'government_nonprofit' | 'government_nonprofit.political' | 'government_nonprofit.charity' | 'healthcare' | 'healthcare.pharmaceutical' | 'healthcare.medical_devices' | 'healthcare.wellness' | 'home_garden' | 'home_garden.furniture' | 'home_garden.home_improvement' | 'media_entertainment' | 'media_entertainment.podcasts' | 'media_entertainment.music' | 'media_entertainment.film_tv' | 'media_entertainment.publishing' | 'media_entertainment.live_events' | 'pets' | 'professional_services' | 'professional_services.legal' | 'professional_services.consulting' | 'real_estate' | 'real_estate.residential' | 'real_estate.commercial' | 'recruitment_hr' | 'retail' | 'retail.ecommerce' | 'retail.department_stores' | 'sports_fitness' | 'sports_fitness.equipment' | 'sports_fitness.teams_leagues' | 'technology' | 'technology.software' | 'technology.hardware' | 'technology.ai_ml' | 'telecom' | 'telecom.mobile_carriers' | 'telecom.internet_providers' | 'transportation_logistics' | 'travel_hospitality' | 'travel_hospitality.airlines' | 'travel_hospitality.hotels' | 'travel_hospitality.cruise' | 'travel_hospitality.tourism';
147
147
 
148
+ /**
149
+ * User-level bases that may resolve age for demographic targeting execution. Population estimates are deliberately absent because aggregate composition cannot establish an individual impression's age.
150
+ */
151
+ export type AgeDeterminationBasis = 'verified' | 'declared' | 'inferred';
152
+
148
153
  /**
149
154
  * Age restriction for compliance. Use for legal requirements (alcohol, gambling), not audience targeting.
150
155
  */
@@ -1152,7 +1157,20 @@ export type DemographicSystem = 'nielsen' | 'nielsen_audio' | 'barb' | 'agf' | '
1152
1157
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
1153
1158
  */
1154
1159
  export interface DemographicTargetingIntent {
1155
- age: DemographicAgeRange & {};
1160
+ age: DemographicAgeRange & {
1161
+ /**
1162
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
1163
+ *
1164
+ * @minItems 1
1165
+ */
1166
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
1167
+ /**
1168
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
1169
+ *
1170
+ * @minItems 1
1171
+ */
1172
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
1173
+ };
1156
1174
  }
1157
1175
 
1158
1176
  /**
@@ -445,6 +445,11 @@ export type ActivationKey = {
445
445
  */
446
446
  export type AdvertiserIndustry = 'automotive' | 'automotive.electric_vehicles' | 'automotive.parts_accessories' | 'automotive.luxury' | 'beauty_cosmetics' | 'beauty_cosmetics.skincare' | 'beauty_cosmetics.fragrance' | 'beauty_cosmetics.haircare' | 'cannabis' | 'cpg' | 'cpg.personal_care' | 'cpg.household' | 'dating' | 'education' | 'education.higher_education' | 'education.online_learning' | 'education.k12' | 'energy_utilities' | 'energy_utilities.renewable' | 'fashion_apparel' | 'fashion_apparel.luxury' | 'fashion_apparel.sportswear' | 'finance' | 'finance.banking' | 'finance.insurance' | 'finance.investment' | 'finance.cryptocurrency' | 'food_beverage' | 'food_beverage.alcohol' | 'food_beverage.restaurants' | 'food_beverage.packaged_goods' | 'gambling_betting' | 'gambling_betting.sports_betting' | 'gambling_betting.casino' | 'gaming' | 'gaming.mobile' | 'gaming.console_pc' | 'gaming.esports' | 'government_nonprofit' | 'government_nonprofit.political' | 'government_nonprofit.charity' | 'healthcare' | 'healthcare.pharmaceutical' | 'healthcare.medical_devices' | 'healthcare.wellness' | 'home_garden' | 'home_garden.furniture' | 'home_garden.home_improvement' | 'media_entertainment' | 'media_entertainment.podcasts' | 'media_entertainment.music' | 'media_entertainment.film_tv' | 'media_entertainment.publishing' | 'media_entertainment.live_events' | 'pets' | 'professional_services' | 'professional_services.legal' | 'professional_services.consulting' | 'real_estate' | 'real_estate.residential' | 'real_estate.commercial' | 'recruitment_hr' | 'retail' | 'retail.ecommerce' | 'retail.department_stores' | 'sports_fitness' | 'sports_fitness.equipment' | 'sports_fitness.teams_leagues' | 'technology' | 'technology.software' | 'technology.hardware' | 'technology.ai_ml' | 'telecom' | 'telecom.mobile_carriers' | 'telecom.internet_providers' | 'transportation_logistics' | 'travel_hospitality' | 'travel_hospitality.airlines' | 'travel_hospitality.hotels' | 'travel_hospitality.cruise' | 'travel_hospitality.tourism';
447
447
 
448
+ /**
449
+ * User-level bases that may resolve age for demographic targeting execution. Population estimates are deliberately absent because aggregate composition cannot establish an individual impression's age.
450
+ */
451
+ export type AgeDeterminationBasis = 'verified' | 'declared' | 'inferred';
452
+
448
453
  /**
449
454
  * Methods for verifying user age for compliance. Does not include 'inferred' as it is not accepted for regulatory compliance.
450
455
  */
@@ -1585,7 +1590,20 @@ export type DemographicSystem = 'nielsen' | 'nielsen_audio' | 'barb' | 'agf' | '
1585
1590
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
1586
1591
  */
1587
1592
  export interface DemographicTargetingIntent {
1588
- age: DemographicAgeRange & {};
1593
+ age: DemographicAgeRange & {
1594
+ /**
1595
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
1596
+ *
1597
+ * @minItems 1
1598
+ */
1599
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
1600
+ /**
1601
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
1602
+ *
1603
+ * @minItems 1
1604
+ */
1605
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
1606
+ };
1589
1607
  }
1590
1608
 
1591
1609
  /**
@@ -486,6 +486,11 @@ export interface AdInventoryConfiguration {
486
486
  supported_formats?: string[];
487
487
  }
488
488
 
489
+ /**
490
+ * User-level bases that may resolve age for demographic targeting execution. Population estimates are deliberately absent because aggregate composition cannot establish an individual impression's age.
491
+ */
492
+ export type AgeDeterminationBasis = 'verified' | 'declared' | 'inferred';
493
+
489
494
  /**
490
495
  * Methods for verifying user age for compliance. Does not include 'inferred' as it is not accepted for regulatory compliance.
491
496
  */
@@ -5526,7 +5531,20 @@ export interface DemographicTargetingCapability {
5526
5531
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
5527
5532
  */
5528
5533
  export interface DemographicTargetingIntent {
5529
- age: DemographicAgeRange & {};
5534
+ age: DemographicAgeRange & {
5535
+ /**
5536
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
5537
+ *
5538
+ * @minItems 1
5539
+ */
5540
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
5541
+ /**
5542
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
5543
+ *
5544
+ * @minItems 1
5545
+ */
5546
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
5547
+ };
5530
5548
  }
5531
5549
 
5532
5550
  /**
@@ -129,6 +129,11 @@ export type ActivationKey = {
129
129
  value: string;
130
130
  };
131
131
 
132
+ /**
133
+ * User-level bases that may resolve age for demographic targeting execution. Population estimates are deliberately absent because aggregate composition cannot establish an individual impression's age.
134
+ */
135
+ export type AgeDeterminationBasis = 'verified' | 'declared' | 'inferred';
136
+
132
137
  /**
133
138
  * Age restriction for compliance. Use for legal requirements (alcohol, gambling), not audience targeting.
134
139
  */
@@ -583,7 +588,20 @@ export type DemographicAgeRange = {} & {
583
588
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
584
589
  */
585
590
  export interface DemographicTargetingIntent {
586
- age: DemographicAgeRange & {};
591
+ age: DemographicAgeRange & {
592
+ /**
593
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
594
+ *
595
+ * @minItems 1
596
+ */
597
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
598
+ /**
599
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
600
+ *
601
+ * @minItems 1
602
+ */
603
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
604
+ };
587
605
  }
588
606
 
589
607
  /**
@@ -6388,7 +6388,20 @@ export interface PackageSignalTargetingGroup {
6388
6388
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
6389
6389
  */
6390
6390
  export interface DemographicTargetingIntent {
6391
- age: DemographicAgeRange & {};
6391
+ age: DemographicAgeRange & {
6392
+ /**
6393
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
6394
+ *
6395
+ * @minItems 1
6396
+ */
6397
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
6398
+ /**
6399
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
6400
+ *
6401
+ * @minItems 1
6402
+ */
6403
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
6404
+ };
6392
6405
  }
6393
6406
  /**
6394
6407
  * Reference to a property list for targeting specific properties within this product. The package runs on the intersection of the product's publisher_properties and this list. Sellers SHOULD return a validation error if the product has property_targeting_allowed: false.
@@ -6388,7 +6388,20 @@ export interface PackageSignalTargetingGroup {
6388
6388
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
6389
6389
  */
6390
6390
  export interface DemographicTargetingIntent {
6391
- age: DemographicAgeRange & {};
6391
+ age: DemographicAgeRange & {
6392
+ /**
6393
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
6394
+ *
6395
+ * @minItems 1
6396
+ */
6397
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
6398
+ /**
6399
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
6400
+ *
6401
+ * @minItems 1
6402
+ */
6403
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
6404
+ };
6392
6405
  }
6393
6406
  /**
6394
6407
  * Reference to a property list for targeting specific properties within this product. The package runs on the intersection of the product's publisher_properties and this list. Sellers SHOULD return a validation error if the product has property_targeting_allowed: false.
@@ -5771,7 +5771,20 @@ export interface DemographicPredicate {
5771
5771
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
5772
5772
  */
5773
5773
  export interface DemographicTargetingIntent {
5774
- age: DemographicAgeRange & {};
5774
+ age: DemographicAgeRange & {
5775
+ /**
5776
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
5777
+ *
5778
+ * @minItems 1
5779
+ */
5780
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
5781
+ /**
5782
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
5783
+ *
5784
+ * @minItems 1
5785
+ */
5786
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
5787
+ };
5775
5788
  }
5776
5789
 
5777
5790
  /**
@@ -4598,7 +4598,20 @@ export type DemographicSystem = 'nielsen' | 'nielsen_audio' | 'barb' | 'agf' | '
4598
4598
  * Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.
4599
4599
  */
4600
4600
  export interface DemographicTargetingIntent {
4601
- age: DemographicAgeRange & {};
4601
+ age: DemographicAgeRange & {
4602
+ /**
4603
+ * User-level age determination bases the buyer permits for this predicate. Sellers MUST use only these bases or reject the request; they MUST NOT silently fall back to another basis. When omitted, the buyer imposes no determination-basis constraint beyond product capability and any age_restriction. population_estimate is structurally unavailable because aggregate evidence cannot identify an eligible user.
4604
+ *
4605
+ * @minItems 1
4606
+ */
4607
+ accepted_bases?: [AgeDeterminationBasis, ...AgeDeterminationBasis[]];
4608
+ /**
4609
+ * Verification methods acceptable when verified is an accepted basis. This field narrows verified demographic execution; age_restriction.accepted_methods independently governs legal eligibility and the two sets are intersected when both are present.
4610
+ *
4611
+ * @minItems 1
4612
+ */
4613
+ accepted_verification_methods?: [AgeVerificationMethod, ...AgeVerificationMethod[]];
4614
+ };
4602
4615
  }
4603
4616
 
4604
4617
  /**