@adcp/sdk 14.0.0-beta.14 → 14.0.0-beta.15

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 (127) hide show
  1. package/dist/lib/auth/oauth/authorization-required.d.mts +25 -11
  2. package/dist/lib/auth/oauth/authorization-required.d.ts +25 -11
  3. package/dist/lib/auth/oauth/authorization-required.js +18 -4
  4. package/dist/lib/auth/oauth/authorization-required.mjs +17 -4
  5. package/dist/lib/auth/oauth/index.d.mts +1 -1
  6. package/dist/lib/auth/oauth/index.d.ts +1 -1
  7. package/dist/lib/auth/oauth/index.js +2 -0
  8. package/dist/lib/auth/oauth/index.mjs +2 -0
  9. package/dist/lib/auth/oauth/resource-url.d.mts +8 -0
  10. package/dist/lib/auth/oauth/resource-url.d.ts +8 -0
  11. package/dist/lib/auth/oauth/resource-url.js +42 -0
  12. package/dist/lib/auth/oauth/resource-url.mjs +40 -0
  13. package/dist/lib/core/ConversationTypes.d.mts +10 -0
  14. package/dist/lib/core/ConversationTypes.d.ts +10 -0
  15. package/dist/lib/core/SingleAgentClient.d.mts +5 -2
  16. package/dist/lib/core/SingleAgentClient.d.ts +5 -2
  17. package/dist/lib/core/SingleAgentClient.js +133 -28
  18. package/dist/lib/core/SingleAgentClient.mjs +138 -29
  19. package/dist/lib/core/TaskExecutor.d.mts +1 -0
  20. package/dist/lib/core/TaskExecutor.d.ts +1 -0
  21. package/dist/lib/core/TaskExecutor.js +7 -1
  22. package/dist/lib/core/TaskExecutor.mjs +7 -1
  23. package/dist/lib/core/webhook-registration.d.mts +8 -1
  24. package/dist/lib/core/webhook-registration.d.ts +8 -1
  25. package/dist/lib/core/webhook-registration.js +65 -5
  26. package/dist/lib/core/webhook-registration.mjs +61 -4
  27. package/dist/lib/errors/index.d.mts +9 -0
  28. package/dist/lib/errors/index.d.ts +9 -0
  29. package/dist/lib/errors/index.js +33 -0
  30. package/dist/lib/errors/index.mjs +32 -0
  31. package/dist/lib/index.d.mts +3 -2
  32. package/dist/lib/index.d.ts +3 -2
  33. package/dist/lib/index.js +4 -0
  34. package/dist/lib/index.mjs +4 -0
  35. package/dist/lib/media-buy/compatibility.js +14 -2
  36. package/dist/lib/media-buy/compatibility.mjs +14 -2
  37. package/dist/lib/protocols/index.js +23 -7
  38. package/dist/lib/protocols/index.mjs +24 -8
  39. package/dist/lib/protocols/mcp.js +8 -6
  40. package/dist/lib/protocols/mcp.mjs +9 -7
  41. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  42. package/dist/lib/server/decisioning/async-outcome.d.mts +11 -0
  43. package/dist/lib/server/decisioning/async-outcome.d.ts +11 -0
  44. package/dist/lib/server/decisioning/context.d.mts +11 -1
  45. package/dist/lib/server/decisioning/context.d.ts +11 -1
  46. package/dist/lib/server/decisioning/index.d.mts +3 -2
  47. package/dist/lib/server/decisioning/index.d.ts +3 -2
  48. package/dist/lib/server/decisioning/index.js +9 -0
  49. package/dist/lib/server/decisioning/index.mjs +10 -0
  50. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -2
  51. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -2
  52. package/dist/lib/server/decisioning/runtime/from-platform.js +40 -8
  53. package/dist/lib/server/decisioning/runtime/from-platform.mjs +40 -8
  54. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +8 -1
  55. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +8 -1
  56. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +10 -1
  57. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +9 -1
  58. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +79 -0
  59. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +79 -0
  60. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +391 -0
  61. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +369 -0
  62. package/dist/lib/server/decisioning/runtime/task-registry.d.mts +2 -0
  63. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +2 -0
  64. package/dist/lib/server/decisioning/runtime/task-registry.js +2 -1
  65. package/dist/lib/server/decisioning/runtime/task-registry.mjs +2 -1
  66. package/dist/lib/server/decisioning/runtime/to-context.js +15 -11
  67. package/dist/lib/server/decisioning/runtime/to-context.mjs +15 -11
  68. package/dist/lib/server/index.d.mts +2 -2
  69. package/dist/lib/server/index.d.ts +2 -2
  70. package/dist/lib/server/index.js +4 -0
  71. package/dist/lib/server/index.mjs +4 -0
  72. package/dist/lib/server/webhook-delivery/index.d.mts +2 -2
  73. package/dist/lib/server/webhook-delivery/index.d.ts +2 -2
  74. package/dist/lib/server/webhook-delivery/index.js +4 -0
  75. package/dist/lib/server/webhook-delivery/index.mjs +5 -1
  76. package/dist/lib/server/webhook-delivery/pg.d.mts +3 -1
  77. package/dist/lib/server/webhook-delivery/pg.d.ts +3 -1
  78. package/dist/lib/server/webhook-delivery/pg.js +25 -2
  79. package/dist/lib/server/webhook-delivery/pg.mjs +25 -2
  80. package/dist/lib/server/webhook-delivery/recovery.d.mts +44 -0
  81. package/dist/lib/server/webhook-delivery/recovery.d.ts +44 -0
  82. package/dist/lib/server/webhook-delivery/recovery.js +146 -43
  83. package/dist/lib/server/webhook-delivery/recovery.mjs +144 -43
  84. package/dist/lib/signing/agent-resolver/index.d.mts +1 -1
  85. package/dist/lib/signing/agent-resolver/index.d.ts +1 -1
  86. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +9 -0
  87. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +9 -0
  88. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +4 -1
  89. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +4 -1
  90. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +17 -4
  91. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +17 -4
  92. package/dist/lib/signing/jwks.d.mts +7 -0
  93. package/dist/lib/signing/jwks.d.ts +7 -0
  94. package/dist/lib/signing/server.d.mts +2 -2
  95. package/dist/lib/signing/server.d.ts +2 -2
  96. package/dist/lib/signing/webhook-verifier.d.mts +6 -0
  97. package/dist/lib/signing/webhook-verifier.d.ts +6 -0
  98. package/dist/lib/signing/webhook-verifier.js +38 -4
  99. package/dist/lib/signing/webhook-verifier.mjs +38 -4
  100. package/dist/lib/testing/client.d.mts +1 -0
  101. package/dist/lib/testing/client.d.ts +1 -0
  102. package/dist/lib/testing/client.js +6 -2
  103. package/dist/lib/testing/client.mjs +6 -2
  104. package/dist/lib/testing/compliance/comply.d.mts +2 -2
  105. package/dist/lib/testing/compliance/comply.d.ts +2 -2
  106. package/dist/lib/testing/compliance/comply.js +41 -31
  107. package/dist/lib/testing/compliance/comply.mjs +44 -21
  108. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.mts +1 -7
  109. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.ts +1 -7
  110. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.js +6 -42
  111. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.mjs +10 -40
  112. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  113. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  114. package/dist/lib/utils/adcp-version-config.d.mts +2 -0
  115. package/dist/lib/utils/adcp-version-config.d.ts +2 -0
  116. package/dist/lib/utils/adcp-version-config.js +5 -0
  117. package/dist/lib/utils/adcp-version-config.mjs +4 -0
  118. package/dist/lib/version.d.mts +3 -3
  119. package/dist/lib/version.d.ts +3 -3
  120. package/dist/lib/version.js +3 -3
  121. package/dist/lib/version.mjs +3 -3
  122. package/docs/llms.txt +3 -1
  123. package/docs/migration-12-to-14.md +6 -5
  124. package/docs/migration-13-to-14.md +48 -7
  125. package/docs/migration-task-registry-scoping.md +164 -11
  126. package/package.json +1 -1
  127. package/skills/build-decisioning-platform/advanced/REFERENCE.md +1 -1
@@ -419,11 +419,14 @@ function requestFingerprint(value) {
419
419
  return createHash("sha256").update(canonicalize(value)).digest("base64url");
420
420
  }
421
421
  function snapshotCompatibilityTaskOptions(options) {
422
- if (!options) return void 0;
422
+ if (!options) return options;
423
423
  return {
424
424
  ...options,
425
425
  ...options.transport !== void 0 && { transport: { ...options.transport } },
426
- ...options.metadata !== void 0 && { metadata: structuredClone(options.metadata) }
426
+ ...options.metadata !== void 0 && { metadata: structuredClone(options.metadata) },
427
+ ...options.delegatedOperatorAuthorization !== void 0 && {
428
+ delegatedOperatorAuthorization: { ...options.delegatedOperatorAuthorization }
429
+ }
427
430
  };
428
431
  }
429
432
  function stripWebhookAuthenticationCredential(value) {
@@ -3756,6 +3759,7 @@ class MediaBuyLifecycleCoordinator {
3756
3759
  return adapt(result);
3757
3760
  }
3758
3761
  async listProducts(params, inputHandler, options) {
3762
+ options = snapshotCompatibilityTaskOptions(options);
3759
3763
  this.assertActive("listProducts");
3760
3764
  const input = record(params);
3761
3765
  const lifecycle = this.selectLifecycle("list_products");
@@ -3828,6 +3832,7 @@ class MediaBuyLifecycleCoordinator {
3828
3832
  );
3829
3833
  }
3830
3834
  async requestProposals(params, inputHandler, options) {
3835
+ options = snapshotCompatibilityTaskOptions(options);
3831
3836
  this.assertActive("requestProposals");
3832
3837
  const input = record(params);
3833
3838
  const lifecycle = this.selectLifecycle("request_proposals");
@@ -6261,6 +6266,7 @@ class MediaBuyLifecycleCoordinator {
6261
6266
  return attachMatch(result);
6262
6267
  }
6263
6268
  async refineProposals(params, inputHandler, options) {
6269
+ options = snapshotCompatibilityTaskOptions(options);
6264
6270
  this.assertActive("refineProposals");
6265
6271
  const lifecycle = this.selectLifecycle("refine_proposals");
6266
6272
  this.assertBeta6ReportingRequest("refineProposals", "refine_proposals", params);
@@ -6556,6 +6562,7 @@ class MediaBuyLifecycleCoordinator {
6556
6562
  }
6557
6563
  }
6558
6564
  async declineProposals(params, inputHandler, options) {
6565
+ options = snapshotCompatibilityTaskOptions(options);
6559
6566
  this.assertActive("declineProposals");
6560
6567
  const input = record(params);
6561
6568
  const lifecycle = this.selectLifecycle("decline_proposals");
@@ -6780,6 +6787,7 @@ class MediaBuyLifecycleCoordinator {
6780
6787
  }
6781
6788
  }
6782
6789
  async buyProducts(params, inputHandler, options) {
6790
+ options = snapshotCompatibilityTaskOptions(options);
6783
6791
  this.assertActive("buyProducts");
6784
6792
  const input = record(params);
6785
6793
  const lifecycle = this.selectLifecycle("buy_products");
@@ -6919,6 +6927,7 @@ class MediaBuyLifecycleCoordinator {
6919
6927
  );
6920
6928
  }
6921
6929
  async acceptProposal(params, inputHandler, options) {
6930
+ options = snapshotCompatibilityTaskOptions(options);
6922
6931
  this.assertActive("acceptProposal");
6923
6932
  const input = record(params);
6924
6933
  const lifecycle = this.selectLifecycle("accept_proposal");
@@ -7397,6 +7406,7 @@ class MediaBuyLifecycleCoordinator {
7397
7406
  return this.attachEstablishedMutationTransitions(adapted, durableMutation);
7398
7407
  }
7399
7408
  async controlMediaBuy(params, inputHandler, options) {
7409
+ options = snapshotCompatibilityTaskOptions(options);
7400
7410
  this.assertActive("controlMediaBuy");
7401
7411
  const input = record(params);
7402
7412
  const lifecycle = this.selectLifecycle("control_media_buy");
@@ -7683,6 +7693,7 @@ class MediaBuyLifecycleCoordinator {
7683
7693
  );
7684
7694
  }
7685
7695
  async getMediaBuys(params, inputHandler, options) {
7696
+ options = snapshotCompatibilityTaskOptions(options);
7686
7697
  this.assertActive("getMediaBuys");
7687
7698
  if (compareRelease(this.negotiated_version, "3.0") < 0) {
7688
7699
  throw this.unsupported(
@@ -7704,6 +7715,7 @@ class MediaBuyLifecycleCoordinator {
7704
7715
  return this.adaptProjectedResult(result, this.makeReport(this.lifecycle, ["get_media_buys"], []), (data) => data);
7705
7716
  }
7706
7717
  async getMediaBuyDelivery(params, inputHandler, options) {
7718
+ options = snapshotCompatibilityTaskOptions(options);
7707
7719
  this.assertActive("getMediaBuyDelivery");
7708
7720
  if (compareRelease(this.negotiated_version, "3.0") < 0) {
7709
7721
  throw this.unsupported(
@@ -62,6 +62,7 @@ var import_mcp3 = require('./mcp.js');
62
62
  var import_a2a3 = require('./a2a.js');
63
63
  var import_auth = require('../auth/index.js');
64
64
  var import_oauth = require('../auth/oauth/index.js');
65
+ var import_authorization_required = require('../auth/oauth/authorization-required.js');
65
66
  var import_provider_cache = require('../auth/oauth/provider-cache.js');
66
67
  var import_errors = require('../errors/index.js');
67
68
  var import_net = require('../net/index.js');
@@ -90,6 +91,13 @@ async function closeScopedConnections(protocol = "mcp") {
90
91
  (0, import_a2a.closeA2AConnections)();
91
92
  }
92
93
  }
94
+ function hasStaticAgentCredentials(agent, authToken) {
95
+ if (authToken) return true;
96
+ return Object.keys(agent.headers ?? {}).some((key) => {
97
+ const normalized = key.toLowerCase();
98
+ return normalized === "authorization" || normalized === "x-adcp-auth";
99
+ });
100
+ }
93
101
  function resolveWireMajor(adcpVersion) {
94
102
  if (adcpVersion === void 0) return import_version.ADCP_MAJOR_VERSION;
95
103
  const parsed = (0, import_version.parseAdcpMajorVersion)(adcpVersion);
@@ -333,7 +341,8 @@ class ProtocolClient {
333
341
  agent.agent_uri,
334
342
  transport?.trustedFetchFn,
335
343
  signal,
336
- transport?.allowPrivateIp
344
+ transport?.allowPrivateIp,
345
+ "oauth"
337
346
  );
338
347
  throw err;
339
348
  }
@@ -394,7 +403,8 @@ class ProtocolClient {
394
403
  agent.agent_uri,
395
404
  transport?.trustedFetchFn,
396
405
  signal,
397
- transport?.allowPrivateIp
406
+ transport?.allowPrivateIp,
407
+ "static"
398
408
  );
399
409
  throw retryErr;
400
410
  }
@@ -404,7 +414,8 @@ class ProtocolClient {
404
414
  agent.agent_uri,
405
415
  transport?.trustedFetchFn,
406
416
  signal,
407
- transport?.allowPrivateIp
417
+ transport?.allowPrivateIp,
418
+ hasStaticAgentCredentials(agent, authToken) ? "static" : "discover"
408
419
  );
409
420
  throw err;
410
421
  }
@@ -459,7 +470,8 @@ class ProtocolClient {
459
470
  agent.agent_uri,
460
471
  transport?.trustedFetchFn,
461
472
  signal,
462
- transport?.allowPrivateIp
473
+ transport?.allowPrivateIp,
474
+ "legacy-a2a"
463
475
  );
464
476
  throw retryErr;
465
477
  }
@@ -469,7 +481,8 @@ class ProtocolClient {
469
481
  agent.agent_uri,
470
482
  transport?.trustedFetchFn,
471
483
  signal,
472
- transport?.allowPrivateIp
484
+ transport?.allowPrivateIp,
485
+ "legacy-a2a"
473
486
  );
474
487
  throw err;
475
488
  }
@@ -482,12 +495,15 @@ class ProtocolClient {
482
495
  );
483
496
  }
484
497
  }
485
- async function rethrowAsNeedsAuthorization(err, agentUrl, fetchFn, signal, configuredAllowPrivateIp) {
498
+ async function rethrowAsNeedsAuthorization(err, agentUrl, fetchFn, signal, configuredAllowPrivateIp, recoveryMode = "discover") {
486
499
  if (err instanceof import_oauth.NeedsAuthorizationError) throw err;
487
500
  if (!(0, import_errors.is401Error)(err)) return;
501
+ if (recoveryMode === "static") {
502
+ throw new import_errors.AuthenticationCredentialsRejectedError(agentUrl, err);
503
+ }
488
504
  const allowPrivateIp = configuredAllowPrivateIp ?? (0, import_net.isLikelyPrivateUrl)(agentUrl);
489
505
  const requirements = await (0, import_oauth.discoverAuthorizationRequirements)(agentUrl, { allowPrivateIp, fetchFn, signal });
490
- if (requirements) {
506
+ if (requirements && (recoveryMode === "legacy-a2a" || (0, import_authorization_required.hasValidatedMcpAuthorizationRequirements)(requirements, agentUrl))) {
491
507
  throw new import_oauth.NeedsAuthorizationError(requirements);
492
508
  }
493
509
  }
@@ -50,8 +50,9 @@ import {
50
50
  getAgentStorage,
51
51
  ensureClientCredentialsTokens
52
52
  } from "../auth/oauth/index.mjs";
53
+ import { hasValidatedMcpAuthorizationRequirements } from "../auth/oauth/authorization-required.mjs";
53
54
  import { getNonInteractiveOAuthProvider } from "../auth/oauth/provider-cache.mjs";
54
- import { is401Error } from "../errors/index.mjs";
55
+ import { AuthenticationCredentialsRejectedError, is401Error } from "../errors/index.mjs";
55
56
  import { isLikelyPrivateUrl } from "../net/index.mjs";
56
57
  import { validateAgentUrl } from "../validation/index.mjs";
57
58
  import { withSpan } from "../observability/tracing.mjs";
@@ -71,6 +72,13 @@ import {
71
72
  withTransportDiagnostics as withTransportDiagnostics2,
72
73
  wrapFetchWithTransportDiagnostics
73
74
  } from "./transportDiagnostics.mjs";
75
+ function hasStaticAgentCredentials(agent, authToken) {
76
+ if (authToken) return true;
77
+ return Object.keys(agent.headers ?? {}).some((key) => {
78
+ const normalized = key.toLowerCase();
79
+ return normalized === "authorization" || normalized === "x-adcp-auth";
80
+ });
81
+ }
74
82
  function resolveWireMajor(adcpVersion) {
75
83
  if (adcpVersion === void 0) return ADCP_MAJOR_VERSION;
76
84
  const parsed = parseAdcpMajorVersion(adcpVersion);
@@ -314,7 +322,8 @@ class ProtocolClient {
314
322
  agent.agent_uri,
315
323
  transport?.trustedFetchFn,
316
324
  signal,
317
- transport?.allowPrivateIp
325
+ transport?.allowPrivateIp,
326
+ "oauth"
318
327
  );
319
328
  throw err;
320
329
  }
@@ -375,7 +384,8 @@ class ProtocolClient {
375
384
  agent.agent_uri,
376
385
  transport?.trustedFetchFn,
377
386
  signal,
378
- transport?.allowPrivateIp
387
+ transport?.allowPrivateIp,
388
+ "static"
379
389
  );
380
390
  throw retryErr;
381
391
  }
@@ -385,7 +395,8 @@ class ProtocolClient {
385
395
  agent.agent_uri,
386
396
  transport?.trustedFetchFn,
387
397
  signal,
388
- transport?.allowPrivateIp
398
+ transport?.allowPrivateIp,
399
+ hasStaticAgentCredentials(agent, authToken) ? "static" : "discover"
389
400
  );
390
401
  throw err;
391
402
  }
@@ -440,7 +451,8 @@ class ProtocolClient {
440
451
  agent.agent_uri,
441
452
  transport?.trustedFetchFn,
442
453
  signal,
443
- transport?.allowPrivateIp
454
+ transport?.allowPrivateIp,
455
+ "legacy-a2a"
444
456
  );
445
457
  throw retryErr;
446
458
  }
@@ -450,7 +462,8 @@ class ProtocolClient {
450
462
  agent.agent_uri,
451
463
  transport?.trustedFetchFn,
452
464
  signal,
453
- transport?.allowPrivateIp
465
+ transport?.allowPrivateIp,
466
+ "legacy-a2a"
454
467
  );
455
468
  throw err;
456
469
  }
@@ -463,12 +476,15 @@ class ProtocolClient {
463
476
  );
464
477
  }
465
478
  }
466
- async function rethrowAsNeedsAuthorization(err, agentUrl, fetchFn, signal, configuredAllowPrivateIp) {
479
+ async function rethrowAsNeedsAuthorization(err, agentUrl, fetchFn, signal, configuredAllowPrivateIp, recoveryMode = "discover") {
467
480
  if (err instanceof NeedsAuthorizationError) throw err;
468
481
  if (!is401Error(err)) return;
482
+ if (recoveryMode === "static") {
483
+ throw new AuthenticationCredentialsRejectedError(agentUrl, err);
484
+ }
469
485
  const allowPrivateIp = configuredAllowPrivateIp ?? isLikelyPrivateUrl(agentUrl);
470
486
  const requirements = await discoverAuthorizationRequirements(agentUrl, { allowPrivateIp, fetchFn, signal });
471
- if (requirements) {
487
+ if (requirements && (recoveryMode === "legacy-a2a" || hasValidatedMcpAuthorizationRequirements(requirements, agentUrl))) {
472
488
  throw new NeedsAuthorizationError(requirements);
473
489
  }
474
490
  }
@@ -787,7 +787,7 @@ async function connectMCP(options) {
787
787
  });
788
788
  return { client: mcpClient, transport };
789
789
  } catch (error) {
790
- if (error instanceof import_auth.UnauthorizedError) {
790
+ if (authProvider && error instanceof import_auth.UnauthorizedError) {
791
791
  debugLogs.push({
792
792
  type: "info",
793
793
  message: "MCP: OAuth authorization required, flow initiated",
@@ -798,13 +798,15 @@ async function connectMCP(options) {
798
798
  if ((0, import_errors.is401Error)(error)) {
799
799
  const scheme = authProvider ? "oauth" : authToken ? "bearer" : hasNonAcceptCustomHeaders ? "header" : "none";
800
800
  const hint = scheme === "none" ? "No credentials were sent. Configure auth_token, headers, or oauth_tokens on the agent config (or pass --auth on the CLI)." : scheme === "header" ? "Verify the Authorization header value matches the gateway (basic-auth: 'Basic ' + base64(user:pass); pair with --auth-scheme basic on the CLI)." : scheme === "bearer" ? "Verify the bearer token matches the agent's expected credential." : "OAuth provider returned tokens that the agent rejected \u2014 check the provider configuration and token scopes.";
801
- const detail = `MCP connect rejected with HTTP 401 from ${agentUrl}. SDK sent auth scheme: ${scheme}. ${hint}`;
801
+ const safeAgentUrl = (0, import_transportDiagnostics.sanitizeTransportUrl)(agentUrl);
802
+ const detail = `MCP connect rejected with HTTP 401 from ${safeAgentUrl}. SDK sent auth scheme: ${scheme}. ${hint}`;
802
803
  const wrapped = Object.assign(new Error(detail), {
803
- cause: error,
804
804
  code: "MCP_AUTH_REJECTED",
805
- scheme,
806
- agentUrl,
807
- originalError: error
805
+ scheme
806
+ });
807
+ Object.defineProperties(wrapped, {
808
+ agentUrl: { value: safeAgentUrl, enumerable: false, configurable: true },
809
+ cause: { value: error, enumerable: false, configurable: true }
808
810
  });
809
811
  throw wrapped;
810
812
  }
@@ -18,7 +18,7 @@ import { buildAgentSigningFetch, signingContextStorage } from "../signing/client
18
18
  import { redactArgsForLog } from "../utils/redact-args.mjs";
19
19
  import { wrapFetchWithCapture } from "./rawResponseCapture.mjs";
20
20
  import { wrapFetchWithSizeLimit } from "./responseSizeLimit.mjs";
21
- import { wrapFetchWithTransportDiagnostics } from "./transportDiagnostics.mjs";
21
+ import { sanitizeTransportUrl, wrapFetchWithTransportDiagnostics } from "./transportDiagnostics.mjs";
22
22
  import {
23
23
  isAbortOrTimeoutError,
24
24
  resolveClientRequestTimeoutMs,
@@ -774,7 +774,7 @@ async function connectMCP(options) {
774
774
  });
775
775
  return { client: mcpClient, transport };
776
776
  } catch (error) {
777
- if (error instanceof UnauthorizedError) {
777
+ if (authProvider && error instanceof UnauthorizedError) {
778
778
  debugLogs.push({
779
779
  type: "info",
780
780
  message: "MCP: OAuth authorization required, flow initiated",
@@ -785,13 +785,15 @@ async function connectMCP(options) {
785
785
  if (is401Error(error)) {
786
786
  const scheme = authProvider ? "oauth" : authToken ? "bearer" : hasNonAcceptCustomHeaders ? "header" : "none";
787
787
  const hint = scheme === "none" ? "No credentials were sent. Configure auth_token, headers, or oauth_tokens on the agent config (or pass --auth on the CLI)." : scheme === "header" ? "Verify the Authorization header value matches the gateway (basic-auth: 'Basic ' + base64(user:pass); pair with --auth-scheme basic on the CLI)." : scheme === "bearer" ? "Verify the bearer token matches the agent's expected credential." : "OAuth provider returned tokens that the agent rejected \u2014 check the provider configuration and token scopes.";
788
- const detail = `MCP connect rejected with HTTP 401 from ${agentUrl}. SDK sent auth scheme: ${scheme}. ${hint}`;
788
+ const safeAgentUrl = sanitizeTransportUrl(agentUrl);
789
+ const detail = `MCP connect rejected with HTTP 401 from ${safeAgentUrl}. SDK sent auth scheme: ${scheme}. ${hint}`;
789
790
  const wrapped = Object.assign(new Error(detail), {
790
- cause: error,
791
791
  code: "MCP_AUTH_REJECTED",
792
- scheme,
793
- agentUrl,
794
- originalError: error
792
+ scheme
793
+ });
794
+ Object.defineProperties(wrapped, {
795
+ agentUrl: { value: safeAgentUrl, enumerable: false, configurable: true },
796
+ cause: { value: error, enumerable: false, configurable: true }
795
797
  });
796
798
  throw wrapped;
797
799
  }
@@ -4,5 +4,5 @@
4
4
  "source_sha": "4e553ad955f83b49c7d221ab5c3ff78237ad02e3",
5
5
  "source_tarball_sha256": "580656d6466ef9f0d1119985e6726c2efea718dc671e2ad30957fcb2fd54af0f",
6
6
  "upstream_adcp_version": "2.5.3",
7
- "synced_at": "2026-08-28T11:30:58.855Z"
7
+ "synced_at": "2026-08-28T20:44:49.802Z"
8
8
  }
@@ -128,6 +128,17 @@ export interface TaskHandoffOptions {
128
128
  */
129
129
  task_id?: string;
130
130
  }
131
+ /**
132
+ * Options for a handoff whose terminal result is owned by a durable worker.
133
+ * The callback must only persist the complete task handle and work item; the
134
+ * framework waits for that commit before acknowledging submitted, then leaves
135
+ * the task submitted for the worker to settle.
136
+ *
137
+ * @public
138
+ */
139
+ export interface ExternalTaskHandoffOptions extends TaskHandoffOptions {
140
+ readonly settlement: 'external';
141
+ }
131
142
  /**
132
143
  * Marker the framework recognizes as "promote this call to a task."
133
144
  * Returned from `ctx.handoffToTask(fn)`. Type parameter `TResult` is the
@@ -128,6 +128,17 @@ export interface TaskHandoffOptions {
128
128
  */
129
129
  task_id?: string;
130
130
  }
131
+ /**
132
+ * Options for a handoff whose terminal result is owned by a durable worker.
133
+ * The callback must only persist the complete task handle and work item; the
134
+ * framework waits for that commit before acknowledging submitted, then leaves
135
+ * the task submitted for the worker to settle.
136
+ *
137
+ * @public
138
+ */
139
+ export interface ExternalTaskHandoffOptions extends TaskHandoffOptions {
140
+ readonly settlement: 'external';
141
+ }
131
142
  /**
132
143
  * Marker the framework recognizes as "promote this call to a task."
133
144
  * Returned from `ctx.handoffToTask(fn)`. Type parameter `TResult` is the
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import type { Account } from './account.mjs';
25
25
  import type { Format, FormatReferenceStructuredObject, PropertyList, CollectionList } from '../../types/tools.generated.mjs';
26
- import type { TaskHandoff, TaskHandoffContext, TaskHandoffOptions } from './async-outcome.mjs';
26
+ import type { ExternalTaskHandoffOptions, TaskHandoff, TaskHandoffContext, TaskHandoffOptions } from './async-outcome.mjs';
27
27
  import type { CtxMetadataRef, ResourceKind } from '../ctx-metadata/index.mjs';
28
28
  import type { BuyerAgent } from './buyer-agent.mjs';
29
29
  import type { Recipe } from './proposal/index.mjs';
@@ -207,7 +207,17 @@ export interface RequestContext<TAccount = Account> {
207
207
  * to echo it verbatim (e.g. `force_create_media_buy_arm`). The framework uses
208
208
  * the supplied id instead of minting a fresh one; `taskCtx.id` reflects it.
209
209
  * Constraints: non-empty, ≤ 128 characters. Throws if violated.
210
+ *
211
+ * For crash-safe queue workers, pass `{ settlement: 'external' }`. The
212
+ * callback must durably enqueue `taskCtx.taskRef` and return only after that
213
+ * write commits; the submitted response waits for it. Returning does not
214
+ * complete the task; a trusted worker must
215
+ * settle it through a scoped settlement helper. If the producer callback
216
+ * throws, the initial invocation fails and the task remains internally
217
+ * submitted, so the framework cannot acknowledge unrecoverable work or
218
+ * create a terminal task without its required durable delivery record.
210
219
  */
220
+ handoffToTask(fn: (taskCtx: TaskHandoffContext) => Promise<void>, options: ExternalTaskHandoffOptions): TaskHandoff<never>;
211
221
  handoffToTask<TResult>(fn: (taskCtx: TaskHandoffContext) => Promise<TResult>, options?: TaskHandoffOptions): TaskHandoff<TResult>;
212
222
  }
213
223
  export interface WorkflowStateReader {
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import type { Account } from './account';
25
25
  import type { Format, FormatReferenceStructuredObject, PropertyList, CollectionList } from '../../types/tools.generated';
26
- import type { TaskHandoff, TaskHandoffContext, TaskHandoffOptions } from './async-outcome';
26
+ import type { ExternalTaskHandoffOptions, TaskHandoff, TaskHandoffContext, TaskHandoffOptions } from './async-outcome';
27
27
  import type { CtxMetadataRef, ResourceKind } from '../ctx-metadata';
28
28
  import type { BuyerAgent } from './buyer-agent';
29
29
  import type { Recipe } from './proposal';
@@ -207,7 +207,17 @@ export interface RequestContext<TAccount = Account> {
207
207
  * to echo it verbatim (e.g. `force_create_media_buy_arm`). The framework uses
208
208
  * the supplied id instead of minting a fresh one; `taskCtx.id` reflects it.
209
209
  * Constraints: non-empty, ≤ 128 characters. Throws if violated.
210
+ *
211
+ * For crash-safe queue workers, pass `{ settlement: 'external' }`. The
212
+ * callback must durably enqueue `taskCtx.taskRef` and return only after that
213
+ * write commits; the submitted response waits for it. Returning does not
214
+ * complete the task; a trusted worker must
215
+ * settle it through a scoped settlement helper. If the producer callback
216
+ * throws, the initial invocation fails and the task remains internally
217
+ * submitted, so the framework cannot acknowledge unrecoverable work or
218
+ * create a terminal task without its required durable delivery record.
210
219
  */
220
+ handoffToTask(fn: (taskCtx: TaskHandoffContext) => Promise<void>, options: ExternalTaskHandoffOptions): TaskHandoff<never>;
211
221
  handoffToTask<TResult>(fn: (taskCtx: TaskHandoffContext) => Promise<TResult>, options?: TaskHandoffOptions): TaskHandoff<TResult>;
212
222
  }
213
223
  export interface WorkflowStateReader {
@@ -10,7 +10,7 @@
10
10
  * @packageDocumentation
11
11
  */
12
12
  export { type AdcpStructuredError, type ErrorCode, AdcpError } from './async-outcome.mjs';
13
- export type { TaskHandoffOptions, TaskHandoffProgress } from './async-outcome.mjs';
13
+ export type { ExternalTaskHandoffOptions, TaskHandoffOptions, TaskHandoffProgress } from './async-outcome.mjs';
14
14
  export { withResponseSummary } from './response-summary.mjs';
15
15
  export type { ResponseWithSummary } from './response-summary.mjs';
16
16
  export type { ServerPayload } from '../../types/server-payload.mjs';
@@ -47,7 +47,8 @@ export type { GetBrandIdentityRequest, GetBrandIdentitySuccess, GetRightsRequest
47
47
  export { createAdcpServerFromPlatform, getHydratedLegacyFormatIds, getAllAdcpMigrations, type CreateAdcpServerFromPlatformOptions, type LegacyDecisioningHandlerGroups, type RequiredOptsFor, type DecisioningAdcpServer, type DecisioningObservabilityHooks, } from './runtime/from-platform.mjs';
48
48
  export { PlatformConfigError, validatePlatform } from './runtime/validate-platform.mjs';
49
49
  export { completeScopedTask, createInMemoryTaskRegistry, failScopedTask, updateScopedTaskProgress, type ScopedTaskRef, type TaskMutationOutcome, type TaskRegistry, type TaskRegistryMutationResult, type TaskRegistryScope, type TaskRecord, type TaskStatus, } from './runtime/task-registry.mjs';
50
- export { createPostgresTaskRegistry, getDecisioningTaskRegistryBootstrap, getDecisioningTaskRegistryMigration, getDecisioningTaskRegistryScopeV1Upgrade, type CreatePostgresTaskRegistryOptions, type DecisioningTaskRegistryScopeV1Upgrade, type DecisioningTaskRegistryScopeV1UpgradeOptions, type PgQueryable, } from './runtime/postgres-task-registry.mjs';
50
+ export { createPostgresTaskRegistry, getDecisioningTaskRegistryBootstrap, getDecisioningTaskRegistryMigration, getDecisioningTaskRegistryScopeV1Upgrade, type CreatePostgresTaskRegistryOptions, type DecisioningTaskRegistryScopeV1Upgrade, type DecisioningTaskRegistryScopeV1UpgradeOptions, type PgQueryable, type PgTransactionClient, type PgTransactionalPool, } from './runtime/postgres-task-registry.mjs';
51
+ export { completeScopedPushTask, createPostgresTaskSettlementCoordinator, failScopedPushTask, TaskPushSettlementConfigurationError, type PostgresTaskSettlementCoordinator, type PostgresTaskSettlementCoordinatorOptions, type TaskPushDeliveryState, type TaskPushSettlementConfig, type TaskPushSettlementOutcome, } from './runtime/postgres-task-settlement.mjs';
51
52
  export { createTenantRegistry, createDefaultJwksValidator, createSelfSignedTenantKey, createNoopJwksValidator, type TenantRegistry, type TenantConfig, type TenantSigningKey, type TenantStatus, type TenantHealth, type TenantRegistryOptions, type JwksValidator, type JwksValidationResult, } from './tenant-registry.mjs';
52
53
  export { getAsset, getAssetSlot, requireAsset } from './manifest-helpers.mjs';
53
54
  export type { CreativeAssetsContainer } from './manifest-helpers.mjs';
@@ -10,7 +10,7 @@
10
10
  * @packageDocumentation
11
11
  */
12
12
  export { type AdcpStructuredError, type ErrorCode, AdcpError } from './async-outcome';
13
- export type { TaskHandoffOptions, TaskHandoffProgress } from './async-outcome';
13
+ export type { ExternalTaskHandoffOptions, TaskHandoffOptions, TaskHandoffProgress } from './async-outcome';
14
14
  export { withResponseSummary } from './response-summary';
15
15
  export type { ResponseWithSummary } from './response-summary';
16
16
  export type { ServerPayload } from '../../types/server-payload';
@@ -47,7 +47,8 @@ export type { GetBrandIdentityRequest, GetBrandIdentitySuccess, GetRightsRequest
47
47
  export { createAdcpServerFromPlatform, getHydratedLegacyFormatIds, getAllAdcpMigrations, type CreateAdcpServerFromPlatformOptions, type LegacyDecisioningHandlerGroups, type RequiredOptsFor, type DecisioningAdcpServer, type DecisioningObservabilityHooks, } from './runtime/from-platform';
48
48
  export { PlatformConfigError, validatePlatform } from './runtime/validate-platform';
49
49
  export { completeScopedTask, createInMemoryTaskRegistry, failScopedTask, updateScopedTaskProgress, type ScopedTaskRef, type TaskMutationOutcome, type TaskRegistry, type TaskRegistryMutationResult, type TaskRegistryScope, type TaskRecord, type TaskStatus, } from './runtime/task-registry';
50
- export { createPostgresTaskRegistry, getDecisioningTaskRegistryBootstrap, getDecisioningTaskRegistryMigration, getDecisioningTaskRegistryScopeV1Upgrade, type CreatePostgresTaskRegistryOptions, type DecisioningTaskRegistryScopeV1Upgrade, type DecisioningTaskRegistryScopeV1UpgradeOptions, type PgQueryable, } from './runtime/postgres-task-registry';
50
+ export { createPostgresTaskRegistry, getDecisioningTaskRegistryBootstrap, getDecisioningTaskRegistryMigration, getDecisioningTaskRegistryScopeV1Upgrade, type CreatePostgresTaskRegistryOptions, type DecisioningTaskRegistryScopeV1Upgrade, type DecisioningTaskRegistryScopeV1UpgradeOptions, type PgQueryable, type PgTransactionClient, type PgTransactionalPool, } from './runtime/postgres-task-registry';
51
+ export { completeScopedPushTask, createPostgresTaskSettlementCoordinator, failScopedPushTask, TaskPushSettlementConfigurationError, type PostgresTaskSettlementCoordinator, type PostgresTaskSettlementCoordinatorOptions, type TaskPushDeliveryState, type TaskPushSettlementConfig, type TaskPushSettlementOutcome, } from './runtime/postgres-task-settlement';
51
52
  export { createTenantRegistry, createDefaultJwksValidator, createSelfSignedTenantKey, createNoopJwksValidator, type TenantRegistry, type TenantConfig, type TenantSigningKey, type TenantStatus, type TenantHealth, type TenantRegistryOptions, type JwksValidator, type JwksValidationResult, } from './tenant-registry';
52
53
  export { getAsset, getAssetSlot, requireAsset } from './manifest-helpers';
53
54
  export type { CreativeAssetsContainer } from './manifest-helpers';
@@ -45,6 +45,7 @@ __export(decisioning_exports, {
45
45
  ProductUnavailableError: () => import_errors_typed.ProductUnavailableError,
46
46
  RateLimitedError: () => import_errors_typed.RateLimitedError,
47
47
  ServiceUnavailableError: () => import_errors_typed.ServiceUnavailableError,
48
+ TaskPushSettlementConfigurationError: () => import_postgres_task_settlement.TaskPushSettlementConfigurationError,
48
49
  UnsupportedFeatureError: () => import_errors_typed.UnsupportedFeatureError,
49
50
  batchPoll: () => import_helpers.batchPoll,
50
51
  buildListCreativesResponse: () => import_list_helpers.buildListCreativesResponse,
@@ -53,6 +54,7 @@ __export(decisioning_exports, {
53
54
  buildPricingOption: () => import_assembly_helpers.buildPricingOption,
54
55
  buildProduct: () => import_assembly_helpers.buildProduct,
55
56
  buildProductLegacy: () => import_assembly_helpers.buildProductLegacy,
57
+ completeScopedPushTask: () => import_postgres_task_settlement.completeScopedPushTask,
56
58
  completeScopedTask: () => import_task_registry.completeScopedTask,
57
59
  composeMethod: () => import_compose.composeMethod,
58
60
  createAdcpServerFromPlatform: () => import_from_platform.createAdcpServerFromPlatform,
@@ -61,6 +63,7 @@ __export(decisioning_exports, {
61
63
  createInMemoryTaskRegistry: () => import_task_registry.createInMemoryTaskRegistry,
62
64
  createNoopJwksValidator: () => import_tenant_registry.createNoopJwksValidator,
63
65
  createPostgresTaskRegistry: () => import_postgres_task_registry.createPostgresTaskRegistry,
66
+ createPostgresTaskSettlementCoordinator: () => import_postgres_task_settlement.createPostgresTaskSettlementCoordinator,
64
67
  createSelfSignedTenantKey: () => import_tenant_registry.createSelfSignedTenantKey,
65
68
  createTenantAdminHandlers: () => import_admin_router.createTenantAdminHandlers,
66
69
  createTenantAdminRouter: () => import_admin_router.createTenantAdminRouter,
@@ -83,6 +86,7 @@ __export(decisioning_exports, {
83
86
  defineSponsoredIntelligencePlatform: () => import_platform_helpers.defineSponsoredIntelligencePlatform,
84
87
  detectFinalizeAction: () => import_proposal.detectFinalizeAction,
85
88
  enforceProposalExpiry: () => import_proposal.enforceProposalExpiry,
89
+ failScopedPushTask: () => import_postgres_task_settlement.failScopedPushTask,
86
90
  failScopedTask: () => import_task_registry.failScopedTask,
87
91
  finalizeProposalConsumption: () => import_proposal.finalizeProposalConsumption,
88
92
  getAllAdcpMigrations: () => import_from_platform.getAllAdcpMigrations,
@@ -137,6 +141,7 @@ var import_from_platform = require('./runtime/from-platform.js');
137
141
  var import_validate_platform = require('./runtime/validate-platform.js');
138
142
  var import_task_registry = require('./runtime/task-registry.js');
139
143
  var import_postgres_task_registry = require('./runtime/postgres-task-registry.js');
144
+ var import_postgres_task_settlement = require('./runtime/postgres-task-settlement.js');
140
145
  var import_tenant_registry = require('./tenant-registry.js');
141
146
  var import_manifest_helpers = require('./manifest-helpers.js');
142
147
  var import_list_helpers = require('./list-helpers.js');
@@ -175,6 +180,7 @@ var import_assembly_helpers = require('./assembly-helpers.js');
175
180
  ProductUnavailableError,
176
181
  RateLimitedError,
177
182
  ServiceUnavailableError,
183
+ TaskPushSettlementConfigurationError,
178
184
  UnsupportedFeatureError,
179
185
  batchPoll,
180
186
  buildListCreativesResponse,
@@ -183,6 +189,7 @@ var import_assembly_helpers = require('./assembly-helpers.js');
183
189
  buildPricingOption,
184
190
  buildProduct,
185
191
  buildProductLegacy,
192
+ completeScopedPushTask,
186
193
  completeScopedTask,
187
194
  composeMethod,
188
195
  createAdcpServerFromPlatform,
@@ -191,6 +198,7 @@ var import_assembly_helpers = require('./assembly-helpers.js');
191
198
  createInMemoryTaskRegistry,
192
199
  createNoopJwksValidator,
193
200
  createPostgresTaskRegistry,
201
+ createPostgresTaskSettlementCoordinator,
194
202
  createSelfSignedTenantKey,
195
203
  createTenantAdminHandlers,
196
204
  createTenantAdminRouter,
@@ -213,6 +221,7 @@ var import_assembly_helpers = require('./assembly-helpers.js');
213
221
  defineSponsoredIntelligencePlatform,
214
222
  detectFinalizeAction,
215
223
  enforceProposalExpiry,
224
+ failScopedPushTask,
216
225
  failScopedTask,
217
226
  finalizeProposalConsumption,
218
227
  getAllAdcpMigrations,
@@ -55,6 +55,12 @@ import {
55
55
  getDecisioningTaskRegistryMigration,
56
56
  getDecisioningTaskRegistryScopeV1Upgrade
57
57
  } from "./runtime/postgres-task-registry.mjs";
58
+ import {
59
+ completeScopedPushTask,
60
+ createPostgresTaskSettlementCoordinator,
61
+ failScopedPushTask,
62
+ TaskPushSettlementConfigurationError
63
+ } from "./runtime/postgres-task-settlement.mjs";
58
64
  import {
59
65
  createTenantRegistry,
60
66
  createDefaultJwksValidator,
@@ -135,6 +141,7 @@ export {
135
141
  ProductUnavailableError,
136
142
  RateLimitedError,
137
143
  ServiceUnavailableError,
144
+ TaskPushSettlementConfigurationError,
138
145
  UnsupportedFeatureError,
139
146
  batchPoll,
140
147
  buildListCreativesResponse,
@@ -143,6 +150,7 @@ export {
143
150
  buildPricingOption,
144
151
  buildProduct,
145
152
  buildProductLegacy,
153
+ completeScopedPushTask,
146
154
  completeScopedTask,
147
155
  composeMethod,
148
156
  createAdcpServerFromPlatform,
@@ -151,6 +159,7 @@ export {
151
159
  createInMemoryTaskRegistry,
152
160
  createNoopJwksValidator,
153
161
  createPostgresTaskRegistry,
162
+ createPostgresTaskSettlementCoordinator,
154
163
  createSelfSignedTenantKey,
155
164
  createTenantAdminHandlers,
156
165
  createTenantAdminRouter,
@@ -173,6 +182,7 @@ export {
173
182
  defineSponsoredIntelligencePlatform,
174
183
  detectFinalizeAction,
175
184
  enforceProposalExpiry,
185
+ failScopedPushTask,
176
186
  failScopedTask,
177
187
  finalizeProposalConsumption,
178
188
  getAllAdcpMigrations,
@@ -167,14 +167,17 @@ export interface DecisioningObservabilityHooks {
167
167
  resourceId: string;
168
168
  }): void;
169
169
  }
170
- export type LegacyDecisioningHandlerGroups = Pick<AdcpServerConfig, 'mediaBuy' | 'creative' | 'governance' | 'brandRights'>;
170
+ export type LegacyDecisioningHandlerGroups = Pick<AdcpServerConfig, 'mediaBuy' | 'creative' | 'governance' | 'brandRights' | 'signals'>;
171
171
  export interface CreateAdcpServerFromPlatformOptions extends Omit<AdcpServerConfig, 'resolveAccount' | 'capabilities' | 'name' | 'version' | 'mediaBuy' | 'creative' | 'governance' | 'brandRights'> {
172
172
  name: string;
173
173
  version: string;
174
174
  /**
175
175
  * Explicit compatibility seam for raw protocol handlers that have not yet
176
176
  * migrated to canonical DecisioningPlatform methods. Wire support remains
177
- * available through AdCP 3.x, but raw creative identity must never look like
177
+ * available through AdCP 3.x. A legacy `signals.getSignals` handler supplied
178
+ * here (or through the inherited `opts.signals` compatibility field) satisfies
179
+ * signal-specialism platform validation without requiring an invented
180
+ * `activateSignal` implementation. Raw creative identity must never look like
178
181
  * a primary platform hook.
179
182
  */
180
183
  legacyHandlers?: LegacyDecisioningHandlerGroups;
@@ -167,14 +167,17 @@ export interface DecisioningObservabilityHooks {
167
167
  resourceId: string;
168
168
  }): void;
169
169
  }
170
- export type LegacyDecisioningHandlerGroups = Pick<AdcpServerConfig, 'mediaBuy' | 'creative' | 'governance' | 'brandRights'>;
170
+ export type LegacyDecisioningHandlerGroups = Pick<AdcpServerConfig, 'mediaBuy' | 'creative' | 'governance' | 'brandRights' | 'signals'>;
171
171
  export interface CreateAdcpServerFromPlatformOptions extends Omit<AdcpServerConfig, 'resolveAccount' | 'capabilities' | 'name' | 'version' | 'mediaBuy' | 'creative' | 'governance' | 'brandRights'> {
172
172
  name: string;
173
173
  version: string;
174
174
  /**
175
175
  * Explicit compatibility seam for raw protocol handlers that have not yet
176
176
  * migrated to canonical DecisioningPlatform methods. Wire support remains
177
- * available through AdCP 3.x, but raw creative identity must never look like
177
+ * available through AdCP 3.x. A legacy `signals.getSignals` handler supplied
178
+ * here (or through the inherited `opts.signals` compatibility field) satisfies
179
+ * signal-specialism platform validation without requiring an invented
180
+ * `activateSignal` implementation. Raw creative identity must never look like
178
181
  * a primary platform hook.
179
182
  */
180
183
  legacyHandlers?: LegacyDecisioningHandlerGroups;