@adcp/sdk 14.0.0-beta.0 → 14.0.0-beta.1

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 (140) hide show
  1. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/get-account-financials-request.json +610 -0
  2. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/get-account-financials-response.json +1055 -0
  3. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/list-accounts-request.json +629 -0
  4. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/list-accounts-response.json +1558 -0
  5. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/report-usage-request.json +702 -0
  6. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/report-usage-response.json +309 -0
  7. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-accounts-request.json +1113 -0
  8. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-accounts-response.json +1567 -0
  9. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-governance-request.json +662 -0
  10. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-governance-response.json +921 -0
  11. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/list-creatives-request.json +992 -0
  12. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/list-creatives-response.json +5965 -0
  13. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/sync-creatives-request.json +3936 -0
  14. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/sync-creatives-response.json +3859 -0
  15. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/manifest.json +206 -0
  16. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json +601 -0
  17. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-response.json +4799 -0
  18. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json +4107 -0
  19. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-response.json +4799 -0
  20. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json +3365 -0
  21. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-response.json +656 -0
  22. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/decline-proposals-request.json +334 -0
  23. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/decline-proposals-response.json +271 -0
  24. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buy-delivery-request.json +1236 -0
  25. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buy-delivery-response.json +2861 -0
  26. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buys-request.json +678 -0
  27. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buys-response.json +10861 -0
  28. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/list-products-request.json +4229 -0
  29. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/list-products-response.json +3824 -0
  30. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/log-event-request.json +421 -0
  31. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/log-event-response.json +394 -0
  32. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/media-buy-delivery-webhook-result.json +1366 -0
  33. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/provide-performance-feedback-request.json +884 -0
  34. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/provide-performance-feedback-response.json +422 -0
  35. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/refine-proposals-request.json +4335 -0
  36. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/refine-proposals-response.json +7328 -0
  37. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/request-proposals-request.json +4307 -0
  38. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/request-proposals-response.json +7105 -0
  39. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-audiences-request.json +760 -0
  40. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-audiences-response.json +541 -0
  41. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-catalogs-request.json +1142 -0
  42. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-catalogs-response.json +1153 -0
  43. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-event-sources-request.json +743 -0
  44. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-event-sources-response.json +619 -0
  45. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/get-account-financials-request.json +544 -0
  46. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/list-accounts-request.json +557 -0
  47. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/report-usage-request.json +617 -0
  48. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/sync-accounts-request.json +984 -0
  49. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/sync-governance-request.json +581 -0
  50. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/creative/list-creatives-request.json +878 -0
  51. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/creative/sync-creatives-request.json +3456 -0
  52. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/manifest.json +175 -0
  53. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json +498 -0
  54. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json +3675 -0
  55. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json +3030 -0
  56. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/decline-proposals-request.json +282 -0
  57. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/get-media-buy-delivery-request.json +1136 -0
  58. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/get-media-buys-request.json +597 -0
  59. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/list-products-request.json +3780 -0
  60. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/log-event-request.json +386 -0
  61. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/provide-performance-feedback-request.json +784 -0
  62. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/refine-proposals-request.json +3878 -0
  63. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/request-proposals-request.json +3852 -0
  64. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-audiences-request.json +682 -0
  65. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-catalogs-request.json +1016 -0
  66. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-event-sources-request.json +660 -0
  67. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/get-adcp-capabilities-request.json +51 -0
  68. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/get-task-status-request.json +534 -0
  69. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/list-tasks-request.json +692 -0
  70. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/sync-agent-notification-configs-request.json +129 -0
  71. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-adcp-capabilities-request.json +58 -0
  72. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-adcp-capabilities-response.json +8069 -0
  73. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-task-status-request.json +601 -0
  74. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-task-status-response.json +612 -0
  75. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/list-tasks-request.json +775 -0
  76. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/list-tasks-response.json +483 -0
  77. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/sync-agent-notification-configs-request.json +155 -0
  78. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/sync-agent-notification-configs-response.json +382 -0
  79. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  80. package/dist/lib/server/create-adcp-server.d.mts +27 -0
  81. package/dist/lib/server/create-adcp-server.d.ts +27 -0
  82. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  83. package/dist/lib/server/create-adcp-server.js +120 -4
  84. package/dist/lib/server/create-adcp-server.js.map +1 -1
  85. package/dist/lib/server/create-adcp-server.mjs +121 -6
  86. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  87. package/dist/lib/server/decisioning/context.d.mts +6 -0
  88. package/dist/lib/server/decisioning/context.d.ts +6 -0
  89. package/dist/lib/server/decisioning/context.d.ts.map +1 -1
  90. package/dist/lib/server/decisioning/context.js.map +1 -1
  91. package/dist/lib/server/decisioning/index.d.mts +1 -1
  92. package/dist/lib/server/decisioning/index.d.ts +1 -1
  93. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  94. package/dist/lib/server/decisioning/index.js.map +1 -1
  95. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  96. package/dist/lib/server/decisioning/platform.d.mts +21 -6
  97. package/dist/lib/server/decisioning/platform.d.ts +21 -6
  98. package/dist/lib/server/decisioning/platform.d.ts.map +1 -1
  99. package/dist/lib/server/decisioning/platform.js.map +1 -1
  100. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  101. package/dist/lib/server/decisioning/runtime/from-platform.js +201 -18
  102. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  103. package/dist/lib/server/decisioning/runtime/from-platform.mjs +203 -19
  104. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  105. package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
  106. package/dist/lib/server/decisioning/runtime/to-context.js +6 -0
  107. package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
  108. package/dist/lib/server/decisioning/runtime/to-context.mjs +6 -0
  109. package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
  110. package/dist/lib/server/decisioning/runtime/validate-platform.d.ts.map +1 -1
  111. package/dist/lib/server/decisioning/runtime/validate-platform.js +35 -4
  112. package/dist/lib/server/decisioning/runtime/validate-platform.js.map +1 -1
  113. package/dist/lib/server/decisioning/runtime/validate-platform.mjs +35 -4
  114. package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
  115. package/dist/lib/server/decisioning/specialisms/sales.d.mts +39 -0
  116. package/dist/lib/server/decisioning/specialisms/sales.d.ts +39 -0
  117. package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
  118. package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
  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/validation/schema-loader.d.mts +2 -0
  122. package/dist/lib/validation/schema-loader.d.ts +2 -0
  123. package/dist/lib/validation/schema-loader.d.ts.map +1 -1
  124. package/dist/lib/validation/schema-loader.js +31 -0
  125. package/dist/lib/validation/schema-loader.js.map +1 -1
  126. package/dist/lib/validation/schema-loader.mjs +30 -0
  127. package/dist/lib/validation/schema-loader.mjs.map +1 -1
  128. package/dist/lib/version.d.mts +3 -3
  129. package/dist/lib/version.d.ts +3 -3
  130. package/dist/lib/version.js +3 -3
  131. package/dist/lib/version.js.map +1 -1
  132. package/dist/lib/version.mjs +3 -3
  133. package/dist/lib/version.mjs.map +1 -1
  134. package/docs/guides/BUILD-AN-AGENT.md +10 -1
  135. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +119 -0
  136. package/docs/llms.txt +1 -1
  137. package/docs/migration-12-to-14.md +8 -0
  138. package/docs/migration-13-to-14.md +30 -4
  139. package/docs/releases/14.0.0-beta.0.md +19 -1
  140. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/server/decisioning/platform.ts"],"sourcesContent":["/**\n * DecisioningPlatform — the top-level interface adopters implement.\n *\n * Per-specialism sub-interfaces (sales, creative, audiences, etc.) are\n * optional; framework's compile-time enforcement (RequiredPlatformsFor<S>)\n * forces the right sub-interfaces based on `capabilities.specialisms[]`.\n *\n * Status: Preview / 6.0. Not yet wired into the framework.\n *\n * @public\n */\n\nimport type { DecisioningCapabilities, BrandCapabilities } from './capabilities';\nimport type { Account, AccountStore } from './account';\nimport type { BuyerAgentRegistry } from './buyer-agent';\nimport type { SessionContext, OnInstructionsError, MaybePromise } from '../create-adcp-server';\nimport type { StatusMappers } from './status-mappers';\nimport type { SalesPlatform, SalesCorePlatform, SalesIngestionPlatform } from './specialisms/sales';\nimport type { ProposalManager, Recipe } from './proposal';\nimport type { CreativeBuilderPlatform } from './specialisms/creative';\nimport type { CreativeAdServerPlatform } from './specialisms/creative-ad-server';\nimport type { AudiencePlatform } from './specialisms/audiences';\nimport type { SignalsPlatform } from './specialisms/signals';\nimport type { SponsoredIntelligencePlatform } from './specialisms/sponsored-intelligence';\nimport type { CampaignGovernancePlatform } from './specialisms/campaign-governance';\nimport type { ContentStandardsPlatform } from './specialisms/content-standards';\nimport type { BrandRightsPlatform } from './specialisms/brand-rights';\nimport type { PropertyListsPlatform, CollectionListsPlatform } from './specialisms/lists';\nimport type { AdCPSpecialism } from '../../types/tools.generated';\n\n/**\n * Top-level platform interface. Adopters implement this; framework wires\n * the wire protocol around it.\n *\n * The \"framework owns X\" claims below are the v6.0 wiring contract — the\n * runtime guarantees the framework will provide once this surface is wired.\n * They are NOT yet enforced; this module is preview-only as of the scaffold\n * landing. Treat them as the design contract a v6.0 reviewer should hold\n * the framework refactor to, not as a description of existing behavior.\n *\n * **What the framework owns** (platform implementations DON'T see these):\n * - Wire-shape mapping (MCP tools/list, A2A skill manifest, request/response envelopes)\n * - Authentication + auth-principal extraction; `accounts.resolve()` is the only\n * place the platform translates auth into its tenant model\n * - Idempotency: dedupe + replay handled before dispatch; platforms see clean traffic\n * - `sandbox` boundary: when `AccountReference.sandbox === true`, framework\n * resolves the buyer's sandbox account via `accounts.resolve()`. The platform\n * sees the resolved sandbox `Account` like any other and is responsible for\n * routing reads/writes to its sandbox backend. There is no separate\n * \"dry-run\" mode — sandbox subsumes \"validate against real platform without\n * writing to production.\" Tool-specific `dry_run` flags on `sync_catalogs`\n * and `sync_creatives` are wire fields the platform receives and honors;\n * they are NOT a framework-level mode.\n * - `context` echo: framework round-trips `context` on every response\n * - Task envelopes: `submitted` outcomes are wrapped into A2A Task envelopes /\n * MCP polling responses; `taskHandle.notify` calls dedupe + retry\n * - Schema validation: requests fail before reaching the platform; responses are\n * shape-validated against the wire schema after the platform returns\n *\n * **What the platform owns**: the business decisions in each `SalesPlatform` /\n * `CreativeBuilderPlatform` / `AudiencePlatform` method. Nothing else.\n *\n * ### Cross-specialism dispatch\n *\n * When one specialism handler needs to consult another (canonical case:\n * `brandRights.acquireRights` calling `campaignGovernance.checkGovernance`\n * before granting rights, against a buyer-registered governance binding),\n * the framework does NOT thread a separate `ctx.platform.<specialism>`\n * accessor on `RequestContext`. Two idiomatic patterns; pick by authoring\n * style:\n *\n * **Pattern A — class instance + `this`** (canonical for holdco hubs;\n * `examples/hello_seller_adapter_multi_tenant.ts` is the reference):\n *\n * ```ts\n * class HoldcoAdapter implements DecisioningPlatform<Config, TenantMeta> {\n * campaignGovernance = defineCampaignGovernancePlatform<TenantMeta>({ });\n * brandRights = defineBrandRightsPlatform<TenantMeta>({\n * acquireRights: async (req, ctx) => {\n * const denial = await this.enforceGovernance(tenant, ctx, offering, req);\n * if (denial) return denial;\n *\n * },\n * });\n * private async enforceGovernance(...) {\n * // calls this.campaignGovernance.checkGovernance(...)\n * }\n * }\n * ```\n *\n * **Pattern B — closure capture** (for adopters using `define<X>Platform({...})`\n * factories standalone):\n *\n * ```ts\n * const campaignGovernance = defineCampaignGovernancePlatform<TenantMeta>({ ... });\n * const brandRights = defineBrandRightsPlatform<TenantMeta>({\n * acquireRights: async (req, ctx) => {\n * const govResp = await campaignGovernance.checkGovernance!(checkReq, ctx);\n *\n * },\n * });\n * const platform: DecisioningPlatform<Config, TenantMeta> = {\n * capabilities: { }, accounts: { }, campaignGovernance, brandRights,\n * };\n * ```\n *\n * Both patterns forward the same `RequestContext` (resolved account, agent,\n * authInfo), so tenant invariants hold transitively. Both bypass wire-side\n * validation, idempotency dedup, and mutating-tool annotations — that's\n * correct because you're inside the seller's code, not handling a buyer\n * request, but it means an in-process `checkGovernance` won't be\n * re-deduped if the originating tool is already idempotency-protected.\n * Single-specialism adopters MUST NOT copy this short-circuit: without a\n * co-resident sibling handler, dial out to the registered governance\n * agent URL via the `@adcp/sdk` client instead.\n *\n * Full walkthrough with same-tenant invariant + production caveats:\n * `skills/build-holdco-agent/SKILL.md` § Cross-specialism dispatch.\n *\n * @template TConfig Platform-specific config typed at the call site.\n * Example: `class GAM implements DecisioningPlatform<{ networkId: string }>`.\n * @template TCtxMeta Shape of the platform's opaque ctx_metadata blob — typed\n * once and propagated into `ctx.account.ctx_metadata`,\n * `ctx.ctxMetadata.get()`, and every specialism handler.\n */\nexport interface DecisioningPlatform<TConfig = unknown, TCtxMeta = Record<string, unknown>> {\n /** Capability declaration; single source of truth for get_adcp_capabilities. */\n capabilities: DecisioningCapabilities<TConfig>;\n\n /** Account model + tenant resolution. */\n accounts: AccountStore<TCtxMeta>;\n\n /**\n * Server-level instructions surfaced on the MCP `initialize` response.\n * Use to publish platform facts, decision policy, and trends that buying\n * agents should read before issuing tool calls (e.g., \"publisher-wide\n * brand safety: alcohol disallowed\", \"carbon-aware pricing applies to\n * display impressions only\", \"weekly cutoff Thursday 17:00 UTC\").\n *\n * Two forms:\n *\n * 1. **Static string** — captured once at construction.\n * 2. **Function** `(ctx: SessionContext) => MaybePromise<string | undefined>` —\n * re-evaluated each time `createAdcpServerFromPlatform` runs. Under the\n * canonical `serve({ reuseAgent: false })` flow that is per session, so the\n * closure can surface tenant-shaped prose (per-buyer brand manifests,\n * storefront-platform copy). `serve()` refuses `reuseAgent: true`\n * when this is a function — the function would only fire once for\n * the lifetime of the shared agent.\n *\n * Async functions are supported: the framework calls the function at\n * construction and awaits the returned Promise during MCP `initialize`.\n * A rejected Promise is governed by `onInstructionsError`.\n *\n * MCP-only today. The A2A `AgentCard` analog is `description` (and\n * per-skill `description`); threading platform.instructions into the\n * agent-card builder is tracked separately so MCP and A2A buyers see\n * the same prose.\n *\n * When set on the platform, takes precedence over any `instructions`\n * supplied via `createAdcpServerFromPlatform` opts — same precedence as\n * `agentRegistry`. Adopters with v5 escape-hatch wiring can keep using\n * `opts.instructions`; v6 callers should declare it here.\n *\n * @see {@link OnInstructionsError} for `onInstructionsError` (default `'skip'`).\n */\n instructions?: string | ((ctx: SessionContext) => MaybePromise<string | undefined>);\n\n /**\n * Behavior when a function-form `instructions` callback throws.\n * Defaults to `'skip'` — best-effort prose (brand manifests, marketing\n * copy) should not kill the buyer's session on a registry fetch failure.\n * Set `'fail'` for adopters whose instructions carry load-bearing policy.\n *\n * Threaded through to {@link createAdcpServer} unchanged.\n */\n onInstructionsError?: OnInstructionsError;\n\n /**\n * Buyer-agent identity registry. Optional. When\n * configured, framework calls `agentRegistry.resolve(authInfo)` once per\n * request before `accounts.resolve` and threads the resolved record\n * through `ctx.agent` to specialism handlers.\n *\n * Adopters construct via {@link BuyerAgentRegistry.signingOnly},\n * {@link BuyerAgentRegistry.bearerOnly}, or {@link BuyerAgentRegistry.mixed}\n * depending on their authentication posture. When omitted, `ctx.agent`\n * is always undefined and the framework's request flow is unchanged.\n *\n * The resolved record drives framework status/sandbox gates and\n * `sync_accounts.billing` enforcement against\n * `BuyerAgent.billing_capabilities`.\n */\n agentRegistry?: BuyerAgentRegistry;\n\n /**\n * Native-status mappers (account, mediaBuy, creative, plan).\n *\n * **Optional.** Default behavior treats the platform's status strings as\n * already-canonical AdCP status values (no translation). Provide mappers\n * only when your platform exposes non-AdCP status strings (e.g., GAM's\n * `DELIVERY_PAUSED` → AdCP's `paused`).\n */\n statusMappers?: StatusMappers;\n\n /**\n * Per-tenant capability override. Multi-tenant SaaS adopters (Prebid-style\n * deployments where one server hosts many advertisers, each with different\n * `manualApprovalOperations` / pricing tiers / channel mixes) implement this\n * to scope capabilities per resolved Account. When absent, the framework\n * uses `capabilities` for every request.\n *\n * The framework calls this AFTER `accounts.resolve()` and uses the returned\n * capabilities to gate the rest of the request. The static `agent-card.json`\n * AND `tools/list` shape is derived from `capabilities` (the union) — per-tenant\n * differences are runtime-only.\n */\n getCapabilitiesFor?(\n account: Account<TCtxMeta>\n ): DecisioningCapabilities<TConfig> | Promise<DecisioningCapabilities<TConfig>>;\n\n // Per-specialism sub-interfaces — optional at the type level; required at the\n // call site by RequiredPlatformsFor<S>. v1.0 ships these. Each is parameterized\n // by `TCtxMeta` so adopters get typed `ctx.account.ctx_metadata` access in their\n // method bodies without casting.\n sales?: SalesPlatform<TCtxMeta>;\n creative?: CreativeBuilderPlatform<TCtxMeta> | CreativeAdServerPlatform<TCtxMeta>;\n audiences?: AudiencePlatform<TCtxMeta>;\n signals?: SignalsPlatform<TCtxMeta>;\n /**\n * Sponsored Intelligence implementation. In AdCP 3.1 this field is required\n * when the agent claims the `sponsored-intelligence` specialism. The\n * framework also derives the legacy wire protocol entry\n * `supported_protocols: ['sponsored_intelligence']` from the SI tool set so\n * protocol-bundle storyboards and 3.0-era consumers keep working.\n */\n sponsoredIntelligence?: SponsoredIntelligencePlatform<TCtxMeta>;\n /** @see DecisioningPlatform — § Cross-specialism dispatch (used as the canonical example: `brandRights.acquireRights` consulting `checkGovernance` before granting rights). */\n campaignGovernance?: CampaignGovernancePlatform<TCtxMeta>;\n contentStandards?: ContentStandardsPlatform<TCtxMeta>;\n propertyLists?: PropertyListsPlatform<TCtxMeta>;\n collectionLists?: CollectionListsPlatform<TCtxMeta>;\n /** @see DecisioningPlatform — § Cross-specialism dispatch (`acquireRights` is the canonical caller into `campaignGovernance.checkGovernance`). */\n brandRights?: BrandRightsPlatform<TCtxMeta>;\n\n /**\n * Optional sibling that owns the proposal side of the two-platform\n * composition (port of `adcp-client-python`'s `ProposalManager`). When\n * present, the framework routes `get_products` and refine traffic to\n * the manager instead of `sales.getProducts`; `sales` stays\n * responsible for media-buy execution. Either side can be mock-backed\n * independently — see `MockProposalManager`.\n *\n * **Status**: primitive types only. Framework dispatch wiring (the\n * five seams that intercept `getProducts`, `createMediaBuy`,\n * `updateMediaBuy`, `getMediaBuyDelivery` to persist drafts, hydrate\n * recipes, and commit on finalize) lands in a follow-up release. v1.5\n * adopters can already implement against this surface; the framework\n * just doesn't drive the lifecycle yet.\n */\n proposalManager?: ProposalManager<Recipe, TCtxMeta>;\n\n // v1.1+ specialisms add: creative-review.\n}\n\n// ---------------------------------------------------------------------------\n// Compile-time capability enforcement\n// ---------------------------------------------------------------------------\n\n/**\n * Maps an AdCP specialism to the platform interface(s) it requires. The\n * framework's `createAdcpServer<P extends DecisioningPlatform>` constrains\n * `P` to satisfy `RequiredPlatformsFor<P['capabilities']['specialisms'][number]>`,\n * forcing every claimed specialism's interface methods to exist.\n *\n * Drop a method, fail compile.\n * Claim a specialism without an implementation, fail compile.\n *\n * The nested-conditional encoding (rather than a union of `S extends X ? {} : never`)\n * is deliberate: when a specialism is claimed without its required platform\n * interface, TypeScript surfaces \"Property 'sales' is missing in type 'P'\"\n * rather than the unactionable \"Type 'P' does not satisfy the constraint 'never'.\"\n *\n * v1.0 covers the 4 specialisms shipping in v1.0; extended in v1.1+.\n * Unknown specialisms (v1.1+ when this module hasn't been updated yet)\n * resolve to an empty requirement — the framework's runtime check is the\n * fallback gate.\n */\n// Sales specialisms — split into two groups by what the adopter actually owns.\n//\n// - **Core sales** specialisms run their own bidding + media-buy lifecycle and\n// are required to implement `SalesCorePlatform` (`getProducts`,\n// `createMediaBuy`, `updateMediaBuy`, `getMediaBuyDelivery`, `getMediaBuys`).\n// The retail-media variants additionally compose ingestion surfaces.\n// - **Ingestion-only** specialisms (today: `sales-social`) front a walled-\n// garden CAPI / audience surface that owns bidding upstream — adopters only\n// need `SalesIngestionPlatform` (`syncCreatives` / `syncCatalogs` /\n// `syncEventSources` / `logEvent` / etc., all optional individually).\n// - **Proposal mode** is a hybrid — only `getProducts` is required; the rest\n// of the lifecycle flows through notification channels.\n//\n// Wired per the AdCP 3.0 GA enum; preview specialisms (sales-streaming-tv,\n// sales-exchange, sales-retail-media) get added when they land in spec.\ntype SalesCoreSpecialism = 'sales-non-guaranteed' | 'sales-guaranteed' | 'sales-broadcast-tv' | 'sales-catalog-driven';\ntype SalesIngestionSpecialism = 'sales-social';\ntype SalesProposalSpecialism = 'sales-proposal-mode';\n\n// Signal specialisms — both share the SignalsPlatform interface. Marketplace\n// = third-party data brokers; owned = first-party data providers.\ntype SignalSpecialism = 'signal-marketplace' | 'signal-owned';\n\n// Today's spec splits campaign governance into spend-authority + delivery-monitor;\n// both share one CampaignGovernancePlatform interface. When adcp#3329 lands and\n// the spec consolidates to `campaign-governance`, this union shrinks to one\n// value without shape changes.\ntype CampaignGovernanceSpecialism = 'governance-spend-authority' | 'governance-delivery-monitor';\n\n// `TCtxMeta` defaults to `any` so callers that don't pass it explicitly (the\n// common case — `RequiredPlatformsFor<S>` without a second argument) get a\n// constraint that accepts any adopter metadata shape. The `any` is not a\n// soundness escape — adopters declare metadata inside `DecisioningPlatform<_,\n// TCtxMeta>` directly; this constraint exists only to compile-check that\n// claimed specialisms have a matching sub-interface field on the platform.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type RequiredPlatformsFor<\n S extends AdCPSpecialism,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TCtxMeta = any,\n> = [S] extends [never]\n ? // Empty specialisms[] (legitimate when the agent's only declared\n // surface is a protocol or custom tool that is not represented as an\n // AdCP specialism).\n // `[S] extends [never]` short-circuits the distributive conditional —\n // without this, a generic `S extends ...` over `never` yields `never`,\n // collapsing `P & RequiredPlatformsFor<...>` to `never` and rejecting\n // every platform value at the call site.\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {}\n : S extends 'creative-template' | 'creative-generative' | 'creative-transformers'\n ? { creative: CreativeBuilderPlatform<TCtxMeta> }\n : S extends 'creative-ad-server'\n ? { creative: CreativeAdServerPlatform<TCtxMeta> }\n : S extends SalesCoreSpecialism\n ? { sales: SalesCorePlatform<TCtxMeta> & SalesIngestionPlatform<TCtxMeta> }\n : S extends SalesIngestionSpecialism\n ? // Walled-garden specialisms (sales-social, today). Bidding owned upstream\n // — only the ingestion surface is required. Adopters can voluntarily\n // implement core methods on the same `sales` object; the SalesPlatform\n // alias accepts both shapes.\n { sales: SalesIngestionPlatform<TCtxMeta> }\n : S extends SalesProposalSpecialism\n ? // Proposal-mode adopters only need `getProducts` — the rest of the\n // lifecycle flows through `publishStatusChange` on\n // `resource_type: 'proposal'`. Ingestion is optional.\n { sales: Required<Pick<SalesPlatform<TCtxMeta>, 'getProducts'>> & SalesIngestionPlatform<TCtxMeta> }\n : S extends 'audience-sync'\n ? { audiences: AudiencePlatform<TCtxMeta> }\n : S extends SignalSpecialism\n ? { signals: SignalsPlatform<TCtxMeta> }\n : S extends CampaignGovernanceSpecialism\n ? { campaignGovernance: CampaignGovernancePlatform<TCtxMeta> }\n : S extends 'sponsored-intelligence'\n ? { sponsoredIntelligence: SponsoredIntelligencePlatform<TCtxMeta> }\n : S extends 'property-lists'\n ? { propertyLists: PropertyListsPlatform<TCtxMeta> }\n : S extends 'collection-lists'\n ? { collectionLists: CollectionListsPlatform<TCtxMeta> }\n : S extends 'content-standards'\n ? { contentStandards: ContentStandardsPlatform<TCtxMeta> }\n : S extends 'brand-rights'\n ? { brandRights: BrandRightsPlatform<TCtxMeta> }\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n// `{}` (not `Record<string, never>`) is the right \"no extra requirements\"\n// fallthrough — intersects to identity (`P & {} = P`) for specialisms\n// without platform constraints. Same reasoning RequiredCapabilitiesFor\n// documents at its own fall-through. `Record<string, never>` would force\n// the platform to have NO extra properties, collapsing `P & Record<string,\n// never>` to `never` for any platform with handler fields.\n\n/**\n * The framework's createAdcpServer<P> signature uses this intersection to\n * enforce capability claims at compile time. Sketch:\n *\n * ```ts\n * declare function createAdcpServer<P extends DecisioningPlatform>(config: {\n * platform: P & RequiredPlatformsFor<P['capabilities']['specialisms'][number]>;\n * }): AdcpServer;\n * ```\n *\n * NOTE: The companion file is preview-only; the actual `createAdcpServer`\n * doesn't yet enforce this. Wiring lands in a follow-up PR with the\n * framework refactor.\n */\n\n/**\n * Compile-time mapping from a claimed specialism to the capability\n * blocks the framework requires on `DecisioningCapabilities`. Sister\n * type to `RequiredPlatformsFor<S>` — that one constrains the per-\n * specialism platform interfaces; this one constrains capability-block\n * declarations on `capabilities.*`.\n *\n * Mappings populated conservatively in v1.0:\n *\n * - `'brand-rights'` → `{ brand: BrandCapabilities }`. Adopters\n * claiming brand-rights MUST declare `capabilities.brand`. The\n * framework auto-derives `rights: true` from the\n * `BrandRightsPlatform` impl, but adopters still need to declare\n * the block (even as `{}`) so `right_types`, `available_uses`,\n * etc. land coherently in `get_adcp_capabilities`.\n *\n * Other specialisms have no required capability blocks today —\n * `audience_targeting` is recommended for `audience-sync` adopters but\n * not enforced (some sync platforms accept anonymous IDs only and\n * legitimately have no `supported_identifier_types` to declare).\n *\n * The `& Record<string, never>` fallthrough means specialisms not\n * mapped here add no constraint — adopters can claim them without\n * declaring extra capability blocks.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type RequiredCapabilitiesFor<S extends AdCPSpecialism> = S extends 'brand-rights'\n ? { capabilities: { brand: BrandCapabilities } }\n : {};\n// `{}` (not `Record<string, never>`) is the right \"no extra requirements\"\n// fallthrough: it intersects to identity (`P & {} = P`) for specialisms\n// without capability constraints. `Record<string, never>` would force the\n// platform to have NO extra properties, which would reject every real\n// platform impl.\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/server/decisioning/platform.ts"],"sourcesContent":["/**\n * DecisioningPlatform — the top-level interface adopters implement.\n *\n * Per-specialism sub-interfaces (sales, creative, audiences, etc.) are\n * optional; framework's compile-time enforcement (RequiredPlatformsFor<S>)\n * forces the right sub-interfaces based on `capabilities.specialisms[]`.\n *\n * Status: Preview / 6.0. Not yet wired into the framework.\n *\n * @public\n */\n\nimport type { DecisioningCapabilities, BrandCapabilities } from './capabilities';\nimport type { Account, AccountStore } from './account';\nimport type { BuyerAgentRegistry } from './buyer-agent';\nimport type { SessionContext, OnInstructionsError, MaybePromise } from '../create-adcp-server';\nimport type { StatusMappers } from './status-mappers';\nimport type {\n SalesPlatform,\n SalesCorePlatform,\n SalesIngestionPlatform,\n MediaBuyLifecyclePlatform,\n MediaBuyLifecycleCorePlatform,\n MediaBuyLifecycleProposalPlatform,\n} from './specialisms/sales';\nimport type { ProposalManager, Recipe } from './proposal';\nimport type { CreativeBuilderPlatform } from './specialisms/creative';\nimport type { CreativeAdServerPlatform } from './specialisms/creative-ad-server';\nimport type { AudiencePlatform } from './specialisms/audiences';\nimport type { SignalsPlatform } from './specialisms/signals';\nimport type { SponsoredIntelligencePlatform } from './specialisms/sponsored-intelligence';\nimport type { CampaignGovernancePlatform } from './specialisms/campaign-governance';\nimport type { ContentStandardsPlatform } from './specialisms/content-standards';\nimport type { BrandRightsPlatform } from './specialisms/brand-rights';\nimport type { PropertyListsPlatform, CollectionListsPlatform } from './specialisms/lists';\nimport type { AdCPSpecialism } from '../../types/tools.generated';\n\n/**\n * Top-level platform interface. Adopters implement this; framework wires\n * the wire protocol around it.\n *\n * The \"framework owns X\" claims below are the v6.0 wiring contract — the\n * runtime guarantees the framework will provide once this surface is wired.\n * They are NOT yet enforced; this module is preview-only as of the scaffold\n * landing. Treat them as the design contract a v6.0 reviewer should hold\n * the framework refactor to, not as a description of existing behavior.\n *\n * **What the framework owns** (platform implementations DON'T see these):\n * - Wire-shape mapping (MCP tools/list, A2A skill manifest, request/response envelopes)\n * - Authentication + auth-principal extraction; `accounts.resolve()` is the only\n * place the platform translates auth into its tenant model\n * - Idempotency: dedupe + replay handled before dispatch; platforms see clean traffic\n * - `sandbox` boundary: when `AccountReference.sandbox === true`, framework\n * resolves the buyer's sandbox account via `accounts.resolve()`. The platform\n * sees the resolved sandbox `Account` like any other and is responsible for\n * routing reads/writes to its sandbox backend. There is no separate\n * \"dry-run\" mode — sandbox subsumes \"validate against real platform without\n * writing to production.\" Tool-specific `dry_run` flags on `sync_catalogs`\n * and `sync_creatives` are wire fields the platform receives and honors;\n * they are NOT a framework-level mode.\n * - `context` echo: framework round-trips `context` on every response\n * - Task envelopes: `submitted` outcomes are wrapped into A2A Task envelopes /\n * MCP polling responses; `taskHandle.notify` calls dedupe + retry\n * - Schema validation: requests fail before reaching the platform; responses are\n * shape-validated against the wire schema after the platform returns\n *\n * **What the platform owns**: the business decisions in each `SalesPlatform` /\n * `CreativeBuilderPlatform` / `AudiencePlatform` method. Nothing else.\n *\n * ### Cross-specialism dispatch\n *\n * When one specialism handler needs to consult another (canonical case:\n * `brandRights.acquireRights` calling `campaignGovernance.checkGovernance`\n * before granting rights, against a buyer-registered governance binding),\n * the framework does NOT thread a separate `ctx.platform.<specialism>`\n * accessor on `RequestContext`. Two idiomatic patterns; pick by authoring\n * style:\n *\n * **Pattern A — class instance + `this`** (canonical for holdco hubs;\n * `examples/hello_seller_adapter_multi_tenant.ts` is the reference):\n *\n * ```ts\n * class HoldcoAdapter implements DecisioningPlatform<Config, TenantMeta> {\n * campaignGovernance = defineCampaignGovernancePlatform<TenantMeta>({ });\n * brandRights = defineBrandRightsPlatform<TenantMeta>({\n * acquireRights: async (req, ctx) => {\n * const denial = await this.enforceGovernance(tenant, ctx, offering, req);\n * if (denial) return denial;\n *\n * },\n * });\n * private async enforceGovernance(...) {\n * // calls this.campaignGovernance.checkGovernance(...)\n * }\n * }\n * ```\n *\n * **Pattern B — closure capture** (for adopters using `define<X>Platform({...})`\n * factories standalone):\n *\n * ```ts\n * const campaignGovernance = defineCampaignGovernancePlatform<TenantMeta>({ ... });\n * const brandRights = defineBrandRightsPlatform<TenantMeta>({\n * acquireRights: async (req, ctx) => {\n * const govResp = await campaignGovernance.checkGovernance!(checkReq, ctx);\n *\n * },\n * });\n * const platform: DecisioningPlatform<Config, TenantMeta> = {\n * capabilities: { }, accounts: { }, campaignGovernance, brandRights,\n * };\n * ```\n *\n * Both patterns forward the same `RequestContext` (resolved account, agent,\n * authInfo), so tenant invariants hold transitively. Both bypass wire-side\n * validation, idempotency dedup, and mutating-tool annotations — that's\n * correct because you're inside the seller's code, not handling a buyer\n * request, but it means an in-process `checkGovernance` won't be\n * re-deduped if the originating tool is already idempotency-protected.\n * Single-specialism adopters MUST NOT copy this short-circuit: without a\n * co-resident sibling handler, dial out to the registered governance\n * agent URL via the `@adcp/sdk` client instead.\n *\n * Full walkthrough with same-tenant invariant + production caveats:\n * `skills/build-holdco-agent/SKILL.md` § Cross-specialism dispatch.\n *\n * @template TConfig Platform-specific config typed at the call site.\n * Example: `class GAM implements DecisioningPlatform<{ networkId: string }>`.\n * @template TCtxMeta Shape of the platform's opaque ctx_metadata blob — typed\n * once and propagated into `ctx.account.ctx_metadata`,\n * `ctx.ctxMetadata.get()`, and every specialism handler.\n */\nexport interface DecisioningPlatform<TConfig = unknown, TCtxMeta = Record<string, unknown>> {\n /** Capability declaration; single source of truth for get_adcp_capabilities. */\n capabilities: DecisioningCapabilities<TConfig>;\n\n /** Account model + tenant resolution. */\n accounts: AccountStore<TCtxMeta>;\n\n /**\n * Server-level instructions surfaced on the MCP `initialize` response.\n * Use to publish platform facts, decision policy, and trends that buying\n * agents should read before issuing tool calls (e.g., \"publisher-wide\n * brand safety: alcohol disallowed\", \"carbon-aware pricing applies to\n * display impressions only\", \"weekly cutoff Thursday 17:00 UTC\").\n *\n * Two forms:\n *\n * 1. **Static string** — captured once at construction.\n * 2. **Function** `(ctx: SessionContext) => MaybePromise<string | undefined>` —\n * re-evaluated each time `createAdcpServerFromPlatform` runs. Under the\n * canonical `serve({ reuseAgent: false })` flow that is per session, so the\n * closure can surface tenant-shaped prose (per-buyer brand manifests,\n * storefront-platform copy). `serve()` refuses `reuseAgent: true`\n * when this is a function — the function would only fire once for\n * the lifetime of the shared agent.\n *\n * Async functions are supported: the framework calls the function at\n * construction and awaits the returned Promise during MCP `initialize`.\n * A rejected Promise is governed by `onInstructionsError`.\n *\n * MCP-only today. The A2A `AgentCard` analog is `description` (and\n * per-skill `description`); threading platform.instructions into the\n * agent-card builder is tracked separately so MCP and A2A buyers see\n * the same prose.\n *\n * When set on the platform, takes precedence over any `instructions`\n * supplied via `createAdcpServerFromPlatform` opts — same precedence as\n * `agentRegistry`. Adopters with v5 escape-hatch wiring can keep using\n * `opts.instructions`; v6 callers should declare it here.\n *\n * @see {@link OnInstructionsError} for `onInstructionsError` (default `'skip'`).\n */\n instructions?: string | ((ctx: SessionContext) => MaybePromise<string | undefined>);\n\n /**\n * Behavior when a function-form `instructions` callback throws.\n * Defaults to `'skip'` — best-effort prose (brand manifests, marketing\n * copy) should not kill the buyer's session on a registry fetch failure.\n * Set `'fail'` for adopters whose instructions carry load-bearing policy.\n *\n * Threaded through to {@link createAdcpServer} unchanged.\n */\n onInstructionsError?: OnInstructionsError;\n\n /**\n * Buyer-agent identity registry. Optional. When\n * configured, framework calls `agentRegistry.resolve(authInfo)` once per\n * request before `accounts.resolve` and threads the resolved record\n * through `ctx.agent` to specialism handlers.\n *\n * Adopters construct via {@link BuyerAgentRegistry.signingOnly},\n * {@link BuyerAgentRegistry.bearerOnly}, or {@link BuyerAgentRegistry.mixed}\n * depending on their authentication posture. When omitted, `ctx.agent`\n * is always undefined and the framework's request flow is unchanged.\n *\n * The resolved record drives framework status/sandbox gates and\n * `sync_accounts.billing` enforcement against\n * `BuyerAgent.billing_capabilities`.\n */\n agentRegistry?: BuyerAgentRegistry;\n\n /**\n * Native-status mappers (account, mediaBuy, creative, plan).\n *\n * **Optional.** Default behavior treats the platform's status strings as\n * already-canonical AdCP status values (no translation). Provide mappers\n * only when your platform exposes non-AdCP status strings (e.g., GAM's\n * `DELIVERY_PAUSED` → AdCP's `paused`).\n */\n statusMappers?: StatusMappers;\n\n /**\n * Per-tenant capability override. Multi-tenant SaaS adopters (Prebid-style\n * deployments where one server hosts many advertisers, each with different\n * `manualApprovalOperations` / pricing tiers / channel mixes) implement this\n * to scope capabilities per resolved Account. When absent, the framework\n * uses `capabilities` for every request.\n *\n * The framework calls this AFTER `accounts.resolve()` and uses the returned\n * capabilities to gate the rest of the request. The static `agent-card.json`\n * AND `tools/list` shape is derived from `capabilities` (the union) — per-tenant\n * differences are runtime-only.\n */\n getCapabilitiesFor?(\n account: Account<TCtxMeta>\n ): DecisioningCapabilities<TConfig> | Promise<DecisioningCapabilities<TConfig>>;\n\n // Per-specialism sub-interfaces — optional at the type level; required at the\n // call site by RequiredPlatformsFor<S>. v1.0 ships these. Each is parameterized\n // by `TCtxMeta` so adopters get typed `ctx.account.ctx_metadata` access in their\n // method bodies without casting.\n sales?: SalesPlatform<TCtxMeta>;\n /** Primary AdCP 3.2 media-buy lifecycle; compose with `sales` for 3.0/3.1 compatibility routes. */\n mediaBuyLifecycle?: MediaBuyLifecyclePlatform<TCtxMeta>;\n creative?: CreativeBuilderPlatform<TCtxMeta> | CreativeAdServerPlatform<TCtxMeta>;\n audiences?: AudiencePlatform<TCtxMeta>;\n signals?: SignalsPlatform<TCtxMeta>;\n /**\n * Sponsored Intelligence implementation. In AdCP 3.1 this field is required\n * when the agent claims the `sponsored-intelligence` specialism. The\n * framework also derives the legacy wire protocol entry\n * `supported_protocols: ['sponsored_intelligence']` from the SI tool set so\n * protocol-bundle storyboards and 3.0-era consumers keep working.\n */\n sponsoredIntelligence?: SponsoredIntelligencePlatform<TCtxMeta>;\n /** @see DecisioningPlatform — § Cross-specialism dispatch (used as the canonical example: `brandRights.acquireRights` consulting `checkGovernance` before granting rights). */\n campaignGovernance?: CampaignGovernancePlatform<TCtxMeta>;\n contentStandards?: ContentStandardsPlatform<TCtxMeta>;\n propertyLists?: PropertyListsPlatform<TCtxMeta>;\n collectionLists?: CollectionListsPlatform<TCtxMeta>;\n /** @see DecisioningPlatform — § Cross-specialism dispatch (`acquireRights` is the canonical caller into `campaignGovernance.checkGovernance`). */\n brandRights?: BrandRightsPlatform<TCtxMeta>;\n\n /**\n * Optional sibling that owns the proposal side of the two-platform\n * composition (port of `adcp-client-python`'s `ProposalManager`). When\n * present, the framework routes `get_products` and refine traffic to\n * the manager instead of `sales.getProducts`; `sales` stays\n * responsible for media-buy execution. Either side can be mock-backed\n * independently — see `MockProposalManager`.\n *\n * **Status**: primitive types only. Framework dispatch wiring (the\n * five seams that intercept `getProducts`, `createMediaBuy`,\n * `updateMediaBuy`, `getMediaBuyDelivery` to persist drafts, hydrate\n * recipes, and commit on finalize) lands in a follow-up release. v1.5\n * adopters can already implement against this surface; the framework\n * just doesn't drive the lifecycle yet.\n */\n proposalManager?: ProposalManager<Recipe, TCtxMeta>;\n\n // v1.1+ specialisms add: creative-review.\n}\n\n// ---------------------------------------------------------------------------\n// Compile-time capability enforcement\n// ---------------------------------------------------------------------------\n\n/**\n * Maps an AdCP specialism to the platform interface(s) it requires. The\n * framework's `createAdcpServer<P extends DecisioningPlatform>` constrains\n * `P` to satisfy `RequiredPlatformsFor<P['capabilities']['specialisms'][number]>`,\n * forcing every claimed specialism's interface methods to exist.\n *\n * Drop a method, fail compile.\n * Claim a specialism without an implementation, fail compile.\n *\n * The nested-conditional encoding (rather than a union of `S extends X ? {} : never`)\n * is deliberate: when a specialism is claimed without its required platform\n * interface, TypeScript surfaces \"Property 'sales' is missing in type 'P'\"\n * rather than the unactionable \"Type 'P' does not satisfy the constraint 'never'.\"\n *\n * v1.0 covers the 4 specialisms shipping in v1.0; extended in v1.1+.\n * Unknown specialisms (v1.1+ when this module hasn't been updated yet)\n * resolve to an empty requirement — the framework's runtime check is the\n * fallback gate.\n */\n// Sales specialisms — split into two groups by what the adopter actually owns.\n//\n// - **Core sales** specialisms run their own bidding + media-buy lifecycle and\n// are required to implement `SalesCorePlatform` (`getProducts`,\n// `createMediaBuy`, `updateMediaBuy`, `getMediaBuyDelivery`, `getMediaBuys`).\n// The retail-media variants additionally compose ingestion surfaces.\n// - **Ingestion-only** specialisms (today: `sales-social`) front a walled-\n// garden CAPI / audience surface that owns bidding upstream — adopters only\n// need `SalesIngestionPlatform` (`syncCreatives` / `syncCatalogs` /\n// `syncEventSources` / `logEvent` / etc., all optional individually).\n// - **Proposal mode** is a hybrid — only `getProducts` is required; the rest\n// of the lifecycle flows through notification channels.\n//\n// Wired per the AdCP 3.0 GA enum; preview specialisms (sales-streaming-tv,\n// sales-exchange, sales-retail-media) get added when they land in spec.\ntype SalesCoreSpecialism = 'sales-non-guaranteed' | 'sales-guaranteed' | 'sales-broadcast-tv';\ntype SalesCatalogSpecialism = 'sales-catalog-driven';\ntype SalesIngestionSpecialism = 'sales-social';\ntype SalesProposalSpecialism = 'sales-proposal-mode';\n\n// Signal specialisms — both share the SignalsPlatform interface. Marketplace\n// = third-party data brokers; owned = first-party data providers.\ntype SignalSpecialism = 'signal-marketplace' | 'signal-owned';\n\n// Today's spec splits campaign governance into spend-authority + delivery-monitor;\n// both share one CampaignGovernancePlatform interface. When adcp#3329 lands and\n// the spec consolidates to `campaign-governance`, this union shrinks to one\n// value without shape changes.\ntype CampaignGovernanceSpecialism = 'governance-spend-authority' | 'governance-delivery-monitor';\n\n// `TCtxMeta` defaults to `any` so callers that don't pass it explicitly (the\n// common case — `RequiredPlatformsFor<S>` without a second argument) get a\n// constraint that accepts any adopter metadata shape. The `any` is not a\n// soundness escape — adopters declare metadata inside `DecisioningPlatform<_,\n// TCtxMeta>` directly; this constraint exists only to compile-check that\n// claimed specialisms have a matching sub-interface field on the platform.\ntype SalesCorePlatformRequirement<TCtxMeta> =\n | {\n sales: SalesCorePlatform<TCtxMeta> & SalesIngestionPlatform<TCtxMeta>;\n mediaBuyLifecycle?: MediaBuyLifecyclePlatform<TCtxMeta>;\n }\n | {\n sales?: SalesPlatform<TCtxMeta>;\n mediaBuyLifecycle: MediaBuyLifecycleCorePlatform<TCtxMeta>;\n };\n\ntype SalesProposalPlatformRequirement<TCtxMeta> =\n | {\n sales: Required<Pick<SalesPlatform<TCtxMeta>, 'getProducts'>> & SalesIngestionPlatform<TCtxMeta>;\n mediaBuyLifecycle?: MediaBuyLifecyclePlatform<TCtxMeta>;\n }\n | {\n sales?: SalesPlatform<TCtxMeta>;\n mediaBuyLifecycle: MediaBuyLifecycleProposalPlatform<TCtxMeta>;\n };\n\nexport type RequiredPlatformsFor<\n S extends AdCPSpecialism,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TCtxMeta = any,\n> = [S] extends [never]\n ? // Empty specialisms[] (legitimate when the agent's only declared\n // surface is a protocol or custom tool that is not represented as an\n // AdCP specialism).\n // `[S] extends [never]` short-circuits the distributive conditional —\n // without this, a generic `S extends ...` over `never` yields `never`,\n // collapsing `P & RequiredPlatformsFor<...>` to `never` and rejecting\n // every platform value at the call site.\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {}\n : S extends 'creative-template' | 'creative-generative' | 'creative-transformers'\n ? { creative: CreativeBuilderPlatform<TCtxMeta> }\n : S extends 'creative-ad-server'\n ? { creative: CreativeAdServerPlatform<TCtxMeta> }\n : S extends SalesCoreSpecialism\n ? SalesCorePlatformRequirement<TCtxMeta>\n : S extends SalesCatalogSpecialism\n ? { sales: SalesCorePlatform<TCtxMeta> & SalesIngestionPlatform<TCtxMeta> }\n : S extends SalesIngestionSpecialism\n ? // Walled-garden specialisms (sales-social, today). Bidding owned upstream\n // — only the ingestion surface is required. Adopters can voluntarily\n // implement core methods on the same `sales` object; the SalesPlatform\n // alias accepts both shapes.\n { sales: SalesIngestionPlatform<TCtxMeta> }\n : S extends SalesProposalSpecialism\n ? // Proposal-mode adopters only need `getProducts` — the rest of the\n // lifecycle flows through `publishStatusChange` on\n // `resource_type: 'proposal'`. Ingestion is optional.\n SalesProposalPlatformRequirement<TCtxMeta>\n : S extends 'audience-sync'\n ? { audiences: AudiencePlatform<TCtxMeta> }\n : S extends SignalSpecialism\n ? { signals: SignalsPlatform<TCtxMeta> }\n : S extends CampaignGovernanceSpecialism\n ? { campaignGovernance: CampaignGovernancePlatform<TCtxMeta> }\n : S extends 'sponsored-intelligence'\n ? { sponsoredIntelligence: SponsoredIntelligencePlatform<TCtxMeta> }\n : S extends 'property-lists'\n ? { propertyLists: PropertyListsPlatform<TCtxMeta> }\n : S extends 'collection-lists'\n ? { collectionLists: CollectionListsPlatform<TCtxMeta> }\n : S extends 'content-standards'\n ? { contentStandards: ContentStandardsPlatform<TCtxMeta> }\n : S extends 'brand-rights'\n ? { brandRights: BrandRightsPlatform<TCtxMeta> }\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n// `{}` (not `Record<string, never>`) is the right \"no extra requirements\"\n// fallthrough — intersects to identity (`P & {} = P`) for specialisms\n// without platform constraints. Same reasoning RequiredCapabilitiesFor\n// documents at its own fall-through. `Record<string, never>` would force\n// the platform to have NO extra properties, collapsing `P & Record<string,\n// never>` to `never` for any platform with handler fields.\n\n/**\n * The framework's createAdcpServer<P> signature uses this intersection to\n * enforce capability claims at compile time. Sketch:\n *\n * ```ts\n * declare function createAdcpServer<P extends DecisioningPlatform>(config: {\n * platform: P & RequiredPlatformsFor<P['capabilities']['specialisms'][number]>;\n * }): AdcpServer;\n * ```\n *\n * NOTE: The companion file is preview-only; the actual `createAdcpServer`\n * doesn't yet enforce this. Wiring lands in a follow-up PR with the\n * framework refactor.\n */\n\n/**\n * Compile-time mapping from a claimed specialism to the capability\n * blocks the framework requires on `DecisioningCapabilities`. Sister\n * type to `RequiredPlatformsFor<S>` — that one constrains the per-\n * specialism platform interfaces; this one constrains capability-block\n * declarations on `capabilities.*`.\n *\n * Mappings populated conservatively in v1.0:\n *\n * - `'brand-rights'` → `{ brand: BrandCapabilities }`. Adopters\n * claiming brand-rights MUST declare `capabilities.brand`. The\n * framework auto-derives `rights: true` from the\n * `BrandRightsPlatform` impl, but adopters still need to declare\n * the block (even as `{}`) so `right_types`, `available_uses`,\n * etc. land coherently in `get_adcp_capabilities`.\n *\n * Other specialisms have no required capability blocks today —\n * `audience_targeting` is recommended for `audience-sync` adopters but\n * not enforced (some sync platforms accept anonymous IDs only and\n * legitimately have no `supported_identifier_types` to declare).\n *\n * The `& Record<string, never>` fallthrough means specialisms not\n * mapped here add no constraint — adopters can claim them without\n * declaring extra capability blocks.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type RequiredCapabilitiesFor<S extends AdCPSpecialism> = S extends 'brand-rights'\n ? { capabilities: { brand: BrandCapabilities } }\n : {};\n// `{}` (not `Record<string, never>`) is the right \"no extra requirements\"\n// fallthrough: it intersects to identity (`P & {} = P`) for specialisms\n// without capability constraints. `Record<string, never>` would force the\n// platform to have NO extra properties, which would reject every real\n// platform impl.\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"from-platform.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/from-platform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"from-platform.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/from-platform.ts"],"names":[],"mappings":"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"}
@@ -1017,8 +1017,8 @@ function createAdcpServerFromPlatform(platform, opts) {
1017
1017
  const som = somCandidate != null && somCandidate.length > 0 ? somCandidate : void 0;
1018
1018
  const fc = platform.capabilities.frequency_capping;
1019
1019
  const targeting = platform.capabilities.targeting ? (0, import_capabilities.normalizeTargetingCapabilities)(platform.capabilities.targeting) : void 0;
1020
- const hasSalesPlatform = platform.sales != null || platform.proposalManager != null;
1021
- const supportsProposals = platform.capabilities.supportsProposals ?? (platform.proposalManager != null ? true : hasSalesPlatform ? false : void 0);
1020
+ const hasSalesPlatform = platform.sales != null || platform.mediaBuyLifecycle != null || platform.proposalManager != null;
1021
+ const supportsProposals = platform.capabilities.supportsProposals ?? (platform.proposalManager != null || platform.mediaBuyLifecycle?.requestProposals != null || platform.mediaBuyLifecycle?.refineProposals != null ? true : hasSalesPlatform ? false : void 0);
1022
1022
  const hasMediaBuyProjection = hasSalesPlatform || at != null || ct != null || cs != null || som != null || fc != null || targeting != null || supportsProposals !== void 0;
1023
1023
  const configuredAdcpVersion = opts.adcpVersion ?? import_version.ADCP_VERSION;
1024
1024
  const configuredRelease = parseAdcpRelease(configuredAdcpVersion);
@@ -1147,6 +1147,23 @@ function createAdcpServerFromPlatform(platform, opts) {
1147
1147
  }
1148
1148
  };
1149
1149
  const ctxFor = makeCtxFor(effectiveCtxMetadata);
1150
+ const platformProposalNegotiation = buildProposalNegotiationHandlers(
1151
+ platform,
1152
+ taskRegistry,
1153
+ taskWebhookEmit,
1154
+ observability,
1155
+ fwLogger,
1156
+ {
1157
+ allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,
1158
+ autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true
1159
+ },
1160
+ ctxFor
1161
+ );
1162
+ if (platformProposalNegotiation && opts.proposalNegotiation) {
1163
+ throw new import_validate_platform.PlatformConfigError(
1164
+ "Configure refine_proposals through platform.mediaBuyLifecycle or opts.proposalNegotiation, not both"
1165
+ );
1166
+ }
1150
1167
  if (opts.resolveIdempotencyPrincipal === void 0) {
1151
1168
  const env = process.env.NODE_ENV;
1152
1169
  const inDevAllowlist = env === "test" || env === "development";
@@ -1159,6 +1176,7 @@ function createAdcpServerFromPlatform(platform, opts) {
1159
1176
  }
1160
1177
  const config = {
1161
1178
  ...opts,
1179
+ requireCompactMutationAccountScope: true,
1162
1180
  taskRegistry,
1163
1181
  ...autoSeedStore != null && { testController: makeAutoSeedBridge(autoSeedStore) },
1164
1182
  ...projectedCapabilitiesConfig != null && { capabilities: projectedCapabilitiesConfig },
@@ -1182,17 +1200,14 @@ function createAdcpServerFromPlatform(platform, opts) {
1182
1200
  // Pool-derived stores override the spread above when adopters supplied
1183
1201
  // `pool` but no explicit per-store opt. Explicit values still win.
1184
1202
  ...effectiveIdempotency !== void 0 && { idempotency: effectiveIdempotency },
1185
- // v6 default principal resolver: every mutating tool requires an
1186
- // idempotency principal (the v5 createAdcpServer surface returns
1187
- // SERVICE_UNAVAILABLE when one isn't wired). v6 platform adopters
1188
- // who skip the explicit hook get a sensible default — auth client
1189
- // id when present (multi-tenant: each buyer owns its own
1190
- // idempotency namespace), else session key, else account id
1191
- // (single-tenant fallback). Adopters override by passing
1192
- // resolveIdempotencyPrincipal in opts; the spread above keeps
1193
- // explicit values winning. Closed by the Emma matrix surfacing
1194
- // SERVICE_UNAVAILABLE on every v6 mutating call.
1195
- resolveIdempotencyPrincipal: opts.resolveIdempotencyPrincipal ?? ((ctx) => ctx.authInfo?.clientId ?? ctx.sessionKey ?? ctx.account?.id ?? void 0),
1203
+ // Preserve the SDK 13 principal namespace for established tools so a
1204
+ // retry spanning a rolling 13→14 deployment still finds its durable
1205
+ // idempotency entry. The new compact lifecycle uses credential-kind
1206
+ // namespacing and refuses session/account fallbacks, preventing
1207
+ // cross-credential collisions without reopening a duplicate-buy window
1208
+ // on create_media_buy/update_media_buy. Explicit adopter resolvers still
1209
+ // win for every tool.
1210
+ resolveIdempotencyPrincipal: opts.resolveIdempotencyPrincipal ?? ((ctx, _params, toolName) => import_create_adcp_server.COMPACT_MEDIA_BUY_MUTATION_TOOLS.has(toolName) ? authenticatedPrincipalFor(ctx) : ctx.authInfo?.clientId ?? ctx.sessionKey ?? ctx.account?.id ?? void 0),
1196
1211
  resolveAccount: async (ref, ctx) => {
1197
1212
  const start = Date.now();
1198
1213
  let resolved = false;
@@ -1294,6 +1309,7 @@ function createAdcpServerFromPlatform(platform, opts) {
1294
1309
  mergeOpts,
1295
1310
  defaultCreativeWireMode
1296
1311
  ),
1312
+ proposalNegotiation: platformProposalNegotiation ?? opts.proposalNegotiation,
1297
1313
  creative: mergeHandlers(
1298
1314
  legacyHandlers.creative,
1299
1315
  buildCreativeHandlers(
@@ -2093,6 +2109,17 @@ function taskOwnerScopeFor(ctx, accountId) {
2093
2109
  }
2094
2110
  return `account:${accountId}`;
2095
2111
  }
2112
+ function authenticatedPrincipalFor(ctx) {
2113
+ if (ctx.agent?.agent_url) return `agent:${ctx.agent.agent_url}`;
2114
+ const credential = ctx.authInfo?.credential;
2115
+ if (credential?.kind === "http_sig") return `http_sig:${credential.agent_url}`;
2116
+ if (credential?.kind === "oauth") return `oauth:${credential.client_id}`;
2117
+ if (credential?.kind === "api_key") return `api_key:${credential.key_id}`;
2118
+ if (typeof ctx.authInfo?.clientId === "string" && ctx.authInfo.clientId.length > 0) {
2119
+ return `client:${ctx.authInfo.clientId}`;
2120
+ }
2121
+ return void 0;
2122
+ }
2096
2123
  function hasPushNotificationConfig(params) {
2097
2124
  return params != null && typeof params === "object" && params.push_notification_config !== void 0;
2098
2125
  }
@@ -2755,11 +2782,167 @@ function validatePushNotificationOperationId(operationId) {
2755
2782
  }
2756
2783
  return { ok: true };
2757
2784
  }
2785
+ function buildProposalNegotiationHandlers(platform, taskRegistry, taskWebhookEmit, observability, logger, pushOpts, ctxFor) {
2786
+ const lifecycle = platform.mediaBuyLifecycle;
2787
+ if (!lifecycle?.refineProposals) return void 0;
2788
+ if (!lifecycle.proposalRefinement) {
2789
+ throw new import_validate_platform.PlatformConfigError(
2790
+ "mediaBuyLifecycle.refineProposals requires mediaBuyLifecycle.proposalRefinement capability metadata"
2791
+ );
2792
+ }
2793
+ return {
2794
+ capabilities: lifecycle.proposalRefinement,
2795
+ resolveScope: (ctx) => {
2796
+ const accountId = ctx.account?.id;
2797
+ if (!accountId) {
2798
+ throw new import_async_outcome.AdcpError("ACCOUNT_NOT_FOUND", {
2799
+ message: "refine_proposals requires an authenticated account scope",
2800
+ recovery: "correctable"
2801
+ });
2802
+ }
2803
+ const principalId = authenticatedPrincipalFor(ctx);
2804
+ if (!principalId) {
2805
+ throw new import_async_outcome.AdcpError("AUTH_REQUIRED", {
2806
+ message: "refine_proposals requires an authenticated buyer principal",
2807
+ recovery: "correctable"
2808
+ });
2809
+ }
2810
+ return { tenant_id: accountId, account_id: accountId, principal_id: principalId };
2811
+ },
2812
+ refineProposals: async (params, ctx) => {
2813
+ const request = params;
2814
+ const reqCtx = ctxFor(ctx, request);
2815
+ if (!reqCtx.account?.id) {
2816
+ throw new import_async_outcome.AdcpError("ACCOUNT_NOT_FOUND", {
2817
+ message: "refine_proposals requires an authenticated account scope",
2818
+ recovery: "correctable"
2819
+ });
2820
+ }
2821
+ return projectSync(
2822
+ async () => {
2823
+ const push = extractPushConfig(request, logger, {
2824
+ allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls
2825
+ });
2826
+ const result = await lifecycle.refineProposals(params, reqCtx);
2827
+ return routeIfHandoff(
2828
+ taskRegistry,
2829
+ {
2830
+ tool: "refine_proposals",
2831
+ accountId: reqCtx.account.id,
2832
+ ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),
2833
+ pushNotificationUrl: push.url,
2834
+ pushNotificationToken: push.token,
2835
+ pushNotificationOperationId: push.operationId,
2836
+ emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,
2837
+ autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,
2838
+ observability,
2839
+ logger
2840
+ },
2841
+ result,
2842
+ (value) => value
2843
+ );
2844
+ },
2845
+ (value) => value
2846
+ );
2847
+ }
2848
+ };
2849
+ }
2758
2850
  function buildMediaBuyHandlers(platform, taskRegistry, taskWebhookEmit, observability, logger, pushOpts, ctxFor, ctxMetadataStore, mediaBuyStore, proposalStore, legacyFormatConverter, canonicalFormatLegacyResolver, creativeWireMode) {
2759
2851
  const sales = platform.sales;
2852
+ const lifecycle = platform.mediaBuyLifecycle;
2853
+ const getMediaBuyDelivery = lifecycle?.getMediaBuyDelivery ?? sales?.getMediaBuyDelivery;
2854
+ const getMediaBuys = lifecycle?.getMediaBuys ?? sales?.getMediaBuys;
2760
2855
  const proposalManager = platform.proposalManager;
2761
- if (!sales && !proposalManager) return void 0;
2856
+ if (!sales && !lifecycle && !proposalManager) return void 0;
2857
+ const dispatchCompactMutation = async (tool, params, ctx, invoke) => {
2858
+ return projectSync(
2859
+ async () => {
2860
+ if (ctx.authInfo === void 0 && ctx.agent === void 0) {
2861
+ throw new import_async_outcome.AdcpError("AUTH_MISSING", {
2862
+ message: `${tool} requires an authenticated buyer principal`,
2863
+ recovery: "correctable"
2864
+ });
2865
+ }
2866
+ const accountId = ctx.account?.id;
2867
+ if (!accountId) {
2868
+ throw new import_async_outcome.AdcpError("ACCOUNT_NOT_FOUND", {
2869
+ message: `${tool} requires a resolved account scope`,
2870
+ recovery: "correctable"
2871
+ });
2872
+ }
2873
+ const principalId = authenticatedPrincipalFor(ctx);
2874
+ if (!principalId) {
2875
+ throw new import_async_outcome.AdcpError("AUTH_MISSING", {
2876
+ message: `${tool} requires an authenticated buyer principal`,
2877
+ recovery: "correctable"
2878
+ });
2879
+ }
2880
+ const callerMutationScope = Object.freeze({
2881
+ tenant_id: accountId,
2882
+ account_id: accountId,
2883
+ principal_id: principalId
2884
+ });
2885
+ const reqCtx = ctxFor({ ...ctx, callerMutationScope }, params);
2886
+ const push = extractPushConfig(params, logger, {
2887
+ allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls
2888
+ });
2889
+ const result = await invoke(reqCtx);
2890
+ return routeIfHandoff(
2891
+ taskRegistry,
2892
+ {
2893
+ tool,
2894
+ accountId,
2895
+ ownerScope: taskOwnerScopeFor(ctx, accountId),
2896
+ pushNotificationUrl: push.url,
2897
+ pushNotificationToken: push.token,
2898
+ pushNotificationOperationId: push.operationId,
2899
+ emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,
2900
+ autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,
2901
+ observability,
2902
+ logger
2903
+ },
2904
+ result,
2905
+ (value) => value
2906
+ );
2907
+ },
2908
+ (value) => value
2909
+ );
2910
+ };
2762
2911
  return {
2912
+ ...lifecycle?.listProducts && {
2913
+ listProducts: async (...[params, ctx]) => {
2914
+ const reqCtx = ctxFor(ctx, params);
2915
+ return projectSync(
2916
+ () => lifecycle.listProducts(params, reqCtx),
2917
+ (value) => value
2918
+ );
2919
+ }
2920
+ },
2921
+ ...lifecycle?.requestProposals && {
2922
+ requestProposals: async (...[params, ctx]) => dispatchCompactMutation(
2923
+ "request_proposals",
2924
+ params,
2925
+ ctx,
2926
+ (reqCtx) => lifecycle.requestProposals(params, reqCtx)
2927
+ )
2928
+ },
2929
+ ...lifecycle?.declineProposals && {
2930
+ declineProposals: async (...[params, ctx]) => dispatchCompactMutation(
2931
+ "decline_proposals",
2932
+ params,
2933
+ ctx,
2934
+ (reqCtx) => lifecycle.declineProposals(params, reqCtx)
2935
+ )
2936
+ },
2937
+ ...lifecycle?.buyProducts && {
2938
+ buyProducts: async (...[params, ctx]) => dispatchCompactMutation("buy_products", params, ctx, (reqCtx) => lifecycle.buyProducts(params, reqCtx))
2939
+ },
2940
+ ...lifecycle?.acceptProposal && {
2941
+ acceptProposal: async (...[params, ctx]) => dispatchCompactMutation("accept_proposal", params, ctx, (reqCtx) => lifecycle.acceptProposal(params, reqCtx))
2942
+ },
2943
+ ...lifecycle?.controlMediaBuy && {
2944
+ controlMediaBuy: async (...[params, ctx]) => dispatchCompactMutation("control_media_buy", params, ctx, (reqCtx) => lifecycle.controlMediaBuy(params, reqCtx))
2945
+ },
2763
2946
  ...(sales?.getProducts || proposalManager) && {
2764
2947
  getProducts: async (...[params, ctx]) => {
2765
2948
  const responseWireMode = creativeWireModeForRequest(
@@ -3107,7 +3290,7 @@ function buildMediaBuyHandlers(platform, taskRegistry, taskWebhookEmit, observab
3107
3290
  );
3108
3291
  }
3109
3292
  },
3110
- ...sales?.getMediaBuyDelivery && {
3293
+ ...getMediaBuyDelivery && {
3111
3294
  getMediaBuyDelivery: async (...[params, ctx]) => {
3112
3295
  const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);
3113
3296
  const reqCtx = ctxFor(ctx, params);
@@ -3127,7 +3310,7 @@ function buildMediaBuyHandlers(platform, taskRegistry, taskWebhookEmit, observab
3127
3310
  }
3128
3311
  return projectSync(
3129
3312
  async () => {
3130
- const result = await sales.getMediaBuyDelivery(asValidatedDomainRequest(params), reqCtx);
3313
+ const result = await getMediaBuyDelivery(asValidatedDomainRequest(params), reqCtx);
3131
3314
  warnIfTruncatedMultiIdResponse(
3132
3315
  "getMediaBuyDelivery",
3133
3316
  "media_buy_ids",
@@ -3160,13 +3343,13 @@ function buildMediaBuyHandlers(platform, taskRegistry, taskWebhookEmit, observab
3160
3343
  // platform-derived handler when absent lets `mergeHandlers` pick up the
3161
3344
  // adopter's custom handler from `opts.legacyHandlers.mediaBuy` instead of throwing
3162
3345
  // `sales.getMediaBuys is not a function`.
3163
- ...sales?.getMediaBuys && {
3346
+ ...getMediaBuys && {
3164
3347
  getMediaBuys: async (...[params, ctx]) => {
3165
3348
  const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);
3166
3349
  const reqCtx = ctxFor(ctx, params);
3167
3350
  return projectSync(
3168
3351
  async () => {
3169
- const result = await sales.getMediaBuys(asValidatedDomainRequest(params), reqCtx);
3352
+ const result = await getMediaBuys(asValidatedDomainRequest(params), reqCtx);
3170
3353
  warnIfTruncatedMultiIdResponse(
3171
3354
  "getMediaBuys",
3172
3355
  "media_buy_ids",