@adcp/sdk 17.0.0-beta.1 → 17.0.0-beta.3

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 (282) hide show
  1. package/dist/lib/adapters/keyed-account-store.js +1 -1
  2. package/dist/lib/adapters/keyed-account-store.mjs +1 -1
  3. package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
  4. package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
  5. package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
  6. package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
  7. package/dist/lib/adapters/version/3.0/index.js +6 -0
  8. package/dist/lib/adapters/version/3.0/index.mjs +7 -1
  9. package/dist/lib/adapters/version/index.d.mts +9 -0
  10. package/dist/lib/adapters/version/index.d.ts +9 -0
  11. package/dist/lib/adapters/version/index.js +20 -6
  12. package/dist/lib/adapters/version/index.mjs +15 -2
  13. package/dist/lib/adapters/version/types.d.mts +5 -0
  14. package/dist/lib/adapters/version/types.d.ts +5 -0
  15. package/dist/lib/canonical-references/index.js +2 -0
  16. package/dist/lib/canonical-references/index.mjs +2 -0
  17. package/dist/lib/client/account-changes.d.mts +3 -1
  18. package/dist/lib/client/account-changes.d.ts +3 -1
  19. package/dist/lib/client/account-changes.js +22 -2
  20. package/dist/lib/client/account-changes.mjs +22 -2
  21. package/dist/lib/conformance/oracle.js +3 -2
  22. package/dist/lib/conformance/oracle.mjs +3 -2
  23. package/dist/lib/core/AgentClient.d.mts +165 -1
  24. package/dist/lib/core/AgentClient.d.ts +165 -1
  25. package/dist/lib/core/AgentClient.js +446 -8
  26. package/dist/lib/core/AgentClient.mjs +446 -8
  27. package/dist/lib/core/ConversationTypes.d.mts +8 -0
  28. package/dist/lib/core/ConversationTypes.d.ts +8 -0
  29. package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
  30. package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
  31. package/dist/lib/core/ProtocolResponseParser.js +28 -18
  32. package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
  33. package/dist/lib/core/SingleAgentClient.d.mts +115 -2
  34. package/dist/lib/core/SingleAgentClient.d.ts +115 -2
  35. package/dist/lib/core/SingleAgentClient.js +547 -67
  36. package/dist/lib/core/SingleAgentClient.mjs +534 -54
  37. package/dist/lib/core/TaskExecutor.d.mts +7 -0
  38. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  39. package/dist/lib/core/TaskExecutor.js +18 -5
  40. package/dist/lib/core/TaskExecutor.mjs +18 -5
  41. package/dist/lib/core/task-status.d.mts +2 -0
  42. package/dist/lib/core/task-status.d.ts +2 -0
  43. package/dist/lib/core/task-status.js +11 -2
  44. package/dist/lib/core/task-status.mjs +9 -1
  45. package/dist/lib/identity-3.3/trust.d.mts +1 -4
  46. package/dist/lib/identity-3.3/trust.d.ts +1 -4
  47. package/dist/lib/identity-3.3/trust.js +43 -23
  48. package/dist/lib/identity-3.3/trust.mjs +43 -23
  49. package/dist/lib/identity-3.3/validation.js +5 -3
  50. package/dist/lib/identity-3.3/validation.mjs +6 -4
  51. package/dist/lib/index.d.mts +6 -52
  52. package/dist/lib/index.d.ts +6 -52
  53. package/dist/lib/index.js +11 -0
  54. package/dist/lib/index.mjs +7 -0
  55. package/dist/lib/media-buy/compatibility.js +6 -1
  56. package/dist/lib/media-buy/compatibility.mjs +6 -1
  57. package/dist/lib/protocols/mcp-scope.d.mts +3 -0
  58. package/dist/lib/protocols/mcp-scope.d.ts +3 -0
  59. package/dist/lib/protocols/mcp-scope.js +8 -3
  60. package/dist/lib/protocols/mcp-scope.mjs +8 -3
  61. package/dist/lib/reporting/inspection.js +1 -0
  62. package/dist/lib/reporting/inspection.mjs +1 -0
  63. package/dist/lib/reporting/ledger/coverage.d.mts +5 -0
  64. package/dist/lib/reporting/ledger/coverage.d.ts +5 -0
  65. package/dist/lib/reporting/ledger/coverage.js +37 -3
  66. package/dist/lib/reporting/ledger/coverage.mjs +36 -3
  67. package/dist/lib/reporting/ledger/handler.js +7 -4
  68. package/dist/lib/reporting/ledger/handler.mjs +7 -4
  69. package/dist/lib/reporting/ledger/producer.js +215 -69
  70. package/dist/lib/reporting/ledger/producer.mjs +217 -70
  71. package/dist/lib/reporting/ledger/schedule.d.mts +2 -2
  72. package/dist/lib/reporting/ledger/schedule.d.ts +2 -2
  73. package/dist/lib/reporting/ledger/schedule.js +8 -5
  74. package/dist/lib/reporting/ledger/schedule.mjs +8 -5
  75. package/dist/lib/reporting/ledger/status-ingest.d.mts +1 -1
  76. package/dist/lib/reporting/ledger/status-ingest.d.ts +1 -1
  77. package/dist/lib/reporting/ledger/status-ingest.js +4 -3
  78. package/dist/lib/reporting/ledger/status-ingest.mjs +4 -3
  79. package/dist/lib/reporting/ledger/types.d.mts +36 -1
  80. package/dist/lib/reporting/ledger/types.d.ts +36 -1
  81. package/dist/lib/reporting/service/index.d.mts +14 -1
  82. package/dist/lib/reporting/service/index.d.ts +14 -1
  83. package/dist/lib/reporting/service/index.js +24 -12
  84. package/dist/lib/reporting/service/index.mjs +24 -12
  85. package/dist/lib/schemas/browser.d.mts +2 -0
  86. package/dist/lib/schemas/browser.d.ts +2 -0
  87. package/dist/lib/schemas/browser.js +3 -0
  88. package/dist/lib/schemas/browser.mjs +2 -0
  89. package/dist/lib/schemas/index.d.mts +5 -3
  90. package/dist/lib/schemas/index.d.ts +5 -3
  91. package/dist/lib/schemas/index.js +5 -0
  92. package/dist/lib/schemas/index.mjs +4 -0
  93. package/dist/lib/server/a2a-adapter.js +2 -1
  94. package/dist/lib/server/a2a-adapter.mjs +2 -1
  95. package/dist/lib/server/account-response-identity.d.mts +17 -0
  96. package/dist/lib/server/account-response-identity.d.ts +17 -0
  97. package/dist/lib/server/account-response-identity.js +52 -0
  98. package/dist/lib/server/account-response-identity.mjs +28 -0
  99. package/dist/lib/server/account-sync-contract.js +2 -2
  100. package/dist/lib/server/account-sync-contract.mjs +2 -2
  101. package/dist/lib/server/auth-signature.d.mts +2 -2
  102. package/dist/lib/server/auth-signature.d.ts +2 -2
  103. package/dist/lib/server/auth-signature.js +3 -0
  104. package/dist/lib/server/auth-signature.mjs +3 -0
  105. package/dist/lib/server/create-adcp-server.d.mts +2 -2
  106. package/dist/lib/server/create-adcp-server.d.ts +2 -2
  107. package/dist/lib/server/create-adcp-server.js +58 -23
  108. package/dist/lib/server/create-adcp-server.mjs +61 -15
  109. package/dist/lib/server/decisioning/account.d.mts +36 -10
  110. package/dist/lib/server/decisioning/account.d.ts +36 -10
  111. package/dist/lib/server/decisioning/account.js +33 -14
  112. package/dist/lib/server/decisioning/account.mjs +33 -14
  113. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
  114. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
  115. package/dist/lib/server/decisioning/runtime/from-platform.js +4 -4
  116. package/dist/lib/server/decisioning/runtime/from-platform.mjs +4 -4
  117. package/dist/lib/server/media-buy-store.d.mts +26 -12
  118. package/dist/lib/server/media-buy-store.d.ts +26 -12
  119. package/dist/lib/server/media-buy-store.js +69 -21
  120. package/dist/lib/server/media-buy-store.mjs +69 -21
  121. package/dist/lib/server/notification-subscriptions/runtime.d.mts +1 -1
  122. package/dist/lib/server/notification-subscriptions/runtime.d.ts +1 -1
  123. package/dist/lib/server/notification-subscriptions/runtime.js +4 -0
  124. package/dist/lib/server/notification-subscriptions/runtime.mjs +4 -0
  125. package/dist/lib/server/responses.js +9 -1
  126. package/dist/lib/server/responses.mjs +9 -1
  127. package/dist/lib/server/serve.js +3 -1
  128. package/dist/lib/server/serve.mjs +3 -1
  129. package/dist/lib/server/signed-request-transport.d.mts +1 -0
  130. package/dist/lib/server/signed-request-transport.d.ts +1 -0
  131. package/dist/lib/server/signed-request-transport.js +46 -0
  132. package/dist/lib/server/signed-request-transport.mjs +20 -0
  133. package/dist/lib/server/test-controller.d.mts +1 -0
  134. package/dist/lib/server/test-controller.d.ts +1 -0
  135. package/dist/lib/server/test-controller.js +5 -1
  136. package/dist/lib/server/test-controller.mjs +5 -1
  137. package/dist/lib/signing/agent-fetch.d.mts +1 -1
  138. package/dist/lib/signing/agent-fetch.d.ts +1 -1
  139. package/dist/lib/signing/agent-fetch.js +3 -3
  140. package/dist/lib/signing/agent-fetch.mjs +3 -3
  141. package/dist/lib/testing/index.d.mts +1 -0
  142. package/dist/lib/testing/index.d.ts +1 -0
  143. package/dist/lib/testing/index.js +3 -0
  144. package/dist/lib/testing/index.mjs +2 -0
  145. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +61 -29
  146. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +61 -29
  147. package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
  148. package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
  149. package/dist/lib/testing/storyboard/compliance.js +62 -13
  150. package/dist/lib/testing/storyboard/compliance.mjs +63 -14
  151. package/dist/lib/testing/storyboard/index.d.mts +1 -0
  152. package/dist/lib/testing/storyboard/index.d.ts +1 -0
  153. package/dist/lib/testing/storyboard/index.js +3 -0
  154. package/dist/lib/testing/storyboard/index.mjs +2 -0
  155. package/dist/lib/testing/storyboard/loader.js +7 -0
  156. package/dist/lib/testing/storyboard/loader.mjs +7 -0
  157. package/dist/lib/testing/storyboard/request-builder.js +9 -6
  158. package/dist/lib/testing/storyboard/request-builder.mjs +9 -6
  159. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  160. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  161. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
  162. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
  163. package/dist/lib/testing/storyboard/runner.js +59 -6
  164. package/dist/lib/testing/storyboard/runner.mjs +59 -6
  165. package/dist/lib/testing/storyboard/types.d.mts +18 -0
  166. package/dist/lib/testing/storyboard/types.d.ts +18 -0
  167. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  168. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  169. package/dist/lib/testing/storyboard/web-bot-auth.d.mts +10 -0
  170. package/dist/lib/testing/storyboard/web-bot-auth.d.ts +10 -0
  171. package/dist/lib/testing/storyboard/web-bot-auth.js +80 -0
  172. package/dist/lib/testing/storyboard/web-bot-auth.mjs +56 -0
  173. package/dist/lib/types/accept-proposal.d.ts +20 -28
  174. package/dist/lib/types/asset-instances.d.mts +1 -1
  175. package/dist/lib/types/asset-instances.d.ts +1 -1
  176. package/dist/lib/types/buy-products.d.ts +20 -28
  177. package/dist/lib/types/check-governance.d.ts +20 -28
  178. package/dist/lib/types/comply-test-controller.d.ts +20 -28
  179. package/dist/lib/types/control-media-buy.d.ts +20 -28
  180. package/dist/lib/types/core.generated.d.mts +273 -184
  181. package/dist/lib/types/core.generated.d.ts +273 -184
  182. package/dist/lib/types/create-media-buy.d.ts +20 -28
  183. package/dist/lib/types/get-media-buys.d.ts +20 -28
  184. package/dist/lib/types/get-products.d.ts +20 -28
  185. package/dist/lib/types/index.d.mts +6 -1
  186. package/dist/lib/types/index.d.ts +6 -1
  187. package/dist/lib/types/index.js +6 -1
  188. package/dist/lib/types/index.mjs +4 -1
  189. package/dist/lib/types/inline-enums.generated.d.mts +30 -4
  190. package/dist/lib/types/inline-enums.generated.d.ts +30 -4
  191. package/dist/lib/types/inline-enums.generated.js +41 -2
  192. package/dist/lib/types/inline-enums.generated.mjs +28 -2
  193. package/dist/lib/types/list-products.d.ts +20 -28
  194. package/dist/lib/types/list-proposals.d.ts +20 -28
  195. package/dist/lib/types/media-buy-delivery-report.d.mts +6 -0
  196. package/dist/lib/types/media-buy-delivery-report.d.ts +6 -0
  197. package/dist/lib/types/media-buy-delivery-report.js +16 -0
  198. package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
  199. package/dist/lib/types/refine-proposals.d.ts +20 -28
  200. package/dist/lib/types/request-proposals.d.ts +20 -28
  201. package/dist/lib/types/schemas.generated.d.ts +63113 -127273
  202. package/dist/lib/types/schemas.generated.js +759 -770
  203. package/dist/lib/types/schemas.generated.mjs +759 -770
  204. package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
  205. package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
  206. package/dist/lib/types/targeting-keys.generated.js +109 -0
  207. package/dist/lib/types/targeting-keys.generated.mjs +84 -0
  208. package/dist/lib/types/tools.generated.d.mts +2 -68
  209. package/dist/lib/types/tools.generated.d.ts +2 -68
  210. package/dist/lib/types/update-media-buy.d.ts +20 -28
  211. package/dist/lib/utils/adcp-version-config.js +5 -2
  212. package/dist/lib/utils/adcp-version-config.mjs +5 -2
  213. package/dist/lib/utils/response-unwrapper.js +6 -1
  214. package/dist/lib/utils/response-unwrapper.mjs +6 -1
  215. package/dist/lib/v2/format-schema/resolver.js +1 -1
  216. package/dist/lib/v2/format-schema/resolver.mjs +1 -1
  217. package/dist/lib/v2/projection/creative-delivery.js +104 -29
  218. package/dist/lib/v2/projection/creative-delivery.mjs +108 -29
  219. package/dist/lib/v2/projection/index.d.mts +1 -0
  220. package/dist/lib/v2/projection/index.d.ts +1 -0
  221. package/dist/lib/v2/projection/index.js +3 -0
  222. package/dist/lib/v2/projection/index.mjs +2 -0
  223. package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
  224. package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
  225. package/dist/lib/v2/projection/legacy-metadata.js +91 -0
  226. package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
  227. package/dist/lib/v2/projection/v1-to-v2.d.mts +1 -1
  228. package/dist/lib/v2/projection/v1-to-v2.d.ts +1 -1
  229. package/dist/lib/v2/projection/v1-to-v2.js +12 -9
  230. package/dist/lib/v2/projection/v1-to-v2.mjs +12 -9
  231. package/dist/lib/validation/budget-allocation.d.mts +3 -3
  232. package/dist/lib/validation/budget-allocation.d.ts +3 -3
  233. package/dist/lib/validation/compact-schema.d.mts +27 -0
  234. package/dist/lib/validation/compact-schema.d.ts +27 -0
  235. package/dist/lib/validation/compact-schema.js +276 -0
  236. package/dist/lib/validation/compact-schema.mjs +250 -0
  237. package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
  238. package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
  239. package/dist/lib/validation/media-buy-delivery-report.js +31 -0
  240. package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
  241. package/dist/lib/validation/nonempty-array.d.mts +15 -0
  242. package/dist/lib/validation/nonempty-array.d.ts +15 -0
  243. package/dist/lib/validation/nonempty-array.js +41 -0
  244. package/dist/lib/validation/nonempty-array.mjs +7 -0
  245. package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
  246. package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
  247. package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
  248. package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
  249. package/dist/lib/validation/schema-loader.js +86 -16
  250. package/dist/lib/validation/schema-loader.mjs +82 -16
  251. package/dist/lib/validation/schema-validator.d.mts +10 -19
  252. package/dist/lib/validation/schema-validator.d.ts +10 -19
  253. package/dist/lib/validation/schema-validator.js +135 -42
  254. package/dist/lib/validation/schema-validator.mjs +139 -43
  255. package/dist/lib/validation/sync-creatives.d.mts +22 -22
  256. package/dist/lib/validation/sync-creatives.d.ts +22 -22
  257. package/dist/lib/version.d.mts +3 -3
  258. package/dist/lib/version.d.ts +3 -3
  259. package/dist/lib/version.js +3 -3
  260. package/dist/lib/version.mjs +3 -3
  261. package/dist/lib/webhooks/index.d.mts +3 -0
  262. package/dist/lib/webhooks/index.d.ts +3 -0
  263. package/dist/lib/webhooks/index.js +3 -0
  264. package/dist/lib/webhooks/index.mjs +2 -0
  265. package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
  266. package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
  267. package/dist/lib/webhooks/media-buy-delivery.js +119 -0
  268. package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
  269. package/docs/TYPE-SUMMARY.md +2 -2
  270. package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
  271. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
  272. package/docs/guides/REPORTING-LEDGER.md +93 -0
  273. package/docs/guides/REPORTING-STABILITY.md +1 -1
  274. package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
  275. package/docs/llms.txt +2 -2
  276. package/docs/migration-14.x-rc-worksheet.md +4 -4
  277. package/docs/migration-16-to-17.md +218 -14
  278. package/docs/migration-6.6-to-6.7.md +14 -0
  279. package/docs/migration-account-change-feed.md +15 -0
  280. package/docs/migration-agent-identity-3.3.md +106 -4
  281. package/docs/recipes/verifying-inbound-webhooks.md +18 -2
  282. package/package.json +16 -3
@@ -67,6 +67,7 @@ __export(testing_exports, {
67
67
  comply: () => import_compliance.comply,
68
68
  createComplyController: () => import_comply_controller.createComplyController,
69
69
  createSeedFixtureCache: () => import_test_controller.createSeedFixtureCache,
70
+ createStoryboardWebBotAuthFetch: () => import_web_bot_auth.createStoryboardWebBotAuthFetch,
70
71
  createTestAgent: () => import_test_helpers.createTestAgent,
71
72
  createTestClient: () => import_agent_tester.createTestClient,
72
73
  creativeAgent: () => import_test_helpers.creativeAgent,
@@ -234,6 +235,7 @@ var import_validation = require('../validation/index.js');
234
235
  var import_storyboard = require('./storyboard/index.js');
235
236
  var import_storyboard2 = require('./storyboard/index.js');
236
237
  var import_storyboard3 = require('./storyboard/index.js');
238
+ var import_web_bot_auth = require('./storyboard/web-bot-auth.js');
237
239
  // Annotate the CommonJS export names for ESM import in node:
238
240
  0 && (module.exports = {
239
241
  AdagentsJsonSchema,
@@ -285,6 +287,7 @@ var import_storyboard3 = require('./storyboard/index.js');
285
287
  comply,
286
288
  createComplyController,
287
289
  createSeedFixtureCache,
290
+ createStoryboardWebBotAuthFetch,
288
291
  createTestAgent,
289
292
  createTestClient,
290
293
  creativeAgent,
@@ -212,6 +212,7 @@ import {
212
212
  withPreparedFixtures
213
213
  } from "./storyboard/index.mjs";
214
214
  import { resolveCreativeBuildProbe, validateCreativeBuildProbeSpec } from "./storyboard/index.mjs";
215
+ import { createStoryboardWebBotAuthFetch } from "./storyboard/web-bot-auth.mjs";
215
216
  export {
216
217
  AdagentsJsonSchema,
217
218
  BrandJsonSchema,
@@ -262,6 +263,7 @@ export {
262
263
  comply,
263
264
  createComplyController,
264
265
  createSeedFixtureCache,
266
+ createStoryboardWebBotAuthFetch,
265
267
  createTestAgent,
266
268
  createTestClient,
267
269
  creativeAgent,
@@ -47,13 +47,6 @@ const HANDLED_CANONICAL_PARAM_KEYS = /* @__PURE__ */ new Set([
47
47
  "duration_ms_range"
48
48
  ]);
49
49
  const ARRAY_SUBSET_PARAM_KEYS = /* @__PURE__ */ new Set(["video_codecs", "audio_codecs", "mime_types", "file_types", "formats"]);
50
- const OMITTABLE_DECLARATION_PARAMS = /* @__PURE__ */ new Set([
51
- "asset_source",
52
- "buyer_asset_acceptance",
53
- "composition_model",
54
- "slots",
55
- "ssl_required"
56
- ]);
57
50
  function validateCanonicalFormatSatisfaction(validation, request, context, taskResult) {
58
51
  if (typeof validation.value !== "boolean") {
59
52
  return {
@@ -208,17 +201,41 @@ function evaluatePackage(pkg, pointer, index, products) {
208
201
  actual: productId ?? null
209
202
  };
210
203
  }
204
+ const routes = [];
211
205
  const formatOptionRefs = Array.isArray(pkg.format_option_refs) ? pkg.format_option_refs : [];
212
206
  if (formatOptionRefs.length > 0) {
213
- return evaluateFormatOptionRefs(formatOptionRefs, product, pointer);
207
+ routes.push({ name: "format_option_refs", verdict: evaluateFormatOptionRefs(formatOptionRefs, product, pointer) });
214
208
  }
215
209
  const formatIds = Array.isArray(pkg.format_ids) ? pkg.format_ids : [];
216
210
  if (formatIds.length > 0) {
217
- return evaluateLegacyFormatIds(formatIds, product, pointer, productId);
211
+ routes.push({ name: "format_ids", verdict: evaluateLegacyFormatIds(formatIds, product, pointer, productId) });
218
212
  }
219
213
  const canonicalSelectors = extractCanonicalSelectors(pkg, pointer);
220
214
  if (canonicalSelectors.length > 0) {
221
- return evaluateCanonicalSelectors(canonicalSelectors, product);
215
+ routes.push({ name: "canonical selectors", verdict: evaluateCanonicalSelectors(canonicalSelectors, product) });
216
+ }
217
+ const failed = routes.find((route) => !route.verdict.satisfied);
218
+ if (failed) return failed.verdict;
219
+ const primary = routes[0];
220
+ if (primary) {
221
+ const selected = new Set(primary.verdict.selectedDeclarations);
222
+ const conflicting = routes.slice(1).find((route) => {
223
+ const other = new Set(route.verdict.selectedDeclarations);
224
+ return selected.size !== other.size || [...selected].some((index2) => !other.has(index2));
225
+ });
226
+ if (conflicting) {
227
+ return {
228
+ satisfied: false,
229
+ bug_class: "directionality",
230
+ detail: `Conflicting selector routes ${primary.name} and ${conflicting.name} select different product format_options[] sets`,
231
+ json_pointer: pointer,
232
+ observations: routes.map((route) => ({
233
+ route: route.name,
234
+ selected_declarations: route.verdict.selectedDeclarations
235
+ }))
236
+ };
237
+ }
238
+ return primary.verdict;
222
239
  }
223
240
  return {
224
241
  satisfied: true,
@@ -238,6 +255,7 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
238
255
  actual: refs
239
256
  };
240
257
  }
258
+ const selected = /* @__PURE__ */ new Set();
241
259
  for (let i = 0; i < refs.length; i++) {
242
260
  const ref = refs[i];
243
261
  if (!isRecord(ref)) {
@@ -267,13 +285,13 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
267
285
  actual: ref
268
286
  };
269
287
  }
270
- const match = declarations.find((decl) => {
288
+ const match = declarations.findIndex((decl) => {
271
289
  if (ref.scope === "publisher") {
272
290
  return decl.publisher_domain === ref.publisher_domain && decl.format_option_id === ref.format_option_id && typeof ref.publisher_domain === "string";
273
291
  }
274
292
  return decl.format_option_id === ref.format_option_id && !decl.publisher_domain;
275
293
  });
276
- if (!match) {
294
+ if (match < 0) {
277
295
  return {
278
296
  satisfied: false,
279
297
  bug_class: "closed_set",
@@ -283,16 +301,19 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
283
301
  observations: [{ available_format_option_ids: declarations.map(declarationLabel).filter(Boolean) }]
284
302
  };
285
303
  }
304
+ selected.add(match);
286
305
  }
287
306
  return {
288
307
  satisfied: true,
289
308
  bug_class: "directionality",
290
309
  detail: "Every format_option_refs[] entry resolved to the target product format_options[] closed set",
291
- json_pointer: `${packagePointer}/format_option_refs`
310
+ json_pointer: `${packagePointer}/format_option_refs`,
311
+ selectedDeclarations: [...selected]
292
312
  };
293
313
  }
294
314
  function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
295
315
  const declarations = productFormatOptions(product);
316
+ const selected = /* @__PURE__ */ new Set();
296
317
  for (let i = 0; i < refs.length; i++) {
297
318
  const ref = refs[i];
298
319
  if (!isFormatId(ref)) {
@@ -304,12 +325,22 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
304
325
  actual: ref
305
326
  };
306
327
  }
307
- const direct = declarations.find((decl) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)));
308
- if (direct) continue;
328
+ const direct = declarations.flatMap(
329
+ (decl, index) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)) ? [index] : []
330
+ );
331
+ if (direct.length > 0) {
332
+ for (const index of direct) selected.add(index);
333
+ continue;
334
+ }
309
335
  const projected = projectLegacyRef(ref, productId, `${packagePointer}/format_ids/${i}`);
310
336
  if (projected) {
311
- const match = declarations.find((decl) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok);
312
- if (match) continue;
337
+ const matches = declarations.flatMap(
338
+ (decl, index) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok ? [index] : []
339
+ );
340
+ if (matches.length > 0) {
341
+ for (const index of matches) selected.add(index);
342
+ continue;
343
+ }
313
344
  }
314
345
  if (declarations.length === 0 && Array.isArray(product.format_ids) && product.format_ids.some((fid) => isFormatId(fid) && sameFormatId(fid, ref))) {
315
346
  continue;
@@ -327,7 +358,8 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
327
358
  satisfied: true,
328
359
  bug_class: "normalization",
329
360
  detail: "Every legacy format_id normalized to a product canonical declaration or product legacy format_id",
330
- json_pointer: `${packagePointer}/format_ids`
361
+ json_pointer: `${packagePointer}/format_ids`,
362
+ selectedDeclarations: [...selected]
331
363
  };
332
364
  }
333
365
  function evaluateCanonicalSelectors(selectors, product) {
@@ -341,6 +373,7 @@ function evaluateCanonicalSelectors(selectors, product) {
341
373
  actual: selectors
342
374
  };
343
375
  }
376
+ const selected = /* @__PURE__ */ new Set();
344
377
  for (const selector of selectors) {
345
378
  const candidates = declarations.filter((decl) => decl.format_kind === selector.format_kind);
346
379
  if (candidates.length === 0) {
@@ -353,7 +386,12 @@ function evaluateCanonicalSelectors(selectors, product) {
353
386
  };
354
387
  }
355
388
  const checks = candidates.map((decl) => canonicalSelectorSatisfiesDeclaration(selector, decl));
356
- if (checks.some((c) => c.ok)) continue;
389
+ if (checks.some((c) => c.ok)) {
390
+ for (const [index, decl] of declarations.entries()) {
391
+ if (canonicalSelectorSatisfiesDeclaration(selector, decl).ok) selected.add(index);
392
+ }
393
+ continue;
394
+ }
357
395
  const primary = checks.find((c) => c.bug_class === "range_containment") ?? checks[0];
358
396
  return {
359
397
  satisfied: false,
@@ -368,7 +406,8 @@ function evaluateCanonicalSelectors(selectors, product) {
368
406
  satisfied: true,
369
407
  bug_class: "directionality",
370
408
  detail: "Every canonical selector satisfies at least one product format_options[] declaration",
371
- json_pointer: selectors[0]?.pointer ?? null
409
+ json_pointer: selectors[0]?.pointer ?? null,
410
+ selectedDeclarations: [...selected]
372
411
  };
373
412
  }
374
413
  function canonicalSelectorSatisfiesDeclaration(selector, decl) {
@@ -438,14 +477,7 @@ function requireRemainingParamContainment(productParams, requestParams) {
438
477
  for (const [key, productValue] of Object.entries(productParams)) {
439
478
  if (HANDLED_CANONICAL_PARAM_KEYS.has(key) || productValue === void 0) continue;
440
479
  if (Array.isArray(productValue) && productValue.length === 0) continue;
441
- if (requestParams[key] === void 0) {
442
- if (OMITTABLE_DECLARATION_PARAMS.has(key)) continue;
443
- return {
444
- ok: false,
445
- bug_class: "directionality",
446
- detail: `Under-specified selector: product constrains params.${key}, but the request selector omits ${key}`
447
- };
448
- }
480
+ if (requestParams[key] === void 0) continue;
449
481
  const requestValue = requestParams[key];
450
482
  if (ARRAY_SUBSET_PARAM_KEYS.has(key)) {
451
483
  const subset = requireArraySubset(key, productValue, requestValue);
@@ -737,7 +769,7 @@ function collectRejectionInfo(value, codes, fields, messages, depth = 0) {
737
769
  }
738
770
  function rejectionSupportsFormatFailure(rejection) {
739
771
  if (!rejection) return false;
740
- if (rejection.codes.some((code) => code.startsWith("FORMAT_"))) return true;
772
+ if (rejection.codes.some((code) => code.startsWith("FORMAT_") || code === "CONFLICTING_SELECTORS")) return true;
741
773
  return [...rejection.fields, ...rejection.messages].some(
742
774
  (text) => /format|format_option|format_id|selector/i.test(text)
743
775
  );
@@ -23,13 +23,6 @@ const HANDLED_CANONICAL_PARAM_KEYS = /* @__PURE__ */ new Set([
23
23
  "duration_ms_range"
24
24
  ]);
25
25
  const ARRAY_SUBSET_PARAM_KEYS = /* @__PURE__ */ new Set(["video_codecs", "audio_codecs", "mime_types", "file_types", "formats"]);
26
- const OMITTABLE_DECLARATION_PARAMS = /* @__PURE__ */ new Set([
27
- "asset_source",
28
- "buyer_asset_acceptance",
29
- "composition_model",
30
- "slots",
31
- "ssl_required"
32
- ]);
33
26
  function validateCanonicalFormatSatisfaction(validation, request, context, taskResult) {
34
27
  if (typeof validation.value !== "boolean") {
35
28
  return {
@@ -184,17 +177,41 @@ function evaluatePackage(pkg, pointer, index, products) {
184
177
  actual: productId ?? null
185
178
  };
186
179
  }
180
+ const routes = [];
187
181
  const formatOptionRefs = Array.isArray(pkg.format_option_refs) ? pkg.format_option_refs : [];
188
182
  if (formatOptionRefs.length > 0) {
189
- return evaluateFormatOptionRefs(formatOptionRefs, product, pointer);
183
+ routes.push({ name: "format_option_refs", verdict: evaluateFormatOptionRefs(formatOptionRefs, product, pointer) });
190
184
  }
191
185
  const formatIds = Array.isArray(pkg.format_ids) ? pkg.format_ids : [];
192
186
  if (formatIds.length > 0) {
193
- return evaluateLegacyFormatIds(formatIds, product, pointer, productId);
187
+ routes.push({ name: "format_ids", verdict: evaluateLegacyFormatIds(formatIds, product, pointer, productId) });
194
188
  }
195
189
  const canonicalSelectors = extractCanonicalSelectors(pkg, pointer);
196
190
  if (canonicalSelectors.length > 0) {
197
- return evaluateCanonicalSelectors(canonicalSelectors, product);
191
+ routes.push({ name: "canonical selectors", verdict: evaluateCanonicalSelectors(canonicalSelectors, product) });
192
+ }
193
+ const failed = routes.find((route) => !route.verdict.satisfied);
194
+ if (failed) return failed.verdict;
195
+ const primary = routes[0];
196
+ if (primary) {
197
+ const selected = new Set(primary.verdict.selectedDeclarations);
198
+ const conflicting = routes.slice(1).find((route) => {
199
+ const other = new Set(route.verdict.selectedDeclarations);
200
+ return selected.size !== other.size || [...selected].some((index2) => !other.has(index2));
201
+ });
202
+ if (conflicting) {
203
+ return {
204
+ satisfied: false,
205
+ bug_class: "directionality",
206
+ detail: `Conflicting selector routes ${primary.name} and ${conflicting.name} select different product format_options[] sets`,
207
+ json_pointer: pointer,
208
+ observations: routes.map((route) => ({
209
+ route: route.name,
210
+ selected_declarations: route.verdict.selectedDeclarations
211
+ }))
212
+ };
213
+ }
214
+ return primary.verdict;
198
215
  }
199
216
  return {
200
217
  satisfied: true,
@@ -214,6 +231,7 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
214
231
  actual: refs
215
232
  };
216
233
  }
234
+ const selected = /* @__PURE__ */ new Set();
217
235
  for (let i = 0; i < refs.length; i++) {
218
236
  const ref = refs[i];
219
237
  if (!isRecord(ref)) {
@@ -243,13 +261,13 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
243
261
  actual: ref
244
262
  };
245
263
  }
246
- const match = declarations.find((decl) => {
264
+ const match = declarations.findIndex((decl) => {
247
265
  if (ref.scope === "publisher") {
248
266
  return decl.publisher_domain === ref.publisher_domain && decl.format_option_id === ref.format_option_id && typeof ref.publisher_domain === "string";
249
267
  }
250
268
  return decl.format_option_id === ref.format_option_id && !decl.publisher_domain;
251
269
  });
252
- if (!match) {
270
+ if (match < 0) {
253
271
  return {
254
272
  satisfied: false,
255
273
  bug_class: "closed_set",
@@ -259,16 +277,19 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
259
277
  observations: [{ available_format_option_ids: declarations.map(declarationLabel).filter(Boolean) }]
260
278
  };
261
279
  }
280
+ selected.add(match);
262
281
  }
263
282
  return {
264
283
  satisfied: true,
265
284
  bug_class: "directionality",
266
285
  detail: "Every format_option_refs[] entry resolved to the target product format_options[] closed set",
267
- json_pointer: `${packagePointer}/format_option_refs`
286
+ json_pointer: `${packagePointer}/format_option_refs`,
287
+ selectedDeclarations: [...selected]
268
288
  };
269
289
  }
270
290
  function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
271
291
  const declarations = productFormatOptions(product);
292
+ const selected = /* @__PURE__ */ new Set();
272
293
  for (let i = 0; i < refs.length; i++) {
273
294
  const ref = refs[i];
274
295
  if (!isFormatId(ref)) {
@@ -280,12 +301,22 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
280
301
  actual: ref
281
302
  };
282
303
  }
283
- const direct = declarations.find((decl) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)));
284
- if (direct) continue;
304
+ const direct = declarations.flatMap(
305
+ (decl, index) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)) ? [index] : []
306
+ );
307
+ if (direct.length > 0) {
308
+ for (const index of direct) selected.add(index);
309
+ continue;
310
+ }
285
311
  const projected = projectLegacyRef(ref, productId, `${packagePointer}/format_ids/${i}`);
286
312
  if (projected) {
287
- const match = declarations.find((decl) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok);
288
- if (match) continue;
313
+ const matches = declarations.flatMap(
314
+ (decl, index) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok ? [index] : []
315
+ );
316
+ if (matches.length > 0) {
317
+ for (const index of matches) selected.add(index);
318
+ continue;
319
+ }
289
320
  }
290
321
  if (declarations.length === 0 && Array.isArray(product.format_ids) && product.format_ids.some((fid) => isFormatId(fid) && sameFormatId(fid, ref))) {
291
322
  continue;
@@ -303,7 +334,8 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
303
334
  satisfied: true,
304
335
  bug_class: "normalization",
305
336
  detail: "Every legacy format_id normalized to a product canonical declaration or product legacy format_id",
306
- json_pointer: `${packagePointer}/format_ids`
337
+ json_pointer: `${packagePointer}/format_ids`,
338
+ selectedDeclarations: [...selected]
307
339
  };
308
340
  }
309
341
  function evaluateCanonicalSelectors(selectors, product) {
@@ -317,6 +349,7 @@ function evaluateCanonicalSelectors(selectors, product) {
317
349
  actual: selectors
318
350
  };
319
351
  }
352
+ const selected = /* @__PURE__ */ new Set();
320
353
  for (const selector of selectors) {
321
354
  const candidates = declarations.filter((decl) => decl.format_kind === selector.format_kind);
322
355
  if (candidates.length === 0) {
@@ -329,7 +362,12 @@ function evaluateCanonicalSelectors(selectors, product) {
329
362
  };
330
363
  }
331
364
  const checks = candidates.map((decl) => canonicalSelectorSatisfiesDeclaration(selector, decl));
332
- if (checks.some((c) => c.ok)) continue;
365
+ if (checks.some((c) => c.ok)) {
366
+ for (const [index, decl] of declarations.entries()) {
367
+ if (canonicalSelectorSatisfiesDeclaration(selector, decl).ok) selected.add(index);
368
+ }
369
+ continue;
370
+ }
333
371
  const primary = checks.find((c) => c.bug_class === "range_containment") ?? checks[0];
334
372
  return {
335
373
  satisfied: false,
@@ -344,7 +382,8 @@ function evaluateCanonicalSelectors(selectors, product) {
344
382
  satisfied: true,
345
383
  bug_class: "directionality",
346
384
  detail: "Every canonical selector satisfies at least one product format_options[] declaration",
347
- json_pointer: selectors[0]?.pointer ?? null
385
+ json_pointer: selectors[0]?.pointer ?? null,
386
+ selectedDeclarations: [...selected]
348
387
  };
349
388
  }
350
389
  function canonicalSelectorSatisfiesDeclaration(selector, decl) {
@@ -414,14 +453,7 @@ function requireRemainingParamContainment(productParams, requestParams) {
414
453
  for (const [key, productValue] of Object.entries(productParams)) {
415
454
  if (HANDLED_CANONICAL_PARAM_KEYS.has(key) || productValue === void 0) continue;
416
455
  if (Array.isArray(productValue) && productValue.length === 0) continue;
417
- if (requestParams[key] === void 0) {
418
- if (OMITTABLE_DECLARATION_PARAMS.has(key)) continue;
419
- return {
420
- ok: false,
421
- bug_class: "directionality",
422
- detail: `Under-specified selector: product constrains params.${key}, but the request selector omits ${key}`
423
- };
424
- }
456
+ if (requestParams[key] === void 0) continue;
425
457
  const requestValue = requestParams[key];
426
458
  if (ARRAY_SUBSET_PARAM_KEYS.has(key)) {
427
459
  const subset = requireArraySubset(key, productValue, requestValue);
@@ -713,7 +745,7 @@ function collectRejectionInfo(value, codes, fields, messages, depth = 0) {
713
745
  }
714
746
  function rejectionSupportsFormatFailure(rejection) {
715
747
  if (!rejection) return false;
716
- if (rejection.codes.some((code) => code.startsWith("FORMAT_"))) return true;
748
+ if (rejection.codes.some((code) => code.startsWith("FORMAT_") || code === "CONFLICTING_SELECTORS")) return true;
717
749
  return [...rejection.fields, ...rejection.messages].some(
718
750
  (text) => /format|format_option|format_id|selector/i.test(text)
719
751
  );
@@ -181,12 +181,9 @@ export declare function getExternalSchemaRootForCompliance(options: ResolveOptio
181
181
  export declare function loadBundleStoryboards(ref: BundleRef): Storyboard[];
182
182
  /** Enumerate every bundle present in the cache (universal + protocols + specialisms). */
183
183
  export declare function listBundles(options?: ResolveOptions): BundleRef[];
184
- /** List every storyboard the cache can produce, across all bundles. */
184
+ /** List every storyboard the selected immutable bundle can produce, as detached records. */
185
185
  export declare function listAllComplianceStoryboards(options?: ResolveOptions): Storyboard[];
186
- /**
187
- * Find a storyboard by its internal `id` (the YAML's `id:` field).
188
- * Scans every bundle in the cache. Returns undefined if no match.
189
- */
186
+ /** Find a storyboard by its internal YAML id without reparsing a warm bundle. */
190
187
  export declare function getComplianceStoryboardById(id: string, options?: ResolveOptions): Storyboard | undefined;
191
188
  /** Find a bundle by its directory/file id (`media-buy`, `sales-guaranteed`, `capability-discovery`). */
192
189
  export declare function findBundleById(id: string, options?: ResolveOptions): BundleRef | undefined;
@@ -181,12 +181,9 @@ export declare function getExternalSchemaRootForCompliance(options: ResolveOptio
181
181
  export declare function loadBundleStoryboards(ref: BundleRef): Storyboard[];
182
182
  /** Enumerate every bundle present in the cache (universal + protocols + specialisms). */
183
183
  export declare function listBundles(options?: ResolveOptions): BundleRef[];
184
- /** List every storyboard the cache can produce, across all bundles. */
184
+ /** List every storyboard the selected immutable bundle can produce, as detached records. */
185
185
  export declare function listAllComplianceStoryboards(options?: ResolveOptions): Storyboard[];
186
- /**
187
- * Find a storyboard by its internal `id` (the YAML's `id:` field).
188
- * Scans every bundle in the cache. Returns undefined if no match.
189
- */
186
+ /** Find a storyboard by its internal YAML id without reparsing a warm bundle. */
190
187
  export declare function getComplianceStoryboardById(id: string, options?: ResolveOptions): Storyboard | undefined;
191
188
  /** Find a bundle by its directory/file id (`media-buy`, `sales-guaranteed`, `capability-discovery`). */
192
189
  export declare function findBundleById(id: string, options?: ResolveOptions): BundleRef | undefined;
@@ -47,6 +47,7 @@ var import_errors = require('../../errors/index.js');
47
47
  var import_adcp_version_config = require('../../utils/adcp-version-config.js');
48
48
  var import_schema_loader = require('../../validation/schema-loader.js');
49
49
  var import_synthesize = require('./request-signing/synthesize.js');
50
+ var import_vector_loader = require('./request-signing/vector-loader.js');
50
51
  var import_provenance = require('./provenance.js');
51
52
  class CapabilityResolutionError extends import_errors.ADCPError {
52
53
  code;
@@ -434,23 +435,71 @@ function listBundles(options = {}) {
434
435
  }
435
436
  return bundles;
436
437
  }
437
- function listAllComplianceStoryboards(options = {}) {
438
- const seen = /* @__PURE__ */ new Set();
439
- const storyboards = [];
440
- for (const ref of listBundles(options)) {
441
- for (const sb of loadBundleStoryboards(ref)) {
442
- if (seen.has(sb.id)) continue;
443
- seen.add(sb.id);
444
- storyboards.push(sb);
438
+ const STORYBOARD_INDEX_CACHE_LIMIT = 8;
439
+ const storyboardIndexes = /* @__PURE__ */ new Map();
440
+ function customComplianceInventory(dir) {
441
+ if (!(0, import_fs.existsSync)(dir)) return "missing";
442
+ const entries = [];
443
+ const visitedDirectories = /* @__PURE__ */ new Set();
444
+ const visit = (file, relative) => {
445
+ const stat = (0, import_fs.statSync)(file, { bigint: true });
446
+ entries.push([relative, String(stat.mtimeNs), String(stat.ctimeNs), String(stat.size), String(stat.ino)]);
447
+ if (!stat.isDirectory()) return;
448
+ const identity = `${stat.dev}:${stat.ino}`;
449
+ if (visitedDirectories.has(identity)) return;
450
+ visitedDirectories.add(identity);
451
+ for (const child of (0, import_fs.readdirSync)(file).sort()) visit((0, import_path.join)(file, child), `${relative}/${child}`);
452
+ };
453
+ visit(dir, "");
454
+ return JSON.stringify(entries);
455
+ }
456
+ function complianceStoryboardIndex(options) {
457
+ const dir = (0, import_path.resolve)(getComplianceCacheDir(options));
458
+ const indexPath = (0, import_path.join)(dir, "index.json");
459
+ const stamp = (0, import_fs.existsSync)(indexPath) ? (0, import_fs.statSync)(indexPath) : void 0;
460
+ const schemaRoot = getConfiguredSchemaRoot(options);
461
+ const customRoot = Boolean(getConfiguredComplianceDir(options));
462
+ const inventory = customRoot ? customComplianceInventory(dir) : null;
463
+ const key = JSON.stringify([
464
+ dir,
465
+ options.version ?? import_version.ADCP_VERSION,
466
+ schemaRoot ? (0, import_path.resolve)(schemaRoot) : null,
467
+ options.hostedStableLineAlias ?? null,
468
+ stamp?.mtimeMs ?? null,
469
+ stamp?.size ?? null,
470
+ inventory
471
+ ]);
472
+ const cached = storyboardIndexes.get(key);
473
+ if (cached) {
474
+ storyboardIndexes.delete(key);
475
+ storyboardIndexes.set(key, cached);
476
+ return cached;
477
+ }
478
+ if (customRoot) (0, import_vector_loader.invalidateRequestSigningVectorCache)(dir);
479
+ const indexed = /* @__PURE__ */ new Map();
480
+ for (const ref of listBundles({ ...options, complianceDir: dir })) {
481
+ for (const storyboard of loadBundleStoryboards(ref)) {
482
+ if (!indexed.has(storyboard.id)) indexed.set(storyboard.id, storyboard);
445
483
  }
446
484
  }
447
- return storyboards;
485
+ storyboardIndexes.set(key, indexed);
486
+ while (storyboardIndexes.size > STORYBOARD_INDEX_CACHE_LIMIT) {
487
+ const oldest = storyboardIndexes.keys().next().value;
488
+ if (oldest !== void 0) storyboardIndexes.delete(oldest);
489
+ }
490
+ return indexed;
491
+ }
492
+ function cloneComplianceStoryboard(storyboard) {
493
+ const copy = structuredClone(storyboard);
494
+ const trustedRoot = (0, import_provenance.trustedStoryboardComplianceRoot)(storyboard);
495
+ return trustedRoot ? (0, import_provenance.markStoryboardComplianceRoot)(copy, trustedRoot) : copy;
496
+ }
497
+ function listAllComplianceStoryboards(options = {}) {
498
+ return [...complianceStoryboardIndex(options).values()].map(cloneComplianceStoryboard);
448
499
  }
449
500
  function getComplianceStoryboardById(id, options = {}) {
450
- for (const sb of listAllComplianceStoryboards(options)) {
451
- if (sb.id === id) return sb;
452
- }
453
- return void 0;
501
+ const storyboard = complianceStoryboardIndex(options).get(id);
502
+ return storyboard ? cloneComplianceStoryboard(storyboard) : void 0;
454
503
  }
455
504
  function findBundleById(id, options = {}) {
456
505
  return listBundles(options).find((b) => b.id === id);
@@ -12,7 +12,8 @@ import { ADCPError } from "../../errors/index.mjs";
12
12
  import { isAdcpVersionSupported } from "../../utils/adcp-version-config.mjs";
13
13
  import { hasSchemaBundle, resolveBundleKey } from "../../validation/schema-loader.mjs";
14
14
  import { synthesizeRequestSigningSteps } from "./request-signing/synthesize.mjs";
15
- import { markStoryboardComplianceRoot } from "./provenance.mjs";
15
+ import { invalidateRequestSigningVectorCache } from "./request-signing/vector-loader.mjs";
16
+ import { markStoryboardComplianceRoot, trustedStoryboardComplianceRoot } from "./provenance.mjs";
16
17
  class CapabilityResolutionError extends ADCPError {
17
18
  code;
18
19
  specialism;
@@ -399,23 +400,71 @@ function listBundles(options = {}) {
399
400
  }
400
401
  return bundles;
401
402
  }
402
- function listAllComplianceStoryboards(options = {}) {
403
- const seen = /* @__PURE__ */ new Set();
404
- const storyboards = [];
405
- for (const ref of listBundles(options)) {
406
- for (const sb of loadBundleStoryboards(ref)) {
407
- if (seen.has(sb.id)) continue;
408
- seen.add(sb.id);
409
- storyboards.push(sb);
403
+ const STORYBOARD_INDEX_CACHE_LIMIT = 8;
404
+ const storyboardIndexes = /* @__PURE__ */ new Map();
405
+ function customComplianceInventory(dir) {
406
+ if (!existsSync(dir)) return "missing";
407
+ const entries = [];
408
+ const visitedDirectories = /* @__PURE__ */ new Set();
409
+ const visit = (file, relative) => {
410
+ const stat = statSync(file, { bigint: true });
411
+ entries.push([relative, String(stat.mtimeNs), String(stat.ctimeNs), String(stat.size), String(stat.ino)]);
412
+ if (!stat.isDirectory()) return;
413
+ const identity = `${stat.dev}:${stat.ino}`;
414
+ if (visitedDirectories.has(identity)) return;
415
+ visitedDirectories.add(identity);
416
+ for (const child of readdirSync(file).sort()) visit(join(file, child), `${relative}/${child}`);
417
+ };
418
+ visit(dir, "");
419
+ return JSON.stringify(entries);
420
+ }
421
+ function complianceStoryboardIndex(options) {
422
+ const dir = resolve(getComplianceCacheDir(options));
423
+ const indexPath = join(dir, "index.json");
424
+ const stamp = existsSync(indexPath) ? statSync(indexPath) : void 0;
425
+ const schemaRoot = getConfiguredSchemaRoot(options);
426
+ const customRoot = Boolean(getConfiguredComplianceDir(options));
427
+ const inventory = customRoot ? customComplianceInventory(dir) : null;
428
+ const key = JSON.stringify([
429
+ dir,
430
+ options.version ?? ADCP_VERSION,
431
+ schemaRoot ? resolve(schemaRoot) : null,
432
+ options.hostedStableLineAlias ?? null,
433
+ stamp?.mtimeMs ?? null,
434
+ stamp?.size ?? null,
435
+ inventory
436
+ ]);
437
+ const cached = storyboardIndexes.get(key);
438
+ if (cached) {
439
+ storyboardIndexes.delete(key);
440
+ storyboardIndexes.set(key, cached);
441
+ return cached;
442
+ }
443
+ if (customRoot) invalidateRequestSigningVectorCache(dir);
444
+ const indexed = /* @__PURE__ */ new Map();
445
+ for (const ref of listBundles({ ...options, complianceDir: dir })) {
446
+ for (const storyboard of loadBundleStoryboards(ref)) {
447
+ if (!indexed.has(storyboard.id)) indexed.set(storyboard.id, storyboard);
410
448
  }
411
449
  }
412
- return storyboards;
450
+ storyboardIndexes.set(key, indexed);
451
+ while (storyboardIndexes.size > STORYBOARD_INDEX_CACHE_LIMIT) {
452
+ const oldest = storyboardIndexes.keys().next().value;
453
+ if (oldest !== void 0) storyboardIndexes.delete(oldest);
454
+ }
455
+ return indexed;
456
+ }
457
+ function cloneComplianceStoryboard(storyboard) {
458
+ const copy = structuredClone(storyboard);
459
+ const trustedRoot = trustedStoryboardComplianceRoot(storyboard);
460
+ return trustedRoot ? markStoryboardComplianceRoot(copy, trustedRoot) : copy;
461
+ }
462
+ function listAllComplianceStoryboards(options = {}) {
463
+ return [...complianceStoryboardIndex(options).values()].map(cloneComplianceStoryboard);
413
464
  }
414
465
  function getComplianceStoryboardById(id, options = {}) {
415
- for (const sb of listAllComplianceStoryboards(options)) {
416
- if (sb.id === id) return sb;
417
- }
418
- return void 0;
466
+ const storyboard = complianceStoryboardIndex(options).get(id);
467
+ return storyboard ? cloneComplianceStoryboard(storyboard) : void 0;
419
468
  }
420
469
  function findBundleById(id, options = {}) {
421
470
  return listBundles(options).find((b) => b.id === id);
@@ -6,6 +6,7 @@
6
6
  * The canonical storyboard set lives in the AdCP compliance tarball
7
7
  * and is pulled into `compliance/cache/{version}/` via `npm run sync-schemas`.
8
8
  */
9
+ export { createStoryboardWebBotAuthFetch } from './web-bot-auth.mjs';
9
10
  export type { A2ATaskEnvelope, AgentEntry, Storyboard, StoryboardFixtureResolution, FixtureResolutionStrategy, FixtureMatchOperator, FixtureMatchClause, FixtureResolutionDeclaration, ProductFixtureResolutionDeclaration, PricingOptionFixtureResolutionDeclaration, FixtureResolutionStatus, FixtureResolutionRecord, FixtureResolutionAttempt, FixtureResolutionEvidence, FixtureResolutionCoverageGap, StoryboardInvariants, StoryboardInvariantsObject, StepInvariantsObject, StoryboardPhase, StoryboardStep, RateLimitTripSpec, StoryboardValidation, StoryboardValidationCheck, WebhookFilterSpec, WebhookRetryTriggerSpec, WebhookAssertionErrorCode, ContextOutput, ContextInput, ContextProvenanceEntry, ContextValueRejectedHint, ShapeDriftHint, MissingRequiredFieldHint, FormatMismatchHint, MonotonicViolationHint, ImpairmentCoherenceHint, ImpairmentCoherenceNotApplicableHint, StoryboardContext, StoryboardRunOptions, PrepareStoryboardFixturesOptions, TrustedMatchContextProviderEndpoint, TrustedMatchContextRegistrationContext, TrustedMatchContextRouterRunnerOptions, TrustedMatchPublisherAuthOperation, TrustedMatchPublisherCredentialState, TrustedMatchPublisherAuthTls, TrustedMatchPublisherAuthProbeConfiguration, TrustedMatchPublisherAuthRunner, ValidationResult, StoryboardStepPreview, StoryboardStepResult, StoryboardStepHint, StoryboardStepHintBase, StoryboardPhaseResult, StoryboardResult, AssertionResult, StrictValidationSummary, StrictValidationVerdict, UpstreamTrafficPayloadMatch, RunnerNotice, NoticeCode, NoticeSeverity, } from './types.mjs';
10
11
  export { WEBHOOK_IDEMPOTENCY_KEY_PATTERN } from './types.mjs';
11
12
  export { MCP_SESSION_PROBE_TASK } from './types.mjs';