@adcp/sdk 14.0.0-rc.42 → 14.0.0-rc.43

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 (170) hide show
  1. package/CONTRIBUTING.md +7 -1
  2. package/README.md +13 -0
  3. package/bin/adcp.js +81 -16
  4. package/dist/lib/acceptance-policy/index.d.mts +176 -0
  5. package/dist/lib/acceptance-policy/index.d.ts +176 -0
  6. package/dist/lib/acceptance-policy/index.js +1107 -0
  7. package/dist/lib/acceptance-policy/index.mjs +1080 -0
  8. package/dist/lib/canonical-references/index.d.mts +1 -1
  9. package/dist/lib/canonical-references/index.d.ts +1 -1
  10. package/dist/lib/canonical-references/index.js +60 -2
  11. package/dist/lib/canonical-references/index.mjs +60 -2
  12. package/dist/lib/client/core.d.mts +8 -0
  13. package/dist/lib/client/core.d.ts +8 -0
  14. package/dist/lib/client/core.js +57 -0
  15. package/dist/lib/client/core.mjs +38 -0
  16. package/dist/lib/core/ADCPMultiAgentClient.d.mts +5 -1
  17. package/dist/lib/core/ADCPMultiAgentClient.d.ts +5 -1
  18. package/dist/lib/core/ADCPMultiAgentClient.js +8 -0
  19. package/dist/lib/core/ADCPMultiAgentClient.mjs +8 -0
  20. package/dist/lib/core/AgentClient.d.mts +10 -2
  21. package/dist/lib/core/AgentClient.d.ts +10 -2
  22. package/dist/lib/core/AgentClient.js +28 -2
  23. package/dist/lib/core/AgentClient.mjs +17 -1
  24. package/dist/lib/core/AsyncHandler.d.mts +3 -1
  25. package/dist/lib/core/AsyncHandler.d.ts +3 -1
  26. package/dist/lib/core/AsyncHandler.js +6 -0
  27. package/dist/lib/core/AsyncHandler.mjs +6 -0
  28. package/dist/lib/core/SingleAgentClient.d.mts +5 -1
  29. package/dist/lib/core/SingleAgentClient.d.ts +5 -1
  30. package/dist/lib/core/SingleAgentClient.js +51 -10
  31. package/dist/lib/core/SingleAgentClient.mjs +56 -10
  32. package/dist/lib/index.d.mts +2 -0
  33. package/dist/lib/index.d.ts +2 -0
  34. package/dist/lib/index.js +11 -0
  35. package/dist/lib/index.mjs +11 -0
  36. package/dist/lib/net/ssrf-fetch.d.mts +1 -1
  37. package/dist/lib/net/ssrf-fetch.d.ts +1 -1
  38. package/dist/lib/net/ssrf-fetch.js +10 -1
  39. package/dist/lib/net/ssrf-fetch.mjs +10 -1
  40. package/dist/lib/principal/index.d.mts +1 -0
  41. package/dist/lib/principal/index.d.ts +1 -0
  42. package/dist/lib/principal/index.js +32 -0
  43. package/dist/lib/principal/index.mjs +10 -0
  44. package/dist/lib/principal/lifecycle.d.mts +77 -0
  45. package/dist/lib/principal/lifecycle.d.ts +77 -0
  46. package/dist/lib/principal/lifecycle.js +319 -0
  47. package/dist/lib/principal/lifecycle.mjs +293 -0
  48. package/dist/lib/registry/index.d.mts +3 -1
  49. package/dist/lib/registry/index.d.ts +3 -1
  50. package/dist/lib/registry/index.js +16 -3
  51. package/dist/lib/registry/index.mjs +16 -3
  52. package/dist/lib/registry/types.generated.d.mts +54 -20
  53. package/dist/lib/registry/types.generated.d.ts +54 -20
  54. package/dist/lib/reporting/core-reconciliation.d.mts +65 -0
  55. package/dist/lib/reporting/core-reconciliation.d.ts +65 -0
  56. package/dist/lib/reporting/core-reconciliation.js +148 -0
  57. package/dist/lib/reporting/core-reconciliation.mjs +124 -0
  58. package/dist/lib/reporting/index.d.mts +2 -0
  59. package/dist/lib/reporting/index.d.ts +2 -0
  60. package/dist/lib/reporting/index.js +5 -2
  61. package/dist/lib/reporting/index.mjs +3 -1
  62. package/dist/lib/reporting/ledger/health.d.mts +26 -2
  63. package/dist/lib/reporting/ledger/health.d.ts +26 -2
  64. package/dist/lib/reporting/ledger/health.js +3 -5
  65. package/dist/lib/reporting/ledger/health.mjs +3 -5
  66. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  67. package/dist/lib/server/create-adcp-server.d.mts +10 -11
  68. package/dist/lib/server/create-adcp-server.d.ts +10 -11
  69. package/dist/lib/server/create-adcp-server.js +39 -25
  70. package/dist/lib/server/create-adcp-server.mjs +44 -27
  71. package/dist/lib/server/index.d.mts +3 -1
  72. package/dist/lib/server/index.d.ts +3 -1
  73. package/dist/lib/server/index.js +9 -0
  74. package/dist/lib/server/index.mjs +10 -0
  75. package/dist/lib/server/mcp-app.d.mts +11 -24
  76. package/dist/lib/server/mcp-app.d.ts +11 -24
  77. package/dist/lib/server/mcp-app.js +30 -4
  78. package/dist/lib/server/mcp-app.mjs +30 -3
  79. package/dist/lib/server/mcp-modern-server.js +18 -14
  80. package/dist/lib/server/mcp-modern-server.mjs +25 -15
  81. package/dist/lib/server/notification-subscriptions/index.d.mts +1 -1
  82. package/dist/lib/server/notification-subscriptions/index.d.ts +1 -1
  83. package/dist/lib/server/notification-subscriptions/runtime.d.mts +3 -1
  84. package/dist/lib/server/notification-subscriptions/runtime.d.ts +3 -1
  85. package/dist/lib/server/notification-subscriptions/runtime.js +108 -64
  86. package/dist/lib/server/notification-subscriptions/runtime.mjs +107 -64
  87. package/dist/lib/server/notification-subscriptions/types.d.mts +41 -0
  88. package/dist/lib/server/notification-subscriptions/types.d.ts +41 -0
  89. package/dist/lib/server/principal/index.d.mts +5 -0
  90. package/dist/lib/server/principal/index.d.ts +5 -0
  91. package/dist/lib/server/principal/index.js +35 -0
  92. package/dist/lib/server/principal/index.mjs +12 -0
  93. package/dist/lib/server/principal/runtime.d.mts +57 -0
  94. package/dist/lib/server/principal/runtime.d.ts +57 -0
  95. package/dist/lib/server/principal/runtime.js +880 -0
  96. package/dist/lib/server/principal/runtime.mjs +861 -0
  97. package/dist/lib/server/principal/store.d.mts +16 -0
  98. package/dist/lib/server/principal/store.d.ts +16 -0
  99. package/dist/lib/server/principal/store.js +248 -0
  100. package/dist/lib/server/principal/store.mjs +223 -0
  101. package/dist/lib/server/principal/types.d.mts +142 -0
  102. package/dist/lib/server/principal/types.d.ts +142 -0
  103. package/dist/lib/server/principal/types.js +16 -0
  104. package/dist/lib/server/principal/types.mjs +0 -0
  105. package/dist/lib/signing/agent-resolver/strict-json.d.mts +11 -0
  106. package/dist/lib/signing/agent-resolver/strict-json.d.ts +11 -0
  107. package/dist/lib/signing/agent-resolver/strict-json.js +6 -4
  108. package/dist/lib/signing/agent-resolver/strict-json.mjs +4 -3
  109. package/dist/lib/testing/compliance/comply.js +44 -0
  110. package/dist/lib/testing/compliance/comply.mjs +43 -0
  111. package/dist/lib/testing/storyboard/agent-routing.d.mts +2 -0
  112. package/dist/lib/testing/storyboard/agent-routing.d.ts +2 -0
  113. package/dist/lib/testing/storyboard/agent-routing.js +31 -4
  114. package/dist/lib/testing/storyboard/agent-routing.mjs +30 -4
  115. package/dist/lib/testing/storyboard/junit.d.mts +1 -1
  116. package/dist/lib/testing/storyboard/junit.d.ts +1 -1
  117. package/dist/lib/testing/storyboard/junit.js +25 -10
  118. package/dist/lib/testing/storyboard/junit.mjs +23 -9
  119. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  120. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  121. package/dist/lib/types/schemas.generated.d.ts +8 -8
  122. package/dist/lib/utils/idempotency.d.mts +4 -2
  123. package/dist/lib/utils/idempotency.d.ts +4 -2
  124. package/dist/lib/utils/idempotency.js +41 -22
  125. package/dist/lib/utils/idempotency.mjs +41 -22
  126. package/dist/lib/utils/media-buy-status.js +3 -2
  127. package/dist/lib/utils/media-buy-status.mjs +3 -2
  128. package/dist/lib/utils/response-schema-cache.d.mts +3 -0
  129. package/dist/lib/utils/response-schema-cache.d.ts +3 -0
  130. package/dist/lib/utils/response-schema-cache.js +45 -0
  131. package/dist/lib/utils/response-schema-cache.mjs +20 -0
  132. package/dist/lib/utils/response-schemas.js +2 -0
  133. package/dist/lib/utils/response-schemas.mjs +2 -0
  134. package/dist/lib/utils/response-unwrapper.d.mts +1 -1
  135. package/dist/lib/utils/response-unwrapper.d.ts +1 -1
  136. package/dist/lib/utils/response-unwrapper.js +15 -8
  137. package/dist/lib/utils/response-unwrapper.mjs +14 -2
  138. package/dist/lib/v2/projection/v1-to-v2.js +2 -2
  139. package/dist/lib/v2/projection/v1-to-v2.mjs +6 -1
  140. package/dist/lib/version.d.mts +3 -3
  141. package/dist/lib/version.d.ts +3 -3
  142. package/dist/lib/version.js +3 -3
  143. package/dist/lib/version.mjs +3 -3
  144. package/dist/lib/wholesale-feed-sync/index.d.mts +3 -1
  145. package/dist/lib/wholesale-feed-sync/index.d.ts +3 -1
  146. package/dist/lib/wholesale-feed-sync/index.js +7 -2
  147. package/dist/lib/wholesale-feed-sync/index.mjs +4 -1
  148. package/dist/lib/wholesale-feed-sync/register.d.mts +49 -0
  149. package/dist/lib/wholesale-feed-sync/register.d.ts +49 -0
  150. package/dist/lib/wholesale-feed-sync/register.js +115 -0
  151. package/dist/lib/wholesale-feed-sync/register.mjs +90 -0
  152. package/dist/lib/wholesale-feed-sync/sync.d.mts +7 -0
  153. package/dist/lib/wholesale-feed-sync/sync.d.ts +7 -0
  154. package/dist/lib/wholesale-feed-sync/sync.js +161 -4
  155. package/dist/lib/wholesale-feed-sync/sync.mjs +161 -4
  156. package/dist/lib/wholesale-feed-sync/types.d.mts +51 -1
  157. package/dist/lib/wholesale-feed-sync/types.d.ts +51 -1
  158. package/docs/TYPE-SUMMARY.md +2 -2
  159. package/docs/guides/ACCEPTANCE-POLICY-DISCOVERY.md +104 -0
  160. package/docs/guides/BUILD-AN-AGENT.md +7 -5
  161. package/docs/guides/PERSISTENT-NOTIFICATION-RUNTIME.md +7 -7
  162. package/docs/guides/PRINCIPAL-LIFECYCLE.md +236 -0
  163. package/docs/guides/PRODUCTION-DURABILITY.md +4 -0
  164. package/docs/guides/REPORTING-RECONCILIATION.md +95 -0
  165. package/docs/guides/VALIDATE-YOUR-AGENT.md +24 -0
  166. package/docs/llms.txt +2 -2
  167. package/docs/migration-14.x-rc-worksheet.md +4 -4
  168. package/examples/README.md +13 -0
  169. package/examples/wholesale-feed-sync.ts +274 -0
  170. package/package.json +17 -1
package/CONTRIBUTING.md CHANGED
@@ -109,7 +109,13 @@ The Node test runner otherwise derives concurrency from the machine CPU count. T
109
109
  too aggressive on developer workstations because several test files launch their own
110
110
  TypeScript compiler or CLI subprocesses. The repository runner therefore caps local
111
111
  fast suites at two workers and runs the slow group serially. CI keeps its existing
112
- machine-derived concurrency and splits the fast suite into three shards.
112
+ machine-derived concurrency and splits the fast suite into three shards. Those CI
113
+ shards use per-file durations recorded by the latest successful `main` run and a
114
+ deterministic longest-first assignment. A new or renamed test uses the median known
115
+ duration; when no history is available, all files use an equal one-second weight.
116
+ Pull requests may restore this history but cannot publish it, so untrusted or failed
117
+ runs cannot poison future shard assignments. Each shard uploads its assignment
118
+ manifest with the timing artifact for debugging.
113
119
 
114
120
  `npm test` and `npm run test:lib` build the library once before starting their test
115
121
  groups, then every test reads that completed `dist/` tree. Set `TEST_CONCURRENCY=1`
package/README.md CHANGED
@@ -59,6 +59,19 @@ Large workspaces should keep the generated schema surface out of the default typ
59
59
  | Runtime Zod schemas and tool schema maps | `@adcp/sdk/schemas` |
60
60
  | Broad generated protocol type barrel | `@adcp/sdk/types` |
61
61
 
62
+ ### Focused client runtime (`@adcp/sdk/client/core`)
63
+
64
+ Applications that only call AdCP agents can avoid evaluating the SDK's server,
65
+ compliance, testing, and unrelated protocol surfaces:
66
+
67
+ ```ts
68
+ import { ADCPMultiAgentClient, InMemoryWebhookRegistrationStore } from '@adcp/sdk/client/core';
69
+ ```
70
+
71
+ The existing `@adcp/sdk/client` path remains an alias of the package root for
72
+ compatibility. Use `/client/core` when cold import and test-worker startup time
73
+ matter.
74
+
62
75
  For application monorepos, keep `skipLibCheck: true` unless you are intentionally auditing SDK declarations. If a package only needs request/response types for a few tools, prefer the per-tool slices over importing generated types through the root package or the broad `@adcp/sdk/types` barrel.
63
76
 
64
77
  ## Quick Start: AdCP 3.2
package/bin/adcp.js CHANGED
@@ -57,7 +57,10 @@ const {
57
57
  } = require('./adcp-storyboard-summary.js');
58
58
 
59
59
  const { scheduleVersionCheck } = require('./adcp-version-check.js');
60
- const { formatStoryboardResultsAsJUnit } = require('../dist/lib/testing/storyboard/junit.js');
60
+ const {
61
+ formatStoryboardResultsAsJUnit,
62
+ routedStoryboardResultGroup,
63
+ } = require('../dist/lib/testing/storyboard/junit.js');
61
64
  const { ADCP_VERSION, LIBRARY_VERSION } = require('../dist/lib/version.js');
62
65
  const { isAdcpVersionSupported } = require('../dist/lib/utils/adcp-version-config.js');
63
66
  const { appendBuiltInVersionUnsupportedHint } = require('./adcp-version-unsupported-hint.js');
@@ -2917,7 +2920,7 @@ async function handleStoryboardRun(args) {
2917
2920
  'Usage: adcp storyboard run <agent> [storyboard_id|--file path] [options]\n' +
2918
2921
  ' Local agent: adcp storyboard run --local-agent <module> [storyboard_id|bundle_id]\n' +
2919
2922
  ' Multi-instance: adcp storyboard run --url <url1> --url <url2> <storyboard_id|bundle_id>\n' +
2920
- ' Multi-agent: adcp storyboard run --agents-map ./agents.yaml <storyboard_id|bundle_id>'
2923
+ ' Multi-agent: adcp storyboard run --agents-map ./agents.yaml [storyboard_id|bundle_id]'
2921
2924
  );
2922
2925
  process.exit(2);
2923
2926
  }
@@ -4638,9 +4641,8 @@ async function handleMultiInstanceStoryboardRun(args, opts, urls) {
4638
4641
  * `get_adcp_capabilities`; tools without a unique claimant fall through to
4639
4642
  * `--default-agent`, or fail-fast with `unroutable_task`.
4640
4643
  *
4641
- * Capability-driven full assessment is intentionally not supported here —
4642
- * the assessment dispatches via `comply()` which expects a single agent.
4643
- * Storyboard ID, bundle ID, or `--file` is required.
4644
+ * With no storyboard or file, every tenant is discovered first and the
4645
+ * topology runs the union of capability-applicable storyboards.
4644
4646
  */
4645
4647
  async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4646
4648
  const { authToken, authScheme, protocolFlag, jsonOutput, dryRun, positionalArgs, file: filePath, format } = opts;
@@ -4669,17 +4671,11 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4669
4671
  }
4670
4672
 
4671
4673
  const storyboardId = firstPositional;
4674
+ const capabilityDriven = !filePath && !storyboardId;
4672
4675
  if (filePath && storyboardId) {
4673
4676
  console.error('ERROR: Cannot combine a storyboard ID with --file. Use one or the other.');
4674
4677
  process.exit(2);
4675
4678
  }
4676
- if (!filePath && !storyboardId) {
4677
- console.error(
4678
- 'ERROR: Multi-agent routing requires a storyboard ID, bundle ID, or --file. ' +
4679
- 'Capability-driven full assessment is not yet routing-aware.'
4680
- );
4681
- process.exit(2);
4682
- }
4683
4679
 
4684
4680
  const { loadStoryboardFile, runStoryboard, getComplianceStoryboardById, loadBundleStoryboards, findBundleById } =
4685
4681
  await import('../dist/lib/testing/storyboard/index.js');
@@ -4692,7 +4688,7 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4692
4688
  console.error(`Failed to load storyboard from ${filePath}: ${err.message}`);
4693
4689
  process.exit(2);
4694
4690
  }
4695
- } else {
4691
+ } else if (storyboardId) {
4696
4692
  const bundle = findBundleById(storyboardId, resolveOptions);
4697
4693
  if (bundle) {
4698
4694
  const bundleStoryboards = loadBundleStoryboards(bundle);
@@ -4748,6 +4744,49 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4748
4744
 
4749
4745
  await loadInvariantModules(args);
4750
4746
 
4747
+ let routedSelection;
4748
+ let routedSelectionSummary;
4749
+ let routingProfiles;
4750
+ if (capabilityDriven) {
4751
+ const { discoverAgentRouting } = await import('../dist/lib/testing/storyboard/agent-routing.js');
4752
+ const { resolveRoutedAssessment } = await import('../dist/lib/testing/compliance/comply.js');
4753
+ const discoveryOptions = {
4754
+ protocol,
4755
+ ...buildResolvedAuthOption({ resolvedAuth: authToken, resolvedAuthScheme: authScheme || 'bearer' }),
4756
+ ...(opts.allowHttp && { allow_http: true }),
4757
+ agents: routing.agents,
4758
+ ...(routing.default_agent ? { default_agent: routing.default_agent } : {}),
4759
+ ...(runComplianceDir && { complianceDir: runComplianceDir }),
4760
+ ...(runAdcpVersion && { adcpVersion: runAdcpVersion }),
4761
+ ...(runSchemaRoot && { schemaRoot: runSchemaRoot }),
4762
+ ...sandboxRunOptions(opts),
4763
+ ...(requestSigningOpts ?? {}),
4764
+ };
4765
+ const restoreDiscoveryLogs = jsonOutput ? captureStdoutLogs() : null;
4766
+ try {
4767
+ if (!jsonOutput) console.error('Discovering routed agent capabilities...');
4768
+ const routingContext = await discoverAgentRouting(discoveryOptions);
4769
+ routingProfiles = routingContext.profiles;
4770
+ routedSelection = resolveRoutedAssessment(routingProfiles, resolveOptions);
4771
+ routedSelectionSummary = {
4772
+ agents: routedSelection.agents,
4773
+ not_applicable: routedSelection.not_applicable,
4774
+ missing_tools: routedSelection.missing_tools,
4775
+ storyboard_ids: routedSelection.storyboards.map(storyboard => storyboard.id),
4776
+ };
4777
+ storyboards.push(...routedSelection.storyboards);
4778
+ } catch (err) {
4779
+ console.error(`ERROR: Failed to resolve routed assessment: ${err.message}`);
4780
+ process.exit(1);
4781
+ } finally {
4782
+ if (restoreDiscoveryLogs) restoreDiscoveryLogs();
4783
+ }
4784
+ if (storyboards.length === 0) {
4785
+ console.error('ERROR: Routed capability discovery selected no runnable storyboards.');
4786
+ process.exit(1);
4787
+ }
4788
+ }
4789
+
4751
4790
  const totalSteps = storyboards.reduce(
4752
4791
  (sum, sb) => sum + sb.phases.reduce((phaseSum, p) => phaseSum + p.steps.length, 0),
4753
4792
  0
@@ -4777,6 +4816,10 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4777
4816
  default_agent: routing.default_agent,
4778
4817
  protocol,
4779
4818
  preview: true,
4819
+ ...(capabilityDriven && {
4820
+ assessment_mode: 'capability-driven',
4821
+ selection: routedSelectionSummary,
4822
+ }),
4780
4823
  storyboards: storyboards.map(sb => ({
4781
4824
  storyboard_id: sb.id,
4782
4825
  storyboard_title: sb.title,
@@ -4799,6 +4842,10 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4799
4842
  }
4800
4843
  console.log(`\n${totalSteps} step(s) would be routed at run time. Use without --dry-run to execute.`);
4801
4844
  }
4845
+ if (capabilityDriven) {
4846
+ const { closeConnections } = await import('../dist/lib/protocols/index.js');
4847
+ await closeConnections(protocol);
4848
+ }
4802
4849
  return;
4803
4850
  }
4804
4851
 
@@ -4825,6 +4872,7 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4825
4872
  }),
4826
4873
  ...(opts.loadedTestKit !== undefined && { test_kit: opts.loadedTestKit }),
4827
4874
  ...(requestSigningOpts ?? {}),
4875
+ ...(routingProfiles && { _routingProfiles: routingProfiles }),
4828
4876
  };
4829
4877
 
4830
4878
  const restoreLogs = jsonOutput ? captureStdoutLogs() : null;
@@ -4842,7 +4890,12 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4842
4890
  }
4843
4891
 
4844
4892
  if (format === 'junit') {
4845
- process.stdout.write(formatStoryboardResultsAsJUnit(results));
4893
+ const suiteGroups = capabilityDriven
4894
+ ? Object.fromEntries(results.map(result => [result.storyboard_id, routedStoryboardResultGroup(result)]))
4895
+ : undefined;
4896
+ process.stdout.write(
4897
+ formatStoryboardResultsAsJUnit(results, suiteGroups ? { suite_groups: suiteGroups } : undefined)
4898
+ );
4846
4899
  if (opts.softFail && hadFailure) {
4847
4900
  printSoftFailBlock(
4848
4901
  results.filter(r => !r.overall_passed).map(r => r.storyboard_id),
@@ -4853,13 +4906,25 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
4853
4906
  }
4854
4907
 
4855
4908
  if (jsonOutput) {
4909
+ const reports = {};
4910
+ if (capabilityDriven) {
4911
+ for (const result of results) {
4912
+ const group = routedStoryboardResultGroup(result);
4913
+ (reports[group] ??= []).push(result);
4914
+ }
4915
+ }
4856
4916
  await writeJsonOutput(
4857
- results.length === 1
4917
+ !capabilityDriven && results.length === 1
4858
4918
  ? results[0]
4859
4919
  : {
4860
4920
  agents: routing.agents,
4861
4921
  default_agent: routing.default_agent,
4862
- storyboards: results,
4922
+ ...(capabilityDriven && {
4923
+ assessment_mode: 'capability-driven',
4924
+ selection: routedSelectionSummary,
4925
+ reports,
4926
+ }),
4927
+ ...(!capabilityDriven && { storyboards: results }),
4863
4928
  overall_passed: !hadFailure,
4864
4929
  }
4865
4930
  );
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Buyer-side resolution of seller acceptance-policy catalogs.
3
+ *
4
+ * Catalog discovery is advisory. A successfully resolved catalog describes
5
+ * likely seller treatment; it never authorizes an exact media-buy request.
6
+ */
7
+ import type { ResolvePolicyResponse } from '../registry/types.mjs';
8
+ export interface AcceptancePolicyDiscoveryCapability {
9
+ catalog_url: string;
10
+ catalog_digest: string;
11
+ default_profile_ids?: readonly string[];
12
+ }
13
+ export interface AcceptancePolicyReference {
14
+ policy_id: string;
15
+ version: string;
16
+ content_digest: string;
17
+ }
18
+ export interface AcceptancePolicyRule {
19
+ rule_id: string;
20
+ subject_category: string;
21
+ jurisdiction_groups?: string[];
22
+ applies_to: string[];
23
+ disposition: 'allowed' | 'conditional' | 'prohibited';
24
+ policy_ids?: string[];
25
+ [key: string]: unknown;
26
+ }
27
+ export interface AcceptancePolicyProfile {
28
+ profile_id: string;
29
+ version: string;
30
+ content_digest: string;
31
+ policy_refs: AcceptancePolicyReference[];
32
+ coverage: 'partial' | 'complete';
33
+ scope?: {
34
+ jurisdiction_groups?: string[];
35
+ [key: string]: unknown;
36
+ };
37
+ region_aliases?: Record<string, string[]>;
38
+ rules: AcceptancePolicyRule[];
39
+ [key: string]: unknown;
40
+ }
41
+ export interface RegistryAcceptancePolicyProfileReference {
42
+ policy_id: string;
43
+ policy_version: string;
44
+ policy_digest: string;
45
+ profile_id: string;
46
+ profile_version: string;
47
+ profile_digest: string;
48
+ }
49
+ export interface AcceptancePolicyCatalog {
50
+ catalog_version: string;
51
+ generated_at?: string;
52
+ profiles?: AcceptancePolicyProfile[];
53
+ registry_profiles?: RegistryAcceptancePolicyProfileReference[];
54
+ ext?: Record<string, unknown>;
55
+ }
56
+ export type ResolvedAcceptancePolicyDefault = {
57
+ source: 'seller';
58
+ resolution: 'resolved';
59
+ profileId: string;
60
+ profile: AcceptancePolicyProfile;
61
+ } | {
62
+ source: 'registry';
63
+ resolution: 'resolved';
64
+ profileId: string;
65
+ profile: AcceptancePolicyProfile;
66
+ ref: RegistryAcceptancePolicyProfileReference;
67
+ } | {
68
+ source: 'registry';
69
+ resolution: 'unresolved';
70
+ profileId: string;
71
+ ref: RegistryAcceptancePolicyProfileReference;
72
+ };
73
+ export type AcceptancePolicyProfileResolution = ResolvedAcceptancePolicyDefault | {
74
+ source: 'catalog';
75
+ resolution: 'missing';
76
+ profileId: string;
77
+ };
78
+ export type AcceptancePolicyCatalogErrorCode = 'invalid_capability' | 'invalid_options' | 'unsafe_url' | 'redirect_blocked' | 'fetch_failed' | 'http_error' | 'body_too_large' | 'digest_mismatch' | 'invalid_json' | 'catalog_document_invalid' | 'schema_unavailable' | 'schema_invalid' | 'duplicate_profile_id' | 'unresolved_profile_id' | 'profile_canonicalization_invalid' | 'profile_digest_mismatch' | 'reference_invalid' | 'registry_fetch_failed' | 'registry_reference_unresolved' | 'registry_policy_mismatch' | 'registry_policy_unverifiable' | 'registry_policy_digest_mismatch' | 'registry_profile_schema_invalid' | 'registry_profile_invalid' | 'registry_profile_mismatch' | 'registry_profile_digest_mismatch' | 'registry_resolution_limit_exceeded' | 'registry_timeout';
79
+ export interface AcceptancePolicyCatalogIssue {
80
+ code: AcceptancePolicyCatalogErrorCode;
81
+ message: string;
82
+ /** JSON Pointer into the capability or catalog. Values are never echoed. */
83
+ pointer: string;
84
+ keyword?: string;
85
+ retryable?: boolean;
86
+ httpStatus?: number;
87
+ }
88
+ export interface AcceptancePolicyCatalogFailure {
89
+ ok: false;
90
+ fromCache: false;
91
+ error: AcceptancePolicyCatalogIssue;
92
+ issues?: AcceptancePolicyCatalogIssue[];
93
+ }
94
+ export interface AcceptancePolicyCatalogSuccess {
95
+ ok: true;
96
+ fromCache: boolean;
97
+ catalog: AcceptancePolicyCatalog;
98
+ defaultProfiles: ResolvedAcceptancePolicyDefault[];
99
+ /** Non-fatal registry diagnostics. Affected profiles remain unresolved. */
100
+ issues?: AcceptancePolicyCatalogIssue[];
101
+ }
102
+ export type AcceptancePolicyCatalogResult = AcceptancePolicyCatalogSuccess | AcceptancePolicyCatalogFailure;
103
+ /** Registry fields covered by acceptance-policy pin verification. */
104
+ export type AcceptancePolicyRegistryPolicy = Pick<ResolvePolicyResponse, 'policy_id' | 'version' | 'content_digest' | 'canonical_content' | 'acceptance_profile'>;
105
+ /** Minimal trusted-registry surface needed to resolve an immutable policy version. */
106
+ export interface AcceptancePolicyRegistryResolver {
107
+ resolvePolicy(params: {
108
+ policy_id: string;
109
+ version?: string;
110
+ signal?: AbortSignal;
111
+ }): Promise<AcceptancePolicyRegistryPolicy | null>;
112
+ }
113
+ export interface ResolveVerifiedAcceptancePolicyProfilesOptions {
114
+ registryResolver: AcceptancePolicyRegistryResolver;
115
+ /** Schema bundle used to validate embedded profiles. Defaults to the SDK pin. */
116
+ adcpVersion?: string;
117
+ /** Overall deadline for all selected registry lookups. Default 5 seconds. */
118
+ timeoutMs?: number;
119
+ /** Maximum distinct registry profiles resolved in one call. Default and maximum 32. */
120
+ maxRegistryProfiles?: number;
121
+ }
122
+ export interface VerifiedAcceptancePolicyProfilesSuccess {
123
+ ok: true;
124
+ profiles: AcceptancePolicyProfileResolution[];
125
+ /** Per-profile failures. Each affected registry profile remains unresolved. */
126
+ issues?: AcceptancePolicyCatalogIssue[];
127
+ }
128
+ export type VerifiedAcceptancePolicyProfilesResult = VerifiedAcceptancePolicyProfilesSuccess | AcceptancePolicyCatalogFailure;
129
+ export interface ResolveAcceptancePolicyCatalogOptions {
130
+ /** Schema bundle used to validate the fetched catalog. Defaults to the SDK pin. */
131
+ adcpVersion?: string;
132
+ /** Overall DNS/connect/body timeout for the catalog fetch. Default 5 seconds. */
133
+ timeoutMs?: number;
134
+ /** Hard response-body cap. Default and maximum 1 MiB; callers may lower it. */
135
+ maxBodyBytes?: number;
136
+ /** Test/dev-only HTTP opt-in; requires allowPrivateNetwork. Production callers must leave false. */
137
+ allowUnsafeHttp?: boolean;
138
+ /** Test/dev-only opt-in for private-network fixtures. Production callers must leave false. */
139
+ allowPrivateNetwork?: boolean;
140
+ /** Trusted AdCP registry client used to resolve and verify registry-backed defaults. */
141
+ registryResolver?: AcceptancePolicyRegistryResolver;
142
+ /** Overall deadline for registry resolution. Default 5 seconds. */
143
+ registryTimeoutMs?: number;
144
+ /** Maximum registry-backed defaults resolved in one call. Default and maximum 32. */
145
+ maxRegistryProfiles?: number;
146
+ }
147
+ export interface AcceptancePolicyCatalogResolver {
148
+ /**
149
+ * Resolve the currently advertised catalog. A capability change atomically
150
+ * invalidates the resolver's single-entry cache before the next fetch.
151
+ */
152
+ resolve(capability: AcceptancePolicyDiscoveryCapability): Promise<AcceptancePolicyCatalogResult>;
153
+ /** Explicit invalidation hook for a capabilities-changed notification. */
154
+ invalidate(): void;
155
+ }
156
+ /**
157
+ * Resolve seller-local profiles and identify registry pins that still require
158
+ * trusted registry resolution. Missing IDs and unresolved registry references
159
+ * are never represented as usable policy rules.
160
+ */
161
+ export declare function resolveAcceptancePolicyProfiles(catalog: AcceptancePolicyCatalog, profileIds: readonly string[]): AcceptancePolicyProfileResolution[];
162
+ /**
163
+ * Resolve selected seller-local and registry-backed profiles from a catalog
164
+ * already obtained through the digest-pinned catalog resolver. Registry
165
+ * content becomes usable only after both immutable policy and embedded profile
166
+ * pins verify; each failed pin remains unresolved with an issue diagnostic.
167
+ */
168
+ export declare function resolveVerifiedAcceptancePolicyProfiles(catalog: AcceptancePolicyCatalog, profileIds: readonly string[], options: ResolveVerifiedAcceptancePolicyProfilesOptions): Promise<VerifiedAcceptancePolicyProfilesResult>;
169
+ /** Resolve once without retaining remote content. */
170
+ export declare function resolveAcceptancePolicyCatalog(capability: AcceptancePolicyDiscoveryCapability, options?: ResolveAcceptancePolicyCatalogOptions): Promise<AcceptancePolicyCatalogResult>;
171
+ /**
172
+ * Create a capability-lifetime resolver. It retains only the current
173
+ * capability's successful catalog and clears that entry whenever any
174
+ * advertised catalog URL, digest, or default profile changes.
175
+ */
176
+ export declare function createAcceptancePolicyCatalogResolver(options?: ResolveAcceptancePolicyCatalogOptions): AcceptancePolicyCatalogResolver;
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Buyer-side resolution of seller acceptance-policy catalogs.
3
+ *
4
+ * Catalog discovery is advisory. A successfully resolved catalog describes
5
+ * likely seller treatment; it never authorizes an exact media-buy request.
6
+ */
7
+ import type { ResolvePolicyResponse } from '../registry/types';
8
+ export interface AcceptancePolicyDiscoveryCapability {
9
+ catalog_url: string;
10
+ catalog_digest: string;
11
+ default_profile_ids?: readonly string[];
12
+ }
13
+ export interface AcceptancePolicyReference {
14
+ policy_id: string;
15
+ version: string;
16
+ content_digest: string;
17
+ }
18
+ export interface AcceptancePolicyRule {
19
+ rule_id: string;
20
+ subject_category: string;
21
+ jurisdiction_groups?: string[];
22
+ applies_to: string[];
23
+ disposition: 'allowed' | 'conditional' | 'prohibited';
24
+ policy_ids?: string[];
25
+ [key: string]: unknown;
26
+ }
27
+ export interface AcceptancePolicyProfile {
28
+ profile_id: string;
29
+ version: string;
30
+ content_digest: string;
31
+ policy_refs: AcceptancePolicyReference[];
32
+ coverage: 'partial' | 'complete';
33
+ scope?: {
34
+ jurisdiction_groups?: string[];
35
+ [key: string]: unknown;
36
+ };
37
+ region_aliases?: Record<string, string[]>;
38
+ rules: AcceptancePolicyRule[];
39
+ [key: string]: unknown;
40
+ }
41
+ export interface RegistryAcceptancePolicyProfileReference {
42
+ policy_id: string;
43
+ policy_version: string;
44
+ policy_digest: string;
45
+ profile_id: string;
46
+ profile_version: string;
47
+ profile_digest: string;
48
+ }
49
+ export interface AcceptancePolicyCatalog {
50
+ catalog_version: string;
51
+ generated_at?: string;
52
+ profiles?: AcceptancePolicyProfile[];
53
+ registry_profiles?: RegistryAcceptancePolicyProfileReference[];
54
+ ext?: Record<string, unknown>;
55
+ }
56
+ export type ResolvedAcceptancePolicyDefault = {
57
+ source: 'seller';
58
+ resolution: 'resolved';
59
+ profileId: string;
60
+ profile: AcceptancePolicyProfile;
61
+ } | {
62
+ source: 'registry';
63
+ resolution: 'resolved';
64
+ profileId: string;
65
+ profile: AcceptancePolicyProfile;
66
+ ref: RegistryAcceptancePolicyProfileReference;
67
+ } | {
68
+ source: 'registry';
69
+ resolution: 'unresolved';
70
+ profileId: string;
71
+ ref: RegistryAcceptancePolicyProfileReference;
72
+ };
73
+ export type AcceptancePolicyProfileResolution = ResolvedAcceptancePolicyDefault | {
74
+ source: 'catalog';
75
+ resolution: 'missing';
76
+ profileId: string;
77
+ };
78
+ export type AcceptancePolicyCatalogErrorCode = 'invalid_capability' | 'invalid_options' | 'unsafe_url' | 'redirect_blocked' | 'fetch_failed' | 'http_error' | 'body_too_large' | 'digest_mismatch' | 'invalid_json' | 'catalog_document_invalid' | 'schema_unavailable' | 'schema_invalid' | 'duplicate_profile_id' | 'unresolved_profile_id' | 'profile_canonicalization_invalid' | 'profile_digest_mismatch' | 'reference_invalid' | 'registry_fetch_failed' | 'registry_reference_unresolved' | 'registry_policy_mismatch' | 'registry_policy_unverifiable' | 'registry_policy_digest_mismatch' | 'registry_profile_schema_invalid' | 'registry_profile_invalid' | 'registry_profile_mismatch' | 'registry_profile_digest_mismatch' | 'registry_resolution_limit_exceeded' | 'registry_timeout';
79
+ export interface AcceptancePolicyCatalogIssue {
80
+ code: AcceptancePolicyCatalogErrorCode;
81
+ message: string;
82
+ /** JSON Pointer into the capability or catalog. Values are never echoed. */
83
+ pointer: string;
84
+ keyword?: string;
85
+ retryable?: boolean;
86
+ httpStatus?: number;
87
+ }
88
+ export interface AcceptancePolicyCatalogFailure {
89
+ ok: false;
90
+ fromCache: false;
91
+ error: AcceptancePolicyCatalogIssue;
92
+ issues?: AcceptancePolicyCatalogIssue[];
93
+ }
94
+ export interface AcceptancePolicyCatalogSuccess {
95
+ ok: true;
96
+ fromCache: boolean;
97
+ catalog: AcceptancePolicyCatalog;
98
+ defaultProfiles: ResolvedAcceptancePolicyDefault[];
99
+ /** Non-fatal registry diagnostics. Affected profiles remain unresolved. */
100
+ issues?: AcceptancePolicyCatalogIssue[];
101
+ }
102
+ export type AcceptancePolicyCatalogResult = AcceptancePolicyCatalogSuccess | AcceptancePolicyCatalogFailure;
103
+ /** Registry fields covered by acceptance-policy pin verification. */
104
+ export type AcceptancePolicyRegistryPolicy = Pick<ResolvePolicyResponse, 'policy_id' | 'version' | 'content_digest' | 'canonical_content' | 'acceptance_profile'>;
105
+ /** Minimal trusted-registry surface needed to resolve an immutable policy version. */
106
+ export interface AcceptancePolicyRegistryResolver {
107
+ resolvePolicy(params: {
108
+ policy_id: string;
109
+ version?: string;
110
+ signal?: AbortSignal;
111
+ }): Promise<AcceptancePolicyRegistryPolicy | null>;
112
+ }
113
+ export interface ResolveVerifiedAcceptancePolicyProfilesOptions {
114
+ registryResolver: AcceptancePolicyRegistryResolver;
115
+ /** Schema bundle used to validate embedded profiles. Defaults to the SDK pin. */
116
+ adcpVersion?: string;
117
+ /** Overall deadline for all selected registry lookups. Default 5 seconds. */
118
+ timeoutMs?: number;
119
+ /** Maximum distinct registry profiles resolved in one call. Default and maximum 32. */
120
+ maxRegistryProfiles?: number;
121
+ }
122
+ export interface VerifiedAcceptancePolicyProfilesSuccess {
123
+ ok: true;
124
+ profiles: AcceptancePolicyProfileResolution[];
125
+ /** Per-profile failures. Each affected registry profile remains unresolved. */
126
+ issues?: AcceptancePolicyCatalogIssue[];
127
+ }
128
+ export type VerifiedAcceptancePolicyProfilesResult = VerifiedAcceptancePolicyProfilesSuccess | AcceptancePolicyCatalogFailure;
129
+ export interface ResolveAcceptancePolicyCatalogOptions {
130
+ /** Schema bundle used to validate the fetched catalog. Defaults to the SDK pin. */
131
+ adcpVersion?: string;
132
+ /** Overall DNS/connect/body timeout for the catalog fetch. Default 5 seconds. */
133
+ timeoutMs?: number;
134
+ /** Hard response-body cap. Default and maximum 1 MiB; callers may lower it. */
135
+ maxBodyBytes?: number;
136
+ /** Test/dev-only HTTP opt-in; requires allowPrivateNetwork. Production callers must leave false. */
137
+ allowUnsafeHttp?: boolean;
138
+ /** Test/dev-only opt-in for private-network fixtures. Production callers must leave false. */
139
+ allowPrivateNetwork?: boolean;
140
+ /** Trusted AdCP registry client used to resolve and verify registry-backed defaults. */
141
+ registryResolver?: AcceptancePolicyRegistryResolver;
142
+ /** Overall deadline for registry resolution. Default 5 seconds. */
143
+ registryTimeoutMs?: number;
144
+ /** Maximum registry-backed defaults resolved in one call. Default and maximum 32. */
145
+ maxRegistryProfiles?: number;
146
+ }
147
+ export interface AcceptancePolicyCatalogResolver {
148
+ /**
149
+ * Resolve the currently advertised catalog. A capability change atomically
150
+ * invalidates the resolver's single-entry cache before the next fetch.
151
+ */
152
+ resolve(capability: AcceptancePolicyDiscoveryCapability): Promise<AcceptancePolicyCatalogResult>;
153
+ /** Explicit invalidation hook for a capabilities-changed notification. */
154
+ invalidate(): void;
155
+ }
156
+ /**
157
+ * Resolve seller-local profiles and identify registry pins that still require
158
+ * trusted registry resolution. Missing IDs and unresolved registry references
159
+ * are never represented as usable policy rules.
160
+ */
161
+ export declare function resolveAcceptancePolicyProfiles(catalog: AcceptancePolicyCatalog, profileIds: readonly string[]): AcceptancePolicyProfileResolution[];
162
+ /**
163
+ * Resolve selected seller-local and registry-backed profiles from a catalog
164
+ * already obtained through the digest-pinned catalog resolver. Registry
165
+ * content becomes usable only after both immutable policy and embedded profile
166
+ * pins verify; each failed pin remains unresolved with an issue diagnostic.
167
+ */
168
+ export declare function resolveVerifiedAcceptancePolicyProfiles(catalog: AcceptancePolicyCatalog, profileIds: readonly string[], options: ResolveVerifiedAcceptancePolicyProfilesOptions): Promise<VerifiedAcceptancePolicyProfilesResult>;
169
+ /** Resolve once without retaining remote content. */
170
+ export declare function resolveAcceptancePolicyCatalog(capability: AcceptancePolicyDiscoveryCapability, options?: ResolveAcceptancePolicyCatalogOptions): Promise<AcceptancePolicyCatalogResult>;
171
+ /**
172
+ * Create a capability-lifetime resolver. It retains only the current
173
+ * capability's successful catalog and clears that entry whenever any
174
+ * advertised catalog URL, digest, or default profile changes.
175
+ */
176
+ export declare function createAcceptancePolicyCatalogResolver(options?: ResolveAcceptancePolicyCatalogOptions): AcceptancePolicyCatalogResolver;