@adcp/sdk 14.0.0-beta.12 → 14.0.0-beta.13
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.
- package/dist/lib/index.d.mts +3 -3
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +3 -1
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +2 -2
- package/dist/lib/server/create-adcp-server.d.ts +2 -2
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +6 -1
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +6 -1
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.d.mts +3 -3
- package/dist/lib/server/decisioning/index.d.ts +3 -3
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +24 -17
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +24 -17
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +71 -42
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +75 -43
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +15 -21
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +15 -21
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +100 -30
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +100 -30
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.d.mts +30 -16
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts +30 -16
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.js +40 -20
- package/dist/lib/server/decisioning/runtime/task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.mjs +38 -19
- package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.d.mts +2 -2
- package/dist/lib/server/decisioning/runtime/to-context.d.ts +2 -2
- package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.js +2 -2
- package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.mjs +2 -2
- package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.mts +3 -2
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +3 -2
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.d.mts +10 -10
- package/dist/lib/server/decisioning/specialisms/creative.d.ts +10 -10
- package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +11 -2
- package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.mjs +11 -2
- package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
- package/dist/lib/testing/storyboard/index.d.mts +1 -1
- package/dist/lib/testing/storyboard/index.d.ts +1 -1
- package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/index.js.map +1 -1
- package/dist/lib/testing/storyboard/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/loader.js +14 -0
- package/dist/lib/testing/storyboard/loader.js.map +1 -1
- package/dist/lib/testing/storyboard/loader.mjs +14 -0
- package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/phase-condition.d.mts +41 -0
- package/dist/lib/testing/storyboard/phase-condition.d.ts +42 -0
- package/dist/lib/testing/storyboard/phase-condition.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/phase-condition.js +215 -0
- package/dist/lib/testing/storyboard/phase-condition.js.map +1 -0
- package/dist/lib/testing/storyboard/phase-condition.mjs +189 -0
- package/dist/lib/testing/storyboard/phase-condition.mjs.map +1 -0
- package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.js +15 -2
- package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +15 -2
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +57 -23
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +57 -23
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/task-map.js +6 -2
- package/dist/lib/testing/storyboard/task-map.js.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +6 -2
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.d.mts +5 -4
- package/dist/lib/testing/storyboard/types.d.ts +5 -4
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.js +60 -4
- package/dist/lib/testing/storyboard/webhook-assertions.js.map +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.mjs +60 -4
- package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.d.mts +15 -0
- package/dist/lib/testing/storyboard/webhook-receiver.d.ts +15 -0
- package/dist/lib/testing/storyboard/webhook-receiver.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.js +57 -6
- package/dist/lib/testing/storyboard/webhook-receiver.js.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +57 -6
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/testing/types.d.mts +2 -0
- package/dist/lib/testing/types.d.ts +2 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/testing/types.js.map +1 -1
- package/dist/lib/types/core.generated.d.mts +5 -2
- package/dist/lib/types/core.generated.d.ts +5 -2
- package/dist/lib/types/core.generated.d.ts.map +1 -1
- package/dist/lib/types/core.generated.js.map +1 -1
- package/dist/lib/types/index.d.mts +1 -1
- package/dist/lib/types/index.d.ts +1 -1
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/types/list-transformers.d.ts +9 -5
- package/dist/lib/types/schemas.generated.d.ts +21 -298
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +5 -2
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/schemas.generated.mjs +4 -2
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/types/server-payload-aliases.d.mts +2 -1
- package/dist/lib/types/server-payload-aliases.d.ts +2 -1
- package/dist/lib/types/server-payload-aliases.d.ts.map +1 -1
- package/dist/lib/types/server-payload-aliases.js.map +1 -1
- package/dist/lib/types/tools.generated.d.mts +5 -2
- package/dist/lib/types/tools.generated.d.ts +5 -2
- package/dist/lib/types/tools.generated.d.ts.map +1 -1
- package/dist/lib/types/tools.generated.js.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.d.mts +5 -1
- package/dist/lib/utils/build-creative-return-builders.d.ts +5 -1
- package/dist/lib/utils/build-creative-return-builders.d.ts.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.js +9 -3
- package/dist/lib/utils/build-creative-return-builders.js.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.mjs +7 -2
- package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
- package/dist/lib/utils/response-unwrapper.js +1 -1
- package/dist/lib/utils/response-unwrapper.js.map +1 -1
- package/dist/lib/utils/response-unwrapper.mjs +1 -1
- package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
- package/dist/lib/validation/schema-loader.d.ts.map +1 -1
- package/dist/lib/validation/schema-loader.js +16 -7
- package/dist/lib/validation/schema-loader.js.map +1 -1
- package/dist/lib/validation/schema-loader.mjs +16 -7
- package/dist/lib/validation/schema-loader.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/llms.txt +2 -2
- package/docs/migration-5.x-to-6.x.md +3 -2
- package/docs/migration-task-registry-scoping.md +61 -0
- package/examples/hello_seller_adapter_guaranteed.ts +1 -1
- package/package.json +4 -4
- package/skills/build-decisioning-creative-template/SKILL.md +2 -2
- package/skills/build-decisioning-platform/SKILL.md +4 -2
- package/skills/build-decisioning-platform/advanced/REFERENCE.md +7 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/from-platform.ts"],"sourcesContent":["/**\n * Build an `AdcpServer` from a `DecisioningPlatform` impl.\n *\n * v6.0 alpha entry point. Translates the per-specialism platform interface\n * into the framework's existing handler-style config and delegates to\n * `createAdcpServer()`. This means every framework primitive — idempotency,\n * RFC 9421 signing, governance, schema validation, state store, MCP/A2A\n * wire mapping, sandbox boundary — applies unchanged. The new code is the\n * adapter shim, not a forked runtime.\n *\n * **Adopter shape (unified hybrid):** each HITL-eligible tool is a single\n * method. The method returns the wire success arm (sync fast path) OR\n * `ctx.handoffToTask(fn)` to promote the call to a background task (HITL\n * slow path). Adopters branch per-call; framework detects the `TaskHandoff`\n * marker and dispatches accordingly:\n *\n * - Sync path: framework awaits the return value in foreground; projects\n * it to the wire success arm. `throw new AdcpError(...)` projects to\n * the wire `adcp_error` envelope.\n * - HITL path: framework detects the `TaskHandoff` marker, allocates\n * `taskId`, returns the submitted envelope to the buyer immediately,\n * then runs the handoff function in background. The function's return\n * value becomes the task's terminal `result`; thrown `AdcpError` becomes\n * the terminal `error`.\n *\n * Generic thrown errors (`Error`, `TypeError`) fall through to the\n * framework's `SERVICE_UNAVAILABLE` mapping.\n *\n * **Wired surface (6.0):** `SalesPlatform` (14 tools — 3 required core +\n * 11 optional; unified hybrid on `create_media_buy` / `sync_creatives`),\n * `CreativeBuilderPlatform` (build_creative / sync_creatives unified\n * hybrid, optional preview_creative sync-only, optional refineCreative),\n * `AudiencePlatform.syncAudiences`, `SignalsPlatform` (get_signals /\n * activate_signal), `AccountStore` (reportUsage, getAccountFinancials),\n * `ContentStandardsPlatform`, `CampaignGovernancePlatform`,\n * `TenantRegistry` (multi-tenant health), `createPostgresTaskRegistry`,\n * `tasks/get` wire handler, per-server + module-level `publishStatusChange`.\n *\n * **Still deferred (rc.1+):** MCP Resources subscription projection for\n * `publishStatusChange`. The no-account tool surface (`preview_creative`,\n * `list_creative_formats`, `provide_performance_feedback`) is now typed\n * via `NoAccountCtx<TCtxMeta>` — handlers receive `ctx.account: Account |\n * undefined` and must narrow before reading `ctx_metadata`.\n *\n * Status: Preview / 6.0. Not yet exported from the public `./server`\n * subpath; reach in via `@adcp/sdk/server/decisioning/runtime` for\n * spike experimentation only.\n *\n * @public\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport type { AdcpServer } from '../../adcp-server';\nimport {\n createAdcpServer,\n COMPACT_MEDIA_BUY_MUTATION_TOOLS,\n type AdcpServerConfig,\n type MediaBuyHandlers,\n type ProposalNegotiationHandlers,\n type CreativeHandlers,\n type EventTrackingHandlers,\n type AccountHandlers,\n type SignalsHandlers,\n type SponsoredIntelligenceHandlers,\n type GovernanceHandlers,\n type BrandRightsHandlers,\n type HandlerContext,\n type AdcpServerToolName,\n} from '../../create-adcp-server';\nimport type { DecisioningPlatform, RequiredPlatformsFor, RequiredCapabilitiesFor } from '../platform';\nimport type { ComplianceTestingCapabilities } from '../capabilities';\nimport { normalizeTargetingCapabilities } from '../capabilities';\nimport { isAdcpVersionAtLeast } from '../../../utils/adcp-version-config';\nimport type { Account, ResolvedAuthInfo, ResolveContext } from '../account';\nimport {\n AccountNotFoundError,\n refAccountId,\n toWireAccount,\n toWireSyncAccountRow,\n toWireSyncGovernanceRow,\n type SyncAccountsResultRow,\n} from '../account';\nimport type { BuyerAgent, BuyerAgentBillingMode, BuyerAgentRegistry } from '../buyer-agent';\nimport { suggestBilling } from '../buyer-agent';\nimport { AdcpError, type AdcpStructuredError } from '../async-outcome';\nimport type { CreativeBuilderPlatform } from '../specialisms/creative';\nimport type { CreativeAdServerPlatform } from '../specialisms/creative-ad-server';\nimport type { CanonicalPreviewCreativeRequest } from '../../../v2/projection/creative-delivery';\nimport type { Audience } from '../specialisms/audiences';\nimport type { RequestContext } from '../context';\nimport {\n maybeInterceptFinalize,\n maybePersistDraftAfterGetProducts,\n maybeReserveProposalForCreateMediaBuy,\n finalizeProposalConsumption,\n releaseProposalReservation,\n maybeHydrateRecipesForMediaBuyId,\n type ReservedProposal,\n type Recipe as ProposalRecipe,\n} from '../proposal';\nimport type {\n AccountReference,\n BillingParty,\n BrandReference,\n BuildCreativeMultiSuccess,\n BuildCreativeSuccess,\n CreativeManifest,\n GetAdCPCapabilitiesResponse,\n PaymentTerms,\n SyncGovernanceRequest,\n} from '../../../types/tools.generated';\nimport type { RequireCacheScopeWhenProducts, ServerPayload } from '../../../types/server-payload';\nimport { rollupOptimizationMetricsFromProducts } from '../../../utils/capability-rollups';\nimport { adcpError, sanitizeStructuredAdcpError, type AdcpErrorResponse } from '../../errors';\nimport { resolveCredentialPolicyForTool, scanArgsForCredentials, type CredentialPolicy } from '../../credential-policy';\nimport { validatePlatform, PlatformConfigError } from './validate-platform';\nimport { validateSpecialismRequiredTools, formatSpecialismIssue } from '../validate-specialisms';\nimport type { AdcpLogger } from '../../create-adcp-server';\nimport { buildRequestContext, buildHandoffContext } from './to-context';\nimport {\n type CtxMetadataStore,\n type ResourceKind,\n createCtxMetadataStore,\n pgCtxMetadataStore,\n getCtxMetadataMigration,\n stripCtxMetadata,\n stripImplementationConfig,\n} from '../../ctx-metadata';\nimport { createIdempotencyStore, type IdempotencyStore } from '../../idempotency';\nimport { pgBackend, getIdempotencyMigration } from '../../idempotency/backends/pg';\nimport type {\n MediaBuyStore,\n CreateMediaBuyInputForStore,\n CreateMediaBuyResultForStore,\n UpdateMediaBuyInputForStore,\n GetMediaBuysResultForStore,\n} from '../../media-buy-store';\nimport { createPostgresTaskRegistry, getDecisioningTaskRegistryMigration } from './postgres-task-registry';\nimport type { PgQueryable } from '../../postgres-task-store';\nimport { isTaskHandoff, _extractHandoffEntry, type TaskHandoff } from '../async-outcome';\nimport { _extractResponseSummaryEntry } from '../response-summary';\nimport { productsResponse } from '../../responses';\nimport { TOOL_ENTITY_FIELDS } from './entity-hydration.generated';\nimport { z } from 'zod';\nimport { createInMemoryTaskRegistry, type TaskRegistry, type TaskRecord, type TaskStatus } from './task-registry';\nimport { protocolForTool, SPEC_WEBHOOK_TASK_TYPES } from './protocol-for-tool';\n\n/**\n * Default logger when adopters don't supply `opts.logger`. `debug` /\n * `info` are no-op; `warn` / `error` route to console so framework\n * warnings (merge-seam collisions, SSRF rejections, observability hook\n * misuse) surface during development. Adopters wiring `pino`/`bunyan`\n * supply all four levels via `opts.logger`.\n */\nconst DEFAULT_FRAMEWORK_LOGGER: AdcpLogger = {\n debug: () => {},\n info: () => {},\n // eslint-disable-next-line no-console\n warn: console.warn.bind(console),\n // eslint-disable-next-line no-console\n error: console.error.bind(console),\n};\nimport { createInMemoryStatusChangeBus, type StatusChangeBus, type PublishStatusChangeOpts } from '../status-changes';\nimport { createComplyController, type ComplyControllerConfig } from '../../../testing/comply-controller';\nimport type { TestControllerBridge } from '../../test-controller-bridge';\nimport { mergeSeedProduct } from '../../../testing/seed-merge';\nimport {\n getSdkServer,\n setToolVisibilityResolver,\n wrapRegisteredToolHandler,\n wrapSdkRequestHandler,\n} from '../../adcp-server';\nimport { isSandboxOrMockAccount } from '../../account-mode';\nimport { recordResolvedAccountMode, hasObservedLiveMode } from './observed-modes';\nimport type { Product } from '../../../types/tools.generated';\nimport { normalizeErrors } from '../../normalize-errors';\nimport { redactCredentialPatterns } from '../../redact';\nimport {\n CreativeFormatProjectionError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n stripLegacyCreativeIdentity,\n} from '../../../v2/projection/creative-delivery';\nimport {\n projectV1ProductToV2,\n type LegacyFormatConversionContext,\n type LegacyFormatConverter,\n type LegacyFormatResolutionContext,\n type LegacyFormatResolver,\n} from '../../../v2/projection/v1-to-v2';\nimport {\n legacyFormatConverterFromCatalogSnapshots,\n type ProjectionCatalogSnapshot,\n} from '../../../v2/projection/catalog-snapshot';\nimport type {\n CanonicalSyncCreativeAsset,\n CanonicalCreateMediaBuyRequest,\n CanonicalGetProductsRequest,\n CanonicalListCreativesRequest,\n CanonicalUpdateMediaBuyRequest,\n} from '../../../v2/projection/creative-delivery';\nimport { toCanonicalOnlyResponse } from '../../../v2/projection/augment-response';\nimport {\n CanonicalFormatLegacyResolutionError,\n projectV2ProductToV1,\n resolveCanonicalFormatLegacyRefs,\n} from '../../../v2/projection/v2-to-v1';\nimport type { CanonicalFormatLegacyResolver } from '../../../v2/projection/v2-to-v1';\nimport {\n isProjectionProductInput,\n type ProjectionDiagnostic,\n type V1FormatId,\n type V1Product,\n type V2Product,\n} from '../../../v2/projection/types';\nimport { legacyFormatRefsForDeclaration } from '../../../v2/projection/legacy-metadata';\nimport { canonicalizeAgentUrl } from '../../../discovery/resolve-agent-properties';\nimport { ADCP_VERSION } from '../../../version';\n\nfunction supportsCanonicalCreativeCapability(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major > 3 || (major === 3 && minor >= 1);\n}\n\nfunction requiresCanonicalCreativeWire(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major > 3 || (major === 3 && minor >= 2);\n}\n\nfunction supportsTransitionalDualCreativeWire(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n return Number(match[1]) === 3 && Number(match[2]) === 1;\n}\n\nfunction shouldEmitTransitionalDualCreativeWire(version: unknown, request: unknown): boolean {\n if (!supportsTransitionalDualCreativeWire(version)) return false;\n if (request === null || typeof request !== 'object') return true;\n const fields = Object.getOwnPropertyDescriptor(request, 'fields');\n if (!fields || !('value' in fields) || !Array.isArray(fields.value)) return true;\n return Object.values(Object.getOwnPropertyDescriptors(fields.value)).some(\n descriptor => descriptor.enumerable && 'value' in descriptor && descriptor.value === 'format_ids'\n );\n}\n\ntype CreativeWireEvidence = 'canonical' | 'legacy' | 'mixed' | 'unknown';\n\n/**\n * AdCP 3.1 is a dual-format transition release. Infer the caller's format\n * dialect from data-only request fields without invoking getters or custom\n * serialization hooks. Ambiguous 3.1 reads use the modern framework's\n * canonical default; legacy buyers can select the compatibility projection\n * with an actual legacy field such as `fields: ['format_ids']`.\n */\nfunction creativeWireEvidenceForRequest(request: unknown): CreativeWireEvidence {\n let canonical = false;\n let legacy = false;\n const seen = new WeakSet<object>();\n\n // Raw-wire migration tooling uses a namespaced extension because read\n // requests such as get_products and list_creatives can otherwise be\n // structurally ambiguous. Read it through data descriptors only so the\n // negotiation path retains the same no-application-code guarantee as the\n // recursive scanner below.\n if (request !== null && typeof request === 'object') {\n const ext = Object.getOwnPropertyDescriptor(request, 'ext');\n if (ext && 'value' in ext && ext.value !== null && typeof ext.value === 'object') {\n const adcp = Object.getOwnPropertyDescriptor(ext.value, 'adcp');\n if (adcp && 'value' in adcp && adcp.value !== null && typeof adcp.value === 'object') {\n const wire = Object.getOwnPropertyDescriptor(adcp.value, 'creative_wire');\n if (wire && 'value' in wire) {\n if (wire.value === 'canonical') canonical = true;\n if (wire.value === 'legacy') legacy = true;\n }\n }\n }\n }\n\n const visit = (value: unknown): void => {\n if (value === null || typeof value !== 'object' || seen.has(value)) return;\n seen.add(value);\n const arrayValue = Array.isArray(value);\n const descriptors = Object.getOwnPropertyDescriptors(value);\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (!descriptor.enumerable || !('value' in descriptor)) continue;\n const child = descriptor.value;\n // Conversation/context payloads can legitimately quote a previous\n // response in the opposite dialect. They are not negotiation signals\n // for the current tool call. The same applies to arbitrary extensions.\n if (key === 'context' || key === 'ext') continue;\n if (/(^|_)(?:format_ids?|v1_format_ref)($|_)/.test(key)) legacy = true;\n if (\n key === 'format_kind' ||\n key === 'format_options' ||\n key === 'format_option_ref' ||\n key === 'format_option_refs'\n ) {\n canonical = true;\n }\n // Inspect array entries through their own data descriptors. Never use\n // iteration here: an Array subclass or ordinary array can install a\n // user-controlled Symbol.iterator, and dialect detection must not run\n // application code.\n if (arrayValue && typeof child === 'string') {\n if (child === 'format_id' || child === 'format_ids') legacy = true;\n if (child === 'format_kind' || child === 'format_options' || child === 'format_option_ref') canonical = true;\n }\n visit(child);\n }\n };\n\n visit(request);\n if (canonical && legacy) return 'mixed';\n if (canonical) return 'canonical';\n if (legacy) return 'legacy';\n return 'unknown';\n}\n\nfunction creativeWireModeForRequest(\n ctx: HandlerContext<Account>,\n fallback: 'canonical' | 'legacy',\n request?: unknown\n): 'canonical' | 'legacy' {\n if (ctx.servedAdcpVersion === undefined) return fallback;\n if (!supportsCanonicalCreativeCapability(ctx.servedAdcpVersion)) return 'legacy';\n if (requiresCanonicalCreativeWire(ctx.servedAdcpVersion)) return 'canonical';\n\n const evidence = creativeWireEvidenceForRequest(request);\n // Transitional 3.1 product/package envelopes may deliberately carry both\n // dialects. Prefer canonical output in that case; the semantic request\n // projector still rejects an individual creative that claims conflicting\n // format_id + format_kind identities.\n if (evidence === 'canonical' || evidence === 'mixed') return 'canonical';\n if (evidence === 'legacy') return 'legacy';\n return fallback;\n}\n\nfunction parseAdcpRelease(version: unknown): readonly [number, number, number] | undefined {\n if (typeof version !== 'string') return undefined;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:-|$)/.exec(version.trim());\n if (!match) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];\n}\n\nfunction compareAdcpReleases(\n left: readonly [number, number, number],\n right: readonly [number, number, number]\n): number {\n for (let index = 0; index < left.length; index++) {\n const delta = left[index]! - right[index]!;\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n if (Array.isArray(v)) return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n}\n\nfunction deepMergePlainObjects(target: unknown, source: unknown): unknown {\n if (source === undefined) return target;\n if (source === null) return null;\n if (!isPlainObject(source)) return source;\n if (!isPlainObject(target)) return { ...source };\n const out: Record<string, unknown> = { ...target };\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue;\n if (value === null) {\n delete out[key];\n continue;\n }\n out[key] = deepMergePlainObjects(out[key], value);\n }\n return out;\n}\n\nfunction mergeCapabilityOverride<T extends object>(adopter: T | null | undefined, framework: Partial<T>): T {\n return deepMergePlainObjects(adopter ?? {}, framework) as T;\n}\n\n/**\n * Apply `normalizeErrors` to a sync_creatives row's optional `errors`\n * field. Adopters often return errors as bare strings, native Error\n * instances, or vendor-specific shapes; the wire schema requires\n * `Error[]` with `{ code, message, ... }`. Normalizing at the\n * projection seam means every adopter's syncCreatives method gets\n * coerced to wire shape — the row passes strict response validation\n * even when the adopter doesn't hand-shape every error.\n */\nfunction normalizeRowErrors<TRow extends { errors?: unknown }>(row: TRow): TRow {\n if (row?.errors == null) return row;\n return { ...row, errors: normalizeErrors(row.errors) } as TRow;\n}\n\nfunction asCanonicalServerResponse<T>(response: T): T {\n return stripLegacyCreativeIdentity(response) as T;\n}\n\nfunction ownEnumerableDataRecord(value: object, operation: string): Record<string, unknown> | undefined {\n const descriptors = Object.getOwnPropertyDescriptors(value);\n const entries = Object.entries(descriptors).filter(([, descriptor]) => descriptor.enumerable);\n if (entries.length === 0) return undefined;\n const record: Record<string, unknown> = {};\n for (const [key, descriptor] of entries) {\n if (!('value' in descriptor)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(response:${key})`,\n 'enumerable accessors cannot cross the creative format boundary safely'\n );\n }\n record[key] = descriptor.value;\n }\n return record;\n}\n\nfunction assertSafeSemanticPayload(value: unknown, operation: string): void {\n const active = new WeakSet<object>();\n const visited = new WeakSet<object>();\n\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object') return;\n if (Array.isArray(current) && Object.getPrototypeOf(current) !== Array.prototype) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path})`,\n 'array subclasses cannot cross the creative format boundary safely'\n );\n }\n for (let owner: object | null = current; owner !== null; owner = Object.getPrototypeOf(owner)) {\n const toJSON = Object.getOwnPropertyDescriptor(owner, 'toJSON');\n if (!toJSON) continue;\n if (!('value' in toJSON) || typeof toJSON.value === 'function') {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path}.toJSON)`,\n 'custom or accessor toJSON hooks cannot cross the creative format boundary safely'\n );\n }\n }\n if (active.has(current)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path})`,\n 'cyclic values cannot cross the creative format boundary'\n );\n }\n if (visited.has(current)) return;\n active.add(current);\n try {\n const descriptors = Object.getOwnPropertyDescriptors(current);\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (!('value' in descriptor)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path}.${key})`,\n 'accessors cannot cross the creative format boundary safely'\n );\n }\n if (!descriptor.enumerable) continue;\n visit(descriptor.value, `${path}.${key}`);\n }\n } finally {\n active.delete(current);\n }\n visited.add(current);\n };\n\n visit(value, '$');\n}\n\nfunction projectResponseCreativeIdentities(\n value: unknown,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n wireMode: 'canonical' | 'legacy',\n selectorContainer: Record<string, unknown> = {}\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item =>\n projectResponseCreativeIdentities(\n item,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n wireMode,\n selectorContainer\n )\n );\n }\n if (value === null || typeof value !== 'object') return value;\n\n const inspectedRecord = ownEnumerableDataRecord(value, operation);\n if (inspectedRecord === undefined) return value;\n // Preserve plain-object identity so SDK-private WeakMap metadata on\n // canonical declarations survives the downgrade path. Non-plain records\n // are copied into a data-only shape so prototype behavior cannot reach the\n // wire.\n const dataRecord = isPlainObject(value) ? value : inspectedRecord;\n let projected: Record<string, unknown> = dataRecord;\n if (isProjectionProductInput(projected)) {\n if (wireMode === 'canonical') {\n const canonical = toCanonicalOnlyResponse({ products: [projected] }, { legacyFormatConverter });\n if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {\n throw new CreativeFormatProjectionError(\n operation,\n `(product:${String(projected.product_id)})`,\n 'legacy product formats in the platform response have no complete canonical representation'\n );\n }\n projected = canonical.response.products[0] as unknown as Record<string, unknown>;\n } else if (Array.isArray(projected.format_options)) {\n const legacy = projectV2ProductToV1(projected, { canonicalFormatLegacyResolver });\n if (legacy.diagnostics.length > 0 || (legacy.v1.format_ids.length === 0 && projected.format_options.length > 0)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(product:${String(projected.product_id)})`,\n 'canonical product formats in the platform response have no complete legacy representation'\n );\n }\n projected = legacy.v1 as unknown as Record<string, unknown>;\n }\n } else if (\n (typeof projected.package_id === 'string' || typeof projected.product_id === 'string') &&\n (Array.isArray(projected.format_ids) ||\n Array.isArray(projected.format_option_refs) ||\n typeof projected.format_kind === 'string')\n ) {\n projected = (\n projectMediaBuyCreativesForDelivery(\n { packages: [projected] },\n wireMode,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n ) as { packages: Record<string, unknown>[] }\n ).packages[0]!;\n }\n\n if (\n typeof projected.creative_id === 'string' &&\n (projected.format_id !== undefined || typeof projected.format_kind === 'string')\n ) {\n projected = projectCreativeForDelivery(\n projected as unknown as import('../../../types/tools.generated').CreativeAsset,\n selectorContainer,\n wireMode,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n ) as unknown as Record<string, unknown>;\n }\n\n const nextSelector =\n Array.isArray(projected.format_ids) ||\n Array.isArray(projected.format_options) ||\n Array.isArray(projected.format_option_refs)\n ? projected\n : selectorContainer;\n let changed = projected !== value;\n const next: Record<string, unknown> = { ...projected };\n for (const [key, child] of Object.entries(projected)) {\n const childProjected = projectResponseCreativeIdentities(\n child,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n wireMode,\n nextSelector\n );\n if (childProjected !== child) {\n next[key] = childProjected;\n changed = true;\n }\n }\n return changed ? next : projected;\n}\n\nfunction asCanonicalSemanticServerResponse<T>(\n response: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver\n): T {\n try {\n assertSafeSemanticPayload(response, operation);\n return asCanonicalServerResponse(\n projectResponseCreativeIdentities(\n response,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n 'canonical'\n )\n ) as T;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} platform response contains a legacy creative format that cannot be represented canonically.`,\n field: 'response',\n suggestion:\n 'Return canonical format_kind values, or configure legacyCreativeFormatConverter for custom legacy formats.',\n });\n }\n}\n\nfunction asSemanticServerResponseForWire<T>(\n response: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n wireMode: 'canonical' | 'legacy'\n): T {\n if (wireMode === 'canonical') {\n return attachCanonicalFormatWireRefs(\n asCanonicalSemanticServerResponse(response, operation, legacyFormatConverter, canonicalFormatLegacyResolver),\n canonicalFormatLegacyResolver,\n operation\n );\n }\n try {\n assertSafeSemanticPayload(response, operation);\n return projectResponseCreativeIdentities(\n response,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n 'legacy'\n ) as T;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} platform response contains a canonical creative format that cannot be represented on the configured legacy wire.`,\n field: 'response',\n suggestion:\n 'Return an explicit legacy mapping for the canonical format, or configure this server for AdCP 3.1 or newer.',\n });\n }\n}\n\ntype LegacyIdentityContext = 'agent' | 'signal' | 'list' | 'default';\n\nfunction legacyIdentityContext(ownerKey?: string): LegacyIdentityContext {\n if (typeof ownerKey !== 'string') return 'default';\n if (ownerKey === 'signal_id' || ownerKey === 'signal_ids') return 'signal';\n if (/(^|_)(?:property_lists?|collection_lists?)($|_)/.test(ownerKey)) return 'list';\n if (\n !/(^|_)(?:creative|format|legacy|placement)($|_)/.test(ownerKey) &&\n /(^|_)(?:agents?|agent_details|agent_info)($|_)/.test(ownerKey)\n ) {\n return 'agent';\n }\n return 'default';\n}\n\nfunction allowsNonCreativeAgentUrl(owner: Record<string, unknown>, context: LegacyIdentityContext): boolean {\n return (\n context === 'agent' ||\n (context === 'list' && typeof owner.list_id === 'string') ||\n (context === 'signal' && owner.source === 'agent')\n );\n}\n\ninterface LegacyIdentityScanSeen {\n agent: WeakSet<object>;\n signal: WeakSet<object>;\n list: WeakSet<object>;\n default: WeakSet<object>;\n}\n\nfunction findLegacyCreativeIdentity(\n value: unknown,\n seen: LegacyIdentityScanSeen = {\n agent: new WeakSet<object>(),\n signal: new WeakSet<object>(),\n list: new WeakSet<object>(),\n default: new WeakSet<object>(),\n },\n ownerKey?: string\n): string | undefined {\n if (value === null || typeof value !== 'object') return undefined;\n const owner = value as Record<string, unknown>;\n const context = legacyIdentityContext(ownerKey);\n const policySeen = seen[context];\n if (policySeen.has(value)) return undefined;\n policySeen.add(value);\n if (Array.isArray(value)) {\n for (const item of value) {\n const nested = findLegacyCreativeIdentity(item, seen, ownerKey);\n if (nested) return nested;\n }\n return undefined;\n }\n for (const [key, child] of Object.entries(owner)) {\n if (/(^|_)(?:format_ids?|v1_format_ref)($|_)/.test(key)) return key;\n if (\n key === 'agent_url' &&\n (typeof owner.id === 'string' || typeof owner.list_id === 'string') &&\n !allowsNonCreativeAgentUrl(owner, context)\n ) {\n return key;\n }\n const nested = findLegacyCreativeIdentity(child, seen, key);\n if (nested) return nested;\n }\n return undefined;\n}\n\nfunction asCanonicalSemanticServerRequest<T>(\n request: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): T {\n try {\n assertSafeSemanticPayload(request, operation);\n const projected = projectResponseCreativeIdentities(\n request,\n operation,\n legacyFormatConverter,\n undefined,\n 'canonical'\n ) as T;\n const forbidden = findLegacyCreativeIdentity(projected);\n if (forbidden) {\n throw new CreativeFormatProjectionError(\n operation,\n '(request extension)',\n `legacy creative identity ${forbidden} has no recognized canonical container`\n );\n }\n return projected;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} request contains a legacy creative format that cannot be represented canonically.`,\n field: 'request',\n suggestion:\n 'Send canonical format_kind values, or configure legacyCreativeFormatConverter for custom legacy formats.',\n });\n }\n}\n\n/**\n * Bridge the runtime-schema input type to the public domain request type.\n *\n * Requests reach this adapter only after validation against the signed AdCP\n * JSON Schema. JSON-Schema-to-Zod represents `minItems: 1` as a validated\n * array, while json-schema-to-typescript represents the same field as a\n * non-empty tuple. The values are equivalent after validation, but TypeScript\n * cannot prove that structural relationship. Keep the assertion at this\n * single validation boundary instead of weakening the public request types.\n */\nfunction asValidatedDomainRequest<T>(request: unknown): T {\n return request as T;\n}\n\nfunction asCanonicalGetProductsRequest(request: Record<string, unknown>): CanonicalGetProductsRequest {\n if (!Array.isArray(request['fields'])) return request as CanonicalGetProductsRequest;\n const fields = [\n ...new Set(\n request['fields'].flatMap(field =>\n field === 'format_ids' ? ['format_options'] : typeof field === 'string' ? [field] : []\n )\n ),\n ] as CanonicalGetProductsRequest['fields'];\n return { ...request, fields } as CanonicalGetProductsRequest;\n}\n\nfunction asCanonicalListCreativesRequest(\n request: Record<string, unknown>,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n responseWireMode: 'canonical' | 'legacy'\n): CanonicalListCreativesRequest {\n const filters =\n request['filters'] !== null && typeof request['filters'] === 'object' && !Array.isArray(request['filters'])\n ? (request['filters'] as Record<string, unknown>)\n : undefined;\n const legacyFormatIds = filters?.['format_ids'];\n if (Array.isArray(legacyFormatIds) && legacyFormatIds.length > 0 && responseWireMode !== 'legacy') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'list_creatives legacy format_ids filters are unavailable on the canonical platform surface.',\n field: 'filters.format_ids',\n suggestion: 'Filter by canonical creative fields, or use an explicit legacy wire handler during migration.',\n });\n }\n const { format_ids: _dropLegacyFormatIds, ...canonicalFilters } = filters ?? {};\n void _dropLegacyFormatIds;\n const withoutLegacyFilter = filters === undefined ? request : { ...request, filters: canonicalFilters };\n const projected = asCanonicalSemanticServerRequest(\n withoutLegacyFilter,\n 'list_creatives',\n legacyFormatConverter\n ) as Record<string, unknown>;\n const withLegacyFilter =\n responseWireMode === 'legacy' && Array.isArray(legacyFormatIds) && legacyFormatIds.length > 0\n ? {\n ...projected,\n filters: {\n ...((projected['filters'] as Record<string, unknown> | undefined) ?? {}),\n format_ids: legacyFormatIds,\n },\n }\n : projected;\n if (!Array.isArray(withLegacyFilter['fields'])) return withLegacyFilter as CanonicalListCreativesRequest;\n const fields = [\n ...new Set(\n withLegacyFilter['fields'].flatMap(field =>\n field === 'format_id' ? ['format_kind'] : typeof field === 'string' ? [field] : []\n )\n ),\n ] as CanonicalListCreativesRequest['fields'];\n return { ...withLegacyFilter, fields } as CanonicalListCreativesRequest;\n}\n\nfunction assertSafeGetProductsResponse(response: unknown): void {\n try {\n assertSafeSemanticPayload(response, 'get_products');\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products platform response cannot be represented safely at the canonical boundary.',\n field: 'response',\n suggestion: 'Return an acyclic data-only product response without enumerable accessors.',\n });\n }\n}\n\nfunction asCanonicalProductResponse<T extends { products?: unknown[] }>(\n response: T,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): T {\n assertSafeGetProductsResponse(response);\n validateDualProductFormatDeclarations(response, legacyFormatConverter);\n const projected = toCanonicalOnlyResponse(response as T & { products?: V1Product[] }, {\n legacyFormatConverter,\n });\n const blockingDiagnostics = projected.diagnostics.filter(\n diagnostic => diagnostic.code !== 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED'\n );\n if (blockingDiagnostics.length > 0) {\n const first = blockingDiagnostics[0]!;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a legacy format that cannot be represented canonically.',\n field: first.field,\n suggestion: 'Declare canonical format_options or configure legacyCreativeFormatConverter for the legacy format.',\n });\n }\n const canonicalResponse = asCanonicalServerResponse(projected.response) as T;\n const resolvedDropDiagnostics = projected.diagnostics.filter(\n (diagnostic): diagnostic is LegacyDropDiagnostic => diagnostic.code === 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED'\n );\n if (resolvedDropDiagnostics.length > 0 && canonicalResponse !== null && typeof canonicalResponse === 'object') {\n resolvedLegacyDropDiagnosticsByResponse.set(canonicalResponse, resolvedDropDiagnostics);\n }\n preserveAuthoredFormatIds(response, canonicalResponse);\n return canonicalResponse;\n}\n\nfunction legacyFormatResolutionKey(context: LegacyFormatConversionContext): string {\n const formatId = context.formatId;\n return JSON.stringify([\n context.productId,\n context.field,\n formatId.agent_url,\n formatId.id,\n formatId.width ?? null,\n formatId.height ?? null,\n formatId.duration_ms ?? null,\n ]);\n}\n\nfunction preparePerProductProjectionCatalogs<T extends { products?: unknown[] }>(\n response: T,\n fallback: LegacyFormatConverter | undefined\n): { response: T; converter: LegacyFormatConverter | undefined } {\n assertSafeGetProductsResponse(response);\n if (!Array.isArray(response.products)) return { response, converter: fallback };\n assertNoReservedLegacyRouteMetadata(response.products, 'products');\n\n const converters = new Map<string, LegacyFormatConverter>();\n const productIdCounts = new Map<string, number>();\n for (const product of response.products) {\n if (!product || typeof product !== 'object' || Array.isArray(product)) continue;\n const productId = (product as Record<string, unknown>).product_id;\n if (typeof productId === 'string') productIdCounts.set(productId, (productIdCounts.get(productId) ?? 0) + 1);\n }\n let strippedCatalogMetadata = false;\n const products = response.products.map(product => {\n if (!product || typeof product !== 'object' || Array.isArray(product)) return product;\n const record = product as Record<string, unknown>;\n if (!Object.prototype.hasOwnProperty.call(record, 'projectionCatalogs')) return product;\n strippedCatalogMetadata = true;\n const { projectionCatalogs, ...wireProduct } = record;\n if (!Array.isArray(projectionCatalogs)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projectionCatalogs must be an array of immutable catalog snapshots.',\n field: `products[${String(record.product_id ?? '?')}].projectionCatalogs`,\n });\n }\n if (typeof record.product_id === 'string' && (productIdCounts.get(record.product_id) ?? 0) > 1) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projection catalogs require unique product identifiers.',\n field: `products[${record.product_id}].projectionCatalogs`,\n });\n }\n if (projectionCatalogs.length > 0 && typeof record.product_id === 'string') {\n if (converters.has(record.product_id)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products cannot attach different projection catalogs to duplicate product identifiers.',\n field: `products[${record.product_id}].projectionCatalogs`,\n });\n }\n const converter = legacyFormatConverterFromCatalogSnapshots(\n projectionCatalogs as readonly ProjectionCatalogSnapshot[]\n );\n if (converter) {\n converters.set(record.product_id, converter);\n const placements = wireProduct.placements;\n if (Array.isArray(placements)) {\n for (let placementIndex = 0; placementIndex < placements.length; placementIndex++) {\n const placement = placements[placementIndex];\n if (!placement || typeof placement !== 'object' || Array.isArray(placement)) continue;\n const placementRecord = placement as Record<string, unknown>;\n const placementId =\n typeof placementRecord.placement_id === 'string' ? placementRecord.placement_id : String(placementIndex);\n const projectionProductId = `${record.product_id}:placement:${placementId}`;\n if (converters.has(projectionProductId)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projection catalog scopes resolve to a duplicate product identifier.',\n field: `products[${record.product_id}].placements[${placementIndex}]`,\n });\n }\n converters.set(projectionProductId, converter);\n }\n }\n }\n }\n return wireProduct;\n });\n\n const converter: LegacyFormatConverter | undefined =\n converters.size === 0\n ? fallback\n : context => {\n const productConverter = converters.get(context.productId);\n const resolved = productConverter?.(context);\n return resolved === undefined ? fallback?.(context) : resolved;\n };\n return {\n response: (strippedCatalogMetadata ? { ...response, products } : response) as T,\n converter,\n };\n}\n\nconst DEFAULT_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS = 10_000;\nconst DEFAULT_LEGACY_FORMAT_RESOLVER_CONCURRENCY = 8;\nconst MAX_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS = 2_147_483_647;\nconst MAX_LEGACY_FORMAT_RESOLVER_CONCURRENCY = 64;\n\nfunction legacyFormatResolverLimit(\n value: number | undefined,\n fallback: number,\n field: string,\n maximum?: number\n): number {\n if (value === undefined) return fallback;\n if (!Number.isSafeInteger(value) || value <= 0 || (maximum !== undefined && value > maximum)) {\n const range = maximum === undefined ? 'a positive safe integer' : `an integer between 1 and ${maximum}`;\n throw new PlatformConfigError(`${field} must be ${range}.`);\n }\n return value;\n}\n\nfunction legacyFormatResolverAbortError(signal: AbortSignal): Error {\n return signal.reason instanceof Error\n ? signal.reason\n : new Error('legacyCreativeFormatResolver was aborted before projection completed.');\n}\n\nfunction createLegacyFormatResolverSignal(\n requestSignal: AbortSignal | undefined,\n timeoutMs: number\n): { signal: AbortSignal; dispose(): void } {\n const controller = new AbortController();\n const abortFromRequest = () => controller.abort(requestSignal?.reason);\n if (requestSignal?.aborted) abortFromRequest();\n else requestSignal?.addEventListener('abort', abortFromRequest, { once: true });\n const timeout = controller.signal.aborted\n ? undefined\n : setTimeout(\n () => controller.abort(new Error(`legacyCreativeFormatResolver exceeded its ${timeoutMs}ms deadline.`)),\n timeoutMs\n );\n return {\n signal: controller.signal,\n dispose() {\n if (timeout !== undefined) clearTimeout(timeout);\n requestSignal?.removeEventListener('abort', abortFromRequest);\n },\n };\n}\n\nasync function invokeLegacyFormatResolver(\n resolver: LegacyFormatResolver,\n context: Omit<LegacyFormatResolutionContext, 'signal'>,\n signal: AbortSignal\n): Promise<Awaited<ReturnType<LegacyFormatResolver>>> {\n if (signal.aborted) throw legacyFormatResolverAbortError(signal);\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n abortListener = () => reject(legacyFormatResolverAbortError(signal));\n signal.addEventListener('abort', abortListener, { once: true });\n });\n try {\n return await Promise.race([Promise.resolve().then(() => resolver({ ...context, signal })), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n\nasync function resolveLegacyProductFormats<T extends { products?: unknown[] }>(\n response: T,\n converter: LegacyFormatConverter | undefined,\n resolver: LegacyFormatResolver | undefined,\n requestContext: {\n servedAdcpVersion?: string;\n accountId?: string;\n signal?: AbortSignal;\n timeoutMs: number;\n concurrency: number;\n }\n): Promise<LegacyFormatConverter | undefined> {\n if (!resolver) return converter;\n assertSafeGetProductsResponse(response);\n if (!Array.isArray(response.products)) return converter;\n\n const resolutions = new Map<\n string,\n Awaited<ReturnType<LegacyFormatResolver>> | { readonly resolutionError: unknown }\n >();\n const pending: Array<(signal: AbortSignal) => Promise<void>> = [];\n const scanScope = (projectionProduct: V1Product, resolverProductId: string, resolverFieldPrefix: string): void => {\n if (Array.isArray((projectionProduct as unknown as V2Product).format_options)) return;\n for (let index = 0; index < projectionProduct.format_ids.length; index++) {\n const formatId = projectionProduct.format_ids[index];\n if (!formatId || typeof formatId !== 'object' || Array.isArray(formatId)) continue;\n const projectionField = `products[${projectionProduct.product_id}].format_ids[${index}]`;\n const resolverField = `${resolverFieldPrefix}.format_ids[${index}]`;\n const projectionContext: LegacyFormatConversionContext = {\n formatId: formatId as V1FormatId,\n productId: projectionProduct.product_id,\n field: projectionField,\n };\n const contextAwareConverter: LegacyFormatConverter | undefined = converter\n ? context => converter({ ...context, field: projectionField })\n : undefined;\n const alreadyProjected = projectV1ProductToV2(\n { ...projectionProduct, format_ids: [formatId] },\n { legacyFormatConverter: contextAwareConverter }\n );\n if (alreadyProjected.diagnostics.length === 0) continue;\n\n let resolverEligible = false;\n projectV1ProductToV2(\n { ...projectionProduct, format_ids: [formatId] },\n {\n legacyFormatConverter: () => {\n resolverEligible = true;\n return {\n format_option_id: '__legacy_resolver_probe__',\n format_kind: 'custom',\n format_shape: '__legacy_resolver_probe__',\n format_schema: {\n uri: 'https://adcontextprotocol.org/schemas/legacy-resolver-probe.json',\n digest: `sha256:${'0'.repeat(64)}`,\n },\n params: {},\n };\n },\n }\n );\n if (!resolverEligible) continue;\n\n const key = legacyFormatResolutionKey(projectionContext);\n const frozenFormatId = Object.freeze({ ...(formatId as V1FormatId) });\n pending.push(async signal => {\n try {\n const value = await invokeLegacyFormatResolver(\n resolver,\n {\n formatId: frozenFormatId,\n productId: resolverProductId,\n field: resolverField,\n operation: 'get_products',\n ...(requestContext.servedAdcpVersion !== undefined && {\n servedAdcpVersion: requestContext.servedAdcpVersion,\n }),\n ...(requestContext.accountId !== undefined && { accountId: requestContext.accountId }),\n },\n signal\n );\n resolutions.set(key, value);\n } catch (error) {\n resolutions.set(key, { resolutionError: error });\n }\n });\n }\n };\n\n for (const product of response.products) {\n if (!isProjectionProductInput(product)) continue;\n if (Array.isArray(product.format_ids)) {\n scanScope(product as V1Product, product.product_id, `products[${product.product_id}]`);\n }\n const placements = (product as unknown as Record<string, unknown>).placements;\n if (!Array.isArray(placements)) continue;\n for (let placementIndex = 0; placementIndex < placements.length; placementIndex++) {\n const placement = placements[placementIndex];\n if (!placement || typeof placement !== 'object' || Array.isArray(placement)) continue;\n const placementRecord = placement as Record<string, unknown>;\n if (Array.isArray(placementRecord.format_options) || !Array.isArray(placementRecord.format_ids)) continue;\n const placementId =\n typeof placementRecord.placement_id === 'string' ? placementRecord.placement_id : String(placementIndex);\n scanScope(\n {\n product_id: `${product.product_id}:placement:${placementId}`,\n name: typeof placementRecord.name === 'string' ? placementRecord.name : placementId,\n description: `Nested placement ${placementId}`,\n format_ids: placementRecord.format_ids as V1FormatId[],\n },\n product.product_id,\n `products[${product.product_id}].placements[${placementIndex}]`\n );\n }\n }\n const resolverSignal = createLegacyFormatResolverSignal(requestContext.signal, requestContext.timeoutMs);\n try {\n let nextJob = 0;\n const workerCount = Math.min(requestContext.concurrency, pending.length);\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (nextJob < pending.length) {\n const job = pending[nextJob++];\n if (job) await job(resolverSignal.signal);\n }\n })\n );\n } finally {\n resolverSignal.dispose();\n }\n if (resolutions.size === 0) return converter;\n\n return context => {\n const resolved = resolutions.get(legacyFormatResolutionKey(context));\n if (resolved !== undefined) {\n if (typeof resolved === 'object' && resolved !== null && 'resolutionError' in resolved) {\n throw resolved.resolutionError;\n }\n return resolved;\n }\n return converter?.(context);\n };\n}\n\nconst authoredFormatIdsByOwner = new WeakMap<object, readonly V1FormatId[]>();\nconst STORED_LEGACY_FORMAT_ROUTES = '__adcp_private_legacy_format_routes';\n\nfunction assertNoReservedLegacyRouteMetadata(value: unknown, path: string): void {\n const visited = new WeakSet<object>();\n const visit = (current: unknown, currentPath: string): void => {\n if (current === null || typeof current !== 'object' || visited.has(current)) return;\n visited.add(current);\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(current))) {\n if (!descriptor.enumerable || !('value' in descriptor)) continue;\n const childPath = Array.isArray(current) ? `${currentPath}[${key}]` : `${currentPath}.${key}`;\n if (key === STORED_LEGACY_FORMAT_ROUTES) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a field reserved for SDK-private route persistence.',\n field: childPath,\n });\n }\n visit(descriptor.value, childPath);\n }\n };\n visit(value, path);\n}\n\ninterface StoredLegacyFormatRoutes {\n formatIds?: readonly V1FormatId[];\n placements?: readonly (StoredLegacyFormatRoutes | null)[];\n}\n\nfunction captureStoredLegacyFormatRoutes(value: unknown): StoredLegacyFormatRoutes | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n const formatIds = authoredFormatIdsByOwner.get(record);\n const placements = Array.isArray(record.placements)\n ? record.placements.map(placement => captureStoredLegacyFormatRoutes(placement) ?? null)\n : undefined;\n if (!formatIds && !placements?.some(Boolean)) return undefined;\n return {\n ...(formatIds && { formatIds: formatIds.map(ref => cloneWireData(ref)) }),\n ...(placements?.some(Boolean) && { placements }),\n };\n}\n\nfunction restoreStoredLegacyFormatRoutes(value: unknown, routes: unknown): void {\n if (\n value === null ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n routes === null ||\n typeof routes !== 'object' ||\n Array.isArray(routes)\n ) {\n return;\n }\n const record = value as Record<string, unknown>;\n const routeRecord = routes as Record<string, unknown>;\n if (\n Array.isArray(routeRecord.formatIds) &&\n routeRecord.formatIds.length > 0 &&\n routeRecord.formatIds.every(ref => isValidStoredLegacyFormatRef(ref))\n ) {\n authoredFormatIdsByOwner.set(\n record,\n routeRecord.formatIds.map(ref => cloneWireData(ref as V1FormatId))\n );\n }\n if (Array.isArray(record.placements) && Array.isArray(routeRecord.placements)) {\n const count = Math.min(record.placements.length, routeRecord.placements.length);\n for (let index = 0; index < count; index++) {\n restoreStoredLegacyFormatRoutes(record.placements[index], routeRecord.placements[index]);\n }\n }\n}\n\nfunction isValidStoredLegacyFormatRef(value: unknown): value is V1FormatId {\n if (legacyFormatRefKey(value) === undefined) return false;\n const ref = value as Record<string, unknown>;\n if (ref.agent_url === '' || ref.id === '') return false;\n for (const field of ['width', 'height', 'duration_ms'] as const) {\n const fieldValue = ref[field];\n if (fieldValue !== undefined && (!Number.isInteger(fieldValue) || (fieldValue as number) <= 0)) return false;\n }\n return true;\n}\n\n/** Read exact SDK-private legacy routes restored on an auto-hydrated product or placement. */\nexport function getHydratedLegacyFormatIds(value: unknown): readonly V1FormatId[] | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const refs = authoredFormatIdsByOwner.get(value);\n return refs?.map(ref => cloneWireData(ref));\n}\n\ntype LegacyDropDiagnostic = Extract<ProjectionDiagnostic, { code: 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED' }>;\nconst resolvedLegacyDropDiagnosticsByResponse = new WeakMap<object, readonly LegacyDropDiagnostic[]>();\n\nfunction ownArrayDataValues(value: readonly unknown[]): unknown[] {\n const lengthDescriptor = Object.getOwnPropertyDescriptor(value, 'length');\n const length = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : 0;\n if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0) return [];\n const values: unknown[] = [];\n for (let index = 0; index < length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index));\n if (descriptor?.enumerable && 'value' in descriptor) values.push(descriptor.value);\n }\n return values;\n}\n\nfunction cloneWireData<T>(value: T): T {\n if (Array.isArray(value)) {\n const cloned: unknown[] = [];\n for (const entry of ownArrayDataValues(value)) cloned.push(cloneWireData(entry));\n return cloned as T;\n }\n if (value === null || typeof value !== 'object') return value;\n const cloned: Record<string, unknown> = {};\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {\n if (descriptor.enumerable && 'value' in descriptor) cloned[key] = cloneWireData(descriptor.value);\n }\n return cloned as T;\n}\n\nfunction preserveAuthoredFormatIds(source: unknown, target: unknown): void {\n if (source === null || target === null || typeof source !== 'object' || typeof target !== 'object') return;\n const sourceProducts = Object.getOwnPropertyDescriptor(source, 'products');\n const targetProducts = Object.getOwnPropertyDescriptor(target, 'products');\n if (\n !sourceProducts ||\n !sourceProducts.enumerable ||\n !('value' in sourceProducts) ||\n !Array.isArray(sourceProducts.value) ||\n !targetProducts ||\n !targetProducts.enumerable ||\n !('value' in targetProducts) ||\n !Array.isArray(targetProducts.value)\n ) {\n return;\n }\n const sourceValues = ownArrayDataValues(sourceProducts.value);\n const targetValues = ownArrayDataValues(targetProducts.value);\n const count = Math.min(sourceValues.length, targetValues.length);\n for (let index = 0; index < count; index++)\n preserveAuthoredFormatIdsForOwner(sourceValues[index], targetValues[index]);\n}\n\nfunction preserveAuthoredFormatIdsForOwner(source: unknown, target: unknown): void {\n if (source === null || target === null || typeof source !== 'object' || typeof target !== 'object') return;\n const sourceProductId = Object.getOwnPropertyDescriptor(source, 'product_id');\n const sourcePlacementId = Object.getOwnPropertyDescriptor(source, 'placement_id');\n const recognizedOwner =\n (sourceProductId?.enumerable && 'value' in sourceProductId && typeof sourceProductId.value === 'string') ||\n (sourcePlacementId?.enumerable && 'value' in sourcePlacementId && typeof sourcePlacementId.value === 'string');\n if (!recognizedOwner) return;\n const sourceFormatIds = Object.getOwnPropertyDescriptor(source, 'format_ids');\n const targetFormatOptions = Object.getOwnPropertyDescriptor(target, 'format_options');\n if (\n sourceFormatIds &&\n sourceFormatIds.enumerable &&\n 'value' in sourceFormatIds &&\n Array.isArray(sourceFormatIds.value) &&\n targetFormatOptions &&\n targetFormatOptions.enumerable &&\n 'value' in targetFormatOptions &&\n Array.isArray(targetFormatOptions.value)\n ) {\n authoredFormatIdsByOwner.set(\n target,\n ownArrayDataValues(sourceFormatIds.value).map(ref => cloneWireData(ref as V1FormatId))\n );\n }\n const sourcePlacements = Object.getOwnPropertyDescriptor(source, 'placements');\n const targetPlacements = Object.getOwnPropertyDescriptor(target, 'placements');\n if (\n sourcePlacements &&\n sourcePlacements.enumerable &&\n 'value' in sourcePlacements &&\n Array.isArray(sourcePlacements.value) &&\n targetPlacements &&\n targetPlacements.enumerable &&\n 'value' in targetPlacements &&\n Array.isArray(targetPlacements.value)\n ) {\n const sourceValues = ownArrayDataValues(sourcePlacements.value);\n const targetValues = ownArrayDataValues(targetPlacements.value);\n const count = Math.min(sourceValues.length, targetValues.length);\n for (let index = 0; index < count; index++) {\n preserveAuthoredFormatIdsForOwner(sourceValues[index], targetValues[index]);\n }\n }\n}\n\nfunction removeResolvedLegacyDropErrors<T>(response: T, diagnostics: readonly LegacyDropDiagnostic[]): T {\n if (response === null || typeof response !== 'object') return response;\n const resolved = diagnostics.filter(diagnostic => diagnostic.code === 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED');\n if (resolved.length === 0) return response;\n const record = response as Record<string, unknown>;\n if (!Array.isArray(record.errors)) return response;\n const retained: unknown[] = [];\n for (const value of ownArrayDataValues(record.errors)) {\n let matchesResolvedDiagnostic = false;\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const error = value as Record<string, unknown>;\n for (const diagnostic of resolved) {\n if (\n error.code === diagnostic.code &&\n error.field === diagnostic.field &&\n error.source === diagnostic.source &&\n error.sdk_id === diagnostic.sdk_id &&\n jsonValuesEqual(error.details, diagnostic.error.details)\n ) {\n matchesResolvedDiagnostic = true;\n break;\n }\n }\n }\n if (!matchesResolvedDiagnostic) retained.push(value);\n }\n if (retained.length > 0) return { ...record, errors: retained } as T;\n const { errors: _resolvedErrors, ...withoutErrors } = record;\n void _resolvedErrors;\n return withoutErrors as T;\n}\n\nfunction legacyFormatRefKey(value: unknown): string | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const ref = value as Record<string, unknown>;\n if (typeof ref.agent_url !== 'string' || typeof ref.id !== 'string') return undefined;\n const agentUrl = canonicalizeAgentUrl(ref.agent_url) ?? ref.agent_url;\n return `${agentUrl}::${ref.id}::${String(ref.width ?? '')}x${String(ref.height ?? '')}::${String(ref.duration_ms ?? '')}`;\n}\n\nfunction jsonValuesEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) || Array.isArray(right)) {\n if (!Array.isArray(left) || !Array.isArray(right)) return false;\n const leftValues = ownArrayDataValues(left);\n const rightValues = ownArrayDataValues(right);\n if (leftValues.length !== rightValues.length) return false;\n for (let index = 0; index < leftValues.length; index++) {\n if (!jsonValuesEqual(leftValues[index], rightValues[index])) return false;\n }\n return true;\n }\n if (left === null || right === null || typeof left !== 'object' || typeof right !== 'object') return false;\n const leftRecord = left as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n const leftKeys = Object.keys(leftRecord);\n const rightKeys = Object.keys(rightRecord);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(key => Object.hasOwn(rightRecord, key) && jsonValuesEqual(leftRecord[key], rightRecord[key]))\n );\n}\n\ntype LegacyRefMatch = 'match' | 'kind_mismatch' | 'params_mismatch' | 'unresolved';\n\nfunction matchLegacyRefToDeclaration(\n declaration: Record<string, unknown>,\n ref: import('../../../v2/projection/types').V1FormatId,\n ownerId: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): LegacyRefMatch {\n const projected = projectV1ProductToV2(\n {\n product_id: ownerId,\n name: ownerId,\n description: ownerId,\n format_ids: [ref],\n },\n { legacyFormatConverter }\n );\n if (projected.diagnostics.length > 0 || projected.v2.format_options.length !== 1) return 'unresolved';\n const expected = projected.v2.format_options[0]!;\n if (declaration.format_kind !== expected.format_kind) return 'kind_mismatch';\n const params =\n declaration.params !== null && typeof declaration.params === 'object' && !Array.isArray(declaration.params)\n ? (declaration.params as Record<string, unknown>)\n : {};\n for (const [key, expectedValue] of Object.entries(expected.params)) {\n if (!Object.hasOwn(params, key) || !jsonValuesEqual(params[key], expectedValue)) return 'params_mismatch';\n }\n return 'match';\n}\n\nfunction validateLegacyRefNarrowing(\n declaration: Record<string, unknown>,\n ref: import('../../../v2/projection/types').V1FormatId,\n ownerId: string,\n field: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): void {\n const match = matchLegacyRefToDeclaration(declaration, ref, ownerId, legacyFormatConverter);\n if (match === 'kind_mismatch') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned divergent legacy and canonical format declarations.',\n field,\n suggestion: 'Make format_ids and format_options.v1_format_ref describe the same canonical format.',\n });\n }\n if (match === 'params_mismatch') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a canonical declaration that does not narrow its v1_format_ref.',\n field: `${field}.params`,\n suggestion: 'Align canonical format parameters with the referenced legacy format requirements.',\n });\n }\n}\n\nfunction validateDualProductFormatDeclarations(\n value: unknown,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): void {\n const seen = new WeakSet<object>();\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object' || seen.has(current)) return;\n seen.add(current);\n if (Array.isArray(current)) {\n const entries = ownArrayDataValues(current);\n for (let index = 0; index < entries.length; index++) visit(entries[index], `${path}[${index}]`);\n return;\n }\n const record = current as Record<string, unknown>;\n const formatOptions = Array.isArray(record.format_options) ? record.format_options : undefined;\n const ownerId =\n typeof record.product_id === 'string'\n ? record.product_id\n : typeof record.placement_id === 'string'\n ? record.placement_id\n : undefined;\n if (formatOptions && ownerId !== undefined) {\n const declarationRefs: import('../../../v2/projection/types').V1FormatId[] = [];\n const declarations = ownArrayDataValues(formatOptions);\n for (let index = 0; index < declarations.length; index++) {\n const value = declarations[index];\n if (value === null || typeof value !== 'object' || Array.isArray(value)) continue;\n const declaration = value as Record<string, unknown>;\n const refs = ownArrayDataValues(\n legacyFormatRefsForDeclaration(declaration)\n ) as import('../../../v2/projection/types').V1FormatId[];\n const field = `${path}.format_options[${index}]`;\n if (declaration.canonical_formats_only === true && refs.length > 0) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned canonical_formats_only together with v1_format_ref.',\n field,\n suggestion: 'Remove v1_format_ref or set canonical_formats_only to false.',\n });\n }\n declarationRefs.push(...refs);\n for (const ref of refs) {\n validateLegacyRefNarrowing(declaration, ref, ownerId, field, legacyFormatConverter);\n }\n }\n if (Array.isArray(record.format_ids)) {\n const formatIds = ownArrayDataValues(record.format_ids) as import('../../../v2/projection/types').V1FormatId[];\n const formatIdKeys = new Set<string>();\n for (const ref of formatIds) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined) formatIdKeys.add(key);\n }\n const declarationRefKeys = new Set<string>();\n for (const ref of declarationRefs) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined) declarationRefKeys.add(key);\n }\n let divergent = false;\n for (const key of declarationRefKeys) {\n if (!formatIdKeys.has(key)) divergent = true;\n }\n for (const ref of formatIds) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined && declarationRefKeys.has(key)) continue;\n let matched = false;\n for (const value of declarations) {\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n (value as Record<string, unknown>).canonical_formats_only !== true &&\n matchLegacyRefToDeclaration(value as Record<string, unknown>, ref, ownerId, legacyFormatConverter) ===\n 'match'\n ) {\n matched = true;\n break;\n }\n }\n if (!matched) divergent = true;\n }\n if (divergent) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned divergent format_ids and format_options.v1_format_ref values.',\n field: path,\n suggestion: 'Dual-emitted product declarations must carry the same legacy format references.',\n });\n }\n }\n }\n for (const [key, child] of Object.entries(record)) {\n if (key === 'format_options') continue;\n visit(child, `${path}.${key}`);\n }\n };\n visit(value, '$');\n}\n\n/**\n * Rehydrate legacy routing references only at the response wire boundary.\n * Custom declarations retain their explicit mapping on every canonical\n * release. AdCP 3.1 additionally dual-emits standard declaration refs and\n * their product-level `format_ids`; the canonical platform object itself\n * remains free of legacy identity through SDK-private WeakMap metadata.\n */\nfunction attachCanonicalFormatWireRefs<T>(\n value: T,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n operation: string,\n emitTransitionalLegacyRefs = false\n): T {\n const visit = (current: unknown): unknown => {\n if (Array.isArray(current)) {\n const mapped: unknown[] = [];\n for (const entry of ownArrayDataValues(current)) mapped.push(visit(entry));\n return mapped;\n }\n if (current === null || typeof current !== 'object') return current;\n const record = current as Record<string, unknown>;\n const hasFormatDeclarations = Array.isArray(record.format_options);\n const declarationOwner =\n typeof record.product_id === 'string'\n ? record.product_id\n : typeof record.placement_id === 'string'\n ? record.placement_id\n : '(response)';\n let projected = record;\n if (hasFormatDeclarations) {\n const wireLegacyRefs: V1FormatId[] = [];\n const wireLegacyRefKeys = new Set<string>();\n const appendWireLegacyRefs = (refs: readonly V1FormatId[]): void => {\n for (const ref of refs) {\n const key = legacyFormatRefKey(ref);\n if (key === undefined || wireLegacyRefKeys.has(key)) continue;\n wireLegacyRefKeys.add(key);\n wireLegacyRefs.push(cloneWireData(ref));\n }\n };\n if (emitTransitionalLegacyRefs) {\n const authoredRefs = authoredFormatIdsByOwner.get(record);\n if (authoredRefs) appendWireLegacyRefs(authoredRefs);\n }\n const formatOptions: unknown[] = [];\n const declarations = ownArrayDataValues(record.format_options as unknown[]);\n for (let index = 0; index < declarations.length; index++) {\n const value = declarations[index];\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n formatOptions.push(value);\n continue;\n }\n const declaration = value as Record<string, unknown>;\n if (declaration.canonical_formats_only === true) {\n formatOptions.push(declaration);\n continue;\n }\n let refs = ownArrayDataValues(\n legacyFormatRefsForDeclaration(declaration)\n ) as import('../../../v2/projection/types').V1FormatId[];\n if (emitTransitionalLegacyRefs && refs.length > 0) {\n const clonedRefs = refs.map(ref => cloneWireData(ref));\n appendWireLegacyRefs(clonedRefs);\n formatOptions.push({ ...declaration, v1_format_ref: clonedRefs });\n continue;\n }\n if (declaration.format_kind !== 'custom') {\n formatOptions.push(declaration);\n continue;\n }\n if (refs.length === 0) {\n try {\n const resolved = resolveCanonicalFormatLegacyRefs(canonicalFormatLegacyResolver, {\n source: 'product',\n declaration: declaration as unknown as import('../../../v2/projection/types').V2ProductFormatDeclaration,\n productId: declarationOwner,\n field: `${declarationOwner}.format_options[${index}]`,\n });\n refs = resolved\n ? (ownArrayDataValues(resolved) as import('../../../v2/projection/types').V1FormatId[])\n : [];\n } catch (error) {\n if (!(error instanceof CanonicalFormatLegacyResolutionError)) throw error;\n throw new CreativeFormatProjectionError(\n operation,\n `(format owner:${declarationOwner})`,\n 'canonical format legacy resolver returned an invalid custom declaration mapping'\n );\n }\n }\n if (refs.length === 0) {\n throw new CreativeFormatProjectionError(\n operation,\n `(format owner:${declarationOwner})`,\n 'custom canonical declaration must set canonical_formats_only or provide an explicit legacy mapping'\n );\n }\n const clonedRefs = refs.map(ref => cloneWireData(ref));\n if (emitTransitionalLegacyRefs) appendWireLegacyRefs(clonedRefs);\n formatOptions.push({ ...declaration, v1_format_ref: clonedRefs });\n }\n projected = {\n ...record,\n format_options: formatOptions,\n ...(emitTransitionalLegacyRefs && wireLegacyRefs.length > 0 && { format_ids: wireLegacyRefs }),\n };\n }\n let changed = projected !== record;\n const next: Record<string, unknown> = { ...projected };\n for (const [key, child] of Object.entries(projected)) {\n if (hasFormatDeclarations && key === 'format_options') continue;\n const visited = visit(child);\n if (visited !== child) {\n next[key] = visited;\n changed = true;\n }\n }\n return changed ? next : projected;\n };\n return visit(value) as T;\n}\n\nfunction asProductResponseForWire<T extends { products?: unknown[] }>(\n canonicalResponse: T,\n wireMode: 'canonical' | 'legacy',\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver,\n emitTransitionalLegacyRefs = false\n): T {\n if (wireMode === 'canonical') {\n const responseForWire =\n emitTransitionalLegacyRefs && canonicalResponse !== null && typeof canonicalResponse === 'object'\n ? removeResolvedLegacyDropErrors(\n canonicalResponse,\n resolvedLegacyDropDiagnosticsByResponse.get(canonicalResponse) ?? []\n )\n : canonicalResponse;\n return attachCanonicalFormatWireRefs(\n responseForWire,\n canonicalFormatLegacyResolver,\n 'get_products',\n emitTransitionalLegacyRefs\n );\n }\n if (!Array.isArray(canonicalResponse.products)) return canonicalResponse;\n const products = canonicalResponse.products.map(product => {\n const projected = projectV2ProductToV1(product as V2Product, { canonicalFormatLegacyResolver });\n if (projected.diagnostics.length > 0) {\n const first = projected.diagnostics[0]!;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a canonical format that cannot be represented on the configured legacy wire.',\n field: first.field,\n suggestion:\n 'Add an explicit legacy format mapping to the canonical declaration, or configure this server for AdCP 3.1 or newer.',\n });\n }\n return projected.v1;\n });\n return { ...canonicalResponse, products } as T;\n}\n\n/**\n * Enforce the documented inline-`account_id` refusal for resolution modes\n * that declare the field meaningless on the wire — `'implicit'` (since\n * #1364) and `'derived'` (since adcp-client#1468). Both modes share the\n * same wire contract: the buyer does not pass `account_id` inline; the\n * framework derives the tenant from the authenticated principal (after a\n * `sync_accounts` step for `'implicit'`; directly for `'derived'`).\n *\n * Throws `AdcpError('INVALID_REQUEST')` before reaching the adopter's\n * `accounts.resolve`, so each adopter doesn't reimplement the same\n * `if (ref?.account_id) return null` branch and the wire response is\n * consistent across both modes. The brand+operator union arm is\n * permitted — only `account_id`-shaped references are refused.\n *\n * Mode-specific message and suggestion: `'implicit'` adopters get the\n * `sync_accounts`-first guidance; `'derived'` adopters get the single-\n * tenant explanation (no `sync_accounts` step exists in derived mode —\n * the auth principal alone identifies the tenant).\n *\n * Documented at `AccountStore.resolution` in `account.ts`.\n */\nfunction refuseInlineAccountIdWhenForbidden(\n resolution: 'explicit' | 'implicit' | 'derived' | undefined,\n ref: AccountReference | undefined\n): void {\n if (resolution !== 'implicit' && resolution !== 'derived') return;\n if (refAccountId(ref) === undefined) return;\n if (resolution === 'implicit') {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'This platform resolves accounts from the authenticated principal — call sync_accounts first; do not pass account.account_id inline.',\n field: 'account.account_id',\n suggestion:\n 'Call sync_accounts to associate accounts with your principal, then omit account_id on subsequent calls.',\n });\n }\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'This single-tenant agent identifies the tenant from the authenticated principal alone — do not pass account.account_id inline; the field is meaningless on the wire for derived-resolution agents.',\n field: 'account.account_id',\n suggestion: 'Omit the account field; the framework derives the tenant from your authenticated credential.',\n });\n}\n\n/**\n * Dev-mode warning when a multi-id read tool returns fewer rows than\n * the buyer requested — the canonical signal that the platform is\n * silently truncating to `<id_field>[0]` (closes #1342, follow-up\n * #1399, extended in #1410 to additional read-by-id surfaces). Catches\n * the bug class where adopters write the recommended pattern wrong on\n * first pass; quiet in production where legitimate misses (deleted,\n * archived, cross-account) are routine and warning on every miss would\n * be noise.\n *\n * Suppressible via `ADCP_SUPPRESS_MULTI_ID_WARN=1` for adopters whose\n * legitimate-miss rate is high (deleted-account-rich datasets, etc.).\n *\n * Sync / upsert surfaces (`syncCreatives`, `syncCatalogs`, `syncPlans`)\n * are intentionally out of scope — those have a different shape where\n * pass-through is the obvious pattern and \"did all rows roundtrip?\"\n * isn't a clean question.\n */\nfunction warnIfTruncatedMultiIdResponse(\n toolName: 'getMediaBuyDelivery' | 'getMediaBuys' | 'listCreatives' | 'getCreativeDelivery' | 'getSignals',\n idFieldName: 'media_buy_ids' | 'creative_ids' | 'signal_ids',\n requestedIds: readonly unknown[] | undefined,\n responseArray: readonly unknown[] | undefined,\n logger: AdcpLogger\n): void {\n if (process.env.NODE_ENV === 'production') return;\n if (process.env.ADCP_SUPPRESS_MULTI_ID_WARN === '1') return;\n if (!requestedIds || requestedIds.length === 0) return;\n const returned = Array.isArray(responseArray) ? responseArray.length : 0;\n if (returned >= requestedIds.length) return;\n // Empty `<id_field>` is filtered above as paginated-mode (no truncation\n // possible without a request to compare against).\n logger.warn(\n `[adcp/sdk] ${toolName}: platform returned ${returned} row${returned === 1 ? '' : 's'} for ${requestedIds.length} requested ${idFieldName} — ` +\n `the platform may be silently truncating to ${idFieldName}[0]. ` +\n `See https://github.com/adcontextprotocol/adcp-client/issues/1342 for the multi-id pass-through contract. ` +\n `Suppress with ADCP_SUPPRESS_MULTI_ID_WARN=1 if legitimate misses (deleted / cross-account) are routine.`\n );\n}\n\n/**\n * Lifecycle observability hooks the v6 runtime fires at well-known points.\n * Each callback is optional; throws are caught and logged via the framework\n * logger so adopter telemetry mistakes never break dispatch.\n *\n * Reach for these to wire DataDog / Prometheus / OpenTelemetry / structured\n * logging without baking any specific backend into the framework. For\n * OpenTelemetry, the `@adcp/sdk/telemetry/otel` peer-dep adapter returns\n * a pre-wired implementation with AdCP-aligned span / metric names.\n *\n * **What's instrumented today (v6.0):**\n * - Task lifecycle (`onTaskCreate`, `onTaskTransition`) — fires from `dispatchHitl`\n * - Webhook delivery (`onWebhookEmit`) — fires after each push-notification post\n * - Status-change events (`onStatusChangePublish`) — wraps the per-server bus\n * - Account resolution (`onAccountResolve`) — fires after every `resolve()` call\n *\n * **Coming in v6.1:**\n * - Per-tool dispatch latency (`onDispatchStart` / `onDispatchEnd`) —\n * requires wrapping every handler entry point; lands when the per-handler\n * instrumentation pass goes through.\n * - Idempotency replay rate (covered at the framework layer when v5 hooks land)\n * - State-store reads (per-handler instrumentation)\n *\n * @public\n */\nexport interface DecisioningObservabilityHooks {\n /**\n * Fired after `accounts.resolve` (or `resolveAccountFromAuth`) returns.\n * `resolved: false` means the resolver returned `null` — caller maps to\n * `ACCOUNT_NOT_FOUND`. `fromAuth: true` indicates the auth-derived path\n * (tools without an `account` field on the wire). `accountId` is the\n * resolved tenant id when `resolved: true`, undefined otherwise — useful\n * for dimensioning DD / Prometheus tag sets by tenant.\n *\n * **Cardinality warning:** if you forward `accountId` to a multi-tenant\n * metric backend, pre-bucket or sample — high tenant counts will\n * explode tag cardinality.\n */\n onAccountResolve?(info: {\n tool: string;\n durationMs: number;\n resolved: boolean;\n fromAuth: boolean;\n accountId?: string;\n }): void;\n\n /**\n * Fired when `dispatchHitl` allocates a new task in the registry.\n * `durationMs` is the registry-create call latency (typically\n * sub-millisecond for in-memory, single-digit ms for Postgres).\n */\n onTaskCreate?(info: { tool: string; taskId: string; accountId: string; durationMs: number }): void;\n\n /**\n * Fired when a task transitions to a terminal state (`completed`,\n * `failed`, or `failed-write` when the registry write itself fails).\n * `durationMs` is from create → terminal. `errorCode` is the structured\n * error code for the failure cases — pre-bucketed for metric tags\n * (matches `ErrorCode` enum + the framework-synthetic\n * `'REGISTRY_WRITE_FAILED'` value).\n */\n onTaskTransition?(info: {\n taskId: string;\n tool: string;\n accountId: string;\n status: 'completed' | 'failed';\n durationMs: number;\n errorCode?: string;\n }): void;\n\n /**\n * Fired after a push-notification webhook delivery attempt completes\n * (success or all retries exhausted). Adopters wire to per-buyer\n * deliverability dashboards.\n *\n * `errorCode` is a single bucketed value adopters tag metrics with\n * (`'TIMEOUT'`, `'CONNECTION_REFUSED'`, `'HTTP_4XX'`, `'HTTP_5XX'`,\n * `'SIGNATURE_FAILURE'`, `'UNKNOWN'` — derived from the underlying\n * emitter error). `errorMessages` is the raw free-text error list for\n * structured-log adopters; do NOT forward this to metrics tag values.\n */\n onWebhookEmit?(info: {\n taskId: string;\n tool: string;\n status: string;\n url: string;\n success: boolean;\n durationMs: number;\n errorCode?: string;\n errorMessages?: string[];\n }): void;\n\n /**\n * Fired after each `publishStatusChange(...)` event (per-server bus +\n * module-level singleton routes both go through the wrapped bus). Lets\n * adopters meter event rates per resource type without subscribing.\n */\n onStatusChangePublish?(info: { accountId: string; resourceType: string; resourceId: string }): void;\n}\n\nexport type LegacyDecisioningHandlerGroups = Pick<\n AdcpServerConfig,\n 'mediaBuy' | 'creative' | 'governance' | 'brandRights'\n>;\n\nexport interface CreateAdcpServerFromPlatformOptions extends Omit<\n AdcpServerConfig,\n 'resolveAccount' | 'capabilities' | 'name' | 'version' | 'mediaBuy' | 'creative' | 'governance' | 'brandRights'\n> {\n name: string;\n version: string;\n /**\n * Explicit compatibility seam for raw protocol handlers that have not yet\n * migrated to canonical DecisioningPlatform methods. Wire support remains\n * available through AdCP 3.x, but raw creative identity must never look like\n * a primary platform hook.\n */\n legacyHandlers?: LegacyDecisioningHandlerGroups;\n /**\n * Convert seller/creative-agent-specific legacy format refs before modern\n * platform handlers run. Known AAO formats are normalized automatically;\n * an unmapped ref is rejected unless this callback returns a canonical\n * declaration (normally `format_kind: 'custom'` + shape/schema).\n */\n legacyCreativeFormatConverter?: LegacyFormatConverter;\n /**\n * Resolve seller-specific legacy product formats asynchronously before the\n * canonical `get_products` projection. The resolver receives only the exact\n * format tuple plus non-secret request routing context and fails closed.\n */\n legacyCreativeFormatResolver?: LegacyFormatResolver;\n /** Shared resolver-phase deadline in milliseconds. Defaults to 10 seconds. */\n legacyCreativeFormatResolverTimeoutMs?: number;\n /** Maximum concurrent resolver calls within one get_products response (1–64). Defaults to 8. */\n legacyCreativeFormatResolverConcurrency?: number;\n /** Resolve persisted canonical custom formats when this server emits a legacy wire response. */\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver;\n /**\n * Override the framework's task registry. Useful for tests that want to\n * pre-seed task records or assert on them across multiple servers.\n * Defaults to a fresh `createInMemoryTaskRegistry()` per server instance\n * (gated by NODE_ENV — see `buildDefaultTaskRegistry`).\n */\n taskRegistry?: TaskRegistry;\n /**\n * Override the framework's status-change event bus for this server.\n * Defaults to a fresh per-server `createInMemoryStatusChangeBus()` so\n * tests get isolation without touching the module-level singleton from\n * `publishStatusChange(...)`. Adopters who publish from non-handler code\n * (webhook handlers, crons) typically use the module-level primitive\n * — pass an explicit bus here only when you want a per-server channel.\n */\n statusChangeBus?: StatusChangeBus;\n\n /**\n * Lifecycle observability hooks. Adopters wire their telemetry backend\n * (DataDog, Prometheus, OpenTelemetry, structured logger, etc.) by\n * supplying any subset of the callbacks below. The framework calls them\n * at well-known dispatch points; throws inside callbacks are caught and\n * logged via `opts.logger.warn` — they never break dispatch.\n *\n * For an out-of-the-box OpenTelemetry binding, `@adcp/sdk/telemetry/otel`\n * (peer-dep, opt-in) returns a pre-wired `DecisioningObservabilityHooks`\n * object. Adopters using DataDog, Prometheus, or hand-rolled metrics\n * implement the callbacks directly.\n */\n observability?: DecisioningObservabilityHooks;\n\n /**\n * Merge-seam collision behavior. When an adopter-supplied custom handler\n * (e.g. `opts.legacyHandlers.mediaBuy.getMediaBuys`) collides with a platform-derived\n * handler (e.g. `platform.sales.getMediaBuys`), the platform-derived one\n * wins per-key and the adopter override is silently shadowed.\n *\n * Modes:\n * - `'warn'` (default) — log a warning at every construction that hits a\n * collision. Migration signal without breaking running deployments.\n * - `'log-once'` — log a warning the first time each `(domain, keys)`\n * collision is seen in the process; subsequent constructions with the\n * same shape stay silent. Right default for multi-tenant hosts (one\n * process, N `createAdcpServerFromPlatform` calls) and hot-reload dev\n * (server reconstructed every file change).\n * - `'strict'` — throw `PlatformConfigError`. Recommended for CI / new\n * deployments where the v6 surface is the canonical source.\n * - `'silent'` — skip the check. For adopters who deliberately use the\n * merge seam as an override (e.g., wrapping platform behavior with\n * logging in their custom handler).\n */\n mergeSeam?: MergeSeamMode;\n\n /**\n * Override the webhook emitter the framework uses to push HITL task\n * completion to the buyer's `push_notification_config.url`. Default: when\n * the host wired `webhooks` on the underlying `AdcpServerConfig`, use\n * `ctx.emitWebhook` from the per-request HandlerContext (the framework\n * binds `webhookEmitter.emit` to it). Pass an explicit emitter here when\n * you want a dedicated webhook delivery path for task completions\n * (different signing key, different retry policy, different fetch impl)\n * separate from your other webhook emissions, or to inject a fake for\n * tests without wiring full RFC 9421 signing.\n *\n * Custom emitters are restricted to test/development because they cannot\n * prove the AdCP 3.2 durable delivery binding, retry horizon, or retired-ID\n * tombstone contract. Production deployments MUST configure `webhooks` and\n * use the framework emitter exposed as `ctx.emitWebhook`.\n */\n taskWebhookEmitter?: {\n emit: NonNullable<HandlerContext<Account>['emitWebhook']>;\n /**\n * Set to `true` when this test/development emitter does NOT sign the\n * webhook payload (RFC 9421). This flag is descriptive only; custom task\n * emitters are rejected outside test/development regardless of signing.\n */\n unsigned?: boolean;\n };\n\n /**\n * `comply_test_controller` adapter set. When supplied, the framework\n * composes `createComplyController` (`@adcp/sdk/testing`) with the adopter's\n * adapters and registers the wire tool after platform handlers wire up. MCP\n * registration is framework-owned so principal visibility, `tools/list`\n * filtering, and direct-call method-not-found behavior can be enforced.\n *\n * Adopter declares the scenarios they support — `seed: { product, … }`,\n * `force: { creative_status, … }`, `simulate: { delivery, … }`. The\n * framework auto-derives `capabilities.compliance_testing.scenarios`\n * from which adapters are present, projecting the discovery field to\n * `get_adcp_capabilities` so conformance harnesses see what's\n * supported.\n *\n * **Deployment + sandbox gating.** Supplying `complyTest` wires the\n * controller for sandbox/conformance deployments. The framework then hides\n * the capability block, filters `tools/list`, and returns MCP method-not-\n * found for direct controller calls unless the auth-derived principal\n * resolves to `mode: 'sandbox' | 'mock'` (or legacy resolved\n * `sandbox: true`, or the legacy deployment bridge `ADCP_SANDBOX=1` is set).\n * Within a visible sandbox/mock deployment, target-account dispatch still\n * refuses live or unresolved non-sandbox accounts with `PERMISSION_DENIED`;\n * a buyer-supplied `account.sandbox: true` is only an unresolved-target\n * fallback and never overrides a resolved live account.\n *\n * **Capability-vs-adapter consistency.** Both directions are enforced:\n *\n * - `capabilities.compliance_testing` declared without `complyTest` →\n * `PlatformConfigError` at construction (and a **compile-time error**\n * when `P` is typed with `compliance_testing` non-optional, via\n * `RequiredOptsFor<P>`).\n * - `complyTest` supplied without `capabilities.compliance_testing` →\n * `PlatformConfigError` at construction (runtime defense-in-depth).\n *\n * To enforce the invariant at compile time when building the platform\n * as an object literal, wrap it with `definePlatformWithCompliance`:\n * TypeScript will then require `compliance_testing` on the platform\n * and `complyTest` on opts together.\n *\n * @public\n */\n complyTest?: ComplyControllerConfig;\n\n /**\n * Single-pool shortcut: pass a `pg.Pool` (or any `PgQueryable`) and the\n * framework wires `idempotency` + `ctxMetadata` + `taskRegistry`\n * internally with sensible defaults. One connection, three concerns.\n *\n * Adopters who pass any of `idempotency` / `ctxMetadata` / `taskRegistry`\n * explicitly keep override priority — the explicit values win, and the\n * pool fills only the unset ones.\n *\n * Run `getAllAdcpMigrations()` once per database to create the three\n * required tables (idempotency cache, ctx-metadata cache, task registry).\n *\n * @example\n * ```ts\n * import { Pool } from 'pg';\n * import {\n * createAdcpServerFromPlatform,\n * getAllAdcpMigrations,\n * } from '@adcp/sdk/server';\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * await pool.query(getAllAdcpMigrations());\n *\n * const server = createAdcpServerFromPlatform(myPlatform, {\n * name: 'my-agent',\n * version: '1.0.0',\n * pool, // wires all three persistence stores\n * });\n * ```\n *\n * **Memory-only deployment:** omit `pool` entirely. Framework defaults to\n * in-memory backends for all three (fine for dev / single-process; not\n * suitable for cluster).\n */\n pool?: PgQueryable;\n\n /**\n * Ctx-metadata store. Wire to enable the v6.1 `ctx_metadata` round-trip\n * cache: publishers attach opaque platform-specific blobs to any returned\n * resource (`{ product_id, ctx_metadata: { gam: {...} } }`); the framework\n * persists by `(account.id, kind, id)` and threads back into\n * `ctx.ctxMetadata` on subsequent calls referencing the same ID.\n *\n * Memory backend (`memoryCtxMetadataStore()`) for dev / single-process.\n * Postgres (`pgCtxMetadataStore(pool)`) for cluster — silent ctx_metadata\n * loss after rolling restart on memory backend produces \"package not\n * found\" errors that look like publisher bugs and run for weeks.\n *\n * @example\n * ```ts\n * import { Pool } from 'pg';\n * import {\n * createAdcpServerFromPlatform,\n * createCtxMetadataStore,\n * pgCtxMetadataStore,\n * getCtxMetadataMigration,\n * } from '@adcp/sdk/server';\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * await pool.query(getCtxMetadataMigration());\n *\n * const ctxMetadata = createCtxMetadataStore({ backend: pgCtxMetadataStore(pool) });\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * name: 'My Adapter',\n * version: '1.0.0',\n * ctxMetadata,\n * });\n * ```\n *\n * @see docs/proposals/decisioning-platform-v6-1-ctx-metadata.md\n */\n ctxMetadata?: CtxMetadataStore;\n\n /**\n * Opinionated media-buy store that satisfies the seller spec contract for\n * `targeting_overlay` echo: persist `packages[].targeting_overlay` from\n * `create_media_buy`, echo it on `get_media_buys`, deep-merge across\n * `update_media_buy` without dropping prior `property_list` /\n * `collection_list` references.\n *\n * Wire to honor the\n * `schemas/cache/<v>/media-buy/get-media-buys-response.json` contract\n * without each adapter persisting + merging by hand. Sellers claiming\n * `property-lists` / `collection-lists` MUST echo the persisted refs;\n * `mediaBuyStore` is the framework-side way to do it.\n *\n * Backed by any `AdcpStateStore` — `InMemoryStateStore` for dev,\n * `PostgresStateStore` for production. Failures are logged and swallowed\n * (auto-echo MUST NOT break a successful seller response).\n *\n * @example\n * ```ts\n * import {\n * createAdcpServerFromPlatform,\n * createMediaBuyStore,\n * InMemoryStateStore,\n * } from '@adcp/sdk/server';\n *\n * const stateStore = new InMemoryStateStore();\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * mediaBuyStore: createMediaBuyStore({ store: stateStore }),\n * });\n * ```\n */\n mediaBuyStore?: MediaBuyStore;\n\n /**\n * Proposal lifecycle ledger — wires the v1.5 ProposalManager dispatch\n * seams. When supplied alongside `platform.proposalManager`, the\n * framework drives the full lifecycle:\n *\n * - `getProducts` / refine responses persist `proposals[]` as DRAFT\n * records (with typed recipes pulled from\n * `Product.implementation_config`).\n * - `refine[i].action: 'finalize'` entries are intercepted before\n * dispatch; the manager's `finalizeProposal` is called and the\n * proposal is committed via the store.\n * - `createMediaBuy` requests carrying `proposal_id` are validated\n * against expiry + capability overlap, the proposal is reserved\n * (atomic CAS `COMMITTED → CONSUMING`), and `ctx.recipes` is\n * hydrated from the record. Adapter success → `CONSUMING →\n * CONSUMED`; adapter throw → rollback to `COMMITTED`.\n * - `updateMediaBuy` / `getMediaBuyDelivery` hydrate `ctx.recipes`\n * via the reverse-index `getByMediaBuyId`.\n *\n * Backed by any {@link ProposalStore} — `InMemoryProposalStore` for\n * dev / single-process; adopters wire their own durable backings for\n * production. Without this option (and/or without\n * `platform.proposalManager`), the v1 path runs unchanged.\n */\n proposalStore?: import('../proposal').ProposalStore;\n\n /**\n * Allow `push_notification_config.url` to point at loopback / private-IP\n * destinations. Default is `false` — the framework's request-ingest\n * validator rejects loopback (`localhost`, `127.0.0.0/8`, `::1`),\n * RFC 1918 / CGNAT / link-local ranges, and IPv4-mapped IPv6 forms\n * targeting any of those, since accepting them at production webhook\n * endpoints is a SSRF / cloud-metadata exfiltration path.\n *\n * Set `true` for sandbox / local-testing deployments where\n * adopter-controlled receivers (storyboard webhook receivers, pytest\n * httptest fixtures) bind to `127.0.0.1:<ephemeral>`. The flag bypasses\n * ONLY the private-range branch — malformed-URL, non-http(s) scheme,\n * and the `http://` reject (separately gated by NODE_ENV / the\n * `ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS` env) all still fire.\n *\n * Adopters typically scope this themselves on `NODE_ENV !== 'production'`\n * or a sandbox env flag — the framework doesn't auto-enable it because\n * the safe default is \"reject private destinations.\" When the flag is\n * `true` AND `NODE_ENV` is unset / `'production'`, the framework emits\n * a one-shot console.warn at construction calling out the relaxation.\n */\n allowPrivateWebhookUrls?: boolean;\n\n /**\n * When `true`, throw `PlatformConfigError` at construction if any\n * specialism declared in `capabilities.specialisms[]` is missing a\n * platform method matching one of its required tools (per the manifest's\n * `SPECIALISM_REQUIRED_TOOLS`). Default `false` — the framework emits a\n * `console.warn` for each missing method instead, so adopters mid-\n * implementation aren't blocked on incomplete specialism coverage.\n *\n * Recommended for production CI builds: catches \"claimed sales-non-\n * guaranteed but forgot to implement getProducts\" before the deploy.\n * Recommended off in dev / sandbox where adopters are iterating.\n *\n * Tracked: adcp-client#1299 (manifest adoption stage 3).\n */\n strictSpecialismValidation?: boolean;\n\n /**\n * @deprecated Ignored under AdCP 3.2. Synchronous terminal responses MUST\n * remain silent on the task-webhook channel; only an async task lifecycle\n * may publish later status observations.\n */\n autoEmitCompletionWebhooks?: boolean;\n\n // ---------------------------------------------------------------------\n // Custom-handler escape hatch (incremental migration seam)\n // ---------------------------------------------------------------------\n //\n // The inherited `mediaBuy` / `creative` / `accounts` / `eventTracking` /\n // `signals` / `governance` / `brandRights` / `sponsoredIntelligence`\n // / `testController` keys (from `AdcpServerConfig`) accept raw\n // handler-style entries for tools the v6 platform doesn't yet model.\n //\n // **Merge semantics**: platform-derived handlers WIN per-key. Adopter-\n // supplied handlers fill gaps for un-wired tools (`getMediaBuys`,\n // `listCreativeFormats`, `providePerformanceFeedback`, `reportUsage`,\n // `syncEventSources`, `logEvent`, `getAccountFinancials`, content-\n // standards CRUD, etc.).\n //\n // Lets adopters with established handler-style adapters migrate\n // incrementally — move sales / audiences / signals to the v6 platform\n // shape today, keep custom handlers wired for tools whose specialism\n // interfaces are deferred to v1.1+ / rc.1 (event-tracking, catalog,\n // financials, content-standards, creative-review, brand-rights).\n //\n // createAdcpServerFromPlatform(platform, {\n // name: 'Adapter', version: '1.0.0',\n // legacyHandlers: { mediaBuy: {\n // // platform.sales already wires get_products / create / update /\n // // sync_creatives / get_media_buy_delivery; fill the rest:\n // getMediaBuys: async (params, ctx) => myDb.queryBuys(params),\n // providePerformanceFeedback: async (params, ctx) => ack(params),\n // } },\n // eventTracking: {\n // // platform.audiences wires sync_audiences; fill the trio:\n // syncEventSources: async (params, ctx) => ...,\n // logEvent: async (params, ctx) => ...,\n // syncCatalogs: async (params, ctx) => ...,\n // },\n // });\n}\n\n/**\n * Derives the opts type for `createAdcpServerFromPlatform` based on whether\n * the platform declares `capabilities.compliance_testing`.\n *\n * When `P` carries a non-optional `compliance_testing` block (e.g. because\n * the caller used `definePlatformWithCompliance`), this resolves to\n * `CreateAdcpServerFromPlatformOptions & { complyTest: ComplyControllerConfig }`,\n * making `complyTest` required. For all other platform shapes the resolved\n * type is the plain `CreateAdcpServerFromPlatformOptions` — no change.\n *\n * Both directions of the mismatch are still caught at runtime by the\n * `PlatformConfigError` check in `createAdcpServerFromPlatform` as\n * defense-in-depth for untyped callers.\n *\n * @public\n */\nexport type RequiredOptsFor<P extends DecisioningPlatform<any, any>> = P extends {\n capabilities: { compliance_testing: ComplianceTestingCapabilities };\n}\n ? CreateAdcpServerFromPlatformOptions & { complyTest: ComplyControllerConfig }\n : CreateAdcpServerFromPlatformOptions;\n\n/**\n * Adcp server returned by `createAdcpServerFromPlatform`. Adds task-state\n * accessors on top of the standard `AdcpServer` so test harnesses (and the\n * forthcoming `tasks/get` wire handler) can inspect lifecycle.\n */\nexport interface DecisioningAdcpServer extends AdcpServer {\n /**\n * Read the current lifecycle state for a HITL task. Returns `null` if the\n * `taskId` is unknown OR (when `expectedAccountId` is supplied) the\n * task's owning account doesn't match.\n *\n * **Multi-tenant isolation: pass `expectedAccountId` whenever the caller\n * has a buyer-derived account in scope.** Adopters wrapping this method\n * in a `tasks/get` wire handler MUST pass `ctx.account.id` to scope reads\n * — without it, any caller with a known `task_id` reads any tenant's\n * task lifecycle, including its `result` and `error` payloads. The\n * unscoped form (single-arg) is for ops / test harnesses that hold no\n * buyer account in scope.\n *\n * Async to accommodate storage-backed task registries\n * (`createPostgresTaskRegistry`); the in-memory impl resolves synchronously.\n */\n getTaskState<TResult = unknown>(taskId: string, expectedAccountId?: string): Promise<TaskRecord<TResult> | null>;\n /**\n * Await any in-flight background completion for `taskId` (HITL handoff\n * function still running). Resolves immediately if the task is terminal\n * or has no registered background. Used by tests + the `tasks/get` wire\n * path for deterministic settlement.\n */\n awaitTask(taskId: string): Promise<void>;\n /**\n * Per-server status-change bus. Delegates to the same internal bus the\n * framework uses for MCP Resources subscription projection.\n *\n * Use `server.statusChange.publish(...)` in tests to push events scoped\n * to this specific server instance — avoids contaminating sibling servers\n * that share the module-level `activeBus` when running multiple servers\n * in the same process. Production webhook/cron code that does not hold a\n * server reference keeps calling the module-level `publishStatusChange(...)`.\n *\n * **Projection wiring contract** (rc.1): when the MCP Resources subscription\n * projection commit lands, the projector MUST fan-in from BOTH this\n * per-server bus AND the module-level `activeBus`. Anchoring the subscriber\n * to only one source silently makes the other call site inert in production\n * — adopters who scope to `server.statusChange.publish(...)` for tenant\n * isolation must still reach buyer-facing subscriptions, and webhook/cron\n * code calling module-level `publishStatusChange(...)` must too.\n */\n statusChange: StatusChangeBus;\n}\n\n// Use `DecisioningPlatform<any, any>` for the generic constraint. The default\n// `TCtxMeta = Record<string, unknown>` doesn't accept adopter metadata interfaces\n// without an index signature (e.g., `interface MyMeta { brand_id: string }`),\n// which is a needless friction point — adopter metadata is opaque to the\n// framework, so we don't need to constrain it here.\nexport function createAdcpServerFromPlatform<P extends DecisioningPlatform<any, any>>(\n platform: P &\n RequiredPlatformsFor<P['capabilities']['specialisms'][number]> &\n RequiredCapabilitiesFor<P['capabilities']['specialisms'][number]>,\n opts: RequiredOptsFor<P>\n): DecisioningAdcpServer {\n // Runtime-only compatibility for pre-13 JavaScript/config objects. The\n // public type exposes these raw handler groups only under legacyHandlers;\n // retaining the hidden fallback avoids turning a type migration into an\n // abrupt wire-support break for untyped deployments.\n const runtimeLegacyOptions = opts as typeof opts & Partial<LegacyDecisioningHandlerGroups>;\n const legacyHandlers: LegacyDecisioningHandlerGroups = {\n mediaBuy: opts.legacyHandlers?.mediaBuy ?? runtimeLegacyOptions.mediaBuy,\n creative: opts.legacyHandlers?.creative ?? runtimeLegacyOptions.creative,\n governance: opts.legacyHandlers?.governance ?? runtimeLegacyOptions.governance,\n brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights,\n };\n validatePlatform(platform, {\n creative: legacyHandlers.creative,\n campaignGovernance: legacyHandlers.governance,\n brandRights: legacyHandlers.brandRights,\n });\n\n // Specialism→required-tools coverage check (adcp-client#1299).\n //\n // For each specialism declared in `capabilities.specialisms[]`, verify the\n // platform exposes a method matching every tool the manifest's\n // `SPECIALISM_REQUIRED_TOOLS` lists for that specialism. Catches the\n // common adopter mistake of declaring `'sales-non-guaranteed'` while\n // forgetting to implement `getProducts` / `createMediaBuy` / etc. —\n // would otherwise surface as a runtime error when a buyer actually\n // calls the missing tool.\n //\n // Default behavior is console.warn — strictSpecialismValidation: true\n // escalates to a thrown `PlatformConfigError`. The check is method-\n // presence-anywhere on the platform (not method-on-specific-field) so\n // adopters with non-standard layouts (e.g., a single mega-platform vs.\n // the conventional sales/creative/accounts split) aren't false-positively\n // flagged.\n {\n const specialisms = (platform.capabilities as { specialisms?: readonly string[] }).specialisms;\n const effectiveSpecialismSurface = {\n ...platform,\n mediaBuy: legacyHandlers.mediaBuy,\n creative: platform.creative ?? legacyHandlers.creative,\n governance: legacyHandlers.governance,\n brandRights: platform.brandRights ?? legacyHandlers.brandRights,\n };\n const issues = validateSpecialismRequiredTools(effectiveSpecialismSurface, specialisms);\n if (issues.length > 0) {\n const messages = issues.map(formatSpecialismIssue);\n if (opts.strictSpecialismValidation === true) {\n throw new PlatformConfigError(\n `Platform missing methods for ${issues.length} specialism-required tool(s). ` +\n `Strict mode (\\`strictSpecialismValidation: true\\`) treats this as fatal.\\n` +\n messages.map(m => ` - ${m}`).join('\\n')\n );\n }\n // eslint-disable-next-line no-console\n for (const message of messages) console.warn(message);\n }\n }\n\n // Compliance-testing capability/adapter consistency.\n //\n // Two failure modes the framework refuses to ship:\n // 1. Capability declared, no adapter — discovery field projects to\n // `get_adcp_capabilities` but the wire tool has no implementation\n // behind it. Conformance harnesses would dispatch and crash.\n // 2. Adapter wired, capability not declared — discovery field is\n // missing from `get_adcp_capabilities` so buyers / harnesses can't\n // tell the agent supports compliance testing.\n //\n // Both throw at construction with `PlatformConfigError`. Adopters who\n // want one without the other are doing it wrong; the right escape hatch\n // is to set `compliance_testing.scenarios = []` (a noop block, but the\n // spec disallows empty `scenarios` so this should never come up in\n // practice — included only to make the constraint explicit).\n const capHasComplianceTesting = platform.capabilities.compliance_testing != null;\n const optsHasComplyTest = opts.complyTest != null;\n if (capHasComplianceTesting && !optsHasComplyTest) {\n throw new PlatformConfigError(\n `capabilities.compliance_testing is declared but opts.complyTest is missing. ` +\n `Either supply complyTest (the ComplyControllerConfig adapter set) or remove ` +\n `the compliance_testing capability block — the framework refuses to advertise ` +\n `comply_test_controller without an implementation.`\n );\n }\n if (optsHasComplyTest && !capHasComplianceTesting) {\n throw new PlatformConfigError(\n `opts.complyTest is supplied but capabilities.compliance_testing is not declared. ` +\n `Add 'compliance_testing: {}' to your platform.capabilities — the framework needs ` +\n `the discovery block to project comply_test_controller scenarios on get_adcp_capabilities. ` +\n `Scenarios auto-derive from your supplied adapters; explicit 'scenarios: [...]' is optional.`\n );\n }\n\n // Footgun guard for `allowPrivateWebhookUrls` — same DEV_ALLOWLIST\n // inversion pattern as other production guards. Adopters\n // intentionally relaxing the SSRF gate for sandbox testing aren't\n // doing anything wrong; production deployments that flip this on\n // accidentally are. Warn on construction when the flag is true AND\n // NODE_ENV is unset / 'staging' / 'prod' / 'live' AND no explicit\n // ack env. Keeps the relaxation usable for real local-test setups\n // without letting it sneak into production.\n if (opts.allowPrivateWebhookUrls === true) {\n const env = process.env.NODE_ENV;\n const isDevOrTest = env === 'test' || env === 'development';\n const ack = process.env.ADCP_DECISIONING_ALLOW_PRIVATE_WEBHOOK_URLS === '1';\n if (!isDevOrTest && !ack) {\n // eslint-disable-next-line no-console\n console.warn(\n '[adcp/decisioning] allowPrivateWebhookUrls: true relaxes the loopback / private-IP ' +\n 'guard on push_notification_config.url. NODE_ENV is not test/development and ' +\n 'ADCP_DECISIONING_ALLOW_PRIVATE_WEBHOOK_URLS is not set — accepting private ' +\n 'destinations in production is a SSRF / cloud-metadata exfiltration path. ' +\n 'For sandbox/local testing, scope this on your own NODE_ENV check.'\n );\n }\n }\n\n if (opts.taskWebhookEmitter && process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'development') {\n throw new PlatformConfigError(\n 'taskWebhookEmitter is test/development-only under AdCP 3.2. Production task webhooks must use the ' +\n 'framework webhooks configuration so durable delivery binding, retry-horizon advertisement, signing, ' +\n 'and retired delivery-ID tombstones are enforced.'\n );\n }\n\n // Pool shortcut: when `opts.pool` is wired and a specific store/registry\n // is NOT explicitly set, derive that store from pool with sensible\n // defaults. Explicit per-store opts always win — this is \"fill the gaps,\"\n // not \"override what the adopter passed.\"\n const pooledIdempotency: IdempotencyStore | undefined =\n opts.pool && opts.idempotency === undefined ? createIdempotencyStore({ backend: pgBackend(opts.pool) }) : undefined;\n const pooledCtxMetadata: CtxMetadataStore | undefined =\n opts.pool && opts.ctxMetadata === undefined\n ? createCtxMetadataStore({ backend: pgCtxMetadataStore(opts.pool) })\n : undefined;\n const pooledTaskRegistry: TaskRegistry | undefined =\n opts.pool && opts.taskRegistry === undefined ? createPostgresTaskRegistry({ pool: opts.pool }) : undefined;\n\n // Effective resolved values. Explicit > pooled > default.\n const effectiveIdempotency: IdempotencyStore | 'disabled' | undefined = opts.idempotency ?? pooledIdempotency;\n const effectiveCtxMetadata: CtxMetadataStore | undefined = opts.ctxMetadata ?? pooledCtxMetadata;\n const taskRegistry = opts.taskRegistry ?? pooledTaskRegistry ?? buildDefaultTaskRegistry();\n const baseBus = opts.statusChangeBus ?? createInMemoryStatusChangeBus();\n const taskWebhookEmit = opts.taskWebhookEmitter?.emit;\n\n // Wrap the status-change bus so every publish fires onStatusChangePublish.\n // Subscribers / recent-buffer behavior pass through unchanged — the wrap\n // is only for the publish side. Hook-throw is caught + logged so adopter\n // telemetry mistakes don't break event delivery.\n const observability = opts.observability;\n const statusChangeBus: StatusChangeBus = observability?.onStatusChangePublish\n ? wrapBusWithObservability(baseBus, observability)\n : baseBus;\n const fwLogger = opts.logger ?? DEFAULT_FRAMEWORK_LOGGER;\n const mergeOpts = { mode: opts.mergeSeam ?? 'warn', logger: fwLogger };\n\n // Project per-domain capability blocks declared on the platform onto\n // get_adcp_capabilities via createAdcpServer's `overrides.media_buy`\n // deep-merge seam. Adopters declare audience_targeting /\n // conversion_tracking / content_standards / supported_optimization_metrics\n // / frequency_capping on `platform.capabilities`; the framework wires\n // the deep-merge so buyers see the discovery fields without an opaque\n // custom get_adcp_capabilities tool (which the framework refuses anyway).\n //\n // Each rich block also forces the corresponding `media_buy.features.*`\n // boolean to `true`. Buyers gating on `features.audience_targeting`\n // (which the framework auto-derives as `false` by default) would\n // otherwise skip the rich block sitting next to it.\n //\n // `supported_optimization_metrics` (adcp#4669) and `frequency_capping`\n // (adcp#4670) are AdCP 3.1 additions. They have no corresponding\n // `features.*` boolean — buyers gate on presence of the block itself.\n const at = platform.capabilities.audience_targeting;\n const ct = platform.capabilities.conversion_tracking;\n const cs = platform.capabilities.content_standards;\n const explicitSom = platform.capabilities.supported_optimization_metrics;\n const derivedSom =\n explicitSom == null && platform.capabilities.productCatalog != null\n ? rollupOptimizationMetricsFromProducts(platform.capabilities.productCatalog)\n : undefined;\n const somCandidate = explicitSom ?? derivedSom;\n // Empty arrays are an explicit \"no seller-level rollup to advertise\" signal,\n // not a malformed capability. Omit the wire field so buyers do not see an\n // empty support list as a positive 3.1 metric-optimization declaration.\n const som = somCandidate != null && somCandidate.length > 0 ? somCandidate : undefined;\n const fc = platform.capabilities.frequency_capping;\n const targeting = platform.capabilities.targeting\n ? normalizeTargetingCapabilities(platform.capabilities.targeting)\n : undefined;\n const hasSalesPlatform =\n platform.sales != null || platform.mediaBuyLifecycle != null || platform.proposalManager != null;\n const supportsProposals =\n platform.capabilities.supportsProposals ??\n (platform.proposalManager != null ||\n platform.mediaBuyLifecycle?.requestProposals != null ||\n platform.mediaBuyLifecycle?.refineProposals != null\n ? true\n : hasSalesPlatform\n ? false\n : undefined);\n const hasMediaBuyProjection =\n hasSalesPlatform ||\n at != null ||\n ct != null ||\n cs != null ||\n som != null ||\n fc != null ||\n targeting != null ||\n supportsProposals !== undefined;\n // App `version` / capability `build_version` are deployment metadata and\n // never negotiate protocol behavior. Only the configured AdCP schema pin\n // determines whether this server may advertise the 3.1 feature bit (3.2+\n // makes canonical creatives part of the release contract itself).\n const configuredAdcpVersion = opts.adcpVersion ?? ADCP_VERSION;\n const configuredRelease = parseAdcpRelease(configuredAdcpVersion);\n if (!configuredRelease) {\n throw new PlatformConfigError(\n `Configured AdCP version '${configuredAdcpVersion}' is not a valid release identifier`\n );\n }\n for (const advertisedVersion of platform.capabilities.supported_versions ?? []) {\n const advertisedRelease = parseAdcpRelease(advertisedVersion);\n if (!advertisedRelease) {\n throw new PlatformConfigError(\n `capabilities.supported_versions contains invalid release identifier '${advertisedVersion}'`\n );\n }\n if (compareAdcpReleases(advertisedRelease, configuredRelease) > 0) {\n throw new PlatformConfigError(\n `capabilities.supported_versions advertises AdCP ${advertisedVersion}, newer than the configured server schema ${configuredAdcpVersion}`\n );\n }\n }\n const canonicalCreativeCapability = supportsCanonicalCreativeCapability(configuredAdcpVersion);\n // createAdcpServerFromPlatform is the modern, canonical SDK boundary and\n // advertises canonicalCreatives for every capable release. In transitional\n // 3.1, concrete legacy request fields still select the legacy projection;\n // an otherwise ambiguous read follows the capability the server advertises.\n const defaultCreativeWireMode = canonicalCreativeCapability ? 'canonical' : 'legacy';\n const mediaBuyOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['media_buy']>> = {\n ...(hasSalesPlatform && {\n buying_modes: supportsProposals ? (['brief', 'refine'] as const) : (['brief'] as const),\n }),\n ...(at != null && { audience_targeting: at }),\n ...(ct != null && { conversion_tracking: ct }),\n ...(cs != null && { content_standards: cs }),\n ...(som != null && { supported_optimization_metrics: som }),\n ...(fc != null && { frequency_capping: fc }),\n ...(targeting != null && { execution: { targeting } }),\n ...(supportsProposals !== undefined && { supports_proposals: supportsProposals }),\n features: {\n ...(canonicalCreativeCapability && { canonical_creatives: true }),\n ...(at != null && { audience_targeting: true }),\n ...(ct != null && { conversion_tracking: true }),\n ...(cs != null && { content_standards: true }),\n },\n };\n\n if (process.env.NODE_ENV !== 'production') {\n if (explicitSom != null && explicitSom.length > 0) {\n fwLogger.info(\n `[adcp/decisioning] using explicit media_buy.supported_optimization_metrics override (${explicitSom.length} metric${explicitSom.length === 1 ? '' : 's'}).`\n );\n } else if (derivedSom != null) {\n fwLogger.info(\n `[adcp/decisioning] derived media_buy.supported_optimization_metrics from productCatalog (${derivedSom.length} metric${derivedSom.length === 1 ? '' : 's'}).`\n );\n }\n }\n\n // Brand-protocol capability projection. Adopters who declare\n // `capabilities.brand` get the block projected via `overrides.brand`.\n // When `BrandRightsPlatform` is supplied, `rights: true` is auto-\n // derived (the framework knows the wire tools are available); adopter-\n // declared `right_types` / `available_uses` / `generation_providers` /\n // `description` ride the deep-merge.\n const adopterBrand = platform.capabilities.brand;\n const hasBrandRightsImpl = platform.brandRights != null;\n const hasBrandProjection = adopterBrand != null || hasBrandRightsImpl;\n const brandOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['brand']>> = {\n ...(hasBrandRightsImpl && { rights: true }),\n ...adopterBrand,\n };\n\n // Account-mode capability projection. Two redundant adopter signals\n // resolve into the same wire bit:\n // - `capabilities.requireOperatorAuth: true` — explicit override\n // - `accounts.resolution: 'explicit'` — derived from the account-store\n // model (operators authenticate independently with the seller; the\n // buyer discovers accounts via `list_accounts`, NOT `sync_accounts`).\n // Either, taken alone, projects to `account.require_operator_auth: true`.\n // The conformance storyboard runner reads this bit at step time and\n // grades `sync_accounts` steps as `'not_applicable'` (rather than the\n // misleading `'missing_tool'`) for explicit-mode adopters who correctly\n // don't implement that tool. See storyboard runner.ts account-mode gate.\n //\n // `supportedBillings` projects onto the parallel `account.supported_billing`\n // wire field — buyers pre-flight check whether the seller bills the\n // operator (retail-media model) or the buying agent (pass-through). Without\n // the projection, retail-media adopters that declared `['operator']` saw\n // their buyers default-route to agent-billed flows.\n const requireOperatorAuth = platform.capabilities.requireOperatorAuth ?? platform.accounts.resolution === 'explicit';\n const supportedBillings = platform.capabilities.supportedBillings;\n const hasAccountProjection = requireOperatorAuth === true || (supportedBillings?.length ?? 0) > 0;\n // Schema requires `supported_billing` (minItems: 1) whenever the account\n // block is emitted. Default to ['agent'] when adopters don't declare —\n // matches the documented platform interface default at\n // `capabilities.ts:130` (\"Defaults to ['agent'] when omitted\"). v6 was\n // dropping the field on undefined which failed schema validation; v5's\n // `?? []` would also fail (minItems: 1). 'agent' (agent consolidates\n // billing) is the least-surprising default for non-media-buy specialisms.\n // An adopter passing supportedBillings: [] also lands in the default\n // branch — the closed enum has no semantic meaning for empty, and\n // emitting an empty array would fail schema regardless.\n const accountOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['account']>> = {\n ...(requireOperatorAuth === true && { require_operator_auth: true }),\n ...(hasAccountProjection && {\n supported_billing: supportedBillings?.length ? [...supportedBillings] : ['agent'],\n }),\n };\n\n const autoSeedStore: Map<string, Map<string, unknown>> | undefined =\n opts.complyTest != null &&\n platform.sales?.getProducts != null &&\n !opts.testController &&\n !opts.complyTest.seed?.product &&\n !opts.complyTest.seed?.pricing_option\n ? new Map<string, Map<string, unknown>>()\n : undefined;\n\n const complyTestForProjection: ComplyControllerConfig | undefined =\n opts.complyTest != null && autoSeedStore != null\n ? {\n ...opts.complyTest,\n seed: {\n ...opts.complyTest.seed,\n // Projection advertises auto-seed scenarios through the normal\n // complyTest surface; makeAutoSeedBridge handles the real writes.\n product: opts.complyTest.seed?.product ?? (() => undefined),\n pricing_option: opts.complyTest.seed?.pricing_option ?? (() => undefined),\n },\n }\n : opts.complyTest;\n\n // Compliance-testing scenarios projection. Adopters who claim the\n // `compliance_testing` capability AND wire `complyTest` adapters\n // expect buyers to discover which scenarios they implement via\n // `get_adcp_capabilities.compliance_testing.scenarios`. Without\n // projection the wire response carried an empty `compliance_testing: {}`\n // block, the comply-track runner emitted a warning on every call,\n // and adopters saw an actionable-looking message pointing at\n // something they'd already done correctly. Auto-derive scenario names\n // from the wired adapters; let an explicit\n // `capabilities.compliance_testing.scenarios` override the\n // auto-derivation when adopters want to advertise a subset.\n const declaredCT = platform.capabilities.compliance_testing;\n const wiredComplyTest = complyTestForProjection;\n const hasComplianceTestingProjection = declaredCT != null && wiredComplyTest != null;\n const complianceTestingOverrides: NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']> | undefined =\n hasComplianceTestingProjection\n ? {\n scenarios: declaredCT.scenarios ? [...declaredCT.scenarios] : deriveScenariosFromAdapters(wiredComplyTest),\n }\n : undefined;\n\n // Forward specialisms declared on the platform into the inner createAdcpServer\n // config. `capabilities` is omitted from CreateAdcpServerFromPlatformOptions so\n // there is no other forwarding path — without this, createAdcpServer's boot-time\n // guards always see an empty specialisms list and throw when signedRequests is wired.\n const platformSpecialisms = platform.capabilities.specialisms ?? [];\n const hasSpecialisms = platformSpecialisms.length > 0;\n // The signed-requests guard in createAdcpServer (lines 3125 + 3145) requires both\n // `capabilities.specialisms` including 'signed-requests' AND `capabilities.request_signing.\n // supported === true`. DecisioningCapabilities has no request_signing field, so synthesize\n // the minimal block from the specialism claim — supported:true is implied by claiming it.\n const claimsSignedSpecialism = platformSpecialisms.includes('signed-requests' as never);\n const hasOverridesProjection =\n hasMediaBuyProjection || hasBrandProjection || hasAccountProjection || hasComplianceTestingProjection;\n\n // Adopter-declared passthrough fields (issue #2199). DecisioningCapabilities\n // exposes a subset of AdcpCapabilitiesConfig that wasn't previously reachable\n // through definePlatform; forward them so adopters can declare not-supported\n // feature blocks, creative-capability flags, account-shape additions,\n // deep-merge overrides, and release-precision supported_versions without\n // dropping to the lower-level createAdcpServer API.\n //\n // Precedence per the brief on #2199:\n // - features: adopter base; auto-derived audience_targeting /\n // conversion_tracking / content_standards booleans take\n // precedence (handled downstream by applyCapabilityOverrides\n // on the inner createAdcpServer call — the framework's\n // media_buy override is applied AFTER capConfig.features\n // lays down the base).\n // - account: adopter base; existing requireOperatorAuth /\n // supportedBilling projections overlay through the\n // per-domain account override below.\n // - overrides: adopter-declared overrides merged before framework's\n // per-domain blocks so framework-derived blocks remain\n // authoritative on the keys the projection engine handles.\n // This framework canonicalizes every creative before adopter handlers run,\n // but the feature bit exists only in canonical-capable protocol schemas.\n // Strip an adopter claim on a 3.0 pin instead of leaking a future feature\n // into a legacy capability response.\n const { canonicalCreatives: _adopterCanonicalCreatives, ...adopterFeatureBase } =\n platform.capabilities.features ?? {};\n void _adopterCanonicalCreatives;\n const adopterFeatures = {\n ...adopterFeatureBase,\n ...(canonicalCreativeCapability && { canonicalCreatives: true }),\n };\n const adopterCreative = platform.capabilities.creative;\n const adopterAccount = platform.capabilities.account;\n const adopterExtensionsSupported = platform.capabilities.extensions_supported;\n const adopterCapabilityExt = platform.capabilities.ext;\n const adopterOverrides = platform.capabilities.overrides;\n const adopterSupportedVersions = platform.capabilities.supported_versions;\n const hasOverridesObject = hasOverridesProjection || adopterOverrides !== undefined;\n\n const projectedCapabilitiesConfig = {\n ...(hasSpecialisms && {\n specialisms: [...platformSpecialisms] as NonNullable<GetAdCPCapabilitiesResponse['specialisms']>,\n }),\n ...(claimsSignedSpecialism && { request_signing: { supported: true as const } }),\n ...((hasMediaBuyProjection || Object.keys(adopterFeatureBase).length > 0) && {\n features: adopterFeatures,\n }),\n ...(adopterCreative !== undefined && { creative: adopterCreative }),\n ...(adopterAccount !== undefined && { account: adopterAccount }),\n ...(adopterExtensionsSupported !== undefined && {\n extensions_supported: [...adopterExtensionsSupported],\n }),\n ...(adopterCapabilityExt !== undefined && { ext: adopterCapabilityExt }),\n ...(adopterSupportedVersions !== undefined && {\n supported_versions: [...adopterSupportedVersions],\n }),\n ...(hasOverridesObject && {\n overrides: {\n ...(adopterOverrides ?? {}),\n ...(hasMediaBuyProjection\n ? { media_buy: mergeCapabilityOverride(adopterOverrides?.media_buy, mediaBuyOverrides) }\n : adopterOverrides?.media_buy !== undefined && { media_buy: adopterOverrides.media_buy }),\n ...(hasBrandProjection && {\n brand: mergeCapabilityOverride(adopterOverrides?.brand, brandOverrides),\n }),\n ...(hasAccountProjection && {\n account: mergeCapabilityOverride(adopterOverrides?.account, accountOverrides),\n }),\n ...(hasComplianceTestingProjection &&\n complianceTestingOverrides != null && { compliance_testing: complianceTestingOverrides }),\n },\n }),\n };\n\n // Per-server `ctxFor` closure; threads the effective ctx-metadata store\n // (explicit > pooled > none) into `buildRequestContext` so handlers see\n // `ctx.ctxMetadata` as an account-scoped accessor. Multi-tenant hosts\n // (TenantRegistry) get one closure per server, so per-tenant store\n // routing is preserved.\n const ctxFor = makeCtxFor(effectiveCtxMetadata);\n const platformProposalNegotiation = buildProposalNegotiationHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor\n );\n if (platformProposalNegotiation && opts.proposalNegotiation) {\n throw new PlatformConfigError(\n 'Configure refine_proposals through platform.mediaBuyLifecycle or opts.proposalNegotiation, not both'\n );\n }\n\n // Construction-time warn: when the default `resolveIdempotencyPrincipal`\n // is used (no explicit hook), established tools retain the SDK 13 chain:\n // ctx.authInfo.clientId → ctx.sessionKey → ctx.account.id → undefined\n // Compact media-buy mutations instead require a stable authenticated\n // principal below; they never fall through to session/account identity.\n // The `account.id` fallback collapses unauthenticated buyers into one\n // shared idempotency namespace per account — fine for single-tenant\n // deployments where every buyer authenticates, dangerous for multi-\n // tenant hosts serving unauthenticated traffic over a shared\n // account_id. Gate via the dev-allowlist pattern: warn unless\n // NODE_ENV ∈ {test, development} OR the operator explicitly acks via\n // ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL=1.\n if (opts.resolveIdempotencyPrincipal === undefined) {\n const env = process.env.NODE_ENV;\n const inDevAllowlist = env === 'test' || env === 'development';\n const acked = process.env.ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL === '1';\n if (!inDevAllowlist && !acked) {\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] resolveIdempotencyPrincipal not explicitly wired. ` +\n `Default falls through: authInfo.clientId → sessionKey → account.id → undefined. ` +\n `The account.id fallback collapses unauthenticated buyers into one shared idempotency ` +\n `namespace per account. SAFE for single-tenant deployments where every buyer ` +\n `authenticates; UNSAFE for multi-tenant hosts serving unauthenticated traffic over a ` +\n `shared account_id. Wire \\`authenticate\\` on serve() (verifyApiKey / verifyIntrospection) ` +\n `OR pass an explicit \\`resolveIdempotencyPrincipal\\` in opts. ` +\n `Set ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL=1 to silence this warning.`\n );\n }\n }\n\n // Auto-seed: when the platform has a `getProducts` catalog and the adopter\n // wired `complyTest` without explicit product/pricing seed adapters and\n // without a `testController` bridge, the framework provides default\n // in-memory seed adapters. The bridge makes seeded products visible in\n // sandbox `get_products` responses. `autoSeedStore` is computed before\n // capability projection so `seed_product` / `seed_pricing_option` are also\n // advertised when the framework wires them on the adopter's behalf.\n\n const config: AdcpServerConfig<Account> = {\n ...opts,\n requireCompactMutationAccountScope: true,\n taskRegistry,\n ...(autoSeedStore != null && { testController: makeAutoSeedBridge(autoSeedStore) }),\n ...(projectedCapabilitiesConfig != null && { capabilities: projectedCapabilitiesConfig }),\n // Buyer-agent registry (Phase 1 of #1269). Threaded through from the\n // platform so the v5 dispatcher can call `agentRegistry.resolve()` on\n // every request and populate `ctx.agent`. When the platform omits the\n // field, the v5 surface stays unchanged.\n //\n // Precedence: this spread runs AFTER `...opts`, so `platform.agentRegistry`\n // wins over any `opts.agentRegistry` an adopter passes via the v5 escape\n // hatch. Same convention as the `idempotency` spread below — the platform\n // is the authoritative v6 surface; opts is a low-level escape hatch.\n ...(platform.agentRegistry !== undefined && { agentRegistry: platform.agentRegistry }),\n // Server-level `instructions` (closes #1312). Same precedence pattern as\n // `agentRegistry` above — platform-declared instructions win over the\n // v5 `opts.instructions` escape hatch when both are present, so v6\n // adopters can colocate platform facts / decision policy with the rest\n // of their platform declaration.\n ...(platform.instructions !== undefined && { instructions: platform.instructions }),\n ...(platform.onInstructionsError !== undefined && { onInstructionsError: platform.onInstructionsError }),\n // Pool-derived stores override the spread above when adopters supplied\n // `pool` but no explicit per-store opt. Explicit values still win.\n ...(effectiveIdempotency !== undefined && { idempotency: effectiveIdempotency }),\n // Preserve the SDK 13 principal namespace for established tools so a\n // retry spanning a rolling 13→14 deployment still finds its durable\n // idempotency entry. The new compact lifecycle uses credential-kind\n // namespacing and refuses session/account fallbacks, preventing\n // cross-credential collisions without reopening a duplicate-buy window\n // on create_media_buy/update_media_buy. Explicit adopter resolvers still\n // win for every tool.\n resolveIdempotencyPrincipal:\n opts.resolveIdempotencyPrincipal ??\n ((ctx, _params, toolName) =>\n COMPACT_MEDIA_BUY_MUTATION_TOOLS.has(toolName)\n ? authenticatedPrincipalFor(ctx)\n : (ctx.authInfo?.clientId ?? ctx.sessionKey ?? ctx.account?.id ?? undefined)),\n resolveAccount: async (ref, ctx) => {\n const start = Date.now();\n let resolved = false;\n let resolvedAccountId: string | undefined;\n try {\n // Enforce the JSDoc contract documented at `AccountStore.resolution`:\n // implicit-mode and derived-mode platforms refuse inline `account_id`\n // references. Implicit: buyers call sync_accounts first, then the\n // framework resolves from the auth principal. Derived: single-tenant;\n // the principal alone identifies the tenant. The brand+operator union\n // arm is permitted (implicit's sync_accounts onboarding flow); only\n // the `{ account_id }` arm is refused. Closes adcp-client#1364\n // (implicit) and adcp-client#1468 (derived).\n refuseInlineAccountIdWhenForbidden(platform.accounts.resolution, ref);\n const account = await platform.accounts.resolve(ref, toResolveCtx(ctx, ctx.toolName, ctx.input));\n resolved = account != null;\n resolvedAccountId = account?.id;\n return account;\n } catch (err) {\n if (err instanceof AccountNotFoundError) return null;\n throw err;\n } finally {\n safeFire(\n observability?.onAccountResolve,\n {\n tool: ctx.toolName,\n durationMs: Date.now() - start,\n resolved,\n fromAuth: false,\n ...(resolvedAccountId !== undefined && { accountId: resolvedAccountId }),\n },\n 'onAccountResolve',\n fwLogger\n );\n }\n },\n // Auth-derived path: framework calls this for tools whose wire request\n // doesn't carry an `account` field (`provide_performance_feedback`,\n // `list_creative_formats`, `tasks_get`). The platform's resolver runs\n // with `undefined` ref + `authInfo` available — adopters of any\n // `resolution` mode can return a non-null Account here:\n //\n // - `'derived'` — return the singleton.\n // - `'implicit'` — look up by `ctx.authInfo.clientId`.\n // - `'explicit'` — also handle the `undefined` ref branch by\n // looking up via `ctx.authInfo.clientId` (or whichever principal\n // field your auth wires). The framework calls this resolver\n // regardless of declared `resolution` mode; only adopters who\n // intentionally don't model these tools return null.\n //\n // A `null` return is legal — handler runs with `ctx.account`\n // undefined. Appropriate for tools that don't need tenant scoping\n // (publisher-wide format catalogs).\n resolveAccountFromAuth: async ctx => {\n const start = Date.now();\n let resolved = false;\n let resolvedAccountId: string | undefined;\n try {\n const account = await platform.accounts.resolve(undefined, toResolveCtx(ctx, ctx.toolName, ctx.input));\n resolved = account != null;\n resolvedAccountId = account?.id;\n return account;\n } catch (err) {\n if (err instanceof AccountNotFoundError) return null;\n throw err;\n } finally {\n safeFire(\n observability?.onAccountResolve,\n {\n tool: ctx.toolName,\n durationMs: Date.now() - start,\n resolved,\n fromAuth: true,\n ...(resolvedAccountId !== undefined && { accountId: resolvedAccountId }),\n },\n 'onAccountResolve',\n fwLogger\n );\n }\n },\n // Merge: platform-derived handlers WIN per-key over adopter-supplied\n // custom handlers. Adopter handlers fill gaps for tools the v6 platform\n // doesn't yet model (content-standards CRUD, sync_event_sources, etc.).\n // See `CreateAdcpServerFromPlatformOptions` JSDoc for the migration-seam\n // contract.\n mediaBuy: mergeMediaBuyHandlers(\n legacyHandlers.mediaBuy,\n buildMediaBuyHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n effectiveCtxMetadata,\n opts.mediaBuyStore,\n opts.proposalStore,\n opts.legacyCreativeFormatConverter,\n opts.legacyCreativeFormatResolver,\n {\n timeoutMs: legacyFormatResolverLimit(\n opts.legacyCreativeFormatResolverTimeoutMs,\n DEFAULT_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS,\n 'legacyCreativeFormatResolverTimeoutMs',\n MAX_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS\n ),\n concurrency: legacyFormatResolverLimit(\n opts.legacyCreativeFormatResolverConcurrency,\n DEFAULT_LEGACY_FORMAT_RESOLVER_CONCURRENCY,\n 'legacyCreativeFormatResolverConcurrency',\n MAX_LEGACY_FORMAT_RESOLVER_CONCURRENCY\n ),\n },\n opts.canonicalFormatLegacyResolver,\n defaultCreativeWireMode\n ),\n 'mediaBuy',\n mergeOpts,\n defaultCreativeWireMode\n ),\n proposalNegotiation: platformProposalNegotiation ?? opts.proposalNegotiation,\n creative: mergeHandlers(\n legacyHandlers.creative,\n buildCreativeHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n opts.legacyCreativeFormatConverter,\n opts.canonicalFormatLegacyResolver,\n defaultCreativeWireMode\n ),\n 'creative',\n mergeOpts\n ),\n eventTracking: mergeHandlers(\n opts.eventTracking,\n buildEventTrackingHandlers(platform, ctxFor),\n 'eventTracking',\n mergeOpts\n ),\n signals: mergeHandlers(\n opts.signals,\n buildSignalsHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n effectiveCtxMetadata\n ),\n 'signals',\n mergeOpts\n ),\n sponsoredIntelligence: mergeHandlers(\n opts.sponsoredIntelligence,\n buildSponsoredIntelligenceHandlers(platform, ctxFor, effectiveCtxMetadata, fwLogger),\n 'sponsoredIntelligence',\n mergeOpts\n ),\n governance: mergeHandlers(\n legacyHandlers.governance,\n buildGovernanceHandlers(platform, ctxFor),\n 'governance',\n mergeOpts\n ),\n accounts: mergeHandlers(opts.accounts, buildAccountHandlers(platform, ctxFor), 'accounts', mergeOpts),\n brandRights: mergeHandlers(\n legacyHandlers.brandRights,\n buildBrandRightsHandlers(platform, ctxFor, effectiveCtxMetadata, fwLogger),\n 'brandRights',\n mergeOpts\n ),\n customTools: (() => {\n // MCP tool names cannot contain `/`, so expose the AdCP work-status\n // polling surface under the MCP-safe `tasks_get` alias only. A2A keeps\n // using the transport-native `tasks/get` method name on its own path.\n const tasksGetTool = buildTasksGetTool(\n platform,\n taskRegistry,\n platform.agentRegistry,\n fwLogger,\n opts.resolveSessionKey,\n opts.credentialPolicy\n );\n return {\n ...opts.customTools,\n tasks_get: tasksGetTool,\n };\n })(),\n };\n\n const server = createAdcpServer(config);\n const mcp = getSdkServer(server);\n type McpExtra = { authInfo?: ResolvedAuthInfo } | undefined;\n\n const resolveComplyBuyerAgent = async (\n extra: McpExtra,\n input?: Readonly<Record<string, unknown>>\n ): Promise<BuyerAgent | undefined> => {\n if (platform.agentRegistry === undefined) return undefined;\n try {\n const inboundCredential = extra?.authInfo?.extra?.credential;\n const credential =\n extra?.authInfo?.credential ?? (inboundCredential as ResolvedAuthInfo['credential'] | undefined);\n const resolved = await platform.agentRegistry.resolve({\n ...(credential !== undefined && { credential }),\n ...(extra?.authInfo?.extra !== undefined && { extra: extra.authInfo.extra }),\n ...(input !== undefined && { input }),\n });\n if (resolved == null) return undefined;\n if (!Object.isFrozen(resolved)) {\n if (resolved.billing_capabilities instanceof Set) {\n Object.freeze(resolved.billing_capabilities);\n }\n Object.freeze(resolved);\n }\n return resolved;\n } catch (err) {\n fwLogger.warn?.('Buyer-agent registry resolution failed during comply controller visibility check', {\n error: redactCredentialPatterns(err instanceof Error ? err.message : String(err)),\n });\n return undefined;\n }\n };\n\n const resolveComplyControllerVisible = async (\n extra: McpExtra,\n toolName?: string,\n input?: Readonly<Record<string, unknown>>\n ): Promise<boolean> => {\n const agent = await resolveComplyBuyerAgent(extra, input);\n let principalAccount: Account | null = null;\n try {\n principalAccount = await platform.accounts.resolve(\n undefined,\n toResolveCtx(\n {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n },\n toolName,\n input\n )\n );\n } catch {\n principalAccount = null;\n }\n\n recordResolvedAccountMode(principalAccount);\n\n if (isSandboxOrMockAccount(principalAccount)) return true;\n\n if (process.env.ADCP_SANDBOX === '1') {\n if (hasObservedLiveMode()) {\n throw new Error(\n 'comply_test_controller: ADCP_SANDBOX=1 is set but this process has resolved at least one ' +\n 'live-mode account from platform.accounts.resolve. Remove ADCP_SANDBOX from your prod ' +\n 'environment; gate the controller via mode: \"sandbox\" on resolved sandbox accounts instead. ' +\n 'See docs/proposals/lifecycle-state-and-sandbox-authority.md.'\n );\n }\n return true;\n }\n\n return false;\n };\n\n if (hasComplianceTestingProjection) {\n setToolVisibilityResolver(server, ({ toolName, authInfo, input }) => {\n if (toolName !== 'comply_test_controller') return true;\n return resolveComplyControllerVisible(authInfo === undefined ? undefined : { authInfo }, toolName, input);\n });\n }\n\n if (mcp != null && hasComplianceTestingProjection) {\n const wrappedCapabilities = wrapRegisteredToolHandler(mcp, 'get_adcp_capabilities', async (orig, args, extra) => {\n const response = await orig(args, extra);\n if (\n await resolveComplyControllerVisible(\n extra as McpExtra,\n 'get_adcp_capabilities',\n args as Readonly<Record<string, unknown>>\n )\n ) {\n return response;\n }\n if (response == null || typeof response !== 'object') return response;\n\n const structured = (response as { structuredContent?: unknown }).structuredContent;\n if (structured == null || typeof structured !== 'object') return response;\n if (!Object.hasOwn(structured, 'compliance_testing')) return response;\n\n const nextStructured = { ...(structured as Record<string, unknown>) };\n delete nextStructured['compliance_testing'];\n return { ...(response as Record<string, unknown>), structuredContent: nextStructured };\n });\n if (!wrappedCapabilities) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap get_adcp_capabilities for comply_test_controller visibility. ' +\n 'The MCP SDK registered-tool internals may have changed.'\n );\n }\n }\n\n // Wire `comply_test_controller` if the adopter supplied adapters.\n // `createComplyController` builds the tool definition + handler + raw\n // dispatch. The framework registers the tool itself (bypassing\n // `controller.register(server)`) so the sandbox-authority gate can\n // resolve the calling account through `platform.accounts.resolve`\n // BEFORE dispatching — under no circumstances should the controller\n // operate on a `live`-mode account, regardless of what the caller\n // claims on the wire. See `docs/proposals/lifecycle-state-and-sandbox-authority.md`\n // for the full three-mode design and #1435 phase 2.\n if (opts.complyTest != null) {\n let complyConfig = opts.complyTest;\n\n if (autoSeedStore != null) {\n // Inject auto-seed adapters for `seed_product` and `seed_pricing_option`\n // when the adopter didn't wire explicit ones. Explicit adapters win — the\n // spread only fills the undefined slots.\n //\n // **Namespace key: raw `account.account_id`.** The adapter does NOT call\n // `platform.accounts.resolve` even though that would seem symmetric with\n // the bridge's `ctx.account?.id` read — calling resolve here without\n // `authInfo` (which `ComplyControllerContext` doesn't expose) lets a\n // caller spoof `account.account_id: 'victim'` and have a non-validating\n // resolver write seeds into the victim's resolved namespace. Raw id is\n // the safe choice: a caller can only write to their own claimed id, and\n // the sandboxGate already filters non-sandbox traffic.\n //\n // **Trade-off.** Adopters whose resolver maps `account_id` to a distinct\n // internal id (e.g., `acc_1` → `tenant_a:acc_1`) will see seeded fixtures\n // disappear — the adapter writes to `acc_1`, the bridge reads\n // `tenant_a:acc_1`, no match. That's a documented limitation, not a\n // security issue: silent test loss, not cross-tenant pollution. The\n // architectural fix (widen `ComplyControllerContext` to expose the\n // framework-resolved account so writes match reads even under mapping\n // resolvers) is tracked at #1216. Mapping-resolver adopters wire\n // explicit seed adapters today.\n const explicitSeed = opts.complyTest.seed ?? {};\n const autoSeed = { ...explicitSeed };\n\n if (!explicitSeed.product) {\n autoSeed.product = async (params, ctx) => {\n const accountId = readAutoSeedAccountId(ctx.input);\n if (accountId == null) {\n fwLogger.warn(\n '[adcp/auto-seed] seed_product fired without `account.account_id`; dropping write. ' +\n 'Verify the request envelope carries an account ref and the sandboxGate is configured correctly.',\n { product_id: params.product_id }\n );\n return;\n }\n autoSeedStoreFor(autoSeedStore, accountId).set(params.product_id, {\n ...params.fixture,\n product_id: params.product_id,\n });\n };\n }\n\n if (!explicitSeed.pricing_option) {\n autoSeed.pricing_option = async (params, ctx) => {\n const accountId = readAutoSeedAccountId(ctx.input);\n if (accountId == null) {\n fwLogger.warn(\n '[adcp/auto-seed] seed_pricing_option fired without `account.account_id`; dropping write. ' +\n 'Verify the request envelope carries an account ref and the sandboxGate is configured correctly.',\n { product_id: params.product_id, pricing_option_id: params.pricing_option_id }\n );\n return;\n }\n const accountStore = autoSeedStoreFor(autoSeedStore, accountId);\n const existing = accountStore.get(params.product_id) as Record<string, unknown> | undefined;\n const pricingOption = { ...params.fixture, pricing_option_id: params.pricing_option_id };\n const existingOptions = Array.isArray(\n (existing as { pricing_options?: unknown[] } | undefined)?.pricing_options\n )\n ? (existing as { pricing_options: unknown[] }).pricing_options\n : [];\n const filtered = existingOptions.filter(\n (p): p is Record<string, unknown> =>\n p != null &&\n typeof p === 'object' &&\n (p as Record<string, unknown>).pricing_option_id !== params.pricing_option_id\n );\n accountStore.set(params.product_id, {\n ...(existing ?? { product_id: params.product_id }),\n pricing_options: [...filtered, pricingOption],\n });\n };\n }\n\n complyConfig = { ...opts.complyTest, seed: autoSeed };\n }\n\n const controller = createComplyController(complyConfig);\n\n // Manual registration with framework-side sandbox-authority gate. See\n // top-of-block rationale and `docs/proposals/lifecycle-state-and-sandbox-authority.md`.\n //\n // Trust boundary: the gate consults the *resolved* account from\n // `platform.accounts.resolve`, NOT a buyer-supplied claim like\n // `account.sandbox === true` on the wire. The resolver is the only\n // thing that names the account's mode; the gate refuses dispatch when\n // mode is `live` (or the resolver fails to produce an account, modulo\n // the narrow fallbacks below).\n //\n // Fallback paths (deprecated):\n // - `account.sandbox === true` admits only for unresolved target-account\n // refs after a sandbox/mock principal has already passed the discovery\n // visibility gate. A buyer wire claim never overrides a resolved live\n // account and is never used for principal visibility.\n // - `process.env.ADCP_SANDBOX === '1'` admits the principal visibility\n // check and target dispatch for legacy conformance deployments. It\n // fails closed if the same process has ever resolved an explicit\n // `mode: 'live'` account from the resolver: that pairing is a\n // misconfiguration (env var should be unset on prod) and leaving it\n // open re-exposes the live principal we just gated against.\n //\n // `list_scenarios` is exempt from the target-account gate once the\n // principal can see the controller. Read-only and reveals nothing beyond\n // which scenarios the adopter advertised in capabilities.\n if (mcp == null) {\n // Non-MCP server — fall back to the controller's own registration so\n // adopters wiring a custom transport keep the v5 behavior. The gate is\n // an MCP-side concern; A2A and other transports are wired separately.\n controller.register(server);\n } else {\n // Permit a top-level `account` field on the wire so the gate can read\n // the buyer's account ref. The canonical AdCP shape strips it (account\n // routes through `context.account`), but adopters' storyboard fixtures\n // commonly send it at the top level — `TOOL_INPUT_SHAPE`'s JSDoc in\n // `src/lib/server/test-controller.ts` documents this extension as the\n // supported escape hatch.\n //\n // Schema is the full canonical `AccountReference` per\n // `schemas/cache/3.0.6/core/account-ref.json`: oneOf\n // { account_id } — explicit accounts\n // { brand, operator, sandbox? } — implicit accounts\n // Modeled here as a single object with all four fields optional so\n // either arm passes; resolvers narrow on the shape at dispatch.\n // `brand` content is `unknown()` because the inner `brand-ref.json`\n // shape is itself a oneOf and resolvers (not the gate) validate it.\n // Top-level `.strict()` still blocks unknown keys at the framework\n // boundary so a buyer can't stuff `__proto__` / arbitrary payloads\n // into adopters' resolvers.\n const gatedInputSchema = {\n ...controller.toolDefinition.inputSchema,\n account: z\n .object({\n account_id: z.string().min(1).optional(),\n brand: z.unknown().optional(),\n operator: z.string().optional(),\n sandbox: z.boolean().optional(),\n })\n .strict()\n .optional(),\n };\n\n mcp.registerTool(\n controller.toolDefinition.name,\n {\n description: controller.toolDefinition.description,\n inputSchema: gatedInputSchema,\n },\n (async (input: Record<string, unknown>, extra: { authInfo?: ResolvedAuthInfo } | undefined) => {\n if (!(await resolveComplyControllerVisible(extra, 'comply_test_controller', input))) {\n throw new McpError(ErrorCode.MethodNotFound, 'Method not found');\n }\n\n // Probe exempt — capability discovery, no state mutation.\n if (input.scenario === 'list_scenarios') {\n return controller.handle(input);\n }\n\n // Read account ref from top-level (extended shape) or from\n // `context.account` (canonical AdCP routing). First non-null wins.\n const refFromTop = input.account as AccountReference | undefined;\n const refFromContext = (input.context as { account?: AccountReference } | undefined)?.account;\n const accountRef = refFromTop ?? refFromContext;\n\n let resolvedAccount: Account | null = null;\n try {\n const agent = await resolveComplyBuyerAgent(extra, input);\n resolvedAccount = await platform.accounts.resolve(\n accountRef,\n toResolveCtx(\n {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n },\n 'comply_test_controller',\n input\n )\n );\n } catch {\n // Resolver failures fall through to the wire-ref / env fallbacks.\n // Treat as \"no account resolved\" — fail-closed by default unless a\n // fallback admits.\n }\n\n // Record the resolved account's explicit mode (if any). Used by the\n // env-fallback fail-closed guard below.\n recordResolvedAccountMode(resolvedAccount);\n\n const accountIsSandbox = resolvedAccount != null && isSandboxOrMockAccount(resolvedAccount);\n // Spec-defined fallback for the unresolved-account path: read\n // `sandbox: true` off the wire `AccountReference` (per\n // `core/account-ref.json`). Only consulted when the resolver\n // returned `null` — if the resolver names the account, the\n // resolver wins. The buyer's wire claim never overrides a\n // resolved live account.\n const refSandbox = (accountRef as { sandbox?: unknown } | undefined)?.sandbox === true;\n const envSandbox = process.env.ADCP_SANDBOX === '1';\n\n const wouldAdmitOnlyViaEnv = envSandbox && !accountIsSandbox && !(resolvedAccount == null && refSandbox);\n\n // Fail-closed guard on the env fallback. If the env var is the only\n // signal that would admit AND this process has ever resolved an\n // explicit `mode: 'live'` account from the resolver, the env is\n // misconfigured. Refuse loudly so operators notice, instead of\n // silently downgrading the gate for live principals.\n if (wouldAdmitOnlyViaEnv && hasObservedLiveMode()) {\n throw new Error(\n 'comply_test_controller: ADCP_SANDBOX=1 is set but this process has resolved at least one ' +\n 'live-mode account from platform.accounts.resolve. Remove ADCP_SANDBOX from your prod ' +\n 'environment; gate the controller via mode: \"sandbox\" on resolved sandbox accounts instead. ' +\n 'See docs/proposals/lifecycle-state-and-sandbox-authority.md.'\n );\n }\n\n const allowed = accountIsSandbox || (resolvedAccount == null && refSandbox) || envSandbox;\n\n if (!allowed) {\n // Refuse with the standard AdCP permission code once the\n // sandbox/mock principal can see the controller but the target\n // account is live or unresolved. Live principals never reach\n // this branch: they get MCP method-not-found above.\n //\n // `context` and `ext` are open-object on the request schema, so a\n // hostile caller could stuff arbitrarily large payloads. Self-\n // reflection only (no cross-tenant amplifier), but we cap at\n // 8 KiB serialized to bound the response body — anything larger\n // gets dropped, mirroring a missing field rather than echoing\n // garbage.\n const ECHO_BYTE_CAP = 8 * 1024;\n const safeEcho = (value: unknown): Record<string, unknown> | undefined => {\n if (value == null || typeof value !== 'object') return undefined;\n try {\n if (JSON.stringify(value).length > ECHO_BYTE_CAP) return undefined;\n return value as Record<string, unknown>;\n } catch {\n return undefined;\n }\n };\n const requestContext = safeEcho((input as { context?: unknown }).context);\n const requestExt = safeEcho((input as { ext?: unknown }).ext);\n const response = adcpError('PERMISSION_DENIED', {\n message:\n 'comply_test_controller requires a sandbox or mock target account; ' +\n 'resolved target account is live or unresolved.',\n recovery: 'terminal',\n details: {\n scope: 'sandbox-gate',\n tool: 'comply_test_controller',\n reason: 'sandbox-or-mock-required',\n },\n });\n if (requestContext !== undefined || requestExt !== undefined) {\n const structured = response.structuredContent as Record<string, unknown>;\n if (requestContext !== undefined) structured['context'] = requestContext;\n if (requestExt !== undefined) structured['ext'] = requestExt;\n response.content = [{ type: 'text', text: JSON.stringify(structured) }];\n }\n return response;\n }\n\n return controller.handle(input);\n }) as Parameters<typeof mcp.registerTool>[2]\n );\n\n const wrappedToolsCall = wrapSdkRequestHandler(mcp, 'tools/call', async (orig, req, extra) => {\n const params = (req.params ?? {}) as { name?: unknown; arguments?: unknown };\n if (params.name === 'comply_test_controller') {\n const input =\n params.arguments != null && typeof params.arguments === 'object'\n ? (params.arguments as Readonly<Record<string, unknown>>)\n : undefined;\n if (!(await resolveComplyControllerVisible(extra as McpExtra, 'comply_test_controller', input))) {\n throw new McpError(ErrorCode.MethodNotFound, 'Method not found');\n }\n }\n return orig(req, extra);\n });\n if (!wrappedToolsCall) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap MCP tools/call for comply_test_controller visibility. ' +\n 'The MCP SDK request-handler internals may have changed.'\n );\n }\n\n const wrappedToolsList = wrapSdkRequestHandler(mcp, 'tools/list', async (orig, req, extra) => {\n const response = await orig(req, extra);\n const input =\n req.params != null && typeof req.params === 'object'\n ? (req.params as Readonly<Record<string, unknown>>)\n : undefined;\n if (await resolveComplyControllerVisible(extra as McpExtra, undefined, input)) return response;\n if (response == null || typeof response !== 'object') return response;\n const tools = (response as { tools?: unknown }).tools;\n if (!Array.isArray(tools)) return response;\n return {\n ...(response as Record<string, unknown>),\n tools: tools.filter(tool => (tool as { name?: unknown } | null)?.name !== 'comply_test_controller'),\n };\n });\n if (!wrappedToolsList) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap MCP tools/list for comply_test_controller visibility. ' +\n 'The MCP SDK request-handler internals may have changed.'\n );\n }\n }\n }\n\n return Object.assign(server, {\n getTaskState: async <TResult = unknown>(\n taskId: string,\n expectedAccountId?: string\n ): Promise<TaskRecord<TResult> | null> => {\n const record = await taskRegistry.getTask<TResult>(taskId);\n if (record == null) return null;\n // Tenant boundary: if caller specified the expected account and the\n // task's owner doesn't match, treat as not-found. Returning null\n // here mirrors the \"not-found / cross-tenant\" envelope and avoids\n // principal-enumeration via task_id probing.\n if (expectedAccountId !== undefined && record.accountId !== expectedAccountId) {\n return null;\n }\n return record;\n },\n awaitTask: (taskId: string): Promise<void> => taskRegistry.awaitTask(taskId),\n statusChange: statusChangeBus,\n });\n}\n\n// ---------------------------------------------------------------------------\n// `tasks_get` polling tool — buyer-facing wire path for HITL task lifecycle\n// ---------------------------------------------------------------------------\n\n/**\n * Custom tool exposing `taskRegistry.getTask(taskId)` over the wire so\n * buyer agents can poll HITL task state. Snake-case `tasks_get` (MCP tool\n * names disallow `/`) approximates the spec's `tasks/get` method.\n *\n * Native MCP `tasks/get` integration via the SDK's experimental\n * `registerToolTask` path lands in v6.1 — that registers HITL tools\n * (`create_media_buy`, `sync_creatives`) as MCP task tools and the SDK\n * handles the protocol-level `tasks/get` natively. Until then, this\n * custom tool is the buyer-facing polling surface.\n *\n * **Tenant scoping.** The tool reads from `taskRegistry.getTask`\n * directly. Adopters with multi-tenant deployments MUST pass `account`\n * in the request so the framework's account-resolution flow scopes the\n * read; the handler then verifies `record.accountId` matches the\n * resolved account before returning the task. Single-tenant agents\n * (`resolution: 'derived'`) get scoping for free via the auth-derived\n * resolver.\n */\nfunction buildTasksGetTool<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n agentRegistry: BuyerAgentRegistry | undefined,\n logger: AdcpLogger,\n resolveSessionKey: AdcpServerConfig['resolveSessionKey'] | undefined,\n credentialPolicy: CredentialPolicy | undefined\n) {\n const credentialPolicyPatterns =\n credentialPolicy === undefined || typeof credentialPolicy === 'string' ? undefined : credentialPolicy.patterns;\n const credentialPolicyError = (\n args: Record<string, unknown>,\n extra: { authInfo?: ResolvedAuthInfo } | undefined\n ): AdcpErrorResponse | undefined => {\n if (credentialPolicy === undefined) return undefined;\n const effectivePolicy = resolveCredentialPolicyForTool(credentialPolicy, 'tasks_get');\n if (effectivePolicy !== 'lax') {\n const hits = scanArgsForCredentials(args, credentialPolicyPatterns);\n const blockedPaths =\n typeof effectivePolicy === 'object' ? hits.filter(p => !effectivePolicy.allow.includes(p)) : hits;\n if (blockedPaths.length > 0) {\n return adcpError('PERMISSION_DENIED', {\n message:\n 'Request args carry credential-shaped keys. Credentials must arrive on authInfo, not in the request body.',\n recovery: 'correctable',\n details: { scope: 'credentials', credential_paths: blockedPaths },\n });\n }\n }\n if (\n typeof credentialPolicy !== 'string' &&\n credentialPolicy.scanAuthInfo === true &&\n extra?.authInfo?.extra !== null &&\n extra?.authInfo?.extra !== undefined &&\n typeof extra.authInfo.extra === 'object'\n ) {\n const authInfoHits = scanArgsForCredentials(extra.authInfo.extra, credentialPolicyPatterns);\n if (authInfoHits.length > 0) {\n try {\n logger.warn?.('credentialPolicy: authInfo.extra carries credential-shaped keys', {\n tool: 'tasks_get',\n paths: authInfoHits.map(p => `authInfo.extra.${p}`),\n });\n } catch {\n // Ignore logger failures on the rejection path.\n }\n return adcpError('PERMISSION_DENIED', {\n message:\n 'Request authentication context carries credential-shaped keys. Configure your authenticator to keep credentials off authInfo.extra.',\n recovery: 'terminal',\n details: { scope: 'credentials' },\n });\n }\n }\n return undefined;\n };\n\n const inputShape = {\n // Cap task_id length: framework-issued task ids are\n // `task_<UUIDv4>` = 41 chars. Cap at 128 so a malicious buyer can't\n // hand us megabytes of string for a parameterized read query.\n task_id: z\n .string()\n .min(1)\n .max(128)\n .describe('Task identifier returned in the submitted envelope of a HITL tool call.'),\n // Full canonical `AccountReference` per `core/account-ref.json`:\n // `oneOf({ account_id }, { brand, operator, sandbox? })`. Modeled as\n // a single object with all four fields optional so either arm\n // passes; the resolver narrows on shape at dispatch. `brand` content\n // is `unknown()` because the inner `brand-ref.json` shape is itself\n // a oneOf and the resolver validates it. Top-level `.strict()`\n // blocks unknown keys at the framework boundary.\n account: z\n .object({\n account_id: z.string().min(1).optional(),\n brand: z.unknown().optional(),\n operator: z.string().optional(),\n sandbox: z.boolean().optional(),\n })\n .strict()\n .optional()\n .describe(\n 'Optional account reference for tenant scoping. Either AccountReference arm is accepted: ' +\n '`{account_id}` for explicit accounts or `{brand, operator, sandbox?}` for implicit accounts.'\n ),\n include_result: z\n .boolean()\n .optional()\n .describe('Include a canonical terminal artifact for completed, failed, or rejected tasks.'),\n };\n return {\n description:\n 'Call this when you receive `{ status: \"submitted\", task_id }` from create_media_buy ' +\n 'or sync_creatives — pass the same `task_id` plus your `account` to retrieve the ' +\n 'terminal lifecycle state. Returns the spec-flat tasks-get-response shape ' +\n '(`status`, `result` on completed, `error: { code, message }` on failed). ' +\n \"Snake-case substitute for the spec's `tasks/get` method (MCP tool names disallow \" +\n '`/`); native MCP method dispatch lands in v6.1. Webhook delivery is the push-based ' +\n 'alternative when the buyer set `push_notification_config` on the original request.',\n title: 'Get Task State',\n inputSchema: inputShape,\n annotations: { readOnlyHint: true },\n // Handler receives the MCP RequestHandlerExtra as second arg — carries\n // the caller's `authInfo` extracted by `serve({ authenticate })`. Thread\n // it through `accounts.resolve(ref, ctx)` so adopters' `'explicit'`-mode\n // resolvers can authorize the resolution against the principal — without\n // this, an attacker passing `{ account: { account_id: 'tenant_B' } }`\n // gets tenant B's account back from a naive `findById(ref.account_id)`\n // resolver and reads tenant B's task. Same threading as the regular\n // `resolveAccount` dispatch flow in `create-adcp-server.ts:2380-2398`.\n handler: async (\n args: { task_id: string; account?: { account_id?: string }; include_result?: boolean },\n extra: { authInfo?: ResolvedAuthInfo }\n ) => {\n const policyError = credentialPolicyError(args as Record<string, unknown>, extra);\n if (policyError) return policyError;\n const ref = args.account;\n if (extra?.authInfo) {\n const inboundCredential = extra.authInfo.extra?.credential;\n if (inboundCredential !== undefined && extra.authInfo.credential === undefined) {\n extra.authInfo.credential = inboundCredential as ResolvedAuthInfo['credential'];\n }\n }\n // Resolve the buyer agent (when an `agentRegistry` is configured) so\n // adopters' `accounts.resolve` impl sees `ctx.agent` — same contract as\n // every other AccountStore method. Bypasses the dispatcher's\n // resolution-and-status-enforcement seam at\n // `create-adcp-server.ts:2748-2832` deliberately:\n //\n // - **Status enforcement is intentionally skipped on tasks_get\n // polls.** A buyer agent suspended AFTER kicking off an HITL task\n // must still be able to learn the task's terminal state — refusing\n // the poll would strand work with no visibility. Hard-cutoff\n // sellers implement that policy inside their `accounts.resolve`\n // or downstream by reading `ctx.agent.status` themselves.\n // - **Registry failures are surfaced as SERVICE_UNAVAILABLE.** The\n // task owner scope may have been persisted as `agent:${agent_url}`;\n // falling back to credential/session/account scope on a transient\n // registry outage would turn a valid task into a false 404.\n let agent: BuyerAgent | undefined;\n if (agentRegistry !== undefined) {\n try {\n const resolved = await agentRegistry.resolve({\n ...(extra?.authInfo?.credential !== undefined && { credential: extra.authInfo.credential }),\n ...(extra?.authInfo?.extra !== undefined && { extra: extra.authInfo.extra }),\n input: args,\n });\n if (resolved != null) {\n // Mirror the dispatcher's freeze contract: lock the resolved\n // record (and `billing_capabilities` Set if present) so adopter\n // code cannot mutate shared registry state across requests.\n // See `create-adcp-server.ts:2762-2779` for the full rationale.\n if (!Object.isFrozen(resolved)) {\n if (resolved.billing_capabilities instanceof Set) {\n Object.freeze(resolved.billing_capabilities);\n }\n Object.freeze(resolved);\n }\n agent = resolved;\n }\n } catch (err) {\n logger.error?.('Buyer-agent registry resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', {\n message: 'Buyer-agent registry resolution failed',\n });\n }\n }\n const resolveCtx = {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n toolName: 'tasks_get',\n ...(agent !== undefined && { agent }),\n };\n let resolvedAccountId: string | undefined;\n let resolvedAccount: Account | undefined;\n if (ref) {\n refuseInlineAccountIdWhenForbidden(platform.accounts.resolution, ref as AccountReference);\n try {\n const resolved = await platform.accounts.resolve(ref as AccountReference, resolveCtx);\n if (resolved) {\n resolvedAccountId = resolved.id;\n resolvedAccount = resolved;\n }\n } catch (err) {\n if (!(err instanceof AccountNotFoundError)) {\n logger.error?.('Account resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Account resolution failed' });\n }\n }\n if (!resolvedAccountId) {\n return adcpError('ACCOUNT_NOT_FOUND', {\n message: 'The specified account does not exist',\n field: 'account',\n });\n }\n } else {\n try {\n const resolved = await platform.accounts.resolve(undefined, resolveCtx);\n if (resolved) {\n resolvedAccountId = resolved.id;\n resolvedAccount = resolved;\n }\n } catch (err) {\n if (!(err instanceof AccountNotFoundError)) {\n logger.error?.('Auth-derived account resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Account resolution failed' });\n }\n }\n }\n let sessionKey: string | undefined;\n if (resolveSessionKey !== undefined) {\n try {\n sessionKey = await resolveSessionKey({\n toolName: 'tasks_get' as AdcpServerToolName,\n params: args,\n ...(resolvedAccount !== undefined && { account: resolvedAccount }),\n ...(agent !== undefined && { agent }),\n });\n } catch (err) {\n logger.error?.('Session key resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', {\n message: 'Session key resolution failed',\n });\n }\n }\n\n let record;\n try {\n record = await taskRegistry.getTask(args.task_id);\n } catch (err) {\n logger.error?.('Task registry read failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Task registry read failed' });\n }\n if (record == null) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n // Tenant boundary. Two checks to close the auth-derived bypass:\n // 1. If we resolved an account, the task's owning account must match.\n // 2. If we did NOT resolve an account but the task IS owned by an\n // account, refuse to leak. This catches the unauthenticated /\n // `'explicit'`-mode-misconfigured caller that hits the auth-derived\n // branch and would otherwise read any task by id.\n if (resolvedAccountId === undefined && record.accountId) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n if (resolvedAccountId !== undefined && record.accountId !== resolvedAccountId) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n if (resolvedAccountId !== undefined) {\n const ownerCtx: HandlerContext<Account> = {\n store: {} as HandlerContext<Account>['store'],\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n ...(sessionKey !== undefined && { sessionKey }),\n account: resolvedAccount ?? ({ id: resolvedAccountId } as Account),\n };\n const expectedOwnerScope = taskOwnerScopeFor(ownerCtx, resolvedAccountId);\n if (\n record.ownerScope === undefined\n ? expectedOwnerScope !== `account:${resolvedAccountId}`\n : record.ownerScope !== expectedOwnerScope\n ) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n }\n\n // Spec shape: `tasks-get-response.json` requires task_id, task_type,\n // status, created_at, updated_at, protocol. Optional: completed_at\n // (terminal states), error (failed tasks — top-level, NOT inside\n // result), result (success-arm body for completed tasks),\n // has_webhook (whether buyer wired push_notification_config).\n const payload: Record<string, unknown> = {\n task_id: record.taskId,\n task_type: record.tool,\n status: record.status,\n protocol: protocolForTool(record.tool),\n has_webhook: record.hasWebhook === true,\n created_at: record.createdAt,\n updated_at: record.updatedAt,\n };\n // Terminal states get `completed_at` per spec (covers completed,\n // failed, canceled). The framework writes terminal-state transitions\n // by stamping `updated_at`, so the two coincide today.\n if (record.status === 'completed' || record.status === 'failed' || record.status === 'canceled') {\n payload.completed_at = record.updatedAt;\n }\n if (record.statusMessage) payload.message = record.statusMessage;\n if (\n args.include_result === true &&\n (record.status === 'completed' || record.status === 'failed' || record.status === 'rejected') &&\n record.result !== undefined\n ) {\n payload.result = record.result;\n }\n if (record.status === 'failed' && record.error) {\n // Spec shape: top-level `error: { code, message, details? }` —\n // matches `tasks-get-response.json`'s required `code` + `message`\n // shape with optional `details` carrying a flattened structured-error\n // tail (`recovery`, `field`, `suggestion`, `retry_after`) plus safe\n // adopter-supplied detail fields.\n const { code, message, details: safeDetails, ...tail } = sanitizeStructuredAdcpError(record.error);\n const details =\n safeDetails !== null &&\n safeDetails !== undefined &&\n typeof safeDetails === 'object' &&\n !Array.isArray(safeDetails)\n ? { ...tail, ...(safeDetails as Record<string, unknown>) }\n : safeDetails !== undefined\n ? { ...tail, details: safeDetails }\n : tail;\n payload.error = {\n code,\n message,\n ...(Object.keys(details).length > 0 && { details }),\n };\n }\n return {\n content: [{ type: 'text' as const, text: `Task ${record.taskId} status: ${record.status}` }],\n structuredContent: payload,\n };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Handler merge — incremental migration seam\n// ---------------------------------------------------------------------------\n\n/**\n * Merge adopter-supplied custom handlers with platform-derived handlers.\n * Platform-derived wins per-key when both define the same handler; adopter\n * handlers fill any gaps. Returns `undefined` when neither side has any\n * handlers (so the framework knows the domain is unrouted and can omit it\n * from `tools/list`).\n *\n * Used to bridge the gap between v6 specialism interfaces (which model the\n * stable v1.0 surface) and adopter codebases that need to dispatch\n * tools the platform shape doesn't cover yet (getMediaBuys,\n * listCreativeFormats, providePerformanceFeedback, reportUsage,\n * sync_event_sources, log_event, content-standards CRUD, etc.).\n *\n * **Collision detection.** When a custom-supplied handler would be\n * shadowed by a platform-derived one (i.e., the framework added native\n * coverage for a tool the adopter previously filled via the merge seam),\n * the resolver logs a warning by default. Tells adopters to migrate the\n * custom logic into the platform method. Adopters who genuinely want\n * the custom logic to win can pass `mergeSeam: 'silent'` to skip the\n * warning, `'strict'` to throw a `PlatformConfigError`, or `'log-once'`\n * to suppress duplicate warnings across multiple server constructions\n * in the same process (multi-tenant deployments, hot-reload dev).\n */\ntype MergeSeamMode = 'warn' | 'log-once' | 'silent' | 'strict';\n\n// Module-level dedupe set for `'log-once'` mode. Keyed on\n// `${domain}|${sortedColliders}` so two constructions hitting the same\n// collision pattern only log once across the lifetime of the process.\n// Cleared via `_resetMergeSeamDedupe()` in tests.\nconst mergeSeamLoggedKeys = new Set<string>();\n\n/** @internal — reset the log-once dedupe set. Tests only. */\nexport function _resetMergeSeamDedupe(): void {\n mergeSeamLoggedKeys.clear();\n}\n\nfunction mergeHandlers<T extends object>(\n custom: T | undefined,\n platform: T | undefined,\n domain: string,\n opts: { mode: MergeSeamMode; logger: AdcpLogger }\n): T | undefined {\n if (!custom && !platform) return undefined;\n if (!custom) return platform;\n if (!platform) return custom;\n\n if (opts.mode !== 'silent') {\n const collisions: string[] = [];\n for (const key of Object.keys(platform)) {\n if (key in (custom as Record<string, unknown>)) collisions.push(key);\n }\n if (collisions.length > 0) {\n // Sort for stable dedupe key — same collision set logs the same key\n // regardless of declaration order across constructions.\n const dedupeKey = `${domain}|${[...collisions].sort().join(',')}`;\n const shouldLog = opts.mode !== 'log-once' || !mergeSeamLoggedKeys.has(dedupeKey);\n\n const message =\n `[adcp/decisioning] opts.legacyHandlers.${domain}.{${collisions.join(', ')}} ` +\n `${collisions.length === 1 ? 'is' : 'are'} shadowed by platform-derived handlers. ` +\n `The merge seam is for tools the platform doesn't model yet — once a tool has a native ` +\n `platform method, move the logic there and remove the opts override.`;\n\n if (opts.mode === 'strict') {\n throw new PlatformConfigError(message);\n }\n if (shouldLog) {\n opts.logger.warn(message);\n if (opts.mode === 'log-once') mergeSeamLoggedKeys.add(dedupeKey);\n }\n }\n }\n\n return { ...custom, ...platform };\n}\n\n/**\n * Native media-buy methods operate on the canonical platform surface, while\n * the explicitly named `legacyHandlers` surface is the adopter's raw-wire\n * compatibility escape hatch. For the three lifecycle methods that can echo\n * package selectors, route an actually negotiated legacy request to that raw\n * handler when both implementations are present. Canonical requests continue\n * to use the native platform method, and strict merge-seam collision checking\n * remains unchanged.\n */\nfunction mergeMediaBuyHandlers(\n custom: MediaBuyHandlers<Account> | undefined,\n platform: MediaBuyHandlers<Account> | undefined,\n domain: string,\n opts: { mode: MergeSeamMode; logger: AdcpLogger },\n fallbackWireMode: 'canonical' | 'legacy'\n): MediaBuyHandlers<Account> | undefined {\n const merged = mergeHandlers(custom, platform, domain, opts);\n if (!custom || !platform || !merged) return merged;\n\n const routed = { ...merged } as Record<string, unknown>;\n for (const key of ['createMediaBuy', 'updateMediaBuy', 'getMediaBuys'] as const) {\n const customHandler = (custom as Record<string, unknown>)[key];\n const platformHandler = (platform as Record<string, unknown>)[key];\n if (typeof customHandler !== 'function' || typeof platformHandler !== 'function') continue;\n routed[key] = (...args: unknown[]) => {\n const ctx = args[1] as HandlerContext<Account> | undefined;\n if (ctx && creativeWireModeForRequest(ctx, fallbackWireMode, args[0]) === 'legacy') {\n return Reflect.apply(customHandler, custom, args);\n }\n return Reflect.apply(platformHandler, platform, args);\n };\n }\n return routed as MediaBuyHandlers<Account>;\n}\n\n// ---------------------------------------------------------------------------\n// Observability hook plumbing\n// ---------------------------------------------------------------------------\n\n/**\n * Fire an observability callback with throw-safe semantics — both sync\n * throws AND rejected promises are caught + logged so a buggy span/metric\n * callback never breaks dispatch. The framework does NOT await the\n * callback; if you need async tracer work, do it inside the callback and\n * the framework will not hold the dispatch path waiting for it.\n */\n/**\n * Derive scenario names from a wired `ComplyControllerConfig` adapter\n * set. Each adapter slot maps to one wire scenario name. Order is\n * stable (force → simulate) so adopter wire-fixture snapshots don't\n * churn between releases. Used by the projection seam to populate\n * `get_adcp_capabilities.compliance_testing.scenarios` when the adopter\n * doesn't supply an explicit subset.\n *\n * `list_scenarios` itself is implicit and is not advertised.\n */\nfunction deriveScenariosFromAdapters(\n cfg: ComplyControllerConfig\n): NonNullable<NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']> {\n const out: Array<NonNullable<NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']>[number]> =\n [];\n if (cfg.force?.creative_status) out.push('force_creative_status');\n if (cfg.force?.account_status) out.push('force_account_status');\n if (cfg.force?.media_buy_status) out.push('force_media_buy_status');\n if (cfg.force?.session_status) out.push('force_session_status');\n if (cfg.force?.create_media_buy_arm) out.push('force_create_media_buy_arm');\n if (cfg.force?.task_completion) out.push('force_task_completion');\n if (cfg.force?.creative_purge) out.push('force_creative_purge');\n if (cfg.simulate?.delivery) out.push('simulate_delivery');\n if (cfg.simulate?.budget_spend) out.push('simulate_budget_spend');\n if (cfg.seed?.account) out.push('seed_account');\n if (cfg.seed?.product) out.push('seed_product');\n if (cfg.seed?.pricing_option) out.push('seed_pricing_option');\n if (cfg.seed?.creative) out.push('seed_creative');\n if (cfg.seed?.plan) out.push('seed_plan');\n if (cfg.seed?.media_buy) out.push('seed_media_buy');\n if (cfg.seed?.creative_format) out.push('seed_creative_format');\n if (cfg.seed?.measurement_catalog) out.push('seed_measurement_catalog');\n if (cfg.queryUpstreamTraffic) out.push('query_upstream_traffic');\n if (cfg.queryProvenanceAuditObservations) out.push('query_provenance_audit_observations');\n if (cfg.force?.upstream_unavailable) out.push('force_upstream_unavailable');\n return out;\n}\n\nfunction safeFire<T>(fn: ((arg: T) => unknown) | undefined, arg: T, hookName: string, logger: AdcpLogger): void {\n if (!fn) return;\n let result: unknown;\n try {\n result = fn(arg);\n } catch (err) {\n logger.warn(\n `[adcp/decisioning] observability hook ${hookName} threw — telemetry callbacks must never throw. ` +\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n return;\n }\n // Catch rejected promises from accidentally-async callbacks. Without\n // this an `async () => { throw ... }` hook would surface as\n // UnhandledPromiseRejection and on `--unhandled-rejections=strict`\n // would crash the process. `Promise.resolve()` coerces both real\n // promises and user-land thenables (a thenable returning sync values\n // is wrapped, a true Promise is returned as-is) — safer than the\n // duck-typed `typeof .catch === 'function'` check.\n if (result !== undefined && result !== null) {\n Promise.resolve(result).catch((err: unknown) => {\n logger.warn(\n `[adcp/decisioning] observability hook ${hookName} returned a rejected promise — ` +\n `telemetry callbacks must never reject. ` +\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n });\n }\n}\n\n/**\n * Wrap a `StatusChangeBus` so every publish fires `onStatusChangePublish`\n * after the underlying bus persists the event. Subscribers + recent-buffer\n * pass through; only the publish side is observed.\n */\nfunction wrapBusWithObservability(bus: StatusChangeBus, observability: DecisioningObservabilityHooks): StatusChangeBus {\n return {\n publish<TPayload>(eventOpts: PublishStatusChangeOpts<TPayload>): void {\n bus.publish(eventOpts);\n if (observability.onStatusChangePublish) {\n try {\n observability.onStatusChangePublish({\n accountId: eventOpts.account_id,\n resourceType: eventOpts.resource_type,\n resourceId: eventOpts.resource_id,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] observability hook onStatusChangePublish threw: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n },\n subscribe: bus.subscribe.bind(bus),\n recent: bus.recent.bind(bus),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Default task registry — gated by NODE_ENV\n// ---------------------------------------------------------------------------\n\n/**\n * Build the default in-memory task registry, gated by NODE_ENV.\n *\n * The in-memory registry loses task state on process restart — fine for\n * tests and local dev, NOT fine for production. Gate via allowlist:\n * `NODE_ENV` must be `'test'` or `'development'`, OR the operator must\n * explicitly opt in via `ADCP_DECISIONING_ALLOW_INMEMORY_TASKS=1`.\n *\n * Pattern follows `feedback_node_env_allowlist.md`: never compare\n * `=== 'production'` (production may unset NODE_ENV entirely); always\n * allowlist the safe modes.\n */\n/**\n * Combined DDL for all framework persistence tables: idempotency cache,\n * ctx-metadata cache, and decisioning task registry. Run once per database\n * during deployment / boot. Idempotent — safe to re-run.\n *\n * Use with the `pool` shortcut on `createAdcpServerFromPlatform`:\n *\n * ```ts\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * await pool.query(getAllAdcpMigrations());\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * name: '...', version: '...',\n * pool,\n * });\n * ```\n *\n * Adopters who don't use the `pool` shortcut should call the per-store\n * migration helpers (`getIdempotencyMigration`, `getCtxMetadataMigration`,\n * `getDecisioningTaskRegistryMigration`) only for the stores they wire.\n *\n * @public\n */\nexport function getAllAdcpMigrations(): string {\n return [getIdempotencyMigration(), getCtxMetadataMigration(), getDecisioningTaskRegistryMigration()].join('\\n\\n');\n}\n\nfunction buildDefaultTaskRegistry(): TaskRegistry {\n const env = process.env.NODE_ENV;\n const safe = env === 'test' || env === 'development';\n const ack = process.env.ADCP_DECISIONING_ALLOW_INMEMORY_TASKS === '1';\n if (!safe && !ack) {\n throw new Error(\n 'createAdcpServerFromPlatform: in-memory task registry refused outside ' +\n '{NODE_ENV=test, NODE_ENV=development}. Production deployments need a ' +\n 'durable task registry — pick one of:\\n' +\n ' 1. (Recommended) Pass `taskRegistry: createPostgresTaskRegistry({ pool })` ' +\n 'to keep HITL tasks across restarts. See `@adcp/sdk/server/decisioning` ' +\n 'for `getDecisioningTaskRegistryMigration()` — run it once against your DB.\\n' +\n ' 2. Pass `taskRegistry: createInMemoryTaskRegistry()` explicitly if you ' +\n 'accept that in-flight tasks are lost on process restart. The explicit ' +\n 'pass-in is the contract — saying \"yes I want in-memory in production\" ' +\n 'in code is the right shape.\\n' +\n ' 3. ADCP_DECISIONING_ALLOW_INMEMORY_TASKS=1 env flag is the ops escape ' +\n 'hatch (same effect as #2 but config-only); prefer #2 in adopter code.'\n );\n }\n return createInMemoryTaskRegistry();\n}\n\n// ---------------------------------------------------------------------------\n// Sync vs HITL dispatch\n// ---------------------------------------------------------------------------\n\ntype SubmittedEnvelope = {\n status: 'submitted';\n task_id: string;\n};\n\n/**\n * Mid-request token refresh hook config (#1145 Gap 2). When `refresh.fn`\n * is defined and the platform method throws `AdcpError` with a\n * recovery-correctable auth code (`AUTH_REQUIRED` from 3.0.x sellers, or\n * `AUTH_MISSING` from 3.1+ sellers), `projectSync` refreshes the account's\n * token via the hook, mutates or creates `account.authInfo`, and retries the\n * platform method ONCE. `AUTH_INVALID` is terminal — credentials were\n * presented and rejected — so we deliberately do NOT refresh on it (auto-\n * retry against an SSO endpoint on a revoked token is the retry-storm\n * pattern adcp#3730 split the code to prevent). If the refresh hook itself\n * throws, projects to legacy-compatible `AUTH_REQUIRED` with\n * `recovery: 'correctable'` so existing buyers re-link via their UI flow.\n *\n * Parameterized over `TCtxMeta` (#1168) so adopters' refresh hooks see\n * typed `account.ctx_metadata` rather than `unknown`. Default `unknown`\n * preserves backward compat for call sites that don't thread the\n * adopter's metadata shape through.\n */\ninterface RefreshConfig<TCtxMeta = unknown> {\n account: Account<TCtxMeta>;\n fn?: (account: Account<TCtxMeta>, reason: 'auth_required') => Promise<{ token: string; expiresAt?: number }>;\n}\n\nfunction cloneAccountForRequest<TCtxMeta>(account: Account<TCtxMeta>): Account<TCtxMeta> {\n try {\n return structuredClone(account);\n } catch (cause) {\n const publicError = new AdcpError('CONFIGURATION_ERROR', {\n message: 'Resolved account is not safely cloneable for request-local auth refresh.',\n recovery: 'terminal',\n });\n (publicError as Error & { cause?: unknown }).cause = cause;\n throw publicError;\n }\n}\n\n/** Auth codes that signal \"credentials missing, refresh and retry once.\" */\nconst REFRESHABLE_AUTH_CODES: ReadonlySet<string> = new Set(['AUTH_REQUIRED', 'AUTH_MISSING']);\n\n/**\n * Run a platform method with reactive token refresh on missing-credential\n * auth codes (`AUTH_REQUIRED` on 3.0.x sellers, `AUTH_MISSING` on 3.1+).\n * Without a refresh fn (or no `refresh` at all) this passes the call\n * through. With one, catches the refreshable code, calls `refresh.fn`,\n * mutates or creates `account.authInfo` (including `expiresAt` when\n * returned), and retries the inner call exactly once.\n *\n * `AUTH_INVALID` is intentionally NOT refreshed — it's terminal by\n * spec (credentials presented and rejected); refreshing creates the\n * SSO retry-storm pattern adcp#3730 split the code to prevent.\n *\n * Failure modes:\n * - Refresh hook throws → re-throw legacy-compatible `AUTH_REQUIRED` with\n * `recovery: 'correctable'` so the buyer re-links via their UI.\n * - Retried call throws a refreshable auth code again → bubble out\n * (don't refresh a second time).\n */\nasync function runWithTokenRefresh<TCtxMeta, T>(\n fn: () => Promise<T>,\n refresh: RefreshConfig<TCtxMeta> | undefined\n): Promise<T> {\n if (!refresh?.fn) return fn();\n try {\n return await fn();\n } catch (err) {\n if (!(err instanceof AdcpError) || !REFRESHABLE_AUTH_CODES.has(err.code)) {\n throw err;\n }\n let refreshed: { token: string; expiresAt?: number };\n try {\n refreshed = await refresh.fn(refresh.account, 'auth_required');\n } catch (cause) {\n // Refresh-fn exception text is intentionally NOT echoed on the wire\n // — upstream identity-provider error messages routinely embed\n // refresh-token prefixes, internal hostnames, OAuth provider error\n // codes, and stack-trace fragments. Adopters log details server-\n // side; the buyer gets a fixed message + correctable recovery\n // signaling they need to re-authorize.\n const publicError = new AdcpError('AUTH_REQUIRED', {\n message: 'Token refresh failed; re-authentication required',\n recovery: 'correctable',\n });\n (publicError as Error & { cause?: unknown }).cause = cause;\n throw publicError;\n }\n // `authInfo` became optional in #1286. A 3.1-native AUTH_MISSING can mean\n // the upstream request had no usable credential at all, so attach the\n // freshly minted OAuth-style token even when the resolver omitted\n // account.authInfo.\n const authInfo = refresh.account.authInfo ?? { kind: 'oauth' as const };\n authInfo.token = refreshed.token;\n if (refreshed.expiresAt !== undefined) {\n authInfo.expiresAt = refreshed.expiresAt;\n }\n refresh.account.authInfo = authInfo;\n return fn();\n }\n}\n\n/**\n * Project a sync platform call onto the wire dispatch shape. `AdcpError`\n * throws → wire `adcp_error` envelope; other thrown errors bubble to the\n * framework's `SERVICE_UNAVAILABLE` mapping.\n *\n * When `refresh` is provided and the call throws a refreshable auth code, the\n * framework calls `refresh.fn(refresh.account, 'auth_required')`, updates\n * `account.authInfo`, and retries the platform method once.\n */\nasync function projectSync<TResult, TWire, TCtxMeta = unknown>(\n fn: () => Promise<TResult>,\n mapResult: (r: TResult) => TWire,\n refresh?: RefreshConfig<TCtxMeta>\n): Promise<TWire | AdcpErrorResponse> {\n try {\n const result = await runWithTokenRefresh(fn, refresh);\n if (_extractResponseSummaryEntry(result)) {\n throw new TypeError('withResponseSummary is supported only for synchronous getProducts results');\n }\n const wire = mapResult(result as TResult);\n // Single-chokepoint runtime strip: ctx_metadata MUST NEVER cross to the\n // buyer. Defense-in-depth (compile-time WireShape<T> + runtime walk).\n // Mutates `wire` in place — every handler builds a fresh response per\n // call so mutation is safe. Runs BEFORE the framework wraps in envelope\n // / caches in idempotency, so cached replays stay clean too.\n //\n // implementation_config strip: same pattern. Recipes ride on\n // Product.implementation_config server-side (typed contract between\n // ProposalManager and DecisioningPlatform via ctx.recipes) but are\n // opaque-to-buyer. The wire schema is `additionalProperties: true`\n // so the field is technically legal — but recipes carry upstream\n // identifiers (network codes, line-item template ids, ad-unit ids,\n // GAM line-item priority) that leak topology to buyers. Strip\n // before the response leaves the dispatcher.\n if (wire != null && typeof wire === 'object') {\n stripCtxMetadata(wire as Record<string, unknown>);\n stripImplementationConfig(wire as Record<string, unknown>);\n }\n return wire;\n } catch (err) {\n if (err instanceof AdcpError) {\n return adcpError(err.code, {\n message: err.message,\n recovery: err.recovery,\n ...(err.field !== undefined && { field: err.field }),\n ...(err.suggestion !== undefined && { suggestion: err.suggestion }),\n ...(err.retry_after !== undefined && { retry_after: err.retry_after }),\n ...(err.details !== undefined && { details: err.details }),\n });\n }\n // AccountNotFoundError is documented as throwable only from\n // AccountStore.resolve(); but adopters new to the framework\n // sometimes throw it from a specialism method body. Project to\n // ACCOUNT_NOT_FOUND so the wire envelope is right either way —\n // closes the silent-SERVICE_UNAVAILABLE foot-gun the security\n // review flagged. Adopters are still encouraged to handle account\n // not-found inside resolve() (canonical) — this is a guardrail.\n if (err instanceof AccountNotFoundError) {\n return adcpError('ACCOUNT_NOT_FOUND', {\n message: 'Account not found',\n field: 'account',\n });\n }\n throw err;\n }\n}\n\n/**\n * HITL dispatch: allocate task, return submitted envelope to buyer\n * immediately, run the handoff function in background. Method's return\n * value becomes terminal `result`; throws become terminal `error`.\n *\n * **Webhook delivery on terminal state.** When the buyer passed\n * `push_notification_config: { url, token? }` in the request and the host\n * wired `webhooks` on `serve()`, the framework emits a signed RFC 9421\n * webhook to that URL on terminal state with the task lifecycle payload.\n * Buyers don't need to poll — they receive completion via push. Polling via\n * `server.getTaskState(taskId)` continues to work for harnesses + the\n * forthcoming wire-level `tasks/get`.\n */\ninterface DispatchHitlOpts {\n tool: string;\n accountId: string;\n ownerScope?: string;\n pushNotificationUrl?: string;\n pushNotificationToken?: string;\n pushNotificationOperationId?: string;\n servedAdcpVersion?: string;\n emitWebhook?: HandlerContext<Account>['emitWebhook'];\n observability?: DecisioningObservabilityHooks;\n logger: AdcpLogger;\n /** @deprecated Ignored; retained internally during the SDK 14 compatibility window. */\n autoEmitCompletion?: boolean;\n}\n\nfunction taskOwnerScopeFor(ctx: HandlerContext<Account>, accountId: string): string {\n if (ctx.sessionKey !== undefined) return `session:${ctx.sessionKey}`;\n if (ctx.agent?.agent_url) return `agent:${ctx.agent.agent_url}`;\n const credential = ctx.authInfo?.credential;\n if (credential?.kind === 'http_sig') return `http_sig:${credential.agent_url}`;\n if (credential?.kind === 'oauth') return `oauth:${credential.client_id}`;\n if (credential?.kind === 'api_key') return `api_key:${credential.key_id}`;\n if (typeof ctx.authInfo?.clientId === 'string' && ctx.authInfo.clientId.length > 0) {\n return `client:${ctx.authInfo.clientId}`;\n }\n return `account:${accountId}`;\n}\n\nfunction authenticatedPrincipalFor(ctx: HandlerContext<Account>): string | undefined {\n if (ctx.agent?.agent_url) return `agent:${ctx.agent.agent_url}`;\n const credential = ctx.authInfo?.credential;\n if (credential?.kind === 'http_sig') return `http_sig:${credential.agent_url}`;\n if (credential?.kind === 'oauth') return `oauth:${credential.client_id}`;\n if (credential?.kind === 'api_key') return `api_key:${credential.key_id}`;\n if (typeof ctx.authInfo?.clientId === 'string' && ctx.authInfo.clientId.length > 0) {\n return `client:${ctx.authInfo.clientId}`;\n }\n return undefined;\n}\n\nfunction hasPushNotificationConfig(params: unknown): boolean {\n return (\n params != null &&\n typeof params === 'object' &&\n (params as { push_notification_config?: unknown }).push_notification_config !== undefined\n );\n}\n\nfunction rejectHandRolledSubmitted(result: unknown): void {\n // Catch the most common LLM-scaffolded mistake: hand-rolling a\n // `{status: 'submitted', task_id: '...'}` envelope instead of returning\n // `ctx.handoffToTask(fn)`. The framework owns the submitted envelope —\n // adopters either return the sync-success arm or a TaskHandoff marker.\n // A bare submitted-shape return here would slip past dispatch and fail\n // response-schema validation downstream with a generic shape error;\n // pointing at the right SDK primitive up-front saves the debug round-trip.\n if (\n result != null &&\n typeof result === 'object' &&\n (result as { status?: unknown }).status === 'submitted' &&\n 'task_id' in (result as object)\n ) {\n throw new Error(\n `Specialism handler returned a hand-rolled \\`{status: 'submitted', task_id}\\` ` +\n `envelope. The framework owns the submitted envelope — return ` +\n `\\`ctx.handoffToTask(async (taskCtx) => { ... })\\` from the handler ` +\n `and the framework will issue the task_id, persist the handoff, and ` +\n `wrap the wire envelope. Returning a bare submitted shape skips the ` +\n `task registry and the buyer ends up polling a task_id the framework ` +\n `never registered.`\n );\n }\n}\n\nconst RETURNED_ERROR_ARM_KEYS = new Set(['errors', 'context', 'ext', 'success', 'conflicting_standards_id']);\n\n/** Match only a pure generated Error arm, never a success payload carrying advisory errors. */\nfunction isReturnedErrorArm(value: unknown): value is { errors: unknown[]; context?: unknown; ext?: unknown } {\n if (value == null || typeof value !== 'object') return false;\n const record = value as Record<string, unknown>;\n if (!Array.isArray(record.errors) || 'status' in record) return false;\n return Object.keys(record).every(key => RETURNED_ERROR_ARM_KEYS.has(key));\n}\n\n/**\n * Route a unified-shape return value: if it's a `TaskHandoff` marker,\n * dispatch through `dispatchHitl`; otherwise pass through the sync\n * projection.\n *\n * Adopter return type is `Success | TaskHandoff<Success>`. Each\n * specialism dispatcher uses this helper so all four call sites\n * (`createMediaBuy`, `updateMediaBuy`, `sales.syncCreatives`,\n * `creative.syncCreatives`)\n * route through a single seam — closes round-6 CR-1 (drift across\n * near-identical `isTaskHandoff` branches).\n *\n * `project` shapes both arms identically — for `syncCreatives`,\n * `rows → { creatives: rows }`; for `createMediaBuy`, identity.\n */\nasync function routeIfHandoff<TInner, TWire>(\n taskRegistry: TaskRegistry,\n opts: DispatchHitlOpts,\n result: TInner | TaskHandoff<TInner>,\n project: (inner: TInner) => TWire | Promise<TWire>\n): Promise<TWire | SubmittedEnvelope> {\n const rejectResponseSummary = (value: unknown): void => {\n if (_extractResponseSummaryEntry(value)) {\n throw new TypeError('withResponseSummary is supported only for synchronous getProducts results');\n }\n };\n if (isTaskHandoff<TInner>(result)) {\n const entry = _extractHandoffEntry(result);\n if (!entry) {\n // Forgery — adopter constructed something with the brand symbol\n // but didn't go through ctx.handoffToTask. Treat as a sync\n // success arm with an empty body (caller-supplied projection\n // shapes the result; this branch is defensive).\n rejectResponseSummary(result);\n return await project(result as unknown as TInner);\n }\n const { fn: taskFn, options } = entry;\n return dispatchHitl(\n taskRegistry,\n opts,\n async taskId => {\n const inner = await taskFn(buildHandoffContext(taskRegistry, taskId));\n rejectResponseSummary(inner);\n return await project(inner);\n },\n options?.task_id\n );\n }\n rejectHandRolledSubmitted(result);\n rejectResponseSummary(result);\n return await project(result);\n}\n\nasync function dispatchHitl<TResult>(\n taskRegistry: TaskRegistry,\n opts: DispatchHitlOpts,\n taskFn: (taskId: string) => Promise<TResult>,\n overrideTaskId?: string\n): Promise<SubmittedEnvelope> {\n const createStart = Date.now();\n const { taskId } = await taskRegistry.create({\n tool: opts.tool,\n accountId: opts.accountId,\n ownerScope: opts.ownerScope ?? `account:${opts.accountId}`,\n hasWebhook: opts.pushNotificationUrl !== undefined,\n ...(overrideTaskId !== undefined && { overrideTaskId }),\n });\n safeFire(\n opts.observability?.onTaskCreate,\n {\n tool: opts.tool,\n taskId,\n accountId: opts.accountId,\n durationMs: Date.now() - createStart,\n },\n 'onTaskCreate',\n opts.logger\n );\n const taskStart = Date.now();\n\n // Single helper for the four `onTaskTransition` fire sites.\n const fireTransition = (status: 'completed' | 'failed', errorCode?: string): void => {\n safeFire(\n opts.observability?.onTaskTransition,\n {\n taskId,\n tool: opts.tool,\n accountId: opts.accountId,\n status,\n durationMs: Date.now() - taskStart,\n ...(errorCode !== undefined && { errorCode }),\n },\n 'onTaskTransition',\n opts.logger\n );\n };\n\n // Three failure surfaces:\n // 1. taskFn throws → record failure → emit failed webhook\n // 2. taskFn succeeds but registry write fails (DB outage) → log only;\n // do NOT emit webhook (buyer doesn't know task succeeded), do NOT\n // try to fail() the task (taskFn DID succeed; mismatch would\n // mislead operator reconciliation)\n // 3. taskFn fails AND registry fail-write also fails → log only;\n // do not emit webhook (registry state is inconsistent)\n //\n // Webhook delivery is gated on the registry write succeeding so the\n // buyer's view (via webhook OR getTaskState) is always consistent.\n const completion: Promise<void> = (async () => {\n let result: TResult | undefined;\n let taskFnError: unknown;\n try {\n result = await taskFn(taskId);\n } catch (err) {\n taskFnError = err;\n }\n\n if (taskFnError === undefined) {\n // Success path. Strip wire-only-server fields BEFORE the registry\n // write so every downstream consumer (tasks/get polling at\n // line 1826, emitTaskWebhook below at line 2493, idempotency\n // replays of the Submitted envelope) inherits a clean payload.\n // Mirrors the same chokepoint pattern projectSync uses for the\n // sync arm. Without this strip, ctx_metadata + implementation_config\n // ride to the buyer via the HITL completion path even though the\n // sync path is clean — surfaced by security review on PR #1562.\n if (result != null && typeof result === 'object') {\n stripCtxMetadata(result as Record<string, unknown>);\n stripImplementationConfig(result as Record<string, unknown>);\n }\n try {\n await taskRegistry.complete(taskId, result as TResult);\n } catch (registryErr) {\n opts.logger.error(\n `[adcp/decisioning] task ${taskId} (${opts.tool}) completed but registry write failed — ` +\n `manual reconciliation required. Webhook not emitted; buyer state will diverge until resolved. ` +\n `Error: ${registryErr instanceof Error ? registryErr.message : String(registryErr)}`\n );\n fireTransition('failed', 'REGISTRY_WRITE_FAILED');\n return;\n }\n fireTransition('completed');\n await emitTaskWebhook(opts, {\n task: { task_id: taskId, status: 'completed', result },\n });\n return;\n }\n\n // Failure path\n const structured = sanitizeStructuredAdcpError(\n taskFnError instanceof AdcpError\n ? taskFnError.toStructuredError()\n : {\n code: 'SERVICE_UNAVAILABLE' as const,\n recovery: 'transient' as const,\n message: 'Task failed',\n }\n );\n const failureArtifact = { errors: [structured] };\n try {\n await taskRegistry.fail(taskId, structured, failureArtifact);\n } catch (registryErr) {\n opts.logger.error(\n `[adcp/decisioning] task ${taskId} (${opts.tool}) failed AND registry fail-write also failed — ` +\n `manual reconciliation required. Webhook not emitted. ` +\n `taskFn error: ${structured.message}; registry error: ${registryErr instanceof Error ? registryErr.message : String(registryErr)}`\n );\n fireTransition('failed', 'REGISTRY_WRITE_FAILED');\n return;\n }\n fireTransition('failed', structured.code);\n await emitTaskWebhook(opts, {\n task: { task_id: taskId, status: 'failed', result: failureArtifact, error: structured },\n });\n })();\n taskRegistry._registerBackground(taskId, completion);\n\n return { status: 'submitted', task_id: taskId };\n}\n\n/**\n * AdCP wire spec puts task / status / context fields on the webhook envelope\n * top level (`mcp-webhook-payload.json`); the success / failure body lives on\n * `result`. This helper builds that shape from the v6 task lifecycle data.\n *\n * Spec requires top-level: `idempotency_key`, `task_id`, `task_type`, `status`,\n * `timestamp`, `operation_id`. Optional: `protocol`, `context_id`, `message`,\n * `result`. We add `validation_token` (echoed from\n * `push_notification_config.token`) outside the spec but consistent with the\n * intent — receivers that don't expect it ignore the extra property.\n *\n * The webhook emitter replaces the placeholder `idempotency_key` with the\n * immutable key bound to its SDK-local `delivery_id`. The payload's\n * `operation_id` remains independent task correlation and can span multiple\n * lifecycle observations, each with a distinct delivery id/key.\n */\nfunction buildTaskWebhookPayload(\n opts: DispatchHitlOpts,\n taskId: string,\n status: TaskStatus,\n artifact: { result?: unknown; error?: AdcpStructuredError }\n): Record<string, unknown> {\n const idempotencyKey = randomUUID();\n const payload: Record<string, unknown> = {\n idempotency_key: idempotencyKey,\n operation_id: resolveWebhookPayloadOperationId(opts, taskId),\n task_id: taskId,\n task_type: opts.tool,\n status,\n timestamp: new Date().toISOString(),\n protocol: protocolForTool(opts.tool),\n };\n // Spec doesn't define a wire field name for the echoed token. Buyers\n // pass `push_notification_config.token` on the request; we echo it back\n // under the same name `token` so receivers verifying via the request\n // field can find it. (Earlier preview drops named this `validation_token`\n // — that wasn't spec-aligned and won't be picked up by buyers wiring\n // against the spec request shape.)\n if (opts.pushNotificationToken !== undefined) {\n payload.token = opts.pushNotificationToken;\n }\n // `result` is the AdCP async-response-data union — for completed it's\n // the success-arm body; for failed it carries `errors: AdcpStructuredError[]`\n // alongside the empty success shape.\n if (status === 'completed' && artifact.result !== undefined) {\n payload.result = artifact.result;\n }\n if (status === 'failed' && artifact.error !== undefined) {\n payload.result = artifact.result ?? { errors: [artifact.error] };\n payload.message = artifact.error.message;\n }\n return payload;\n}\n\nfunction resolveWebhookPayloadOperationId(opts: DispatchHitlOpts, taskId: string): string {\n if (opts.pushNotificationOperationId === undefined && isAdcpVersionAtLeast(opts.servedAdcpVersion, '3.2.0-beta.5')) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'push_notification_config.operation_id is required for webhook delivery',\n field: 'push_notification_config.operation_id',\n });\n }\n // Older negotiated bundles predate buyer-supplied operation IDs. Preserve\n // their stable compatibility value without allowing beta.5+ to synthesize.\n return opts.pushNotificationOperationId ?? `${opts.tool}.${taskId}`;\n}\n\nfunction resolveWebhookDeliveryId(opts: DispatchHitlOpts, taskId: string): string {\n return `task-webhook:${opts.accountId}:${opts.tool}:${taskId}`;\n}\n\n// `protocolForTool` and `SPEC_WEBHOOK_TASK_TYPES` are exported from\n// `protocol-for-tool.ts` — see import at top of file.\n\nasync function emitTaskWebhook(\n opts: DispatchHitlOpts,\n source: { task: { task_id: string; status: 'completed' | 'failed'; result?: unknown; error?: AdcpStructuredError } }\n): Promise<void> {\n if (!opts.emitWebhook || !opts.pushNotificationUrl) return;\n const taskId = source.task.task_id;\n // Spec gate: `enums/task-type.json` is a closed 20-value enum at AdCP\n // 3.0 GA. Spec-validating receivers reject envelopes with a non-spec\n // `task_type` value. The framework dispatches a wider tool surface\n // than the spec-listed task types — for those, skip webhook delivery\n // (adopters surface long-running state via `publishStatusChange`\n // instead). Tracking spec issue to widen the enum.\n if (!SPEC_WEBHOOK_TASK_TYPES.has(opts.tool)) {\n opts.logger.warn(\n `[adcp/decisioning] task webhook for ${taskId} (${opts.tool}) skipped — ` +\n `tool not in spec task-type enum (closed 20-value set per enums/task-type.json). ` +\n `Use publishStatusChange for long-running ${opts.tool} state.`\n );\n return;\n }\n const wirePayload = buildTaskWebhookPayload(opts, taskId, source.task.status, {\n ...(source.task.result !== undefined && { result: source.task.result }),\n ...(source.task.error !== undefined && { error: source.task.error }),\n });\n const start = Date.now();\n let success = false;\n let errorMessages: string[] | undefined;\n let errorCode: string | undefined;\n try {\n const result = await opts.emitWebhook({\n url: opts.pushNotificationUrl,\n payload: wirePayload,\n delivery_id: resolveWebhookDeliveryId(opts, taskId),\n });\n success = result?.delivered === true;\n if (result && Array.isArray(result.errors) && result.errors.length > 0) {\n errorMessages = result.errors;\n errorCode = bucketWebhookError(result.errors[0] ?? '');\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errorMessages = [msg];\n errorCode = bucketWebhookError(msg);\n // Webhook failures don't fail the task — registry already records the\n // terminal state. URL redacted from log to avoid leaking buyer-supplied\n // attacker-controllable values into operator log aggregators.\n opts.logger.warn(\n `[adcp/decisioning] task webhook for ${taskId} (${opts.tool}, status=${source.task.status}) ` + `failed: ${msg}`\n );\n } finally {\n safeFire(\n opts.observability?.onWebhookEmit,\n {\n taskId,\n tool: opts.tool,\n status: source.task.status,\n url: opts.pushNotificationUrl,\n success,\n durationMs: Date.now() - start,\n ...(errorCode && { errorCode }),\n ...(errorMessages && { errorMessages }),\n },\n 'onWebhookEmit',\n opts.logger\n );\n }\n}\n\n/**\n * Bucket a free-text webhook error into a metric-tag-safe code. Matches\n * `DecisioningObservabilityHooks.onWebhookEmit.errorCode` documented enum\n * (`'TIMEOUT'`, `'CONNECTION_REFUSED'`, `'HTTP_4XX'`, `'HTTP_5XX'`,\n * `'SIGNATURE_FAILURE'`, `'UNKNOWN'`). Adopters tag DD/Prom by the bucket;\n * `errorMessages` carries the raw text for log adopters.\n */\nfunction bucketWebhookError(msg: string): string {\n const lower = msg.toLowerCase();\n if (lower.includes('timeout') || lower.includes('etimedout')) return 'TIMEOUT';\n if (lower.includes('econnrefused') || lower.includes('connection refused')) return 'CONNECTION_REFUSED';\n if (lower.includes('signature') || lower.includes('rfc 9421')) return 'SIGNATURE_FAILURE';\n // Find ALL 3-digit HTTP-status-shaped tokens. Take the LARGEST one —\n // operator triage cares about the most-severe status, not the\n // left-most occurrence. Fixes \"upstream 502 (proxy received 401)\"\n // which would mis-bucket as HTTP_4XX under a first-match policy.\n // 3xx is included because signed webhook delivery never follows redirects, so\n // a redirecting endpoint is a real (and common) misconfiguration that would\n // otherwise bucket as UNKNOWN and stay invisible in operator dashboards.\n const matches = lower.match(/\\b[345]\\d\\d\\b/g);\n if (matches && matches.length > 0) {\n const codes = matches.map(m => parseInt(m, 10));\n const max = Math.max(...codes);\n if (max >= 500) return 'HTTP_5XX';\n if (max >= 400) return 'HTTP_4XX';\n return 'HTTP_REDIRECT';\n }\n return 'UNKNOWN';\n}\n\n// ---------------------------------------------------------------------------\n// Specialism → handler-map adapters\n// ---------------------------------------------------------------------------\n\n/**\n * Per-server `ctxFor` builder. `createAdcpServerFromPlatform` constructs\n * one closure per server (capturing `opts.ctxMetadata` if wired) and\n * threads it into each handler-builder. Handler bodies invoke\n * `ctxFor(ctx, params)` at request time to derive the per-call\n * `RequestContext`. The `params` argument is the un-destructured wire\n * envelope; it lands on `RequestContext.input` so platform methods can\n * read request fields the typed signature doesn't model (`assignments[]`\n * on `sync_creatives`, `delete_missing` on `sync_audiences`, etc.).\n */\ntype CtxForFn = (\n handlerCtx: HandlerContext<Account>,\n input?: Readonly<Record<string, unknown>>\n) => RequestContext<Account>;\n\nfunction makeCtxFor(ctxMetadataStore?: CtxMetadataStore): CtxForFn {\n return (handlerCtx, input) => buildRequestContext(handlerCtx, ctxMetadataStore, input);\n}\n\n/**\n * Project a framework `HandlerContext` / `RequestContext` to the public\n * `ResolveContext` shape passed to every `AccountStore` method\n * (`resolve`, `upsert`, `list`, `reportUsage`, `getAccountFinancials`).\n *\n * Single source of truth for the threading shape: when `ResolveContext`\n * gains a new field, update this function and every account-method call\n * site picks it up. The alternative (inline literals at each call site)\n * is what produced the original asymmetric `agent` gap on `reportUsage`\n * and `getAccountFinancials` — fixed by routing all six framework call\n * sites through here.\n *\n * `toolName` is supplied per call site (handlers hardcode their tool\n * name; the dispatcher's `resolveAccount` / `resolveAccountFromAuth`\n * paths read it off `RequestContext.toolName`). Spread guards keep\n * `authInfo` / `agent` keys absent rather than `undefined` — adopters\n * can use `'authInfo' in ctx` as a presence check.\n */\nfunction toResolveCtx(\n ctx: { authInfo?: ResolvedAuthInfo; agent?: BuyerAgent },\n toolName: string | undefined,\n input?: Readonly<Record<string, unknown>>\n): ResolveContext {\n return {\n ...(ctx.authInfo !== undefined && { authInfo: ctx.authInfo }),\n ...(toolName !== undefined && { toolName }),\n ...(ctx.agent != null && { agent: ctx.agent }),\n ...(input != null && { input }),\n };\n}\n\n/**\n * Auto-store helper. After a publisher returns resources from a discovery\n * tool (`getProducts`, `getMediaBuys`, etc.), persist each resource's wire\n * shape (minus `ctx_metadata`) alongside the publisher's `ctx_metadata`\n * blob. Subsequent calls referencing the same id by string can be hydrated\n * (publisher sees the full resource as `req.packages[i].product`).\n *\n * Failures are logged + swallowed — auto-store must NEVER break a\n * successful response.\n */\nasync function autoStoreResources(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n kind: ResourceKind,\n resources: readonly unknown[] | undefined,\n idField: string,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId || !resources) return;\n let skippedMissingId = 0;\n for (const r of resources) {\n if (r == null || typeof r !== 'object') continue;\n const obj = r as Record<string, unknown>;\n const id = obj[idField];\n if (typeof id !== 'string' || id.length === 0) {\n // The id field is wire-required on every resource the framework\n // auto-stores (e.g. `signal_agent_segment_id` on a signal,\n // `product_id` on a product). Silently skipping leaves buyers with\n // no way to reference the resource on a downstream mutating call —\n // a strong indicator the handler returned a misshaped response.\n skippedMissingId++;\n continue;\n }\n const ctxMeta = obj['ctx_metadata'];\n // Strip ctx_metadata from the resource before storing — round-trip\n // restores it on hydration. Keeping a pristine wire copy in `resource`.\n const {\n ctx_metadata: _stripped,\n [STORED_LEGACY_FORMAT_ROUTES]: _reservedRouteMetadata,\n ...wireResource\n } = obj as Record<string, unknown>;\n void _stripped;\n void _reservedRouteMetadata;\n const legacyFormatRoutes = kind === 'product' ? captureStoredLegacyFormatRoutes(obj) : undefined;\n if (legacyFormatRoutes) wireResource[STORED_LEGACY_FORMAT_ROUTES] = legacyFormatRoutes;\n try {\n // Use `setResource` (not `setEntry`) so a publisher's prior\n // `ctx.ctxMetadata.set(kind, id, blob)` is preserved when the\n // publisher returns the resource WITHOUT `ctx_metadata` inline.\n // Auto-store should never clobber adopter-managed state.\n await store.setResource(accountId, kind, id, wireResource, ctxMeta);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store ${kind} ${id} failed: ${msg}`);\n }\n }\n if (skippedMissingId > 0) {\n logger.warn(\n `[adcp/decisioning] auto-store skipped ${skippedMissingId} ${kind} ` +\n `record(s) missing required '${idField}' — buyers will not be able ` +\n `to reference these resources on a subsequent mutating call.`\n );\n }\n}\n\n/**\n * Persist `packages[].targeting_overlay` from a successful\n * `create_media_buy`. Called from the createMediaBuy projection so the\n * persistence applies to both the sync arm and the HITL completion arm\n * (the projection runs after the handoff fn resolves).\n *\n * Failures are logged + swallowed: a successful seller response must\n * never be turned into an error by the auto-echo plumbing.\n */\nasync function persistTargetingOverlayFromCreate(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n request: unknown,\n result: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n if (result == null || typeof result !== 'object') return;\n try {\n await store.persistFromCreate(\n accountId,\n request as CreateMediaBuyInputForStore,\n result as CreateMediaBuyResultForStore\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.persistFromCreate failed: ${msg}`);\n }\n}\n\n/**\n * Apply an `update_media_buy` patch to the persisted media-buy store.\n * Per-field merge inside `targeting_overlay`: omitted keeps prior,\n * present-non-null replaces, present-null clears.\n *\n * Failures are logged + swallowed for the same reason as the create\n * path — the seller's update succeeded; auto-merge is best-effort.\n */\nasync function persistTargetingOverlayFromUpdate(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n mediaBuyId: string,\n patch: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n try {\n await store.mergeFromUpdate(accountId, mediaBuyId, patch as UpdateMediaBuyInputForStore);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.mergeFromUpdate failed: ${msg}`);\n }\n}\n\n/**\n * Backfill missing `packages[].targeting_overlay` on a `get_media_buys`\n * response from the persisted store. Mutates the response. Packages the\n * seller already echoed are left alone.\n *\n * Failures are logged + swallowed: a partial-echo response is strictly\n * better than a hard error wiping out the seller's correctly-returned\n * media-buy data.\n */\nasync function backfillTargetingOverlay(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n result: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n if (result == null || typeof result !== 'object') return;\n try {\n await store.backfill(accountId, result as GetMediaBuysResultForStore);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.backfill failed: ${msg}`);\n }\n}\n\n/**\n * Auto-hydrate helper. Before invoking a publisher's mutating handler,\n * walk the request's resource references and attach the full wire\n * resource (including `ctx_metadata`) to each. Mutates the request in\n * place — adds an extra typed field alongside the original id.\n *\n * For `createMediaBuy`: walks `req.packages`, hydrates each with\n * `pkg.product = { ...resource, ctx_metadata }` keyed by `pkg.product_id`.\n *\n * Failures are logged + swallowed; the publisher still receives the\n * un-hydrated request and can fall back to its own DB.\n */\nasync function hydratePackagesWithProducts(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n packages: unknown[] | undefined,\n logger: AdcpLogger,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): Promise<void> {\n if (!store || !accountId || !packages || packages.length === 0) return;\n const refs: Array<{ kind: 'product'; id: string }> = [];\n for (const pkg of packages) {\n if (pkg == null || typeof pkg !== 'object') continue;\n const productId = (pkg as Record<string, unknown>)['product_id'];\n if (typeof productId === 'string' && productId.length > 0) {\n refs.push({ kind: 'product', id: productId });\n }\n }\n if (refs.length === 0) return;\n let entries: ReadonlyMap<string, { value: unknown; resource?: unknown }>;\n try {\n entries = await store.bulkGetEntries(accountId, refs);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-hydrate bulkGet failed: ${msg}`);\n return;\n }\n for (const pkg of packages) {\n if (pkg == null || typeof pkg !== 'object') continue;\n const productId = (pkg as Record<string, unknown>)['product_id'];\n if (typeof productId !== 'string') continue;\n const entry = entries.get(`product:${productId}`);\n if (!entry?.resource || typeof entry.resource !== 'object') continue;\n let hydrated: Record<string, unknown>;\n try {\n const storedResource = entry.resource as Record<string, unknown>;\n const { [STORED_LEGACY_FORMAT_ROUTES]: storedLegacyFormatRoutes, ...resource } = storedResource;\n hydrated = asCanonicalSemanticServerRequest(resource, 'hydrate_product', legacyFormatConverter) as Record<\n string,\n unknown\n >;\n restoreStoredLegacyFormatRoutes(hydrated, storedLegacyFormatRoutes);\n } catch {\n logger.warn(\n `[adcp/decisioning] auto-hydrate product:${productId} skipped: stored creative format has no canonical representation`\n );\n continue;\n }\n if (entry.value !== null && entry.value !== undefined) {\n hydrated['ctx_metadata'] = entry.value;\n }\n Object.defineProperty(hydrated, '__adcp_hydrated__', {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n // Non-enumerable: see hydrateSingleResource for rationale (no leak via\n // JSON.stringify / spread / Object.entries; direct access works).\n Object.defineProperty(pkg, 'product', {\n value: hydrated,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n}\n\n/**\n * Auto-hydrate one resource referenced by id at the top level of a request.\n *\n * Generalization of {@link hydratePackagesWithProducts} for verbs whose\n * primary resource lives directly on the request body (`update_media_buy`,\n * `provide_performance_feedback`, `activate_signal`, `acquire_rights`).\n * Walks the store for `(kind, id)`, attaches `target[attachField] =\n * { ...resource, ctx_metadata }` when the entry has a wire resource.\n *\n * ## Error contract on missing references\n *\n * **Misses are silent. The handler runs anyway with `target[attachField]`\n * undefined.** This is deliberate — the framework cache is a *hint*, not\n * the source of truth. A miss can mean any of:\n *\n * 1. The buyer never called the discovery verb in this session (cold\n * start, fresh tenant). Hydration is purely additive context; the\n * publisher's own DB is authoritative for whether the id exists.\n * 2. The cache evicted (TTL, LRU). Same: publisher's DB stays the\n * source of truth.\n * 3. The buyer truly referenced an unknown id. The publisher SHOULD\n * reject this — see the handler-side guard pattern below.\n *\n * Adopters who want strict existence checks (option 1: framework throws\n * `PRODUCT_NOT_FOUND` / `MEDIA_BUY_NOT_FOUND` and the handler never runs)\n * implement that check inside the handler:\n *\n * ```ts\n * updateMediaBuy: async (id, patch, ctx) => {\n * // Hydration miss + DB miss = unknown to this seller.\n * if (!patch.media_buy && !(await db.findMediaBuy(id))) {\n * throw new MediaBuyNotFoundError({ message: `media_buy ${id} not found` });\n * }\n * // ...\n * }\n * ```\n *\n * The framework cannot distinguish (1)/(2) from (3) without consulting the\n * publisher's DB, which is exactly what the handler does. Erroring at the\n * framework layer would force every adopter to manage cache warmth or\n * pre-load every media_buy into the cache before serving traffic — wrong\n * default for a hint-based cache.\n *\n * ## Field semantics on the hydrated value\n *\n * The attached field is **non-enumerable** so accidental serialization\n * (`JSON.stringify(req)`, spread `{...req}`, `Object.entries(req)`)\n * doesn't leak the publisher's `ctx_metadata` blob into request-side audit\n * sinks. Direct property access (`req.media_buy.ctx_metadata`) still\n * works; the field is invisible only to enumeration-based serializers.\n *\n * Hydrated fields carry a `__adcp_hydrated__: true` non-enumerable marker\n * so handler authors and middleware can disambiguate \"publisher passed it\"\n * from \"framework attached it\" — the field is **advisory context only**;\n * the wire contract is defined by the spec request fields, not by what\n * the SDK happens to attach.\n *\n * Store-fetch failures (Postgres unavailable, etc.) are logged + swallowed.\n * Hydration must NEVER break a successful dispatch — same posture as a\n * cache miss.\n */\nasync function hydrateSingleResource(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n kind: ResourceKind,\n id: string | undefined,\n attachField: string,\n target: unknown,\n logger: AdcpLogger,\n legacyFormatConverter?: LegacyFormatConverter\n): Promise<void> {\n if (!store || !accountId || !id || target == null || typeof target !== 'object') return;\n let entry: { value: unknown; resource?: unknown } | undefined;\n try {\n entry = await store.getEntry(accountId, kind, id);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-hydrate ${kind}:${id} failed: ${msg}`);\n return;\n }\n if (!entry?.resource || typeof entry.resource !== 'object') return;\n let hydrated: Record<string, unknown>;\n if (legacyFormatConverter !== undefined || kind === 'media_buy' || kind === 'package' || kind === 'creative') {\n try {\n hydrated = asCanonicalSemanticServerRequest(entry.resource, `hydrate_${kind}`, legacyFormatConverter) as Record<\n string,\n unknown\n >;\n } catch {\n logger.warn(\n `[adcp/decisioning] auto-hydrate ${kind}:${id} skipped: stored creative format has no canonical representation`\n );\n return;\n }\n } else {\n hydrated = { ...(entry.resource as Record<string, unknown>) };\n }\n if (entry.value !== null && entry.value !== undefined) {\n hydrated['ctx_metadata'] = entry.value;\n }\n Object.defineProperty(hydrated, '__adcp_hydrated__', {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n // Attach as non-enumerable so JSON.stringify(req), spread {...req}, and\n // Object.entries(req) do NOT carry the publisher's ctx_metadata blob into\n // log lines, audit sinks, or replay payloads. Direct access (req.foo)\n // still works.\n Object.defineProperty(target, attachField, {\n value: hydrated,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Spec `x-entity` annotation → SDK `ResourceKind`. The SDK only hydrates\n * resource kinds it has a backing store for; unmapped entities (e.g.\n * `vendor_pricing_option`, `governance_plan`) are gracefully skipped.\n *\n * The annotation acts as a renaming-firewall: if the spec renames\n * `media_buy_id` → `mediabuy_id`, the `x-entity: \"media_buy\"` tag travels\n * with the field and the codegen step in `scripts/generate-entity-hydration.ts`\n * picks up the new field name automatically — no SDK code change required.\n *\n * Adding a new `ResourceKind` for hydration is a coordinated change: add\n * it to `ResourceKind` (in `ctx-metadata/store.ts`) and to this map.\n */\n/** @internal Exported for the coverage test in `test/lib/x-entity-hydration.test.js`. */\nexport const ENTITY_TO_RESOURCE_KIND: Readonly<Record<string, ResourceKind>> = {\n media_buy: 'media_buy',\n package: 'package',\n creative: 'creative',\n audience: 'audience',\n // Spec quirk: `signal_activation_id` is a SEPARATE entity from `signal`\n // (per AdCP `core/x-entity-types.json` — the activation handle is\n // scoped to the issuing signals agent, not interchangeable with the\n // catalog's `signal_id`). The SDK collapses them onto the existing\n // `signal` ResourceKind for backward-compat: adopters already seed\n // the cache keyed by `signal_agent_segment_id` under `kind: 'signal'`.\n // Splitting `signal_activation` to its own ResourceKind would orphan\n // those entries. Tracked upstream — file an `adcp` issue if/when this\n // collapse causes confusion.\n signal_activation_id: 'signal',\n rights_grant: 'rights_grant',\n property_list: 'property_list',\n collection_list: 'collection_list',\n account: 'account',\n product: 'product',\n // SI session lifecycle, hydrated on `si_send_message` /\n // `si_terminate_session` from the entry the framework auto-stores after\n // `si_initiate_session`. See `buildSponsoredIntelligenceHandlers`.\n si_session: 'si_session',\n};\n\n/**\n * `x-entity` values the SDK does NOT hydrate today — graceful skip rather\n * than failure. Entries here are documented intentional skips so a future\n * code reader can distinguish \"we forgot to map this\" from \"the SDK\n * doesn't model this kind.\"\n *\n * The codegen-derived `TOOL_ENTITY_FIELDS` map carries every `x-entity`\n * the spec emits on dispatchable tools (webhook-only payloads like\n * `creative_approval` are filtered out at codegen time); this allowlist\n * + `ENTITY_TO_RESOURCE_KIND` together must cover the full set,\n * enforced by a test (`test/lib/x-entity-hydration.test.js`) that\n * imports both.\n *\n * @internal Exported for the coverage test; not part of the public API.\n */\nexport const INTENTIONALLY_UNHYDRATED_ENTITIES: ReadonlySet<string> = new Set([\n 'vendor_pricing_option', // Scoped to issuing vendor agent; adopters seed pricing context themselves.\n 'governance_plan', // No SDK ResourceKind yet; campaign-governance follow-up.\n 'governance_check', // Transient request envelope; not stored.\n 'event_source', // No SDK ResourceKind yet.\n 'offering', // SI offering catalog; correlation handled by brand-side `offering_token`, not framework hydration.\n 'rights_holder_brand', // Read-through `get_brand_identity`; not separately stored.\n 'advertiser_brand', // Same as above.\n 'transformer', // Creative build capability catalog entry; no ctx-metadata ResourceKind yet.\n 'build_variant', // Build lineage/refinement handle; no ctx-metadata ResourceKind yet.\n 'task', // Protocol task reconciliation id; task registry handles lookup, not ctx_metadata hydration.\n 'proposal', // ProposalStore owns proposal lifecycle/CAS; ctx-metadata hydration would bypass those controls.\n 'governance_adjustment', // Durable governance receipt identifier; no SDK ResourceKind/store yet.\n 'governance_outcome', // Durable governance receipt identifier; no SDK ResourceKind/store yet.\n 'seller_adjustment', // Seller-authored adjustment reference; resolved by governance workflows, not ctx metadata.\n]);\n\n/**\n * Per-tool, per-field destination property name for hydrated resources.\n *\n * The hydrator's default is to derive the destination from the field name\n * by stripping the `_id` suffix (e.g. `media_buy_id` → attach as\n * `params.media_buy`). Three cases need explicit overrides because their\n * historical attach-fields don't match that convention — adopters already\n * read these in handler code and a rename would be wire-visible behavior:\n *\n * - `acquire_rights.rights_id` → `params.rights` (NOT `rights_grant`).\n * Predates the entity-driven hydrator. Kept for backward-compat.\n * - `activate_signal.signal_agent_segment_id` → `params.signal`\n * (NOT `signal_agent_segment` — `_id` suffix isn't on the boundary\n * the convention strips).\n * - `update_rights.rights_id` → `params.rights_grant` (NOT `rights`).\n * Diverges from `acquire_rights`'s historical `params.rights` because\n * the wire payloads model different things — acquire takes an\n * offering selection, update modifies an existing grant.\n *\n * Other tools either follow the convention (`update_media_buy`,\n * `provide_performance_feedback`) or don't currently have hydration\n * registered (the unmapped `x-entity` skips above).\n */\nconst HYDRATION_ATTACH_FIELD_OVERRIDES: Readonly<Record<string, Readonly<Record<string, string>>>> = {\n acquire_rights: { rights_id: 'rights' },\n activate_signal: { signal_agent_segment_id: 'signal' },\n update_rights: { rights_id: 'rights_grant' },\n};\n\nfunction deriveAttachField(toolName: string, field: string): string {\n const override = HYDRATION_ATTACH_FIELD_OVERRIDES[toolName]?.[field];\n if (override) return override;\n // Default: strip the `_id` suffix so `media_buy_id` → `media_buy`,\n // `creative_id` → `creative`, etc. This is the convention every existing\n // hydration call site followed before the schema-driven refactor.\n return field.endsWith('_id') ? field.slice(0, -3) : field;\n}\n\n/**\n * Schema-driven auto-hydration for a tool's request payload.\n *\n * Walks the codegen-derived `TOOL_ENTITY_FIELDS` table for the named tool,\n * looks up each spec-tagged identifier on `params`, maps the `x-entity`\n * annotation to a `ResourceKind`, and attaches the resolved record at the\n * conventional destination field. Replaces the four hand-rolled\n * `hydrateSingleResource` call sites that hardcoded `(field_name, kind)`\n * pairs and were vulnerable to a silent break under a future spec rename\n * (protocol-expert review of #1086 → tracked as #1109).\n */\nasync function hydrateForTool(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n toolName: string,\n params: unknown,\n logger: AdcpLogger,\n legacyFormatConverter?: LegacyFormatConverter\n): Promise<void> {\n if (!store || !accountId || params == null || typeof params !== 'object') return;\n const fields = TOOL_ENTITY_FIELDS[toolName];\n if (!fields || fields.length === 0) return;\n const paramsRecord = params as Record<string, unknown>;\n for (const { field, xEntity } of fields) {\n const id = paramsRecord[field];\n if (typeof id !== 'string' || id.length === 0) continue;\n const kind = ENTITY_TO_RESOURCE_KIND[xEntity];\n if (!kind) continue; // Unknown entity — graceful skip; don't break unknown verbs.\n const attachField = deriveAttachField(toolName, field);\n await hydrateSingleResource(store, accountId, kind, id, attachField, params, logger, legacyFormatConverter);\n }\n}\n\n/**\n * Extract the buyer's push-notification webhook config from a request body\n * and validate the URL + token against SSRF / replay primitives.\n *\n * AdCP wire requests for HITL tools carry `push_notification_config: { url,\n * token? }`. The buyer-supplied URL is attacker-controllable — without\n * validation, a buyer with `create_media_buy` access can force the agent\n * process to POST signed payloads to internal admin endpoints, AWS metadata\n * (`http://169.254.169.254/`), or RFC 1918 private ranges. Validation\n * gates here:\n *\n * 1. **Scheme**: `https://` only in production; `http://` allowed when\n * `NODE_ENV` ∈ {test, development} OR the operator opts in via\n * `ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS=1`. Same allowlist pattern as\n * the in-memory task registry.\n * 2. **Host**: rejects IP-literals targeting RFC 1918 private ranges\n * (10/8, 172.16/12, 192.168/16), link-local (169.254/16, fe80::/10),\n * loopback (127/8, ::1), CGNAT (100.64/10), and unspecified addresses\n * (0.0.0.0, ::). Rejects bare hostnames `localhost` / `0`.\n * 3. **Token shape**: rejects tokens longer than 255 chars or containing\n * control characters. Tokens past 255 chars combined with a malicious\n * URL would inflate webhook payload size; control characters break log\n * redaction.\n *\n * Adopters who need stricter rules (host allowlist) can re-validate\n * inside their `taskWebhookEmitter` impl. Adopters needing to relax for\n * legitimate internal-network test setups use the env-var ack.\n *\n * **DNS rebinding caveat.** This validator only inspects the literal\n * hostname/IP in the URL. A buyer registers `https://rebind.attacker.com/`\n * whose A-record returns `8.8.8.8` at validate time and `127.0.0.1` /\n * `169.254.169.254` at fetch time bypasses this layer. The framework's\n * own `serve({ webhooks })`-wired emitter (RFC 9421-signed delivery via\n * `WebhookManager`) re-resolves the host at fetch time and DOES NOT\n * pin-and-bind to the validate-time IP. Adopters wiring a custom\n * `taskWebhookEmitter` SHOULD pin the resolved IP at validate time and\n * connect to that specific IP, OR run all webhook delivery through a\n * forward proxy with an egress allowlist. Tracking issue:\n * `adcp-client#TBD` for framework-side pin-and-bind.\n *\n * On rejection, throws `AdcpError('INVALID_REQUEST', { field })` so the\n * buyer sees the bad config at the request boundary. Previous silent-skip\n * posture lost buyer visibility.\n */\nfunction extractPushConfig(\n params: unknown,\n _logger: AdcpLogger,\n opts: { allowPrivateWebhookUrls?: boolean } = {}\n): { url?: string; token?: string; operationId?: string } {\n if (!params || typeof params !== 'object') return {};\n const cfg = (params as { push_notification_config?: unknown }).push_notification_config;\n if (!cfg || typeof cfg !== 'object') return {};\n const cfgObj = cfg as { url?: unknown; token?: unknown; operation_id?: unknown };\n const rawUrl = cfgObj.url;\n const rawToken = cfgObj.token;\n const rawOperationId = cfgObj.operation_id;\n\n let url: string | undefined;\n if (typeof rawUrl === 'string') {\n const validation = validatePushNotificationUrl(rawUrl, { allowPrivate: opts.allowPrivateWebhookUrls === true });\n if (!validation.ok) {\n // Fail fast: buyers thought they wired push and never saw it under\n // the previous silent-skip posture. Rejecting upfront with\n // `INVALID_REQUEST` and `field: 'push_notification_config.url'`\n // surfaces the problem at the request boundary so buyers can fix\n // their config before relying on webhooks. Buyers can still poll\n // via `tasks_get` if they need a fallback path.\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.url rejected: ${validation.reason}`,\n field: 'push_notification_config.url',\n });\n }\n url = rawUrl;\n }\n\n let token: string | undefined;\n if (typeof rawToken === 'string') {\n const validation = validatePushNotificationToken(rawToken);\n if (!validation.ok) {\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.token rejected: ${validation.reason}`,\n field: 'push_notification_config.token',\n });\n }\n token = rawToken;\n }\n\n let operationId: string | undefined;\n if (Object.prototype.hasOwnProperty.call(cfgObj, 'operation_id')) {\n if (typeof rawOperationId !== 'string') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'push_notification_config.operation_id rejected: operation_id must be a string',\n field: 'push_notification_config.operation_id',\n });\n }\n const validation = validatePushNotificationOperationId(rawOperationId);\n if (!validation.ok) {\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.operation_id rejected: ${validation.reason}`,\n field: 'push_notification_config.operation_id',\n });\n }\n operationId = rawOperationId;\n }\n\n return {\n ...(url !== undefined && { url }),\n ...(token !== undefined && { token }),\n ...(operationId !== undefined && { operationId }),\n };\n}\n\ninterface UrlValidationResult {\n ok: boolean;\n reason?: string;\n}\n\nfunction validatePushNotificationUrl(rawUrl: string, opts: { allowPrivate?: boolean } = {}): UrlValidationResult {\n let parsed: URL;\n try {\n parsed = new URL(rawUrl);\n } catch {\n return { ok: false, reason: 'malformed URL' };\n }\n\n const allowHttp =\n process.env.NODE_ENV === 'test' ||\n process.env.NODE_ENV === 'development' ||\n process.env.ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS === '1';\n\n if (parsed.protocol === 'http:' && !allowHttp) {\n return {\n ok: false,\n reason: 'http:// scheme not allowed (use https:// or set ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS=1)',\n };\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { ok: false, reason: `unsupported scheme \"${parsed.protocol}\" (only http: / https:)` };\n }\n\n // Adopter-set flag bypasses ONLY the private-IP / loopback rejection.\n // Malformed-URL and scheme checks above always fire — the relaxation\n // is scoped to \"let sandbox webhook receivers bind to loopback\" not\n // \"trust everything.\" See CreateAdcpServerFromPlatformOptions.\n if (opts.allowPrivate === true) {\n return { ok: true };\n }\n\n // Node's `URL.hostname` returns IPv6 literals WITH brackets — so\n // `https://[::1]/` yields `[::1]`. Strip them so our IPv6 checks below\n // can match the unbracketed form. (`URL.host` includes the port, which\n // we don't want here.)\n let host = parsed.hostname.toLowerCase();\n if (host.startsWith('[') && host.endsWith(']')) {\n host = host.slice(1, -1);\n }\n if (host === '' || host === 'localhost' || host === '0') {\n return { ok: false, reason: `host \"${host}\" rejected (loopback / unspecified)` };\n }\n\n // Note on IPv4 alternate forms (integer `2130706433`, hex `0x7f000001`,\n // octal `0177.0.0.1`): Node's WHATWG URL parser canonicalizes all of\n // these to dotted-decimal before we see `parsed.hostname`. So\n // `https://2130706433/` arrives here with host `127.0.0.1` and falls\n // through to the dotted-decimal range check below. Defense-in-depth\n // alternate-form regex rejectors are not needed at this layer.\n\n // IPv4 dotted-decimal check\n const ipv4Match = host.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (ipv4Match) {\n const a = Number(ipv4Match[1]);\n const b = Number(ipv4Match[2]);\n if (a === 10) return { ok: false, reason: 'RFC 1918 private range 10/8 rejected' };\n if (a === 127) return { ok: false, reason: 'loopback range 127/8 rejected' };\n if (a === 0) return { ok: false, reason: 'unspecified range 0/8 rejected' };\n if (a === 169 && b === 254) return { ok: false, reason: 'link-local 169.254/16 rejected (cloud metadata)' };\n if (a === 172 && b >= 16 && b <= 31) return { ok: false, reason: 'RFC 1918 private range 172.16/12 rejected' };\n if (a === 192 && b === 168) return { ok: false, reason: 'RFC 1918 private range 192.168/16 rejected' };\n if (a === 100 && b >= 64 && b <= 127) return { ok: false, reason: 'CGNAT range 100.64/10 rejected' };\n if (a >= 224) return { ok: false, reason: 'multicast / reserved range rejected' };\n }\n\n // IPv6 literal check — Node strips brackets so we match unbracketed forms.\n // A hostname containing `:` is an IPv6 literal (DNS hostnames disallow `:`).\n if (host.includes(':')) {\n // Loopback + unspecified — exact match\n if (host === '::1') return { ok: false, reason: 'IPv6 loopback ::1 rejected' };\n if (host === '::') return { ok: false, reason: 'IPv6 unspecified :: rejected' };\n // Link-local fe80::/10 — match strict prefix `fe80:` (not just `fe80`)\n if (host.startsWith('fe80:')) {\n return { ok: false, reason: 'IPv6 link-local fe80::/10 rejected' };\n }\n // Unique-local fc00::/7 — match strict prefix `fc` or `fd` followed\n // by exactly one more hex char (so fc00:, fcab:, fd00:, fdef:) and\n // then `:`. Old check `host.startsWith('fc')` would match the\n // hostname-not-IP `fc-cdn.example.com`; since IPv6 hostnames always\n // contain `:`, restrict to literals where char[2] is hex + `:`.\n if (/^f[cd][0-9a-f]{2}:/.test(host)) {\n return { ok: false, reason: 'IPv6 unique-local fc00::/7 rejected' };\n }\n // IPv4-mapped IPv6 — `::ffff:127.0.0.1` or `::ffff:7f00:0001`. Either\n // form: extract the embedded IPv4 (if dotted) or the last 32 bits and\n // re-run the IPv4 range checks. Simpler: reject any `::ffff:` prefix\n // pointing to a private IPv4 by recursive validation.\n const v4MappedMatch = host.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (v4MappedMatch) {\n const inner = v4MappedMatch[1];\n const innerCheck = validatePushNotificationUrl(`http://${inner}/`);\n if (!innerCheck.ok) {\n return { ok: false, reason: `IPv4-mapped IPv6 ${host}: ${innerCheck.reason}` };\n }\n }\n // Hex IPv4-mapped form (`::ffff:7f00:0001`): match the 32-bit\n // suffix and convert to dotted form for re-check.\n const v4MappedHexMatch = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (v4MappedHexMatch) {\n const high = parseInt(v4MappedHexMatch[1]!, 16);\n const low = parseInt(v4MappedHexMatch[2]!, 16);\n const dotted = `${(high >> 8) & 0xff}.${high & 0xff}.${(low >> 8) & 0xff}.${low & 0xff}`;\n const innerCheck = validatePushNotificationUrl(`http://${dotted}/`);\n if (!innerCheck.ok) {\n return { ok: false, reason: `IPv4-mapped IPv6 ${host}: ${innerCheck.reason}` };\n }\n }\n }\n\n return { ok: true };\n}\n\nconst TOKEN_MAX_LENGTH = 255;\nconst TOKEN_CONTROL_CHAR_RE = /[\\x00-\\x1f\\x7f]/;\nconst PUSH_OPERATION_ID_RE = /^[A-Za-z0-9_.:-]{1,255}$/;\n\nfunction validatePushNotificationToken(token: string): UrlValidationResult {\n if (token.length === 0) {\n return { ok: false, reason: 'token is empty' };\n }\n if (token.length > TOKEN_MAX_LENGTH) {\n return { ok: false, reason: `token longer than ${TOKEN_MAX_LENGTH} chars` };\n }\n if (TOKEN_CONTROL_CHAR_RE.test(token)) {\n return { ok: false, reason: 'token contains control characters' };\n }\n return { ok: true };\n}\n\nfunction validatePushNotificationOperationId(operationId: string): UrlValidationResult {\n if (!PUSH_OPERATION_ID_RE.test(operationId)) {\n return { ok: false, reason: `operation_id must match ${PUSH_OPERATION_ID_RE.source}` };\n }\n return { ok: true };\n}\n\nfunction buildProposalNegotiationHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn\n): ProposalNegotiationHandlers<Account> | undefined {\n const lifecycle = platform.mediaBuyLifecycle;\n if (!lifecycle?.refineProposals) return undefined;\n if (!lifecycle.proposalRefinement) {\n throw new PlatformConfigError(\n 'mediaBuyLifecycle.refineProposals requires mediaBuyLifecycle.proposalRefinement capability metadata'\n );\n }\n\n return {\n capabilities: lifecycle.proposalRefinement,\n resolveScope: ctx => {\n const accountId = ctx.account?.id;\n if (!accountId) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'refine_proposals requires an authenticated account scope',\n recovery: 'correctable',\n });\n }\n const principalId = authenticatedPrincipalFor(ctx);\n if (!principalId) {\n throw new AdcpError('AUTH_REQUIRED', {\n message: 'refine_proposals requires an authenticated buyer principal',\n recovery: 'correctable',\n });\n }\n return { tenant_id: accountId, account_id: accountId, principal_id: principalId };\n },\n refineProposals: async (params, ctx) => {\n const request = params as unknown as Readonly<Record<string, unknown>>;\n const reqCtx = ctxFor(ctx, request);\n if (!reqCtx.account?.id) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'refine_proposals requires an authenticated account scope',\n recovery: 'correctable',\n });\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(request, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await lifecycle.refineProposals!(params, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'refine_proposals',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n value => value\n );\n },\n value => value\n );\n },\n };\n}\n\nfunction buildMediaBuyHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n mediaBuyStore: MediaBuyStore | undefined,\n proposalStore: import('../proposal').ProposalStore | undefined,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n legacyFormatResolver: LegacyFormatResolver | undefined,\n legacyFormatResolverOptions: { timeoutMs: number; concurrency: number },\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n creativeWireMode: 'canonical' | 'legacy'\n): MediaBuyHandlers<Account> | undefined {\n const sales = platform.sales;\n const lifecycle = platform.mediaBuyLifecycle;\n const getMediaBuyDelivery = lifecycle?.getMediaBuyDelivery ?? sales?.getMediaBuyDelivery;\n const getMediaBuys = lifecycle?.getMediaBuys ?? sales?.getMediaBuys;\n const proposalManager = (platform as { proposalManager?: import('../proposal').ProposalManager }).proposalManager;\n // Without a legacy sales surface, compact lifecycle, or proposal manager,\n // there's nothing to dispatch.\n if (!sales && !lifecycle && !proposalManager) return undefined;\n\n const dispatchCompactMutation = async <TResult>(\n tool: string,\n params: Readonly<Record<string, unknown>>,\n ctx: HandlerContext<Account>,\n invoke: (reqCtx: RequestContext<Account>) => Promise<TResult | TaskHandoff<TResult>>\n ) => {\n return projectSync(\n async () => {\n if (ctx.authInfo === undefined && ctx.agent === undefined) {\n throw new AdcpError('AUTH_MISSING', {\n message: `${tool} requires an authenticated buyer principal`,\n recovery: 'correctable',\n });\n }\n const accountId = ctx.account?.id;\n if (!accountId) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: `${tool} requires a resolved account scope`,\n recovery: 'correctable',\n });\n }\n const principalId = authenticatedPrincipalFor(ctx);\n if (!principalId) {\n throw new AdcpError('AUTH_MISSING', {\n message: `${tool} requires an authenticated buyer principal`,\n recovery: 'correctable',\n });\n }\n const callerMutationScope = Object.freeze({\n tenant_id: accountId,\n account_id: accountId,\n principal_id: principalId,\n });\n const reqCtx = ctxFor({ ...ctx, callerMutationScope }, params);\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await invoke(reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool,\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n value => value\n );\n },\n value => value\n );\n };\n\n // Core lifecycle methods are optional on the SalesPlatform interface\n // (#1341) — the per-specialism mapping in `RequiredPlatformsFor<S>`\n // enforces \"you claimed `sales-non-guaranteed`, therefore you must\n // implement getProducts\" at the type level, while specialisms whose\n // upstream owns bidding (`sales-social`) skip them entirely. The\n // dispatcher mirrors that with conditional spreads — we don't register\n // a wire handler when the platform method is absent, so the merge seam\n // (`opts.legacyHandlers.mediaBuy.X`) can supply it OR the framework returns\n // `METHOD_NOT_FOUND` from `tools/list` for the unsupported tool.\n return {\n ...(lifecycle?.listProducts && {\n listProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listProducts']>>) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => lifecycle.listProducts!(params, reqCtx),\n value => value\n );\n },\n }),\n ...(lifecycle?.requestProposals && {\n requestProposals: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['requestProposals']>>\n ) =>\n dispatchCompactMutation('request_proposals', params, ctx, reqCtx =>\n lifecycle.requestProposals!(params, reqCtx)\n ),\n }),\n ...(lifecycle?.declineProposals && {\n declineProposals: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['declineProposals']>>\n ) =>\n dispatchCompactMutation('decline_proposals', params, ctx, reqCtx =>\n lifecycle.declineProposals!(params, reqCtx)\n ),\n }),\n ...(lifecycle?.buyProducts && {\n buyProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['buyProducts']>>) =>\n dispatchCompactMutation('buy_products', params, ctx, reqCtx => lifecycle.buyProducts!(params, reqCtx)),\n }),\n ...(lifecycle?.acceptProposal && {\n acceptProposal: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['acceptProposal']>>) =>\n dispatchCompactMutation('accept_proposal', params, ctx, reqCtx => lifecycle.acceptProposal!(params, reqCtx)),\n }),\n ...(lifecycle?.controlMediaBuy && {\n controlMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['controlMediaBuy']>>\n ) =>\n dispatchCompactMutation('control_media_buy', params, ctx, reqCtx => lifecycle.controlMediaBuy!(params, reqCtx)),\n }),\n ...((sales?.getProducts || proposalManager) && {\n getProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getProducts']>>) => {\n const responseWireMode = creativeWireModeForRequest(\n ctx,\n creativeWireMode,\n params as Readonly<Record<string, unknown>>\n );\n const canonicalParams = asCanonicalGetProductsRequest(params as unknown as Record<string, unknown>);\n const reqCtx = ctxFor(ctx, params as Readonly<Record<string, unknown>>);\n // v1.5 seam: intercept refine[i].action='finalize' before\n // dispatching to the manager / sales. When the framework\n // commits the proposal inline, project the response directly.\n if (proposalManager && proposalStore) {\n const intercept = await maybeInterceptFinalize({\n request: canonicalParams,\n manager: proposalManager,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (intercept.kind === 'intercepted') {\n // Unified sync-or-HITL dispatch. routeIfHandoff runs\n // `intercept.project` inline for sync `FinalizeProposalSuccess`\n // returns and inside the background task for HITL handoffs.\n // Same machinery createMediaBuy / syncCreatives use — finalize\n // inherits the framework's task-lifecycle guarantees.\n //\n // **Known gap (HITL only)**: if the buyer calls tasks/cancel\n // while the adopter's handoff fn is still mid-run, the\n // framework marks the task cancelled but `intercept.project`\n // (which fires when the handoff fn resolves) still runs\n // store.commit. The committed proposal then sits in the\n // store with no buyer-facing task to retrieve it. Same gap\n // exists for createMediaBuy HITL today (see comment in\n // `sales.createMediaBuy` body re: CONSUMING reservation\n // cleanup). Mitigations: the proposal expires via the\n // 7-day eviction window in `InMemoryProposalStore`, and\n // production durable stores can implement a sweep against\n // the task registry to release stale committed-but-\n // unretrievable proposals. Closing the gap end-to-end\n // requires propagating an AbortSignal into the projection\n // — framework-level work tracked separately, not finalize-\n // specific.\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const out = await routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_products',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n intercept.result,\n intercept.project\n );\n return out as never;\n }\n }\n return projectSync(\n async () => {\n const buyingMode = (params as { buying_mode?: string }).buying_mode;\n if (buyingMode === 'wholesale' && hasPushNotificationConfig(params)) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_products buying_mode=wholesale is synchronous and does not support push_notification_config; use incomplete[] for partial feed results.',\n field: 'push_notification_config',\n recovery: 'correctable',\n });\n }\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n // Pick dispatch target: ProposalManager (when wired) takes\n // ownership of get_products; sales is the v1 fallback.\n // Refine routing per Python's _select_proposal_method:\n // refine_products iff buying_mode='refine' AND\n // capabilities.refine AND the manager implements it.\n type GetProductsPayload = import('../specialisms/sales').GetProductsPayload;\n type GetProductsHandlerResult = import('../specialisms/sales').GetProductsHandlerResult;\n let result: GetProductsHandlerResult;\n if (proposalManager) {\n const useRefine =\n buyingMode === 'refine' &&\n proposalManager.capabilities.refine === true &&\n typeof proposalManager.refineProducts === 'function';\n result = useRefine\n ? await proposalManager.refineProducts!(canonicalParams, reqCtx as never)\n : await proposalManager.getProducts(canonicalParams, reqCtx as never);\n } else {\n result = (await sales!.getProducts!(canonicalParams, reqCtx)) as GetProductsHandlerResult;\n }\n const summarized = _extractResponseSummaryEntry<GetProductsPayload>(result);\n if (\n summarized &&\n (isTaskHandoff(summarized.payload) || _extractResponseSummaryEntry(summarized.payload) !== undefined)\n ) {\n throw new TypeError('withResponseSummary may wrap only a synchronous getProducts payload');\n }\n const resultForRouting = summarized?.payload ?? result;\n const projectProducts = async (terminalResult: GetProductsPayload) => {\n const preparedProjection = preparePerProductProjectionCatalogs(terminalResult, legacyFormatConverter);\n const requestLegacyFormatConverter = await resolveLegacyProductFormats(\n preparedProjection.response,\n preparedProjection.converter,\n legacyFormatResolver,\n {\n ...(ctx.servedAdcpVersion !== undefined && { servedAdcpVersion: ctx.servedAdcpVersion }),\n ...(reqCtx.account?.id !== undefined && { accountId: reqCtx.account.id }),\n ...(ctx.signal !== undefined && { signal: ctx.signal }),\n ...legacyFormatResolverOptions,\n }\n );\n const canonicalResult = asCanonicalProductResponse(\n preparedProjection.response,\n requestLegacyFormatConverter\n );\n // Auto-store products: persist each Product's wire shape +\n // ctx_metadata so subsequent createMediaBuy / updateMediaBuy\n // calls referencing product_id can hydrate the full Product\n // automatically (publisher sees `req.packages[i].product`).\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'product',\n (canonicalResult as { products?: readonly unknown[] })?.products,\n 'product_id',\n logger\n );\n // v1.5 seam: persist proposals[] as DRAFT records (with\n // typed recipes pulled from Product.implementation_config)\n // so subsequent finalize / create_media_buy can hydrate.\n // Read recipes from the adopter's original semantic result,\n // before wire sanitization turns Set-backed capability overlap\n // into transport-safe data. Recipes are internal state and never\n // cross the buyer-facing response boundary.\n if (proposalStore) {\n await maybePersistDraftAfterGetProducts({\n response: terminalResult as unknown as import('../proposal').ProposalGetProductsPayload,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n }\n const wireResponse = asProductResponseForWire(\n canonicalResult,\n responseWireMode,\n canonicalFormatLegacyResolver,\n shouldEmitTransitionalDualCreativeWire(ctx.servedAdcpVersion, params)\n ) as unknown as import('../../../types/tools.generated').GetProductsResponse;\n return summarized\n ? productsResponse(\n wireResponse as unknown as Parameters<typeof productsResponse>[0],\n summarized.summary\n )\n : wireResponse;\n };\n const isHandoff = isTaskHandoff<GetProductsPayload>(resultForRouting);\n if (buyingMode === 'wholesale' && isHandoff) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_products buying_mode=wholesale must return synchronously; use incomplete[] for partial feed results.',\n field: 'buying_mode',\n recovery: 'correctable',\n });\n }\n if (!isHandoff && push.url === undefined) {\n rejectHandRolledSubmitted(resultForRouting);\n return projectProducts(resultForRouting as GetProductsPayload);\n }\n const accountId = reqCtx.account?.id;\n if (accountId === undefined) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'Async get_products and push_notification_config require account-scoped discovery.',\n field: 'account',\n recovery: 'correctable',\n });\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_products',\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n resultForRouting as GetProductsPayload | TaskHandoff<GetProductsPayload>,\n projectProducts\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.createMediaBuy && {\n createMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['createMediaBuy']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(\n ctx,\n creativeWireMode,\n params as Readonly<Record<string, unknown>>\n );\n params = asCanonicalSemanticServerRequest(params, 'create_media_buy', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params as Readonly<Record<string, unknown>>);\n // Auto-hydrate: walk `params.packages`, attach the full Product object\n // (including `ctx_metadata`) at `pkg.product`. Publisher reads\n // `pkg.product.format_ids`, `pkg.product.ctx_metadata?.gam?.ad_unit_ids`\n // directly — no separate lookup, no boilerplate.\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { packages?: unknown[] })?.packages,\n logger,\n legacyFormatConverter\n );\n // v1.5 seam: when the request carries a proposal_id, reserve\n // the proposal (atomic CAS COMMITTED → CONSUMING), validate\n // expiry + capability overlap, hydrate ctx.recipes. The\n // adapter runs against the reservation; finalize_consumption\n // (success) or release_consumption (failure) closes it out.\n let reservation: ReservedProposal<ProposalRecipe> | null = null;\n if (proposalStore) {\n reservation = await maybeReserveProposalForCreateMediaBuy({\n request: params as { proposal_id?: string; packages?: ReadonlyArray<unknown> } & Record<string, unknown>,\n manager: proposalManager,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (reservation) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = reservation.recipes;\n }\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n let result: Awaited<ReturnType<NonNullable<typeof sales.createMediaBuy>>>;\n try {\n result = await sales!.createMediaBuy!(params as unknown as CanonicalCreateMediaBuyRequest, reqCtx);\n } catch (err) {\n // Adapter rejected — roll back the reservation so the buyer\n // can retry without PROPOSAL_NOT_COMMITTED blocking them.\n if (reservation && proposalStore) {\n await releaseProposalReservation({\n store: proposalStore,\n record: reservation,\n logger,\n });\n }\n throw err;\n }\n if (isReturnedErrorArm(result)) {\n // A returned domain Error arm is a failed create, not a\n // successful proposal consumption or sync-completion webhook.\n // Restore the proposal so the corrected request can retry.\n if (reservation && proposalStore) {\n await releaseProposalReservation({\n store: proposalStore,\n record: reservation,\n logger,\n });\n }\n return asSemanticServerResponseForWire(\n result,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n // Inline-success path: promote CONSUMING → CONSUMED with the\n // adapter's media_buy_id. HITL handoff: the proposal stays\n // CONSUMING until the handoff completes — wiring the\n // post-completion commit hook is a v1.6 follow-up; for now\n // adopters using HITL accept the reservation lingers until\n // eviction. Most adopters use inline create_media_buy.\n if (reservation && proposalStore && !isTaskHandoff(result)) {\n const mediaBuyId = (result as { media_buy_id?: string }).media_buy_id;\n if (mediaBuyId) {\n await finalizeProposalConsumption({\n store: proposalStore,\n record: reservation,\n mediaBuyId,\n });\n }\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'create_media_buy',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n async r => {\n await persistTargetingOverlayFromCreate(mediaBuyStore, reqCtx.account?.id, params, r, logger);\n return asSemanticServerResponseForWire(\n r,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.updateMediaBuy && {\n updateMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['updateMediaBuy']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'update_media_buy', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n // `media_buy_id` is required on the wire schema, but `validation: 'off'`\n // mode skips the schema parse — guard at the seam so platform code can\n // trust the value rather than re-checking. Also catches buyers calling\n // with the param missing under an off-spec server config.\n const { media_buy_id } = params;\n if (!media_buy_id) {\n return adcpError('INVALID_REQUEST', {\n message: 'update_media_buy requires media_buy_id',\n field: 'media_buy_id',\n });\n }\n // Auto-hydrate: attach the full MediaBuy (wire shape + ctx_metadata)\n // at `req.media_buy`. Publisher reads `req.media_buy.ctx_metadata?.gam`\n // directly — no separate lookup. Misses are silent; publisher falls\n // back to its own DB. Schema-driven via `x-entity` (#1109).\n await hydrateForTool(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'update_media_buy',\n params,\n logger,\n legacyFormatConverter\n );\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { packages?: unknown[] }).packages,\n logger,\n legacyFormatConverter\n );\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { new_packages?: unknown[] }).new_packages,\n logger,\n legacyFormatConverter\n );\n // v1.5 seam: hydrate ctx.recipes via reverse-index so the adapter's\n // updateMediaBuy can apply the same recipe that drove createMediaBuy.\n // Re-validates capability overlap on any packages-shaped patch\n // (Resolutions §5).\n if (proposalStore) {\n const record = await maybeHydrateRecipesForMediaBuyId({\n mediaBuyId: media_buy_id,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n packages: (params as { packages?: ReadonlyArray<unknown> }).packages,\n });\n if (record) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = record.recipes;\n }\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await sales!.updateMediaBuy!(\n media_buy_id,\n params as unknown as CanonicalUpdateMediaBuyRequest,\n reqCtx\n );\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'update_media_buy',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n async r => {\n // A TaskHandoff marker is not acceptance of the patch. Apply\n // the local overlay only when the sync call or background\n // task completes and the result is projected to the wire.\n await persistTargetingOverlayFromUpdate(\n mediaBuyStore,\n reqCtx.account?.id,\n media_buy_id,\n params,\n logger\n );\n return asSemanticServerResponseForWire(\n r,\n 'update_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.syncCreatives && {\n syncCreatives: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['syncCreatives']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'sync_creatives', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n const creatives = (params.creatives ?? []) as CanonicalSyncCreativeAsset[];\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await sales.syncCreatives!(creatives, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'sync_creatives',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n rows =>\n asSemanticServerResponseForWire(\n { creatives: rows.map(normalizeRowErrors) },\n 'sync_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n r => r\n );\n },\n }),\n\n ...(getMediaBuyDelivery && {\n getMediaBuyDelivery: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getMediaBuyDelivery']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n // v1.5 seam: hydrate ctx.recipes for delivery reads. Per\n // Resolutions §5, recipe-driven delivery aggregation needs the\n // same recipe view the originating createMediaBuy used.\n if (proposalStore) {\n const ids = (params as { media_buy_ids?: readonly string[] }).media_buy_ids;\n // The wire shape uses `media_buy_ids[]`; hydrate from the first id\n // when present (per-buy recipe lookup; if buyer queries multiple\n // ids, the adapter is responsible for per-id recipe routing).\n const firstId = Array.isArray(ids) && ids.length > 0 ? ids[0] : undefined;\n if (firstId) {\n const record = await maybeHydrateRecipesForMediaBuyId({\n mediaBuyId: firstId,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (record) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = record.recipes;\n }\n }\n }\n return projectSync(\n async () => {\n const result = await getMediaBuyDelivery(asValidatedDomainRequest(params), reqCtx);\n warnIfTruncatedMultiIdResponse(\n 'getMediaBuyDelivery',\n 'media_buy_ids',\n (params as { media_buy_ids?: readonly string[] }).media_buy_ids,\n (result as { media_buy_deliveries?: readonly unknown[] })?.media_buy_deliveries,\n logger\n );\n return asSemanticServerResponseForWire(\n result,\n 'get_media_buy_delivery',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n },\n actuals => actuals\n );\n },\n }),\n\n // Optional methods — return UNSUPPORTED_FEATURE when the platform omits\n // them. Adopters that haven't migrated to the v6 platform interface for\n // these specific tools can still pass raw handlers via opts.legacyHandlers.mediaBuy\n // (merge seam) — the merge runs AFTER buildMediaBuyHandlers, so opts\n // handlers fill in for the methods this platform omits.\n // `getMediaBuys` is REQUIRED at the type level, but we keep a runtime\n // guard for the merge-seam migration path: legacy adopters wire it via\n // `opts.legacyHandlers.mediaBuy.getMediaBuys` rather than on the platform interface.\n // Once the migration completes (every adopter implements it natively),\n // this conditional spreads can collapse — but for now, omitting the\n // platform-derived handler when absent lets `mergeHandlers` pick up the\n // adopter's custom handler from `opts.legacyHandlers.mediaBuy` instead of throwing\n // `sales.getMediaBuys is not a function`.\n ...(getMediaBuys && {\n getMediaBuys: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getMediaBuys']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await getMediaBuys(asValidatedDomainRequest(params), reqCtx);\n warnIfTruncatedMultiIdResponse(\n 'getMediaBuys',\n 'media_buy_ids',\n (params as { media_buy_ids?: readonly string[] }).media_buy_ids,\n (result as { media_buys?: readonly unknown[] })?.media_buys,\n logger\n );\n const canonicalResult = asCanonicalSemanticServerResponse(\n result,\n 'get_media_buys',\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n );\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'media_buy',\n (canonicalResult as { media_buys?: readonly unknown[] })?.media_buys,\n 'media_buy_id',\n logger\n );\n const wireResult =\n responseWireMode === 'canonical'\n ? attachCanonicalFormatWireRefs(canonicalResult, canonicalFormatLegacyResolver, 'get_media_buys')\n : asSemanticServerResponseForWire(\n result,\n 'get_media_buys',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n await backfillTargetingOverlay(mediaBuyStore, reqCtx.account?.id, wireResult, logger);\n return wireResult;\n },\n r => r\n );\n },\n }),\n ...(sales?.providePerformanceFeedback && {\n providePerformanceFeedback: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['providePerformanceFeedback']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'provide_performance_feedback', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.media_buy` from the prior createMediaBuy /\n // getMediaBuys store entry, plus `req.creative` when the buyer\n // scoped feedback to a specific creative, plus `req.package`\n // when scoped to a package. All three are optional hydration\n // targets — adopters who only care about the feedback payload\n // itself can ignore them. Schema-driven via `x-entity` (#1109);\n // package hydration is additive vs the prior hardcoded version\n // (silent no-op when packages aren't seeded).\n await hydrateForTool(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'provide_performance_feedback',\n params,\n logger,\n legacyFormatConverter\n );\n return projectSync(\n () => sales!.providePerformanceFeedback!(asValidatedDomainRequest(params), reqCtx),\n result =>\n asSemanticServerResponseForWire(\n result,\n 'provide_performance_feedback',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n }),\n ...(sales?.listCreativeFormatsLegacy && {\n listCreativeFormats: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listCreativeFormats']>>\n ) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales!.listCreativeFormatsLegacy!(params, reqCtx),\n r => r\n );\n },\n }),\n ...(sales?.listCreatives && {\n listCreatives: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listCreatives']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const canonicalParams = asCanonicalListCreativesRequest(\n params as unknown as Record<string, unknown>,\n legacyFormatConverter,\n responseWireMode\n );\n const reqCtx = ctxFor(ctx, canonicalParams);\n return projectSync(\n async () => {\n const result = await sales!.listCreatives!(canonicalParams, reqCtx);\n const canonicalResult = asSemanticServerResponseForWire(\n result,\n 'list_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n warnIfTruncatedMultiIdResponse(\n 'listCreatives',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (canonicalResult as { creatives?: readonly unknown[] })?.creatives,\n logger\n );\n return canonicalResult as unknown as import('../../../types/tools.generated').ListCreativesResponse;\n },\n r => r\n );\n },\n }),\n } as unknown as MediaBuyHandlers<Account>;\n}\n\n/**\n * Project an adopter `buildCreative` return value into the wire response\n * shape. Handles the four legal adopter shapes per `BuildCreativeReturn`:\n *\n * - Already-shaped Single envelope (`creative_manifest` field present) →\n * passthrough. Adopter set `sandbox` / `expires_at` / `preview` themselves.\n * - Already-shaped Multi envelope (`creative_manifests` field present) →\n * passthrough. Same metadata-controlled case for multi-format requests.\n * - Bare array → wrap as `{ creative_manifests: <array> }` (multi, no metadata).\n * - Plain `CreativeManifest` → wrap as `{ creative_manifest: <obj> }`\n * (single, no metadata).\n *\n * The discriminator order matters: check shaped envelopes first so an\n * adopter that returned `{ creative_manifest, sandbox: true }` (a Single\n * envelope) doesn't get re-wrapped into\n * `{ creative_manifest: { creative_manifest, sandbox: true } }`. Same\n * concern applies symmetrically for Multi.\n */\nfunction projectBuildCreativeReturn(ret: unknown): BuildCreativeSuccess | BuildCreativeMultiSuccess {\n if (ret != null && typeof ret === 'object' && !Array.isArray(ret)) {\n if ('creative_manifest' in ret) return ret as BuildCreativeSuccess;\n if ('creative_manifests' in ret) return ret as BuildCreativeMultiSuccess;\n }\n if (Array.isArray(ret)) {\n return { creative_manifests: ret as CreativeManifest[] };\n }\n return { creative_manifest: ret as CreativeManifest };\n}\n\nfunction buildCreativeHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n creativeWireMode: 'canonical' | 'legacy'\n): CreativeHandlers<Account> | undefined {\n const creative = platform.creative;\n if (!creative) return undefined;\n\n return {\n buildCreative: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => creative.buildCreativeLegacy(asValidatedDomainRequest(params), reqCtx),\n ret => projectBuildCreativeReturn(ret)\n );\n },\n\n previewCreative: async (params, ctx) => {\n const canonicalHandler =\n 'previewCreative' in creative ? (creative as CreativeBuilderPlatform).previewCreative : undefined;\n const legacyHandler =\n 'previewCreativeLegacy' in creative ? (creative as CreativeBuilderPlatform).previewCreativeLegacy : undefined;\n const usesLegacyFormatId =\n params.format_id != null ||\n (Array.isArray(params.requests) && params.requests.some(request => request.format_id != null));\n\n if (usesLegacyFormatId && legacyHandler == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'preview_creative: this creative platform does not support legacy format_id preview requests. ' +\n 'Use target_capability_id, creative_id, or creative_manifest with the canonical previewCreative handler.',\n });\n }\n if (canonicalHandler == null && legacyHandler == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'preview_creative: this creative platform did not implement previewCreative. ' +\n 'Add `previewCreative(req, ctx)` to your CreativeBuilderPlatform / CreativeAdServerPlatform literal.',\n });\n }\n const reqCtx = ctxFor(ctx, params);\n if (usesLegacyFormatId || canonicalHandler == null) {\n return projectSync(\n () => legacyHandler!(params, reqCtx),\n preview => preview\n );\n }\n return projectSync(\n () => canonicalHandler(params as CanonicalPreviewCreativeRequest, reqCtx),\n preview => preview\n );\n },\n\n // No-account tool — `list_creative_formats` request schema doesn't carry\n // `account`. The framework's `resolveAccountFromAuth` runs and accepts a\n // null return; the platform method receives `ctx.account` possibly\n // undefined per `NoAccountCtx`. Wired identically on both\n // `CreativeBuilderPlatform` and `CreativeAdServerPlatform`.\n listCreativeFormats: async (params, ctx) => {\n if (!('listCreativeFormatsLegacy' in creative) || creative.listCreativeFormatsLegacy == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'list_creative_formats: this creative platform did not implement listCreativeFormatsLegacy. ' +\n 'Add `listCreativeFormatsLegacy(req, ctx)` to your CreativeBuilderPlatform / CreativeAdServerPlatform literal, ' +\n 'or delegate via `capabilities.creative_agents`.',\n });\n }\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => (creative as CreativeBuilderPlatform).listCreativeFormatsLegacy!(params, reqCtx),\n r => r\n );\n },\n\n // Only register sync_creatives when the platform actually implements it.\n // Unconditionally returning UNSUPPORTED_FEATURE would advertise the tool in\n // tools/list and trigger the buyer retry-policy (two wasted round-trips) for\n // platforms that never supported it. Mirrors the conditional pattern used by\n // buildAccountHandlers — see comment at line 4544.\n ...(creative.syncCreatives != null && {\n syncCreatives: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'sync_creatives', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n const creatives = (params.creatives ?? []) as CanonicalSyncCreativeAsset[];\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await creative.syncCreatives!(creatives, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'sync_creatives',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n rows =>\n asSemanticServerResponseForWire(\n { creatives: rows.map(normalizeRowErrors) },\n 'sync_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n r => r\n );\n },\n }),\n\n // Ad-server-specialism methods. Only CreativeAdServerPlatform declares\n // listCreatives and getCreativeDelivery. Registering unconditional stubs\n // would advertise these tools in tools/list for CreativeBuilderPlatform\n // adopters, misleading buyer agents and triggering UNSUPPORTED_FEATURE on\n // every call. Only emit handlers when the platform method is present.\n ...('listCreatives' in creative &&\n (creative as CreativeAdServerPlatform).listCreatives != null && {\n listCreatives: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const canonicalParams = asCanonicalListCreativesRequest(\n params as unknown as Record<string, unknown>,\n legacyFormatConverter,\n responseWireMode\n );\n const reqCtx = ctxFor(ctx, canonicalParams);\n return projectSync(\n async () => {\n const result = await (creative as CreativeAdServerPlatform).listCreatives(canonicalParams, reqCtx);\n const canonicalResult = asSemanticServerResponseForWire(\n result,\n 'list_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n warnIfTruncatedMultiIdResponse(\n 'listCreatives',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (canonicalResult as { creatives?: readonly unknown[] })?.creatives,\n logger\n );\n return canonicalResult as unknown as import('../../../types/tools.generated').ListCreativesResponse;\n },\n r => r\n );\n },\n }),\n\n ...('getCreativeDelivery' in creative &&\n (creative as CreativeAdServerPlatform).getCreativeDelivery != null && {\n getCreativeDelivery: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await (creative as CreativeAdServerPlatform).getCreativeDelivery(\n asValidatedDomainRequest(params),\n reqCtx\n );\n warnIfTruncatedMultiIdResponse(\n 'getCreativeDelivery',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (result as { creative_deliveries?: readonly unknown[] })?.creative_deliveries,\n logger\n );\n return asSemanticServerResponseForWire(\n result,\n 'get_creative_delivery',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n ) as unknown as import('../../../types/tools.generated').GetCreativeDeliveryResponse;\n },\n r => r\n );\n },\n }),\n };\n}\n\nfunction buildEventTrackingHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): EventTrackingHandlers<Account> | undefined {\n const audiences = platform.audiences;\n const sales = platform.sales;\n // Retail-media adopters (sales-catalog-driven) implement sync_catalogs /\n // log_event / sync_event_sources on `SalesPlatform`. The wire spec routes\n // these through the `event-tracking` framework category so the handlers\n // land on `EventTrackingHandlers` regardless of which specialism owns\n // them on the platform side.\n if (!audiences && !sales) return undefined;\n\n const handlers: EventTrackingHandlers<Account> = {};\n\n if (audiences) {\n handlers.syncAudiences = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n const audienceList = (params.audiences ?? []) as Audience[];\n return projectSync(\n () => audiences.syncAudiences(audienceList, reqCtx),\n rows => ({ audiences: rows })\n );\n };\n }\n\n if (sales?.syncCatalogs) {\n handlers.syncCatalogs = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.syncCatalogs!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (sales?.logEvent) {\n handlers.logEvent = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.logEvent!(params, reqCtx),\n r => r\n );\n };\n }\n\n if (sales?.syncEventSources) {\n handlers.syncEventSources = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.syncEventSources!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n return Object.keys(handlers).length > 0 ? handlers : undefined;\n}\n\nfunction buildSignalsHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined\n): SignalsHandlers<Account> | undefined {\n const signals = platform.signals;\n if (!signals) return undefined;\n return {\n getSignals: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const discoveryMode = (params as { discovery_mode?: string }).discovery_mode;\n if (discoveryMode === 'wholesale' && hasPushNotificationConfig(params)) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_signals discovery_mode=wholesale is synchronous and does not support push_notification_config; use incomplete[] for partial feed results.',\n field: 'push_notification_config',\n recovery: 'correctable',\n });\n }\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await signals.getSignals(asValidatedDomainRequest(params), reqCtx);\n const projectSignals = async (terminalResult: import('../specialisms/signals').GetSignalsPayload) => {\n // signal_ids is `SignalID[]` (`{source, data_provider_domain, id}`\n // objects), not bare strings — but the helper's truncation-detection\n // is purely length-based, so the object element type is irrelevant.\n warnIfTruncatedMultiIdResponse(\n 'getSignals',\n 'signal_ids',\n (params as { signal_ids?: readonly unknown[] }).signal_ids,\n (terminalResult as { signals?: readonly unknown[] })?.signals,\n logger\n );\n // Auto-store signals so subsequent activate_signal can hydrate\n // `req.signal` from the publisher's prior catalog entry.\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'signal',\n (terminalResult as { signals?: readonly unknown[] })?.signals,\n 'signal_agent_segment_id',\n logger\n );\n return terminalResult;\n };\n const isHandoff = isTaskHandoff<import('../specialisms/signals').GetSignalsPayload>(result);\n if (discoveryMode === 'wholesale' && isHandoff) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_signals discovery_mode=wholesale must return synchronously; use incomplete[] for partial feed results.',\n field: 'discovery_mode',\n recovery: 'correctable',\n });\n }\n if (!isHandoff && push.url === undefined) {\n rejectHandRolledSubmitted(result);\n return projectSignals(result as import('../specialisms/signals').GetSignalsPayload);\n }\n const accountId = reqCtx.account?.id;\n if (accountId === undefined) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'Async get_signals and push_notification_config require account-scoped discovery.',\n field: 'account',\n recovery: 'correctable',\n });\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_signals',\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n projectSignals\n );\n },\n r => r\n );\n },\n activateSignal: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.signal` from the prior getSignals store entry —\n // publisher reads pricing options, agent segment id, ctx_metadata\n // directly without the buyer round-tripping the full signal object.\n // Schema-driven via `x-entity` (#1109): `signal_agent_segment_id`\n // carries `x-entity: \"signal_activation_id\"`, mapped to ResourceKind\n // `signal`; attached at `params.signal` per the override table.\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'activate_signal', params, logger);\n return projectSync(\n () => signals.activateSignal(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n };\n}\n\n/**\n * Adapt `SponsoredIntelligencePlatform` (v6 platform-specialism shape) onto the v5\n * `SponsoredIntelligenceHandlers` handler-bag the dispatcher consumes.\n *\n * Auto-store on `initiateSession`: stash a session record keyed by\n * `session_id` under `ResourceKind: 'si_session'`. The framework's\n * schema-driven hydrator (TOOL_ENTITY_FIELDS for `si_send_message` /\n * `si_terminate_session`) attaches that record at `params.session` on\n * subsequent calls so the platform reads transcript context from\n * `req.session` without manual `ctx.store.get`.\n *\n * Hydrate on `sendMessage` / `terminateSession`: schema-driven\n * `hydrateForTool` reads `params.session_id`, looks up the stored\n * session, and attaches at `params.session`.\n */\nfunction buildSponsoredIntelligenceHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n logger: AdcpLogger\n): SponsoredIntelligenceHandlers<Account> | undefined {\n const si = platform.sponsoredIntelligence;\n if (!si) return undefined;\n return {\n getOffering: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => si.getOffering(params, reqCtx),\n r => r\n );\n },\n initiateSession: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await si.initiateSession(asValidatedDomainRequest(params), reqCtx);\n // Auto-store the session record so subsequent `sendMessage` /\n // `terminateSession` calls hydrate `req.session` without a\n // manual lookup. Stored payload preserves the bits the brand\n // engine needs to resume context across turns: identity\n // consent, offering scoping, negotiated capabilities,\n // placement provenance, and any media-buy linkage. The full\n // request intent is stored alongside so brand handlers can\n // re-read what the user originally asked for. Production\n // brand engines that own transcript state in their own\n // backend can ignore this and read from their own store —\n // see SponsoredIntelligencePlatform JSDoc.\n if (ctxMetadataStore && reqCtx.account?.id) {\n const sessionId = (result as { session_id?: unknown })?.session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n const reqRec = params as unknown as Record<string, unknown>;\n const resRec = result as unknown as Record<string, unknown>;\n const sessionRecord = {\n session_id: sessionId,\n // Request-side scoping the brand engine needs across turns.\n intent: reqRec.intent,\n offering_id: reqRec.offering_id,\n offering_token: reqRec.offering_token,\n placement: reqRec.placement,\n media_buy_id: reqRec.media_buy_id,\n identity: reqRec.identity,\n supported_capabilities: reqRec.supported_capabilities,\n // Response-side state.\n negotiated_capabilities: resRec.negotiated_capabilities,\n session_status: resRec.session_status,\n session_ttl_seconds: resRec.session_ttl_seconds,\n };\n try {\n await ctxMetadataStore.setResource(reqCtx.account.id, 'si_session', sessionId, sessionRecord);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store si_session ${sessionId} failed: ${msg}`);\n }\n }\n }\n return result;\n },\n r => r\n );\n },\n sendMessage: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.session` from the stored si_session record. The\n // schema-driven hydrator reads `params.session_id` and attaches the\n // stored session at `params.session` (via the `_id` → strip\n // convention; `session_id` → `session`).\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'si_send_message', params, logger);\n return projectSync(\n () => si.sendMessage(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n terminateSession: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'si_terminate_session', params, logger);\n return projectSync(\n async () => {\n const result = await si.terminateSession(params, reqCtx);\n // Persist `acp_handoff` and terminal `session_status` onto the\n // stored session record so a re-terminate replay (which is\n // naturally idempotent on `session_id` per the spec) hydrates\n // the same handoff payload via `req.session` without the\n // adopter having to remember to write through. Honors the\n // platform interface JSDoc contract:\n // \"Re-terminating a closed session MUST return the same\n // payload, including any acp_handoff block.\"\n if (ctxMetadataStore && reqCtx.account?.id) {\n const sessionId = (params as { session_id?: unknown })?.session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n const resRec = result as unknown as Record<string, unknown>;\n try {\n const existing = await ctxMetadataStore.getEntry(reqCtx.account.id, 'si_session', sessionId);\n const merged = {\n ...((existing?.resource as Record<string, unknown>) ?? { session_id: sessionId }),\n session_status: resRec.session_status,\n acp_handoff: resRec.acp_handoff,\n follow_up: resRec.follow_up,\n terminated: resRec.terminated,\n };\n await ctxMetadataStore.setResource(reqCtx.account.id, 'si_session', sessionId, merged);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store si_session ${sessionId} on terminate failed: ${msg}`);\n }\n }\n }\n return result;\n },\n r => r\n );\n },\n };\n}\n\nfunction buildBrandRightsHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n logger: AdcpLogger\n): BrandRightsHandlers<Account> | undefined {\n const br = platform.brandRights;\n if (!br) return undefined;\n return {\n getBrandIdentity: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => br.getBrandIdentity(params, reqCtx),\n r => r\n );\n },\n getRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await br.getRightsLegacy(asValidatedDomainRequest(params), reqCtx);\n // Auto-store rights offerings so subsequent acquire_rights can\n // hydrate `req.rights` (pricing_options + ctx_metadata) without\n // a separate publisher lookup.\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'rights_grant',\n (result as { rights?: readonly unknown[] })?.rights,\n 'rights_id',\n logger\n );\n return result;\n },\n r => r\n );\n },\n // `acquire_rights` has 3 native wire-spec arms (Acquired / PendingApproval /\n // Rejected) handled by the platform directly. No framework task envelope —\n // adopters return the spec-defined arm. Async delivery for the\n // PendingApproval arm rides the buyer's `push_notification_config` webhook\n // (the spec doesn't define a polling tool for `acquire_rights`).\n acquireRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.rights` from the prior getRights catalog entry.\n // Publisher reads selected pricing option + ctx_metadata directly.\n // Schema-driven via `x-entity` (#1109); destination field stays at\n // `params.rights` per the override table — historical, predates\n // the entity-driven hydrator and `updateRights`'s convention of\n // `params.rights_grant`. Adopters already read this field, so a\n // rename would be wire-visible behavior.\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'acquire_rights', params, logger);\n return projectSync(\n () => br.acquireRightsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n // `update_rights` modifies an existing grant. The framework hydrates\n // the grant record from `req.rights_id` so the implementation reads\n // the resolved state from `ctx.store` (or as `params.rights_grant`\n // — see field-name divergence note on `acquireRights` above; this\n // tool attaches under `rights_grant` because the wire payload has\n // no `rights` field). Schema-driven via `x-entity` (#1109). Async\n // delivery — when the change requires rights-holder counter-\n // signature — rides the buyer's `push_notification_config` webhook;\n // the immediate response carries `implementation_date: null` to\n // signal pending state.\n updateRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'update_rights', params, logger);\n return projectSync(\n () => br.updateRightsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n };\n}\n\nfunction buildGovernanceHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): GovernanceHandlers<Account> | undefined {\n const cg = platform.campaignGovernance;\n const pl = platform.propertyLists;\n const cl = platform.collectionLists;\n const cs = platform.contentStandards;\n if (!cg && !pl && !cl && !cs) return undefined;\n\n const handlers: GovernanceHandlers<Account> = {};\n\n if (cg) {\n handlers.checkGovernance = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.checkGovernance(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.syncPlans = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.syncPlans(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.reportPlanOutcome = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.reportPlanOutcome(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getPlanAuditLogs = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.getPlanAuditLogs(params, reqCtx),\n r => r\n );\n };\n }\n\n if (pl) {\n handlers.createPropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.createPropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updatePropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.updatePropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getPropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.getPropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.listPropertyLists = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.listPropertyLists(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.deletePropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.deletePropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (cl) {\n handlers.createCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.createCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updateCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.updateCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.getCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.listCollectionLists = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.listCollectionLists(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.deleteCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.deleteCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (cs) {\n handlers.listContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.listContentStandardsLegacy(params, reqCtx),\n r => r\n );\n };\n handlers.getContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getContentStandardsLegacy(params, reqCtx),\n r => r\n );\n };\n handlers.createContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.createContentStandardsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updateContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.updateContentStandardsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.calibrateContent = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.calibrateContentLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.validateContentDelivery = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.validateContentDeliveryLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n if (cs.getMediaBuyArtifactsLegacy) {\n handlers.getMediaBuyArtifacts = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getMediaBuyArtifactsLegacy!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n if (cs.getCreativeFeaturesLegacy) {\n handlers.getCreativeFeatures = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getCreativeFeaturesLegacy!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n }\n\n return handlers;\n}\n\ntype SyncAccountsEntry = AccountReference & {\n account?: AccountReference;\n brand?: BrandReference;\n operator?: string;\n billing?: BillingParty;\n payment_terms?: PaymentTerms;\n billing_entity?: unknown;\n};\n\ntype SyncAccountsPolicyResult = {\n acceptedEntries: SyncAccountsEntry[];\n acceptedParams: Record<string, unknown>;\n failedRows: Map<number, SyncAccountsResultRow>;\n};\n\nconst BILLING_VALUES: readonly BillingParty[] = ['operator', 'agent', 'advertiser'];\n\nfunction isBillingParty(value: unknown): value is BillingParty {\n return typeof value === 'string' && (BILLING_VALUES as readonly string[]).includes(value);\n}\n\nfunction isPaymentTerms(value: unknown): value is PaymentTerms {\n return typeof value === 'string';\n}\n\nfunction supportedBillingsFor(platform: DecisioningPlatform<any, any>): readonly BillingParty[] {\n const configured = platform.capabilities.supportedBillings;\n return configured?.length ? configured : ['agent'];\n}\n\nfunction entryBrandOperator(entry: SyncAccountsEntry): { brand: BrandReference; operator: string } | undefined {\n if (entry.brand !== undefined && typeof entry.operator === 'string') {\n return { brand: entry.brand, operator: entry.operator };\n }\n const account = entry.account;\n if (\n account !== undefined &&\n 'brand' in account &&\n account.brand !== undefined &&\n 'operator' in account &&\n typeof account.operator === 'string'\n ) {\n return { brand: account.brand as BrandReference, operator: account.operator };\n }\n return undefined;\n}\n\nfunction entryHasAccountId(entry: SyncAccountsEntry): boolean {\n if (refAccountId(entry) !== undefined) return true;\n return entry.account !== undefined && refAccountId(entry.account) !== undefined;\n}\n\nfunction failedSyncAccountRow(entry: SyncAccountsEntry, error: AdcpStructuredError): SyncAccountsResultRow {\n const key = entryBrandOperator(entry);\n if (key === undefined) {\n throw new AdcpError(error.code, {\n message: error.message,\n recovery: error.recovery,\n ...(error.field !== undefined && { field: error.field }),\n ...(error.suggestion !== undefined && { suggestion: error.suggestion }),\n ...(error.retry_after !== undefined && { retry_after: error.retry_after }),\n ...(error.details !== undefined && { details: error.details }),\n });\n }\n return {\n brand: key.brand,\n operator: key.operator,\n action: 'failed',\n status: 'rejected',\n errors: [error],\n };\n}\n\nfunction buildBillingNotSupportedError(opts: {\n requestedBilling: BillingParty;\n supportedBillings?: readonly BillingParty[];\n exposeCapabilityScope: boolean;\n}): AdcpStructuredError {\n return new AdcpError('BILLING_NOT_SUPPORTED', {\n message: `Billing value \"${opts.requestedBilling}\" is not supported for this account sync request.`,\n recovery: 'correctable',\n field: 'accounts[].billing',\n ...(opts.exposeCapabilityScope && opts.supportedBillings !== undefined\n ? { details: { scope: 'capability', supported_billing: [...opts.supportedBillings] } }\n : {}),\n }).toStructuredError();\n}\n\nfunction buildBillingNotPermittedError(\n agent: BuyerAgent,\n requestedBilling: BuyerAgentBillingMode\n): AdcpStructuredError {\n const fallback = suggestBilling(agent.billing_capabilities, requestedBilling);\n return new AdcpError('BILLING_NOT_PERMITTED_FOR_AGENT', {\n message: `Billing value \"${requestedBilling}\" is not permitted for this buyer agent.`,\n recovery: 'correctable',\n field: 'accounts[].billing',\n details: {\n rejected_billing: requestedBilling,\n ...(fallback !== undefined && { suggested_billing: fallback }),\n },\n }).toStructuredError();\n}\n\nfunction enforceSyncAccountsCommercialPolicy<P extends DecisioningPlatform<any, any>>(\n platform: P,\n params: Record<string, unknown>,\n resolveCtx: ResolveContext\n): SyncAccountsPolicyResult {\n const entries = ((params.accounts as unknown[]) ?? []) as SyncAccountsEntry[];\n const supportedBillings = supportedBillingsFor(platform);\n const supportedPaymentTerms = platform.capabilities.supportedPaymentTerms;\n const failedRows = new Map<number, SyncAccountsResultRow>();\n const acceptedEntries: SyncAccountsEntry[] = [];\n\n entries.forEach((entry, index) => {\n const hasBillableFields =\n entry.billing !== undefined || entry.payment_terms !== undefined || entry.billing_entity !== undefined;\n if (hasBillableFields && entryBrandOperator(entry) === undefined && !entryHasAccountId(entry)) {\n throw new AdcpError('BRAND_REQUIRED', {\n message: 'Billable account sync entries require a brand reference or account_id.',\n recovery: 'correctable',\n field: `accounts[${index}].brand`,\n });\n }\n\n let failure: AdcpStructuredError | undefined;\n if (isBillingParty(entry.billing)) {\n if (!supportedBillings.includes(entry.billing)) {\n failure = buildBillingNotSupportedError({\n requestedBilling: entry.billing,\n supportedBillings,\n exposeCapabilityScope: true,\n });\n } else if (platform.agentRegistry !== undefined && resolveCtx.agent === undefined) {\n failure = buildBillingNotSupportedError({\n requestedBilling: entry.billing,\n exposeCapabilityScope: false,\n });\n } else if (resolveCtx.agent !== undefined && !resolveCtx.agent.billing_capabilities.has(entry.billing)) {\n failure = buildBillingNotPermittedError(resolveCtx.agent, entry.billing);\n }\n }\n\n if (\n failure === undefined &&\n supportedPaymentTerms !== undefined &&\n supportedPaymentTerms.length > 0 &&\n isPaymentTerms(entry.payment_terms) &&\n !supportedPaymentTerms.includes(entry.payment_terms)\n ) {\n failure = new AdcpError('PAYMENT_TERMS_NOT_SUPPORTED', {\n message: `Payment terms \"${entry.payment_terms}\" are not supported for this account sync request.`,\n recovery: 'correctable',\n field: `accounts[${index}].payment_terms`,\n }).toStructuredError();\n }\n\n if (failure !== undefined) {\n failedRows.set(index, failedSyncAccountRow(entry, failure));\n } else {\n acceptedEntries.push(entry);\n }\n });\n\n return {\n acceptedEntries,\n acceptedParams: { ...params, accounts: acceptedEntries },\n failedRows,\n };\n}\n\nfunction buildAccountHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): AccountHandlers<Account> {\n const accounts = platform.accounts;\n\n // Only emit framework-derived handlers for methods the platform actually\n // implements. Emitting an UNSUPPORTED_FEATURE stub for an undefined\n // method shadows adopter-supplied `opts.accounts.{syncAccounts,listAccounts}`\n // fillers under the merge seam (platform-derived wins per-key), so the\n // adopter's working handler silently never runs. This pattern matches the\n // gating already used for `reportUsage` / `getAccountFinancials` below.\n // Adopters who claim sync_accounts / list_accounts capability without\n // implementing `accounts.upsert` / `accounts.list` AND without supplying a\n // merge-seam override get framework's \"tool not registered\" path —\n // closer to the truth than a fabricated UNSUPPORTED_FEATURE envelope.\n const handlers: AccountHandlers<Account> = {};\n\n if (accounts.upsert) {\n handlers.syncAccounts = async (params, ctx) => {\n const resolveCtx = toResolveCtx(ctx, 'sync_accounts', params);\n const policy = enforceSyncAccountsCommercialPolicy(platform, params as Record<string, unknown>, resolveCtx);\n const dispatchCtx =\n policy.failedRows.size === 0 ? resolveCtx : toResolveCtx(ctx, 'sync_accounts', policy.acceptedParams);\n return projectSync(\n () =>\n policy.acceptedEntries.length > 0\n ? accounts.upsert!(policy.acceptedEntries as AccountReference[], dispatchCtx)\n : Promise.resolve([]),\n rows => {\n if (rows.length !== policy.acceptedEntries.length) {\n throw new Error(\n `sync_accounts accounts.upsert returned ${rows.length} ${\n rows.length === 1 ? 'row' : 'rows'\n } for ${policy.acceptedEntries.length} accepted account ${\n policy.acceptedEntries.length === 1 ? 'entry' : 'entries'\n }`\n );\n }\n if (policy.failedRows.size === 0) {\n return { accounts: rows.map(toWireSyncAccountRow) };\n }\n const combined: SyncAccountsResultRow[] = [];\n let acceptedIndex = 0;\n const originalCount = ((params.accounts as unknown[]) ?? []).length;\n for (let index = 0; index < originalCount; index += 1) {\n const failed = policy.failedRows.get(index);\n if (failed !== undefined) {\n combined.push(failed);\n } else {\n combined.push(rows[acceptedIndex] as SyncAccountsResultRow);\n acceptedIndex += 1;\n }\n }\n return { accounts: combined.map(toWireSyncAccountRow) };\n }\n );\n };\n }\n\n if (accounts.syncGovernance) {\n handlers.syncGovernance = async (params, ctx) => {\n const entries = params.accounts as SyncGovernanceRequest['accounts'];\n const resolveCtx = toResolveCtx(ctx, 'sync_governance', params);\n return projectSync(\n () => accounts.syncGovernance!(entries, resolveCtx),\n rows => ({ accounts: rows.map(toWireSyncGovernanceRow) })\n );\n };\n }\n\n if (accounts.list) {\n handlers.listAccounts = async (params, ctx) => {\n const filter = params as Parameters<NonNullable<typeof accounts.list>>[0];\n const resolveCtx = toResolveCtx(ctx, 'list_accounts', params);\n // Wrap in projectSync so adopter `throw new AdcpError('PERMISSION_DENIED', ...)`\n // from the list impl projects to the structured wire envelope rather\n // than falling through to the framework's `SERVICE_UNAVAILABLE` mapping.\n //\n // Wire shape: 3.0 + 3.1 `list-accounts-response` model pagination via a\n // `pagination` block referencing `core/pagination-response.json`\n // (`has_more` required, `cursor` present only when `has_more=true`).\n // Emitting top-level `next_cursor` — the shape shipped before this fix —\n // was schema-invisible (`additionalProperties: true` on the response) but\n // silently failed the `pagination_integrity_list_accounts` storyboard's\n // `field_value pagination.has_more: true` + `field_present pagination.cursor`\n // assertions for every adopter, regardless of `CursorPage` output.\n // See adcontextprotocol/adcp#5723 for the reproduction from a 3.1 seller.\n return projectSync(\n () => accounts.list!(filter, resolveCtx),\n page => ({\n status: 'completed' as const,\n accounts: page.items.map(toWireAccount),\n pagination: {\n has_more: page.nextCursor != null,\n ...(page.nextCursor != null && { cursor: page.nextCursor }),\n ...(page.totalCount !== undefined && { total_count: page.totalCount }),\n },\n })\n );\n };\n }\n\n if (accounts.reportUsage) {\n handlers.reportUsage = async (params, ctx) => {\n const resolveCtx = toResolveCtx(ctx, 'report_usage', params);\n return projectSync(\n () => accounts.reportUsage!(asValidatedDomainRequest(params), resolveCtx),\n r => r\n );\n };\n }\n\n if (accounts.getAccountFinancials) {\n handlers.getAccountFinancials = async (params, ctx) => {\n // Resolve the account first so `ctx.account` is populated when the\n // platform method runs. Adopters fronting an upstream platform read\n // tokens / upstream IDs off `ctx.account.ctx_metadata` without\n // having to re-resolve from `params.account`.\n const resolveCtx = toResolveCtx(ctx, 'get_account_financials', params);\n const accountRef = asValidatedDomainRequest<AccountReference | undefined>(params.account);\n refuseInlineAccountIdWhenForbidden(accounts.resolution, accountRef);\n const resolved = await accounts.resolve(accountRef, resolveCtx);\n if (!resolved) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'Account not found',\n recovery: 'terminal',\n });\n }\n // Request-local clone: refreshToken mutates account.authInfo before the\n // retry. Never write refreshed credentials onto a resolver-owned object;\n // adopters sometimes cache Account rows between requests.\n const account = cloneAccountForRequest(resolved);\n const toolCtx = { ...resolveCtx, account };\n return projectSync(\n () => accounts.getAccountFinancials!(asValidatedDomainRequest(params), toolCtx),\n r => r,\n accounts.refreshToken ? { account, fn: accounts.refreshToken.bind(accounts) } : undefined\n );\n };\n }\n\n return handlers;\n}\n\n// ────────────────────────────────────────────────────────────\n// Auto-seed helpers (catalog-backed comply sandbox; issue #1091)\n// ────────────────────────────────────────────────────────────\n\n// Auto-seed namespace key extractor. Used by both the write side (the\n// `seed.product` / `seed.pricing_option` adapter closures injected\n// inline in the auto-seed wiring) and the read side (`makeAutoSeedBridge`\n// when `ctx.account?.id` is absent — i.e., the framework didn't\n// pre-resolve the account on a custom dispatcher path).\n//\n// Write-side rationale: the adapter cannot reach the framework-resolved\n// `ctx.account.id` (the comply-controller's `ComplyControllerContext`\n// only exposes `{ input }`), and calling `platform.accounts.resolve`\n// here without `authInfo` would let a caller spoof `account.account_id`\n// and write into another tenant's resolved namespace. The architectural\n// fix (widen `ComplyControllerContext` to surface the resolved account)\n// is tracked at #1216 — until then, raw id is the secure choice.\nfunction readAutoSeedAccountId(input: Record<string, unknown>): string | undefined {\n const account = input.account;\n if (account == null || typeof account !== 'object') return undefined;\n const id = (account as { account_id?: unknown }).account_id;\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n}\n\nfunction autoSeedStoreFor(store: Map<string, Map<string, unknown>>, accountId: string): Map<string, unknown> {\n let inner = store.get(accountId);\n if (inner == null) {\n inner = new Map<string, unknown>();\n store.set(accountId, inner);\n }\n return inner;\n}\n\n// Build a `TestControllerBridge` over the per-account auto-seed store. The\n// bridge filters seeded products by the resolved account so multi-tenant\n// servers (TenantRegistry-fronted, or single-tenant with multiple sandbox\n// accounts) never leak fixtures across tenants. Reads\n// `ctx.account?.id` first (set by `resolveAccount` at request time) and\n// falls back to `ctx.input.account.account_id` when no resolver is wired.\nfunction makeAutoSeedBridge(store: Map<string, Map<string, unknown>>): TestControllerBridge<unknown> {\n return {\n getSeededProducts: ctx => {\n const resolved = (ctx.account as { id?: unknown } | undefined)?.id;\n const accountId =\n typeof resolved === 'string' && resolved.length > 0 ? resolved : readAutoSeedAccountId(ctx.input);\n if (accountId == null) return [];\n const inner = store.get(accountId);\n if (inner == null || inner.size === 0) return [];\n const products: Product[] = [];\n for (const [productId, fixture] of inner.entries()) {\n const merged = mergeSeedProduct(\n {},\n {\n ...(fixture && typeof fixture === 'object' ? (fixture as Partial<Product>) : {}),\n product_id: productId,\n }\n );\n products.push(merged as Product);\n }\n return products;\n },\n };\n}\n"],"mappings":"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","names":["import_async_outcome","import_types","converter","cloned","value","clonedRefs"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/from-platform.ts"],"sourcesContent":["/**\n * Build an `AdcpServer` from a `DecisioningPlatform` impl.\n *\n * v6.0 alpha entry point. Translates the per-specialism platform interface\n * into the framework's existing handler-style config and delegates to\n * `createAdcpServer()`. This means every framework primitive — idempotency,\n * RFC 9421 signing, governance, schema validation, state store, MCP/A2A\n * wire mapping, sandbox boundary — applies unchanged. The new code is the\n * adapter shim, not a forked runtime.\n *\n * **Adopter shape (unified hybrid):** each HITL-eligible tool is a single\n * method. The method returns the wire success arm (sync fast path) OR\n * `ctx.handoffToTask(fn)` to promote the call to a background task (HITL\n * slow path). Adopters branch per-call; framework detects the `TaskHandoff`\n * marker and dispatches accordingly:\n *\n * - Sync path: framework awaits the return value in foreground; projects\n * it to the wire success arm. `throw new AdcpError(...)` projects to\n * the wire `adcp_error` envelope.\n * - HITL path: framework detects the `TaskHandoff` marker, allocates\n * `taskId`, returns the submitted envelope to the buyer immediately,\n * then runs the handoff function in background. The function's return\n * value becomes the task's terminal `result`; thrown `AdcpError` becomes\n * the terminal `error`.\n *\n * Generic thrown errors (`Error`, `TypeError`) fall through to the\n * framework's `SERVICE_UNAVAILABLE` mapping.\n *\n * **Wired surface (6.0):** `SalesPlatform` (14 tools — 3 required core +\n * 11 optional; unified hybrid on `create_media_buy` / `sync_creatives`),\n * `CreativeBuilderPlatform` (build_creative / sync_creatives unified\n * hybrid, optional preview_creative sync-only, optional refineCreative),\n * `AudiencePlatform.syncAudiences`, `SignalsPlatform` (get_signals /\n * activate_signal), `AccountStore` (reportUsage, getAccountFinancials),\n * `ContentStandardsPlatform`, `CampaignGovernancePlatform`,\n * `TenantRegistry` (multi-tenant health), `createPostgresTaskRegistry`,\n * `tasks/get` wire handler, per-server + module-level `publishStatusChange`.\n *\n * **Still deferred (rc.1+):** MCP Resources subscription projection for\n * `publishStatusChange`. The no-account tool surface (`preview_creative`,\n * `list_creative_formats`, `provide_performance_feedback`) is now typed\n * via `NoAccountCtx<TCtxMeta>` — handlers receive `ctx.account: Account |\n * undefined` and must narrow before reading `ctx_metadata`.\n *\n * Status: Preview / 6.0. Not yet exported from the public `./server`\n * subpath; reach in via `@adcp/sdk/server/decisioning/runtime` for\n * spike experimentation only.\n *\n * @public\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport type { AdcpServer } from '../../adcp-server';\nimport {\n createAdcpServer,\n COMPACT_MEDIA_BUY_MUTATION_TOOLS,\n type AdcpServerConfig,\n type MediaBuyHandlers,\n type ProposalNegotiationHandlers,\n type CreativeHandlers,\n type EventTrackingHandlers,\n type AccountHandlers,\n type SignalsHandlers,\n type SponsoredIntelligenceHandlers,\n type GovernanceHandlers,\n type BrandRightsHandlers,\n type HandlerContext,\n type AdcpServerToolName,\n} from '../../create-adcp-server';\nimport type { DecisioningPlatform, RequiredPlatformsFor, RequiredCapabilitiesFor } from '../platform';\nimport type { ComplianceTestingCapabilities } from '../capabilities';\nimport { normalizeTargetingCapabilities } from '../capabilities';\nimport { isAdcpVersionAtLeast } from '../../../utils/adcp-version-config';\nimport type { Account, ResolvedAuthInfo, ResolveContext } from '../account';\nimport {\n AccountNotFoundError,\n refAccountId,\n toWireAccount,\n toWireSyncAccountRow,\n toWireSyncGovernanceRow,\n type SyncAccountsResultRow,\n} from '../account';\nimport type { BuyerAgent, BuyerAgentBillingMode, BuyerAgentRegistry } from '../buyer-agent';\nimport { suggestBilling } from '../buyer-agent';\nimport { AdcpError, type AdcpStructuredError } from '../async-outcome';\nimport type { CreativeBuilderPlatform } from '../specialisms/creative';\nimport type { CreativeAdServerPlatform } from '../specialisms/creative-ad-server';\nimport type { CanonicalPreviewCreativeRequest } from '../../../v2/projection/creative-delivery';\nimport type { Audience } from '../specialisms/audiences';\nimport type { RequestContext } from '../context';\nimport {\n maybeInterceptFinalize,\n maybePersistDraftAfterGetProducts,\n maybeReserveProposalForCreateMediaBuy,\n finalizeProposalConsumption,\n releaseProposalReservation,\n maybeHydrateRecipesForMediaBuyId,\n type ReservedProposal,\n type Recipe as ProposalRecipe,\n} from '../proposal';\nimport type {\n AccountReference,\n BillingParty,\n BrandReference,\n BuildCreativeMultiSuccess,\n BuildCreativeSuccess,\n BuildCreativeVariantSuccess,\n CreativeManifest,\n GetAdCPCapabilitiesResponse,\n PaymentTerms,\n SyncGovernanceRequest,\n} from '../../../types/tools.generated';\nimport type { RequireCacheScopeWhenProducts, ServerPayload } from '../../../types/server-payload';\nimport { rollupOptimizationMetricsFromProducts } from '../../../utils/capability-rollups';\nimport { adcpError, sanitizeStructuredAdcpError, type AdcpErrorResponse } from '../../errors';\nimport { resolveCredentialPolicyForTool, scanArgsForCredentials, type CredentialPolicy } from '../../credential-policy';\nimport { validatePlatform, PlatformConfigError } from './validate-platform';\nimport { validateSpecialismRequiredTools, formatSpecialismIssue } from '../validate-specialisms';\nimport type { AdcpLogger } from '../../create-adcp-server';\nimport { buildRequestContext, buildHandoffContext } from './to-context';\nimport {\n type CtxMetadataStore,\n type ResourceKind,\n createCtxMetadataStore,\n pgCtxMetadataStore,\n getCtxMetadataMigration,\n stripCtxMetadata,\n stripImplementationConfig,\n} from '../../ctx-metadata';\nimport { createIdempotencyStore, type IdempotencyStore } from '../../idempotency';\nimport { pgBackend, getIdempotencyMigration } from '../../idempotency/backends/pg';\nimport type {\n MediaBuyStore,\n CreateMediaBuyInputForStore,\n CreateMediaBuyResultForStore,\n UpdateMediaBuyInputForStore,\n GetMediaBuysResultForStore,\n} from '../../media-buy-store';\nimport { createPostgresTaskRegistry, getDecisioningTaskRegistryMigration } from './postgres-task-registry';\nimport type { PgQueryable } from '../../postgres-task-store';\nimport { isTaskHandoff, _extractHandoffEntry, type TaskHandoff } from '../async-outcome';\nimport { _extractResponseSummaryEntry } from '../response-summary';\nimport { productsResponse } from '../../responses';\nimport { TOOL_ENTITY_FIELDS } from './entity-hydration.generated';\nimport { z } from 'zod';\nimport {\n createInMemoryTaskRegistry,\n taskRecordMatchesScope,\n type TaskRegistry,\n type TaskRecord,\n type TaskRegistryScope,\n type TaskStatus,\n} from './task-registry';\nimport { protocolForTool, SPEC_WEBHOOK_TASK_TYPES } from './protocol-for-tool';\n\n/**\n * Default logger when adopters don't supply `opts.logger`. `debug` /\n * `info` are no-op; `warn` / `error` route to console so framework\n * warnings (merge-seam collisions, SSRF rejections, observability hook\n * misuse) surface during development. Adopters wiring `pino`/`bunyan`\n * supply all four levels via `opts.logger`.\n */\nconst DEFAULT_FRAMEWORK_LOGGER: AdcpLogger = {\n debug: () => {},\n info: () => {},\n // eslint-disable-next-line no-console\n warn: console.warn.bind(console),\n // eslint-disable-next-line no-console\n error: console.error.bind(console),\n};\nimport { createInMemoryStatusChangeBus, type StatusChangeBus, type PublishStatusChangeOpts } from '../status-changes';\nimport { createComplyController, type ComplyControllerConfig } from '../../../testing/comply-controller';\nimport type { TestControllerBridge } from '../../test-controller-bridge';\nimport { mergeSeedProduct } from '../../../testing/seed-merge';\nimport {\n getSdkServer,\n setToolVisibilityResolver,\n wrapRegisteredToolHandler,\n wrapSdkRequestHandler,\n} from '../../adcp-server';\nimport { isSandboxOrMockAccount } from '../../account-mode';\nimport { recordResolvedAccountMode, hasObservedLiveMode } from './observed-modes';\nimport type { Product } from '../../../types/tools.generated';\nimport { normalizeErrors } from '../../normalize-errors';\nimport { redactCredentialPatterns } from '../../redact';\nimport {\n CreativeFormatProjectionError,\n projectCreativeForDelivery,\n projectMediaBuyCreativesForDelivery,\n stripLegacyCreativeIdentity,\n} from '../../../v2/projection/creative-delivery';\nimport {\n projectV1ProductToV2,\n type LegacyFormatConversionContext,\n type LegacyFormatConverter,\n type LegacyFormatResolutionContext,\n type LegacyFormatResolver,\n} from '../../../v2/projection/v1-to-v2';\nimport {\n legacyFormatConverterFromCatalogSnapshots,\n type ProjectionCatalogSnapshot,\n} from '../../../v2/projection/catalog-snapshot';\nimport type {\n CanonicalSyncCreativeAsset,\n CanonicalCreateMediaBuyRequest,\n CanonicalGetProductsRequest,\n CanonicalListCreativesRequest,\n CanonicalUpdateMediaBuyRequest,\n} from '../../../v2/projection/creative-delivery';\nimport { toCanonicalOnlyResponse } from '../../../v2/projection/augment-response';\nimport {\n CanonicalFormatLegacyResolutionError,\n projectV2ProductToV1,\n resolveCanonicalFormatLegacyRefs,\n} from '../../../v2/projection/v2-to-v1';\nimport type { CanonicalFormatLegacyResolver } from '../../../v2/projection/v2-to-v1';\nimport {\n isProjectionProductInput,\n type ProjectionDiagnostic,\n type V1FormatId,\n type V1Product,\n type V2Product,\n} from '../../../v2/projection/types';\nimport { legacyFormatRefsForDeclaration } from '../../../v2/projection/legacy-metadata';\nimport { canonicalizeAgentUrl } from '../../../discovery/resolve-agent-properties';\nimport { ADCP_VERSION } from '../../../version';\n\nfunction supportsCanonicalCreativeCapability(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major > 3 || (major === 3 && minor >= 1);\n}\n\nfunction requiresCanonicalCreativeWire(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major > 3 || (major === 3 && minor >= 2);\n}\n\nfunction supportsTransitionalDualCreativeWire(version: unknown): boolean {\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.|-|$)/.exec(version.trim());\n if (!match) return false;\n return Number(match[1]) === 3 && Number(match[2]) === 1;\n}\n\nfunction shouldEmitTransitionalDualCreativeWire(version: unknown, request: unknown): boolean {\n if (!supportsTransitionalDualCreativeWire(version)) return false;\n if (request === null || typeof request !== 'object') return true;\n const fields = Object.getOwnPropertyDescriptor(request, 'fields');\n if (!fields || !('value' in fields) || !Array.isArray(fields.value)) return true;\n return Object.values(Object.getOwnPropertyDescriptors(fields.value)).some(\n descriptor => descriptor.enumerable && 'value' in descriptor && descriptor.value === 'format_ids'\n );\n}\n\ntype CreativeWireEvidence = 'canonical' | 'legacy' | 'mixed' | 'unknown';\n\n/**\n * AdCP 3.1 is a dual-format transition release. Infer the caller's format\n * dialect from data-only request fields without invoking getters or custom\n * serialization hooks. Ambiguous 3.1 reads use the modern framework's\n * canonical default; legacy buyers can select the compatibility projection\n * with an actual legacy field such as `fields: ['format_ids']`.\n */\nfunction creativeWireEvidenceForRequest(request: unknown): CreativeWireEvidence {\n let canonical = false;\n let legacy = false;\n const seen = new WeakSet<object>();\n\n // Raw-wire migration tooling uses a namespaced extension because read\n // requests such as get_products and list_creatives can otherwise be\n // structurally ambiguous. Read it through data descriptors only so the\n // negotiation path retains the same no-application-code guarantee as the\n // recursive scanner below.\n if (request !== null && typeof request === 'object') {\n const ext = Object.getOwnPropertyDescriptor(request, 'ext');\n if (ext && 'value' in ext && ext.value !== null && typeof ext.value === 'object') {\n const adcp = Object.getOwnPropertyDescriptor(ext.value, 'adcp');\n if (adcp && 'value' in adcp && adcp.value !== null && typeof adcp.value === 'object') {\n const wire = Object.getOwnPropertyDescriptor(adcp.value, 'creative_wire');\n if (wire && 'value' in wire) {\n if (wire.value === 'canonical') canonical = true;\n if (wire.value === 'legacy') legacy = true;\n }\n }\n }\n }\n\n const visit = (value: unknown): void => {\n if (value === null || typeof value !== 'object' || seen.has(value)) return;\n seen.add(value);\n const arrayValue = Array.isArray(value);\n const descriptors = Object.getOwnPropertyDescriptors(value);\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (!descriptor.enumerable || !('value' in descriptor)) continue;\n const child = descriptor.value;\n // Conversation/context payloads can legitimately quote a previous\n // response in the opposite dialect. They are not negotiation signals\n // for the current tool call. The same applies to arbitrary extensions.\n if (key === 'context' || key === 'ext') continue;\n if (/(^|_)(?:format_ids?|v1_format_ref)($|_)/.test(key)) legacy = true;\n if (\n key === 'format_kind' ||\n key === 'format_options' ||\n key === 'format_option_ref' ||\n key === 'format_option_refs'\n ) {\n canonical = true;\n }\n // Inspect array entries through their own data descriptors. Never use\n // iteration here: an Array subclass or ordinary array can install a\n // user-controlled Symbol.iterator, and dialect detection must not run\n // application code.\n if (arrayValue && typeof child === 'string') {\n if (child === 'format_id' || child === 'format_ids') legacy = true;\n if (child === 'format_kind' || child === 'format_options' || child === 'format_option_ref') canonical = true;\n }\n visit(child);\n }\n };\n\n visit(request);\n if (canonical && legacy) return 'mixed';\n if (canonical) return 'canonical';\n if (legacy) return 'legacy';\n return 'unknown';\n}\n\nfunction creativeWireModeForRequest(\n ctx: HandlerContext<Account>,\n fallback: 'canonical' | 'legacy',\n request?: unknown\n): 'canonical' | 'legacy' {\n if (ctx.servedAdcpVersion === undefined) return fallback;\n if (!supportsCanonicalCreativeCapability(ctx.servedAdcpVersion)) return 'legacy';\n if (requiresCanonicalCreativeWire(ctx.servedAdcpVersion)) return 'canonical';\n\n const evidence = creativeWireEvidenceForRequest(request);\n // Transitional 3.1 product/package envelopes may deliberately carry both\n // dialects. Prefer canonical output in that case; the semantic request\n // projector still rejects an individual creative that claims conflicting\n // format_id + format_kind identities.\n if (evidence === 'canonical' || evidence === 'mixed') return 'canonical';\n if (evidence === 'legacy') return 'legacy';\n return fallback;\n}\n\nfunction parseAdcpRelease(version: unknown): readonly [number, number, number] | undefined {\n if (typeof version !== 'string') return undefined;\n const match = /^v?(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:-|$)/.exec(version.trim());\n if (!match) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];\n}\n\nfunction compareAdcpReleases(\n left: readonly [number, number, number],\n right: readonly [number, number, number]\n): number {\n for (let index = 0; index < left.length; index++) {\n const delta = left[index]! - right[index]!;\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n if (Array.isArray(v)) return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n}\n\nfunction deepMergePlainObjects(target: unknown, source: unknown): unknown {\n if (source === undefined) return target;\n if (source === null) return null;\n if (!isPlainObject(source)) return source;\n if (!isPlainObject(target)) return { ...source };\n const out: Record<string, unknown> = { ...target };\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue;\n if (value === null) {\n delete out[key];\n continue;\n }\n out[key] = deepMergePlainObjects(out[key], value);\n }\n return out;\n}\n\nfunction mergeCapabilityOverride<T extends object>(adopter: T | null | undefined, framework: Partial<T>): T {\n return deepMergePlainObjects(adopter ?? {}, framework) as T;\n}\n\n/**\n * Apply `normalizeErrors` to a sync_creatives row's optional `errors`\n * field. Adopters often return errors as bare strings, native Error\n * instances, or vendor-specific shapes; the wire schema requires\n * `Error[]` with `{ code, message, ... }`. Normalizing at the\n * projection seam means every adopter's syncCreatives method gets\n * coerced to wire shape — the row passes strict response validation\n * even when the adopter doesn't hand-shape every error.\n */\nfunction normalizeRowErrors<TRow extends { errors?: unknown }>(row: TRow): TRow {\n if (row?.errors == null) return row;\n return { ...row, errors: normalizeErrors(row.errors) } as TRow;\n}\n\nfunction asCanonicalServerResponse<T>(response: T): T {\n return stripLegacyCreativeIdentity(response) as T;\n}\n\nfunction ownEnumerableDataRecord(value: object, operation: string): Record<string, unknown> | undefined {\n const descriptors = Object.getOwnPropertyDescriptors(value);\n const entries = Object.entries(descriptors).filter(([, descriptor]) => descriptor.enumerable);\n if (entries.length === 0) return undefined;\n const record: Record<string, unknown> = {};\n for (const [key, descriptor] of entries) {\n if (!('value' in descriptor)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(response:${key})`,\n 'enumerable accessors cannot cross the creative format boundary safely'\n );\n }\n record[key] = descriptor.value;\n }\n return record;\n}\n\nfunction assertSafeSemanticPayload(value: unknown, operation: string): void {\n const active = new WeakSet<object>();\n const visited = new WeakSet<object>();\n\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object') return;\n if (Array.isArray(current) && Object.getPrototypeOf(current) !== Array.prototype) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path})`,\n 'array subclasses cannot cross the creative format boundary safely'\n );\n }\n for (let owner: object | null = current; owner !== null; owner = Object.getPrototypeOf(owner)) {\n const toJSON = Object.getOwnPropertyDescriptor(owner, 'toJSON');\n if (!toJSON) continue;\n if (!('value' in toJSON) || typeof toJSON.value === 'function') {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path}.toJSON)`,\n 'custom or accessor toJSON hooks cannot cross the creative format boundary safely'\n );\n }\n }\n if (active.has(current)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path})`,\n 'cyclic values cannot cross the creative format boundary'\n );\n }\n if (visited.has(current)) return;\n active.add(current);\n try {\n const descriptors = Object.getOwnPropertyDescriptors(current);\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (!('value' in descriptor)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(payload:${path}.${key})`,\n 'accessors cannot cross the creative format boundary safely'\n );\n }\n if (!descriptor.enumerable) continue;\n visit(descriptor.value, `${path}.${key}`);\n }\n } finally {\n active.delete(current);\n }\n visited.add(current);\n };\n\n visit(value, '$');\n}\n\nfunction projectResponseCreativeIdentities(\n value: unknown,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n wireMode: 'canonical' | 'legacy',\n selectorContainer: Record<string, unknown> = {}\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item =>\n projectResponseCreativeIdentities(\n item,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n wireMode,\n selectorContainer\n )\n );\n }\n if (value === null || typeof value !== 'object') return value;\n\n const inspectedRecord = ownEnumerableDataRecord(value, operation);\n if (inspectedRecord === undefined) return value;\n // Preserve plain-object identity so SDK-private WeakMap metadata on\n // canonical declarations survives the downgrade path. Non-plain records\n // are copied into a data-only shape so prototype behavior cannot reach the\n // wire.\n const dataRecord = isPlainObject(value) ? value : inspectedRecord;\n let projected: Record<string, unknown> = dataRecord;\n if (isProjectionProductInput(projected)) {\n if (wireMode === 'canonical') {\n const canonical = toCanonicalOnlyResponse({ products: [projected] }, { legacyFormatConverter });\n if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {\n throw new CreativeFormatProjectionError(\n operation,\n `(product:${String(projected.product_id)})`,\n 'legacy product formats in the platform response have no complete canonical representation'\n );\n }\n projected = canonical.response.products[0] as unknown as Record<string, unknown>;\n } else if (Array.isArray(projected.format_options)) {\n const legacy = projectV2ProductToV1(projected, { canonicalFormatLegacyResolver });\n if (legacy.diagnostics.length > 0 || (legacy.v1.format_ids.length === 0 && projected.format_options.length > 0)) {\n throw new CreativeFormatProjectionError(\n operation,\n `(product:${String(projected.product_id)})`,\n 'canonical product formats in the platform response have no complete legacy representation'\n );\n }\n projected = legacy.v1 as unknown as Record<string, unknown>;\n }\n } else if (\n (typeof projected.package_id === 'string' || typeof projected.product_id === 'string') &&\n (Array.isArray(projected.format_ids) ||\n Array.isArray(projected.format_option_refs) ||\n typeof projected.format_kind === 'string')\n ) {\n projected = (\n projectMediaBuyCreativesForDelivery(\n { packages: [projected] },\n wireMode,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n ) as { packages: Record<string, unknown>[] }\n ).packages[0]!;\n }\n\n if (\n typeof projected.creative_id === 'string' &&\n (projected.format_id !== undefined || typeof projected.format_kind === 'string')\n ) {\n projected = projectCreativeForDelivery(\n projected as unknown as import('../../../types/tools.generated').CreativeAsset,\n selectorContainer,\n wireMode,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n ) as unknown as Record<string, unknown>;\n }\n\n const nextSelector =\n Array.isArray(projected.format_ids) ||\n Array.isArray(projected.format_options) ||\n Array.isArray(projected.format_option_refs)\n ? projected\n : selectorContainer;\n let changed = projected !== value;\n const next: Record<string, unknown> = { ...projected };\n for (const [key, child] of Object.entries(projected)) {\n const childProjected = projectResponseCreativeIdentities(\n child,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n wireMode,\n nextSelector\n );\n if (childProjected !== child) {\n next[key] = childProjected;\n changed = true;\n }\n }\n return changed ? next : projected;\n}\n\nfunction asCanonicalSemanticServerResponse<T>(\n response: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver\n): T {\n try {\n assertSafeSemanticPayload(response, operation);\n return asCanonicalServerResponse(\n projectResponseCreativeIdentities(\n response,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n 'canonical'\n )\n ) as T;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} platform response contains a legacy creative format that cannot be represented canonically.`,\n field: 'response',\n suggestion:\n 'Return canonical format_kind values, or configure legacyCreativeFormatConverter for custom legacy formats.',\n });\n }\n}\n\nfunction asSemanticServerResponseForWire<T>(\n response: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n wireMode: 'canonical' | 'legacy'\n): T {\n if (wireMode === 'canonical') {\n return attachCanonicalFormatWireRefs(\n asCanonicalSemanticServerResponse(response, operation, legacyFormatConverter, canonicalFormatLegacyResolver),\n canonicalFormatLegacyResolver,\n operation\n );\n }\n try {\n assertSafeSemanticPayload(response, operation);\n return projectResponseCreativeIdentities(\n response,\n operation,\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n 'legacy'\n ) as T;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} platform response contains a canonical creative format that cannot be represented on the configured legacy wire.`,\n field: 'response',\n suggestion:\n 'Return an explicit legacy mapping for the canonical format, or configure this server for AdCP 3.1 or newer.',\n });\n }\n}\n\ntype LegacyIdentityContext = 'agent' | 'signal' | 'list' | 'default';\n\nfunction legacyIdentityContext(ownerKey?: string): LegacyIdentityContext {\n if (typeof ownerKey !== 'string') return 'default';\n if (ownerKey === 'signal_id' || ownerKey === 'signal_ids') return 'signal';\n if (/(^|_)(?:property_lists?|collection_lists?)($|_)/.test(ownerKey)) return 'list';\n if (\n !/(^|_)(?:creative|format|legacy|placement)($|_)/.test(ownerKey) &&\n /(^|_)(?:agents?|agent_details|agent_info)($|_)/.test(ownerKey)\n ) {\n return 'agent';\n }\n return 'default';\n}\n\nfunction allowsNonCreativeAgentUrl(owner: Record<string, unknown>, context: LegacyIdentityContext): boolean {\n return (\n context === 'agent' ||\n (context === 'list' && typeof owner.list_id === 'string') ||\n (context === 'signal' && owner.source === 'agent')\n );\n}\n\ninterface LegacyIdentityScanSeen {\n agent: WeakSet<object>;\n signal: WeakSet<object>;\n list: WeakSet<object>;\n default: WeakSet<object>;\n}\n\nfunction findLegacyCreativeIdentity(\n value: unknown,\n seen: LegacyIdentityScanSeen = {\n agent: new WeakSet<object>(),\n signal: new WeakSet<object>(),\n list: new WeakSet<object>(),\n default: new WeakSet<object>(),\n },\n ownerKey?: string\n): string | undefined {\n if (value === null || typeof value !== 'object') return undefined;\n const owner = value as Record<string, unknown>;\n const context = legacyIdentityContext(ownerKey);\n const policySeen = seen[context];\n if (policySeen.has(value)) return undefined;\n policySeen.add(value);\n if (Array.isArray(value)) {\n for (const item of value) {\n const nested = findLegacyCreativeIdentity(item, seen, ownerKey);\n if (nested) return nested;\n }\n return undefined;\n }\n for (const [key, child] of Object.entries(owner)) {\n if (/(^|_)(?:format_ids?|v1_format_ref)($|_)/.test(key)) return key;\n if (\n key === 'agent_url' &&\n (typeof owner.id === 'string' || typeof owner.list_id === 'string') &&\n !allowsNonCreativeAgentUrl(owner, context)\n ) {\n return key;\n }\n const nested = findLegacyCreativeIdentity(child, seen, key);\n if (nested) return nested;\n }\n return undefined;\n}\n\nfunction asCanonicalSemanticServerRequest<T>(\n request: T,\n operation: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): T {\n try {\n assertSafeSemanticPayload(request, operation);\n const projected = projectResponseCreativeIdentities(\n request,\n operation,\n legacyFormatConverter,\n undefined,\n 'canonical'\n ) as T;\n const forbidden = findLegacyCreativeIdentity(projected);\n if (forbidden) {\n throw new CreativeFormatProjectionError(\n operation,\n '(request extension)',\n `legacy creative identity ${forbidden} has no recognized canonical container`\n );\n }\n return projected;\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: `${operation} request contains a legacy creative format that cannot be represented canonically.`,\n field: 'request',\n suggestion:\n 'Send canonical format_kind values, or configure legacyCreativeFormatConverter for custom legacy formats.',\n });\n }\n}\n\n/**\n * Bridge the runtime-schema input type to the public domain request type.\n *\n * Requests reach this adapter only after validation against the signed AdCP\n * JSON Schema. JSON-Schema-to-Zod represents `minItems: 1` as a validated\n * array, while json-schema-to-typescript represents the same field as a\n * non-empty tuple. The values are equivalent after validation, but TypeScript\n * cannot prove that structural relationship. Keep the assertion at this\n * single validation boundary instead of weakening the public request types.\n */\nfunction asValidatedDomainRequest<T>(request: unknown): T {\n return request as T;\n}\n\nfunction asCanonicalGetProductsRequest(request: Record<string, unknown>): CanonicalGetProductsRequest {\n if (!Array.isArray(request['fields'])) return request as CanonicalGetProductsRequest;\n const fields = [\n ...new Set(\n request['fields'].flatMap(field =>\n field === 'format_ids' ? ['format_options'] : typeof field === 'string' ? [field] : []\n )\n ),\n ] as CanonicalGetProductsRequest['fields'];\n return { ...request, fields } as CanonicalGetProductsRequest;\n}\n\nfunction asCanonicalListCreativesRequest(\n request: Record<string, unknown>,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n responseWireMode: 'canonical' | 'legacy'\n): CanonicalListCreativesRequest {\n const filters =\n request['filters'] !== null && typeof request['filters'] === 'object' && !Array.isArray(request['filters'])\n ? (request['filters'] as Record<string, unknown>)\n : undefined;\n const legacyFormatIds = filters?.['format_ids'];\n if (Array.isArray(legacyFormatIds) && legacyFormatIds.length > 0 && responseWireMode !== 'legacy') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'list_creatives legacy format_ids filters are unavailable on the canonical platform surface.',\n field: 'filters.format_ids',\n suggestion: 'Filter by canonical creative fields, or use an explicit legacy wire handler during migration.',\n });\n }\n const { format_ids: _dropLegacyFormatIds, ...canonicalFilters } = filters ?? {};\n void _dropLegacyFormatIds;\n const withoutLegacyFilter = filters === undefined ? request : { ...request, filters: canonicalFilters };\n const projected = asCanonicalSemanticServerRequest(\n withoutLegacyFilter,\n 'list_creatives',\n legacyFormatConverter\n ) as Record<string, unknown>;\n const withLegacyFilter =\n responseWireMode === 'legacy' && Array.isArray(legacyFormatIds) && legacyFormatIds.length > 0\n ? {\n ...projected,\n filters: {\n ...((projected['filters'] as Record<string, unknown> | undefined) ?? {}),\n format_ids: legacyFormatIds,\n },\n }\n : projected;\n if (!Array.isArray(withLegacyFilter['fields'])) return withLegacyFilter as CanonicalListCreativesRequest;\n const fields = [\n ...new Set(\n withLegacyFilter['fields'].flatMap(field =>\n field === 'format_id' ? ['format_kind'] : typeof field === 'string' ? [field] : []\n )\n ),\n ] as CanonicalListCreativesRequest['fields'];\n return { ...withLegacyFilter, fields } as CanonicalListCreativesRequest;\n}\n\nfunction assertSafeGetProductsResponse(response: unknown): void {\n try {\n assertSafeSemanticPayload(response, 'get_products');\n } catch (error) {\n if (!(error instanceof CreativeFormatProjectionError)) throw error;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products platform response cannot be represented safely at the canonical boundary.',\n field: 'response',\n suggestion: 'Return an acyclic data-only product response without enumerable accessors.',\n });\n }\n}\n\nfunction asCanonicalProductResponse<T extends { products?: unknown[] }>(\n response: T,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): T {\n assertSafeGetProductsResponse(response);\n validateDualProductFormatDeclarations(response, legacyFormatConverter);\n const projected = toCanonicalOnlyResponse(response as T & { products?: V1Product[] }, {\n legacyFormatConverter,\n });\n const blockingDiagnostics = projected.diagnostics.filter(\n diagnostic => diagnostic.code !== 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED'\n );\n if (blockingDiagnostics.length > 0) {\n const first = blockingDiagnostics[0]!;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a legacy format that cannot be represented canonically.',\n field: first.field,\n suggestion: 'Declare canonical format_options or configure legacyCreativeFormatConverter for the legacy format.',\n });\n }\n const canonicalResponse = asCanonicalServerResponse(projected.response) as T;\n const resolvedDropDiagnostics = projected.diagnostics.filter(\n (diagnostic): diagnostic is LegacyDropDiagnostic => diagnostic.code === 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED'\n );\n if (resolvedDropDiagnostics.length > 0 && canonicalResponse !== null && typeof canonicalResponse === 'object') {\n resolvedLegacyDropDiagnosticsByResponse.set(canonicalResponse, resolvedDropDiagnostics);\n }\n preserveAuthoredFormatIds(response, canonicalResponse);\n return canonicalResponse;\n}\n\nfunction legacyFormatResolutionKey(context: LegacyFormatConversionContext): string {\n const formatId = context.formatId;\n return JSON.stringify([\n context.productId,\n context.field,\n formatId.agent_url,\n formatId.id,\n formatId.width ?? null,\n formatId.height ?? null,\n formatId.duration_ms ?? null,\n ]);\n}\n\nfunction preparePerProductProjectionCatalogs<T extends { products?: unknown[] }>(\n response: T,\n fallback: LegacyFormatConverter | undefined\n): { response: T; converter: LegacyFormatConverter | undefined } {\n assertSafeGetProductsResponse(response);\n if (!Array.isArray(response.products)) return { response, converter: fallback };\n assertNoReservedLegacyRouteMetadata(response.products, 'products');\n\n const converters = new Map<string, LegacyFormatConverter>();\n const productIdCounts = new Map<string, number>();\n for (const product of response.products) {\n if (!product || typeof product !== 'object' || Array.isArray(product)) continue;\n const productId = (product as Record<string, unknown>).product_id;\n if (typeof productId === 'string') productIdCounts.set(productId, (productIdCounts.get(productId) ?? 0) + 1);\n }\n let strippedCatalogMetadata = false;\n const products = response.products.map(product => {\n if (!product || typeof product !== 'object' || Array.isArray(product)) return product;\n const record = product as Record<string, unknown>;\n if (!Object.prototype.hasOwnProperty.call(record, 'projectionCatalogs')) return product;\n strippedCatalogMetadata = true;\n const { projectionCatalogs, ...wireProduct } = record;\n if (!Array.isArray(projectionCatalogs)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projectionCatalogs must be an array of immutable catalog snapshots.',\n field: `products[${String(record.product_id ?? '?')}].projectionCatalogs`,\n });\n }\n if (typeof record.product_id === 'string' && (productIdCounts.get(record.product_id) ?? 0) > 1) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projection catalogs require unique product identifiers.',\n field: `products[${record.product_id}].projectionCatalogs`,\n });\n }\n if (projectionCatalogs.length > 0 && typeof record.product_id === 'string') {\n if (converters.has(record.product_id)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products cannot attach different projection catalogs to duplicate product identifiers.',\n field: `products[${record.product_id}].projectionCatalogs`,\n });\n }\n const converter = legacyFormatConverterFromCatalogSnapshots(\n projectionCatalogs as readonly ProjectionCatalogSnapshot[]\n );\n if (converter) {\n converters.set(record.product_id, converter);\n const placements = wireProduct.placements;\n if (Array.isArray(placements)) {\n for (let placementIndex = 0; placementIndex < placements.length; placementIndex++) {\n const placement = placements[placementIndex];\n if (!placement || typeof placement !== 'object' || Array.isArray(placement)) continue;\n const placementRecord = placement as Record<string, unknown>;\n const placementId =\n typeof placementRecord.placement_id === 'string' ? placementRecord.placement_id : String(placementIndex);\n const projectionProductId = `${record.product_id}:placement:${placementId}`;\n if (converters.has(projectionProductId)) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products projection catalog scopes resolve to a duplicate product identifier.',\n field: `products[${record.product_id}].placements[${placementIndex}]`,\n });\n }\n converters.set(projectionProductId, converter);\n }\n }\n }\n }\n return wireProduct;\n });\n\n const converter: LegacyFormatConverter | undefined =\n converters.size === 0\n ? fallback\n : context => {\n const productConverter = converters.get(context.productId);\n const resolved = productConverter?.(context);\n return resolved === undefined ? fallback?.(context) : resolved;\n };\n return {\n response: (strippedCatalogMetadata ? { ...response, products } : response) as T,\n converter,\n };\n}\n\nconst DEFAULT_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS = 10_000;\nconst DEFAULT_LEGACY_FORMAT_RESOLVER_CONCURRENCY = 8;\nconst MAX_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS = 2_147_483_647;\nconst MAX_LEGACY_FORMAT_RESOLVER_CONCURRENCY = 64;\n\nfunction legacyFormatResolverLimit(\n value: number | undefined,\n fallback: number,\n field: string,\n maximum?: number\n): number {\n if (value === undefined) return fallback;\n if (!Number.isSafeInteger(value) || value <= 0 || (maximum !== undefined && value > maximum)) {\n const range = maximum === undefined ? 'a positive safe integer' : `an integer between 1 and ${maximum}`;\n throw new PlatformConfigError(`${field} must be ${range}.`);\n }\n return value;\n}\n\nfunction legacyFormatResolverAbortError(signal: AbortSignal): Error {\n return signal.reason instanceof Error\n ? signal.reason\n : new Error('legacyCreativeFormatResolver was aborted before projection completed.');\n}\n\nfunction createLegacyFormatResolverSignal(\n requestSignal: AbortSignal | undefined,\n timeoutMs: number\n): { signal: AbortSignal; dispose(): void } {\n const controller = new AbortController();\n const abortFromRequest = () => controller.abort(requestSignal?.reason);\n if (requestSignal?.aborted) abortFromRequest();\n else requestSignal?.addEventListener('abort', abortFromRequest, { once: true });\n const timeout = controller.signal.aborted\n ? undefined\n : setTimeout(\n () => controller.abort(new Error(`legacyCreativeFormatResolver exceeded its ${timeoutMs}ms deadline.`)),\n timeoutMs\n );\n return {\n signal: controller.signal,\n dispose() {\n if (timeout !== undefined) clearTimeout(timeout);\n requestSignal?.removeEventListener('abort', abortFromRequest);\n },\n };\n}\n\nasync function invokeLegacyFormatResolver(\n resolver: LegacyFormatResolver,\n context: Omit<LegacyFormatResolutionContext, 'signal'>,\n signal: AbortSignal\n): Promise<Awaited<ReturnType<LegacyFormatResolver>>> {\n if (signal.aborted) throw legacyFormatResolverAbortError(signal);\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n abortListener = () => reject(legacyFormatResolverAbortError(signal));\n signal.addEventListener('abort', abortListener, { once: true });\n });\n try {\n return await Promise.race([Promise.resolve().then(() => resolver({ ...context, signal })), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n\nasync function resolveLegacyProductFormats<T extends { products?: unknown[] }>(\n response: T,\n converter: LegacyFormatConverter | undefined,\n resolver: LegacyFormatResolver | undefined,\n requestContext: {\n servedAdcpVersion?: string;\n accountId?: string;\n signal?: AbortSignal;\n timeoutMs: number;\n concurrency: number;\n }\n): Promise<LegacyFormatConverter | undefined> {\n if (!resolver) return converter;\n assertSafeGetProductsResponse(response);\n if (!Array.isArray(response.products)) return converter;\n\n const resolutions = new Map<\n string,\n Awaited<ReturnType<LegacyFormatResolver>> | { readonly resolutionError: unknown }\n >();\n const pending: Array<(signal: AbortSignal) => Promise<void>> = [];\n const scanScope = (projectionProduct: V1Product, resolverProductId: string, resolverFieldPrefix: string): void => {\n if (Array.isArray((projectionProduct as unknown as V2Product).format_options)) return;\n for (let index = 0; index < projectionProduct.format_ids.length; index++) {\n const formatId = projectionProduct.format_ids[index];\n if (!formatId || typeof formatId !== 'object' || Array.isArray(formatId)) continue;\n const projectionField = `products[${projectionProduct.product_id}].format_ids[${index}]`;\n const resolverField = `${resolverFieldPrefix}.format_ids[${index}]`;\n const projectionContext: LegacyFormatConversionContext = {\n formatId: formatId as V1FormatId,\n productId: projectionProduct.product_id,\n field: projectionField,\n };\n const contextAwareConverter: LegacyFormatConverter | undefined = converter\n ? context => converter({ ...context, field: projectionField })\n : undefined;\n const alreadyProjected = projectV1ProductToV2(\n { ...projectionProduct, format_ids: [formatId] },\n { legacyFormatConverter: contextAwareConverter }\n );\n if (alreadyProjected.diagnostics.length === 0) continue;\n\n let resolverEligible = false;\n projectV1ProductToV2(\n { ...projectionProduct, format_ids: [formatId] },\n {\n legacyFormatConverter: () => {\n resolverEligible = true;\n return {\n format_option_id: '__legacy_resolver_probe__',\n format_kind: 'custom',\n format_shape: '__legacy_resolver_probe__',\n format_schema: {\n uri: 'https://adcontextprotocol.org/schemas/legacy-resolver-probe.json',\n digest: `sha256:${'0'.repeat(64)}`,\n },\n params: {},\n };\n },\n }\n );\n if (!resolverEligible) continue;\n\n const key = legacyFormatResolutionKey(projectionContext);\n const frozenFormatId = Object.freeze({ ...(formatId as V1FormatId) });\n pending.push(async signal => {\n try {\n const value = await invokeLegacyFormatResolver(\n resolver,\n {\n formatId: frozenFormatId,\n productId: resolverProductId,\n field: resolverField,\n operation: 'get_products',\n ...(requestContext.servedAdcpVersion !== undefined && {\n servedAdcpVersion: requestContext.servedAdcpVersion,\n }),\n ...(requestContext.accountId !== undefined && { accountId: requestContext.accountId }),\n },\n signal\n );\n resolutions.set(key, value);\n } catch (error) {\n resolutions.set(key, { resolutionError: error });\n }\n });\n }\n };\n\n for (const product of response.products) {\n if (!isProjectionProductInput(product)) continue;\n if (Array.isArray(product.format_ids)) {\n scanScope(product as V1Product, product.product_id, `products[${product.product_id}]`);\n }\n const placements = (product as unknown as Record<string, unknown>).placements;\n if (!Array.isArray(placements)) continue;\n for (let placementIndex = 0; placementIndex < placements.length; placementIndex++) {\n const placement = placements[placementIndex];\n if (!placement || typeof placement !== 'object' || Array.isArray(placement)) continue;\n const placementRecord = placement as Record<string, unknown>;\n if (Array.isArray(placementRecord.format_options) || !Array.isArray(placementRecord.format_ids)) continue;\n const placementId =\n typeof placementRecord.placement_id === 'string' ? placementRecord.placement_id : String(placementIndex);\n scanScope(\n {\n product_id: `${product.product_id}:placement:${placementId}`,\n name: typeof placementRecord.name === 'string' ? placementRecord.name : placementId,\n description: `Nested placement ${placementId}`,\n format_ids: placementRecord.format_ids as V1FormatId[],\n },\n product.product_id,\n `products[${product.product_id}].placements[${placementIndex}]`\n );\n }\n }\n const resolverSignal = createLegacyFormatResolverSignal(requestContext.signal, requestContext.timeoutMs);\n try {\n let nextJob = 0;\n const workerCount = Math.min(requestContext.concurrency, pending.length);\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (nextJob < pending.length) {\n const job = pending[nextJob++];\n if (job) await job(resolverSignal.signal);\n }\n })\n );\n } finally {\n resolverSignal.dispose();\n }\n if (resolutions.size === 0) return converter;\n\n return context => {\n const resolved = resolutions.get(legacyFormatResolutionKey(context));\n if (resolved !== undefined) {\n if (typeof resolved === 'object' && resolved !== null && 'resolutionError' in resolved) {\n throw resolved.resolutionError;\n }\n return resolved;\n }\n return converter?.(context);\n };\n}\n\nconst authoredFormatIdsByOwner = new WeakMap<object, readonly V1FormatId[]>();\nconst STORED_LEGACY_FORMAT_ROUTES = '__adcp_private_legacy_format_routes';\n\nfunction assertNoReservedLegacyRouteMetadata(value: unknown, path: string): void {\n const visited = new WeakSet<object>();\n const visit = (current: unknown, currentPath: string): void => {\n if (current === null || typeof current !== 'object' || visited.has(current)) return;\n visited.add(current);\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(current))) {\n if (!descriptor.enumerable || !('value' in descriptor)) continue;\n const childPath = Array.isArray(current) ? `${currentPath}[${key}]` : `${currentPath}.${key}`;\n if (key === STORED_LEGACY_FORMAT_ROUTES) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a field reserved for SDK-private route persistence.',\n field: childPath,\n });\n }\n visit(descriptor.value, childPath);\n }\n };\n visit(value, path);\n}\n\ninterface StoredLegacyFormatRoutes {\n formatIds?: readonly V1FormatId[];\n placements?: readonly (StoredLegacyFormatRoutes | null)[];\n}\n\nfunction captureStoredLegacyFormatRoutes(value: unknown): StoredLegacyFormatRoutes | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n const formatIds = authoredFormatIdsByOwner.get(record);\n const placements = Array.isArray(record.placements)\n ? record.placements.map(placement => captureStoredLegacyFormatRoutes(placement) ?? null)\n : undefined;\n if (!formatIds && !placements?.some(Boolean)) return undefined;\n return {\n ...(formatIds && { formatIds: formatIds.map(ref => cloneWireData(ref)) }),\n ...(placements?.some(Boolean) && { placements }),\n };\n}\n\nfunction restoreStoredLegacyFormatRoutes(value: unknown, routes: unknown): void {\n if (\n value === null ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n routes === null ||\n typeof routes !== 'object' ||\n Array.isArray(routes)\n ) {\n return;\n }\n const record = value as Record<string, unknown>;\n const routeRecord = routes as Record<string, unknown>;\n if (\n Array.isArray(routeRecord.formatIds) &&\n routeRecord.formatIds.length > 0 &&\n routeRecord.formatIds.every(ref => isValidStoredLegacyFormatRef(ref))\n ) {\n authoredFormatIdsByOwner.set(\n record,\n routeRecord.formatIds.map(ref => cloneWireData(ref as V1FormatId))\n );\n }\n if (Array.isArray(record.placements) && Array.isArray(routeRecord.placements)) {\n const count = Math.min(record.placements.length, routeRecord.placements.length);\n for (let index = 0; index < count; index++) {\n restoreStoredLegacyFormatRoutes(record.placements[index], routeRecord.placements[index]);\n }\n }\n}\n\nfunction isValidStoredLegacyFormatRef(value: unknown): value is V1FormatId {\n if (legacyFormatRefKey(value) === undefined) return false;\n const ref = value as Record<string, unknown>;\n if (ref.agent_url === '' || ref.id === '') return false;\n for (const field of ['width', 'height', 'duration_ms'] as const) {\n const fieldValue = ref[field];\n if (fieldValue !== undefined && (!Number.isInteger(fieldValue) || (fieldValue as number) <= 0)) return false;\n }\n return true;\n}\n\n/** Read exact SDK-private legacy routes restored on an auto-hydrated product or placement. */\nexport function getHydratedLegacyFormatIds(value: unknown): readonly V1FormatId[] | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const refs = authoredFormatIdsByOwner.get(value);\n return refs?.map(ref => cloneWireData(ref));\n}\n\ntype LegacyDropDiagnostic = Extract<ProjectionDiagnostic, { code: 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED' }>;\nconst resolvedLegacyDropDiagnosticsByResponse = new WeakMap<object, readonly LegacyDropDiagnostic[]>();\n\nfunction ownArrayDataValues(value: readonly unknown[]): unknown[] {\n const lengthDescriptor = Object.getOwnPropertyDescriptor(value, 'length');\n const length = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : 0;\n if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0) return [];\n const values: unknown[] = [];\n for (let index = 0; index < length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index));\n if (descriptor?.enumerable && 'value' in descriptor) values.push(descriptor.value);\n }\n return values;\n}\n\nfunction cloneWireData<T>(value: T): T {\n if (Array.isArray(value)) {\n const cloned: unknown[] = [];\n for (const entry of ownArrayDataValues(value)) cloned.push(cloneWireData(entry));\n return cloned as T;\n }\n if (value === null || typeof value !== 'object') return value;\n const cloned: Record<string, unknown> = {};\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {\n if (descriptor.enumerable && 'value' in descriptor) cloned[key] = cloneWireData(descriptor.value);\n }\n return cloned as T;\n}\n\nfunction preserveAuthoredFormatIds(source: unknown, target: unknown): void {\n if (source === null || target === null || typeof source !== 'object' || typeof target !== 'object') return;\n const sourceProducts = Object.getOwnPropertyDescriptor(source, 'products');\n const targetProducts = Object.getOwnPropertyDescriptor(target, 'products');\n if (\n !sourceProducts ||\n !sourceProducts.enumerable ||\n !('value' in sourceProducts) ||\n !Array.isArray(sourceProducts.value) ||\n !targetProducts ||\n !targetProducts.enumerable ||\n !('value' in targetProducts) ||\n !Array.isArray(targetProducts.value)\n ) {\n return;\n }\n const sourceValues = ownArrayDataValues(sourceProducts.value);\n const targetValues = ownArrayDataValues(targetProducts.value);\n const count = Math.min(sourceValues.length, targetValues.length);\n for (let index = 0; index < count; index++)\n preserveAuthoredFormatIdsForOwner(sourceValues[index], targetValues[index]);\n}\n\nfunction preserveAuthoredFormatIdsForOwner(source: unknown, target: unknown): void {\n if (source === null || target === null || typeof source !== 'object' || typeof target !== 'object') return;\n const sourceProductId = Object.getOwnPropertyDescriptor(source, 'product_id');\n const sourcePlacementId = Object.getOwnPropertyDescriptor(source, 'placement_id');\n const recognizedOwner =\n (sourceProductId?.enumerable && 'value' in sourceProductId && typeof sourceProductId.value === 'string') ||\n (sourcePlacementId?.enumerable && 'value' in sourcePlacementId && typeof sourcePlacementId.value === 'string');\n if (!recognizedOwner) return;\n const sourceFormatIds = Object.getOwnPropertyDescriptor(source, 'format_ids');\n const targetFormatOptions = Object.getOwnPropertyDescriptor(target, 'format_options');\n if (\n sourceFormatIds &&\n sourceFormatIds.enumerable &&\n 'value' in sourceFormatIds &&\n Array.isArray(sourceFormatIds.value) &&\n targetFormatOptions &&\n targetFormatOptions.enumerable &&\n 'value' in targetFormatOptions &&\n Array.isArray(targetFormatOptions.value)\n ) {\n authoredFormatIdsByOwner.set(\n target,\n ownArrayDataValues(sourceFormatIds.value).map(ref => cloneWireData(ref as V1FormatId))\n );\n }\n const sourcePlacements = Object.getOwnPropertyDescriptor(source, 'placements');\n const targetPlacements = Object.getOwnPropertyDescriptor(target, 'placements');\n if (\n sourcePlacements &&\n sourcePlacements.enumerable &&\n 'value' in sourcePlacements &&\n Array.isArray(sourcePlacements.value) &&\n targetPlacements &&\n targetPlacements.enumerable &&\n 'value' in targetPlacements &&\n Array.isArray(targetPlacements.value)\n ) {\n const sourceValues = ownArrayDataValues(sourcePlacements.value);\n const targetValues = ownArrayDataValues(targetPlacements.value);\n const count = Math.min(sourceValues.length, targetValues.length);\n for (let index = 0; index < count; index++) {\n preserveAuthoredFormatIdsForOwner(sourceValues[index], targetValues[index]);\n }\n }\n}\n\nfunction removeResolvedLegacyDropErrors<T>(response: T, diagnostics: readonly LegacyDropDiagnostic[]): T {\n if (response === null || typeof response !== 'object') return response;\n const resolved = diagnostics.filter(diagnostic => diagnostic.code === 'LEGACY_FORMAT_ID_DROPPED_UNMAPPED');\n if (resolved.length === 0) return response;\n const record = response as Record<string, unknown>;\n if (!Array.isArray(record.errors)) return response;\n const retained: unknown[] = [];\n for (const value of ownArrayDataValues(record.errors)) {\n let matchesResolvedDiagnostic = false;\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const error = value as Record<string, unknown>;\n for (const diagnostic of resolved) {\n if (\n error.code === diagnostic.code &&\n error.field === diagnostic.field &&\n error.source === diagnostic.source &&\n error.sdk_id === diagnostic.sdk_id &&\n jsonValuesEqual(error.details, diagnostic.error.details)\n ) {\n matchesResolvedDiagnostic = true;\n break;\n }\n }\n }\n if (!matchesResolvedDiagnostic) retained.push(value);\n }\n if (retained.length > 0) return { ...record, errors: retained } as T;\n const { errors: _resolvedErrors, ...withoutErrors } = record;\n void _resolvedErrors;\n return withoutErrors as T;\n}\n\nfunction legacyFormatRefKey(value: unknown): string | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const ref = value as Record<string, unknown>;\n if (typeof ref.agent_url !== 'string' || typeof ref.id !== 'string') return undefined;\n const agentUrl = canonicalizeAgentUrl(ref.agent_url) ?? ref.agent_url;\n return `${agentUrl}::${ref.id}::${String(ref.width ?? '')}x${String(ref.height ?? '')}::${String(ref.duration_ms ?? '')}`;\n}\n\nfunction jsonValuesEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) || Array.isArray(right)) {\n if (!Array.isArray(left) || !Array.isArray(right)) return false;\n const leftValues = ownArrayDataValues(left);\n const rightValues = ownArrayDataValues(right);\n if (leftValues.length !== rightValues.length) return false;\n for (let index = 0; index < leftValues.length; index++) {\n if (!jsonValuesEqual(leftValues[index], rightValues[index])) return false;\n }\n return true;\n }\n if (left === null || right === null || typeof left !== 'object' || typeof right !== 'object') return false;\n const leftRecord = left as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n const leftKeys = Object.keys(leftRecord);\n const rightKeys = Object.keys(rightRecord);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(key => Object.hasOwn(rightRecord, key) && jsonValuesEqual(leftRecord[key], rightRecord[key]))\n );\n}\n\ntype LegacyRefMatch = 'match' | 'kind_mismatch' | 'params_mismatch' | 'unresolved';\n\nfunction matchLegacyRefToDeclaration(\n declaration: Record<string, unknown>,\n ref: import('../../../v2/projection/types').V1FormatId,\n ownerId: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): LegacyRefMatch {\n const projected = projectV1ProductToV2(\n {\n product_id: ownerId,\n name: ownerId,\n description: ownerId,\n format_ids: [ref],\n },\n { legacyFormatConverter }\n );\n if (projected.diagnostics.length > 0 || projected.v2.format_options.length !== 1) return 'unresolved';\n const expected = projected.v2.format_options[0]!;\n if (declaration.format_kind !== expected.format_kind) return 'kind_mismatch';\n const params =\n declaration.params !== null && typeof declaration.params === 'object' && !Array.isArray(declaration.params)\n ? (declaration.params as Record<string, unknown>)\n : {};\n for (const [key, expectedValue] of Object.entries(expected.params)) {\n if (!Object.hasOwn(params, key) || !jsonValuesEqual(params[key], expectedValue)) return 'params_mismatch';\n }\n return 'match';\n}\n\nfunction validateLegacyRefNarrowing(\n declaration: Record<string, unknown>,\n ref: import('../../../v2/projection/types').V1FormatId,\n ownerId: string,\n field: string,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): void {\n const match = matchLegacyRefToDeclaration(declaration, ref, ownerId, legacyFormatConverter);\n if (match === 'kind_mismatch') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned divergent legacy and canonical format declarations.',\n field,\n suggestion: 'Make format_ids and format_options.v1_format_ref describe the same canonical format.',\n });\n }\n if (match === 'params_mismatch') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a canonical declaration that does not narrow its v1_format_ref.',\n field: `${field}.params`,\n suggestion: 'Align canonical format parameters with the referenced legacy format requirements.',\n });\n }\n}\n\nfunction validateDualProductFormatDeclarations(\n value: unknown,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): void {\n const seen = new WeakSet<object>();\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object' || seen.has(current)) return;\n seen.add(current);\n if (Array.isArray(current)) {\n const entries = ownArrayDataValues(current);\n for (let index = 0; index < entries.length; index++) visit(entries[index], `${path}[${index}]`);\n return;\n }\n const record = current as Record<string, unknown>;\n const formatOptions = Array.isArray(record.format_options) ? record.format_options : undefined;\n const ownerId =\n typeof record.product_id === 'string'\n ? record.product_id\n : typeof record.placement_id === 'string'\n ? record.placement_id\n : undefined;\n if (formatOptions && ownerId !== undefined) {\n const declarationRefs: import('../../../v2/projection/types').V1FormatId[] = [];\n const declarations = ownArrayDataValues(formatOptions);\n for (let index = 0; index < declarations.length; index++) {\n const value = declarations[index];\n if (value === null || typeof value !== 'object' || Array.isArray(value)) continue;\n const declaration = value as Record<string, unknown>;\n const refs = ownArrayDataValues(\n legacyFormatRefsForDeclaration(declaration)\n ) as import('../../../v2/projection/types').V1FormatId[];\n const field = `${path}.format_options[${index}]`;\n if (declaration.canonical_formats_only === true && refs.length > 0) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned canonical_formats_only together with v1_format_ref.',\n field,\n suggestion: 'Remove v1_format_ref or set canonical_formats_only to false.',\n });\n }\n declarationRefs.push(...refs);\n for (const ref of refs) {\n validateLegacyRefNarrowing(declaration, ref, ownerId, field, legacyFormatConverter);\n }\n }\n if (Array.isArray(record.format_ids)) {\n const formatIds = ownArrayDataValues(record.format_ids) as import('../../../v2/projection/types').V1FormatId[];\n const formatIdKeys = new Set<string>();\n for (const ref of formatIds) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined) formatIdKeys.add(key);\n }\n const declarationRefKeys = new Set<string>();\n for (const ref of declarationRefs) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined) declarationRefKeys.add(key);\n }\n let divergent = false;\n for (const key of declarationRefKeys) {\n if (!formatIdKeys.has(key)) divergent = true;\n }\n for (const ref of formatIds) {\n const key = legacyFormatRefKey(ref);\n if (key !== undefined && declarationRefKeys.has(key)) continue;\n let matched = false;\n for (const value of declarations) {\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n (value as Record<string, unknown>).canonical_formats_only !== true &&\n matchLegacyRefToDeclaration(value as Record<string, unknown>, ref, ownerId, legacyFormatConverter) ===\n 'match'\n ) {\n matched = true;\n break;\n }\n }\n if (!matched) divergent = true;\n }\n if (divergent) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned divergent format_ids and format_options.v1_format_ref values.',\n field: path,\n suggestion: 'Dual-emitted product declarations must carry the same legacy format references.',\n });\n }\n }\n }\n for (const [key, child] of Object.entries(record)) {\n if (key === 'format_options') continue;\n visit(child, `${path}.${key}`);\n }\n };\n visit(value, '$');\n}\n\n/**\n * Rehydrate legacy routing references only at the response wire boundary.\n * Custom declarations retain their explicit mapping on every canonical\n * release. AdCP 3.1 additionally dual-emits standard declaration refs and\n * their product-level `format_ids`; the canonical platform object itself\n * remains free of legacy identity through SDK-private WeakMap metadata.\n */\nfunction attachCanonicalFormatWireRefs<T>(\n value: T,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n operation: string,\n emitTransitionalLegacyRefs = false\n): T {\n const visit = (current: unknown): unknown => {\n if (Array.isArray(current)) {\n const mapped: unknown[] = [];\n for (const entry of ownArrayDataValues(current)) mapped.push(visit(entry));\n return mapped;\n }\n if (current === null || typeof current !== 'object') return current;\n const record = current as Record<string, unknown>;\n const hasFormatDeclarations = Array.isArray(record.format_options);\n const declarationOwner =\n typeof record.product_id === 'string'\n ? record.product_id\n : typeof record.placement_id === 'string'\n ? record.placement_id\n : '(response)';\n let projected = record;\n if (hasFormatDeclarations) {\n const wireLegacyRefs: V1FormatId[] = [];\n const wireLegacyRefKeys = new Set<string>();\n const appendWireLegacyRefs = (refs: readonly V1FormatId[]): void => {\n for (const ref of refs) {\n const key = legacyFormatRefKey(ref);\n if (key === undefined || wireLegacyRefKeys.has(key)) continue;\n wireLegacyRefKeys.add(key);\n wireLegacyRefs.push(cloneWireData(ref));\n }\n };\n if (emitTransitionalLegacyRefs) {\n const authoredRefs = authoredFormatIdsByOwner.get(record);\n if (authoredRefs) appendWireLegacyRefs(authoredRefs);\n }\n const formatOptions: unknown[] = [];\n const declarations = ownArrayDataValues(record.format_options as unknown[]);\n for (let index = 0; index < declarations.length; index++) {\n const value = declarations[index];\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n formatOptions.push(value);\n continue;\n }\n const declaration = value as Record<string, unknown>;\n if (declaration.canonical_formats_only === true) {\n formatOptions.push(declaration);\n continue;\n }\n let refs = ownArrayDataValues(\n legacyFormatRefsForDeclaration(declaration)\n ) as import('../../../v2/projection/types').V1FormatId[];\n if (emitTransitionalLegacyRefs && refs.length > 0) {\n const clonedRefs = refs.map(ref => cloneWireData(ref));\n appendWireLegacyRefs(clonedRefs);\n formatOptions.push({ ...declaration, v1_format_ref: clonedRefs });\n continue;\n }\n if (declaration.format_kind !== 'custom') {\n formatOptions.push(declaration);\n continue;\n }\n if (refs.length === 0) {\n try {\n const resolved = resolveCanonicalFormatLegacyRefs(canonicalFormatLegacyResolver, {\n source: 'product',\n declaration: declaration as unknown as import('../../../v2/projection/types').V2ProductFormatDeclaration,\n productId: declarationOwner,\n field: `${declarationOwner}.format_options[${index}]`,\n });\n refs = resolved\n ? (ownArrayDataValues(resolved) as import('../../../v2/projection/types').V1FormatId[])\n : [];\n } catch (error) {\n if (!(error instanceof CanonicalFormatLegacyResolutionError)) throw error;\n throw new CreativeFormatProjectionError(\n operation,\n `(format owner:${declarationOwner})`,\n 'canonical format legacy resolver returned an invalid custom declaration mapping'\n );\n }\n }\n if (refs.length === 0) {\n throw new CreativeFormatProjectionError(\n operation,\n `(format owner:${declarationOwner})`,\n 'custom canonical declaration must set canonical_formats_only or provide an explicit legacy mapping'\n );\n }\n const clonedRefs = refs.map(ref => cloneWireData(ref));\n if (emitTransitionalLegacyRefs) appendWireLegacyRefs(clonedRefs);\n formatOptions.push({ ...declaration, v1_format_ref: clonedRefs });\n }\n projected = {\n ...record,\n format_options: formatOptions,\n ...(emitTransitionalLegacyRefs && wireLegacyRefs.length > 0 && { format_ids: wireLegacyRefs }),\n };\n }\n let changed = projected !== record;\n const next: Record<string, unknown> = { ...projected };\n for (const [key, child] of Object.entries(projected)) {\n if (hasFormatDeclarations && key === 'format_options') continue;\n const visited = visit(child);\n if (visited !== child) {\n next[key] = visited;\n changed = true;\n }\n }\n return changed ? next : projected;\n };\n return visit(value) as T;\n}\n\nfunction asProductResponseForWire<T extends { products?: unknown[] }>(\n canonicalResponse: T,\n wireMode: 'canonical' | 'legacy',\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver,\n emitTransitionalLegacyRefs = false\n): T {\n if (wireMode === 'canonical') {\n const responseForWire =\n emitTransitionalLegacyRefs && canonicalResponse !== null && typeof canonicalResponse === 'object'\n ? removeResolvedLegacyDropErrors(\n canonicalResponse,\n resolvedLegacyDropDiagnosticsByResponse.get(canonicalResponse) ?? []\n )\n : canonicalResponse;\n return attachCanonicalFormatWireRefs(\n responseForWire,\n canonicalFormatLegacyResolver,\n 'get_products',\n emitTransitionalLegacyRefs\n );\n }\n if (!Array.isArray(canonicalResponse.products)) return canonicalResponse;\n const products = canonicalResponse.products.map(product => {\n const projected = projectV2ProductToV1(product as V2Product, { canonicalFormatLegacyResolver });\n if (projected.diagnostics.length > 0) {\n const first = projected.diagnostics[0]!;\n throw new AdcpError('INVALID_REQUEST', {\n message: 'get_products returned a canonical format that cannot be represented on the configured legacy wire.',\n field: first.field,\n suggestion:\n 'Add an explicit legacy format mapping to the canonical declaration, or configure this server for AdCP 3.1 or newer.',\n });\n }\n return projected.v1;\n });\n return { ...canonicalResponse, products } as T;\n}\n\n/**\n * Enforce the documented inline-`account_id` refusal for resolution modes\n * that declare the field meaningless on the wire — `'implicit'` (since\n * #1364) and `'derived'` (since adcp-client#1468). Both modes share the\n * same wire contract: the buyer does not pass `account_id` inline; the\n * framework derives the tenant from the authenticated principal (after a\n * `sync_accounts` step for `'implicit'`; directly for `'derived'`).\n *\n * Throws `AdcpError('INVALID_REQUEST')` before reaching the adopter's\n * `accounts.resolve`, so each adopter doesn't reimplement the same\n * `if (ref?.account_id) return null` branch and the wire response is\n * consistent across both modes. The brand+operator union arm is\n * permitted — only `account_id`-shaped references are refused.\n *\n * Mode-specific message and suggestion: `'implicit'` adopters get the\n * `sync_accounts`-first guidance; `'derived'` adopters get the single-\n * tenant explanation (no `sync_accounts` step exists in derived mode —\n * the auth principal alone identifies the tenant).\n *\n * Documented at `AccountStore.resolution` in `account.ts`.\n */\nfunction refuseInlineAccountIdWhenForbidden(\n resolution: 'explicit' | 'implicit' | 'derived' | undefined,\n ref: AccountReference | undefined\n): void {\n if (resolution !== 'implicit' && resolution !== 'derived') return;\n if (refAccountId(ref) === undefined) return;\n if (resolution === 'implicit') {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'This platform resolves accounts from the authenticated principal — call sync_accounts first; do not pass account.account_id inline.',\n field: 'account.account_id',\n suggestion:\n 'Call sync_accounts to associate accounts with your principal, then omit account_id on subsequent calls.',\n });\n }\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'This single-tenant agent identifies the tenant from the authenticated principal alone — do not pass account.account_id inline; the field is meaningless on the wire for derived-resolution agents.',\n field: 'account.account_id',\n suggestion: 'Omit the account field; the framework derives the tenant from your authenticated credential.',\n });\n}\n\n/**\n * Dev-mode warning when a multi-id read tool returns fewer rows than\n * the buyer requested — the canonical signal that the platform is\n * silently truncating to `<id_field>[0]` (closes #1342, follow-up\n * #1399, extended in #1410 to additional read-by-id surfaces). Catches\n * the bug class where adopters write the recommended pattern wrong on\n * first pass; quiet in production where legitimate misses (deleted,\n * archived, cross-account) are routine and warning on every miss would\n * be noise.\n *\n * Suppressible via `ADCP_SUPPRESS_MULTI_ID_WARN=1` for adopters whose\n * legitimate-miss rate is high (deleted-account-rich datasets, etc.).\n *\n * Sync / upsert surfaces (`syncCreatives`, `syncCatalogs`, `syncPlans`)\n * are intentionally out of scope — those have a different shape where\n * pass-through is the obvious pattern and \"did all rows roundtrip?\"\n * isn't a clean question.\n */\nfunction warnIfTruncatedMultiIdResponse(\n toolName: 'getMediaBuyDelivery' | 'getMediaBuys' | 'listCreatives' | 'getCreativeDelivery' | 'getSignals',\n idFieldName: 'media_buy_ids' | 'creative_ids' | 'signal_ids',\n requestedIds: readonly unknown[] | undefined,\n responseArray: readonly unknown[] | undefined,\n logger: AdcpLogger\n): void {\n if (process.env.NODE_ENV === 'production') return;\n if (process.env.ADCP_SUPPRESS_MULTI_ID_WARN === '1') return;\n if (!requestedIds || requestedIds.length === 0) return;\n const returned = Array.isArray(responseArray) ? responseArray.length : 0;\n if (returned >= requestedIds.length) return;\n // Empty `<id_field>` is filtered above as paginated-mode (no truncation\n // possible without a request to compare against).\n logger.warn(\n `[adcp/sdk] ${toolName}: platform returned ${returned} row${returned === 1 ? '' : 's'} for ${requestedIds.length} requested ${idFieldName} — ` +\n `the platform may be silently truncating to ${idFieldName}[0]. ` +\n `See https://github.com/adcontextprotocol/adcp-client/issues/1342 for the multi-id pass-through contract. ` +\n `Suppress with ADCP_SUPPRESS_MULTI_ID_WARN=1 if legitimate misses (deleted / cross-account) are routine.`\n );\n}\n\n/**\n * Lifecycle observability hooks the v6 runtime fires at well-known points.\n * Each callback is optional; throws are caught and logged via the framework\n * logger so adopter telemetry mistakes never break dispatch.\n *\n * Reach for these to wire DataDog / Prometheus / OpenTelemetry / structured\n * logging without baking any specific backend into the framework. For\n * OpenTelemetry, the `@adcp/sdk/telemetry/otel` peer-dep adapter returns\n * a pre-wired implementation with AdCP-aligned span / metric names.\n *\n * **What's instrumented today (v6.0):**\n * - Task lifecycle (`onTaskCreate`, `onTaskTransition`) — fires from `dispatchHitl`\n * - Webhook delivery (`onWebhookEmit`) — fires after each push-notification post\n * - Status-change events (`onStatusChangePublish`) — wraps the per-server bus\n * - Account resolution (`onAccountResolve`) — fires after every `resolve()` call\n *\n * **Coming in v6.1:**\n * - Per-tool dispatch latency (`onDispatchStart` / `onDispatchEnd`) —\n * requires wrapping every handler entry point; lands when the per-handler\n * instrumentation pass goes through.\n * - Idempotency replay rate (covered at the framework layer when v5 hooks land)\n * - State-store reads (per-handler instrumentation)\n *\n * @public\n */\nexport interface DecisioningObservabilityHooks {\n /**\n * Fired after `accounts.resolve` (or `resolveAccountFromAuth`) returns.\n * `resolved: false` means the resolver returned `null` — caller maps to\n * `ACCOUNT_NOT_FOUND`. `fromAuth: true` indicates the auth-derived path\n * (tools without an `account` field on the wire). `accountId` is the\n * resolved tenant id when `resolved: true`, undefined otherwise — useful\n * for dimensioning DD / Prometheus tag sets by tenant.\n *\n * **Cardinality warning:** if you forward `accountId` to a multi-tenant\n * metric backend, pre-bucket or sample — high tenant counts will\n * explode tag cardinality.\n */\n onAccountResolve?(info: {\n tool: string;\n durationMs: number;\n resolved: boolean;\n fromAuth: boolean;\n accountId?: string;\n }): void;\n\n /**\n * Fired when `dispatchHitl` allocates a new task in the registry.\n * `durationMs` is the registry-create call latency (typically\n * sub-millisecond for in-memory, single-digit ms for Postgres).\n */\n onTaskCreate?(info: { tool: string; taskId: string; accountId: string; durationMs: number }): void;\n\n /**\n * Fired when a task transitions to a terminal state (`completed`,\n * `failed`, or `failed-write` when the registry write itself fails).\n * `durationMs` is from create → terminal. `errorCode` is the structured\n * error code for the failure cases — pre-bucketed for metric tags\n * (matches `ErrorCode` enum + the framework-synthetic\n * `'REGISTRY_WRITE_FAILED'` value).\n */\n onTaskTransition?(info: {\n taskId: string;\n tool: string;\n accountId: string;\n status: 'completed' | 'failed';\n durationMs: number;\n errorCode?: string;\n }): void;\n\n /**\n * Fired after a push-notification webhook delivery attempt completes\n * (success or all retries exhausted). Adopters wire to per-buyer\n * deliverability dashboards.\n *\n * `errorCode` is a single bucketed value adopters tag metrics with\n * (`'TIMEOUT'`, `'CONNECTION_REFUSED'`, `'HTTP_4XX'`, `'HTTP_5XX'`,\n * `'SIGNATURE_FAILURE'`, `'UNKNOWN'` — derived from the underlying\n * emitter error). `errorMessages` is the raw free-text error list for\n * structured-log adopters; do NOT forward this to metrics tag values.\n */\n onWebhookEmit?(info: {\n taskId: string;\n tool: string;\n status: string;\n url: string;\n success: boolean;\n durationMs: number;\n errorCode?: string;\n errorMessages?: string[];\n }): void;\n\n /**\n * Fired after each `publishStatusChange(...)` event (per-server bus +\n * module-level singleton routes both go through the wrapped bus). Lets\n * adopters meter event rates per resource type without subscribing.\n */\n onStatusChangePublish?(info: { accountId: string; resourceType: string; resourceId: string }): void;\n}\n\nexport type LegacyDecisioningHandlerGroups = Pick<\n AdcpServerConfig,\n 'mediaBuy' | 'creative' | 'governance' | 'brandRights'\n>;\n\nexport interface CreateAdcpServerFromPlatformOptions extends Omit<\n AdcpServerConfig,\n 'resolveAccount' | 'capabilities' | 'name' | 'version' | 'mediaBuy' | 'creative' | 'governance' | 'brandRights'\n> {\n name: string;\n version: string;\n /**\n * Explicit compatibility seam for raw protocol handlers that have not yet\n * migrated to canonical DecisioningPlatform methods. Wire support remains\n * available through AdCP 3.x, but raw creative identity must never look like\n * a primary platform hook.\n */\n legacyHandlers?: LegacyDecisioningHandlerGroups;\n /**\n * Convert seller/creative-agent-specific legacy format refs before modern\n * platform handlers run. Known AAO formats are normalized automatically;\n * an unmapped ref is rejected unless this callback returns a canonical\n * declaration (normally `format_kind: 'custom'` + shape/schema).\n */\n legacyCreativeFormatConverter?: LegacyFormatConverter;\n /**\n * Resolve seller-specific legacy product formats asynchronously before the\n * canonical `get_products` projection. The resolver receives only the exact\n * format tuple plus non-secret request routing context and fails closed.\n */\n legacyCreativeFormatResolver?: LegacyFormatResolver;\n /** Shared resolver-phase deadline in milliseconds. Defaults to 10 seconds. */\n legacyCreativeFormatResolverTimeoutMs?: number;\n /** Maximum concurrent resolver calls within one get_products response (1–64). Defaults to 8. */\n legacyCreativeFormatResolverConcurrency?: number;\n /** Resolve persisted canonical custom formats when this server emits a legacy wire response. */\n canonicalFormatLegacyResolver?: CanonicalFormatLegacyResolver;\n /**\n * Override the framework's task registry. Useful for tests that want to\n * pre-seed task records or assert on them across multiple servers.\n * Defaults to a fresh `createInMemoryTaskRegistry()` per server instance\n * (gated by NODE_ENV — see `buildDefaultTaskRegistry`).\n */\n taskRegistry?: TaskRegistry;\n /**\n * Trusted tenant/deployment namespace for the `pool` task-registry shortcut.\n * Required when `pool` supplies the registry. Use the same value with the\n * migration helper so legacy rows remain reachable after upgrade.\n */\n taskRegistryNamespace?: string;\n /**\n * Override the framework's status-change event bus for this server.\n * Defaults to a fresh per-server `createInMemoryStatusChangeBus()` so\n * tests get isolation without touching the module-level singleton from\n * `publishStatusChange(...)`. Adopters who publish from non-handler code\n * (webhook handlers, crons) typically use the module-level primitive\n * — pass an explicit bus here only when you want a per-server channel.\n */\n statusChangeBus?: StatusChangeBus;\n\n /**\n * Lifecycle observability hooks. Adopters wire their telemetry backend\n * (DataDog, Prometheus, OpenTelemetry, structured logger, etc.) by\n * supplying any subset of the callbacks below. The framework calls them\n * at well-known dispatch points; throws inside callbacks are caught and\n * logged via `opts.logger.warn` — they never break dispatch.\n *\n * For an out-of-the-box OpenTelemetry binding, `@adcp/sdk/telemetry/otel`\n * (peer-dep, opt-in) returns a pre-wired `DecisioningObservabilityHooks`\n * object. Adopters using DataDog, Prometheus, or hand-rolled metrics\n * implement the callbacks directly.\n */\n observability?: DecisioningObservabilityHooks;\n\n /**\n * Merge-seam collision behavior. When an adopter-supplied custom handler\n * (e.g. `opts.legacyHandlers.mediaBuy.getMediaBuys`) collides with a platform-derived\n * handler (e.g. `platform.sales.getMediaBuys`), the platform-derived one\n * wins per-key and the adopter override is silently shadowed.\n *\n * Modes:\n * - `'warn'` (default) — log a warning at every construction that hits a\n * collision. Migration signal without breaking running deployments.\n * - `'log-once'` — log a warning the first time each `(domain, keys)`\n * collision is seen in the process; subsequent constructions with the\n * same shape stay silent. Right default for multi-tenant hosts (one\n * process, N `createAdcpServerFromPlatform` calls) and hot-reload dev\n * (server reconstructed every file change).\n * - `'strict'` — throw `PlatformConfigError`. Recommended for CI / new\n * deployments where the v6 surface is the canonical source.\n * - `'silent'` — skip the check. For adopters who deliberately use the\n * merge seam as an override (e.g., wrapping platform behavior with\n * logging in their custom handler).\n */\n mergeSeam?: MergeSeamMode;\n\n /**\n * Override the webhook emitter the framework uses to push HITL task\n * completion to the buyer's `push_notification_config.url`. Default: when\n * the host wired `webhooks` on the underlying `AdcpServerConfig`, use\n * `ctx.emitWebhook` from the per-request HandlerContext (the framework\n * binds `webhookEmitter.emit` to it). Pass an explicit emitter here when\n * you want a dedicated webhook delivery path for task completions\n * (different signing key, different retry policy, different fetch impl)\n * separate from your other webhook emissions, or to inject a fake for\n * tests without wiring full RFC 9421 signing.\n *\n * Custom emitters are restricted to test/development because they cannot\n * prove the AdCP 3.2 durable delivery binding, retry horizon, or retired-ID\n * tombstone contract. Production deployments MUST configure `webhooks` and\n * use the framework emitter exposed as `ctx.emitWebhook`.\n */\n taskWebhookEmitter?: {\n emit: NonNullable<HandlerContext<Account>['emitWebhook']>;\n /**\n * Set to `true` when this test/development emitter does NOT sign the\n * webhook payload (RFC 9421). This flag is descriptive only; custom task\n * emitters are rejected outside test/development regardless of signing.\n */\n unsigned?: boolean;\n };\n\n /**\n * `comply_test_controller` adapter set. When supplied, the framework\n * composes `createComplyController` (`@adcp/sdk/testing`) with the adopter's\n * adapters and registers the wire tool after platform handlers wire up. MCP\n * registration is framework-owned so principal visibility, `tools/list`\n * filtering, and direct-call method-not-found behavior can be enforced.\n *\n * Adopter declares the scenarios they support — `seed: { product, … }`,\n * `force: { creative_status, … }`, `simulate: { delivery, … }`. The\n * framework auto-derives `capabilities.compliance_testing.scenarios`\n * from which adapters are present, projecting the discovery field to\n * `get_adcp_capabilities` so conformance harnesses see what's\n * supported.\n *\n * **Deployment + sandbox gating.** Supplying `complyTest` wires the\n * controller for sandbox/conformance deployments. The framework then hides\n * the capability block, filters `tools/list`, and returns MCP method-not-\n * found for direct controller calls unless the auth-derived principal\n * resolves to `mode: 'sandbox' | 'mock'` (or legacy resolved\n * `sandbox: true`, or the legacy deployment bridge `ADCP_SANDBOX=1` is set).\n * Within a visible sandbox/mock deployment, target-account dispatch still\n * refuses live or unresolved non-sandbox accounts with `PERMISSION_DENIED`;\n * a buyer-supplied `account.sandbox: true` is only an unresolved-target\n * fallback and never overrides a resolved live account.\n *\n * **Capability-vs-adapter consistency.** Both directions are enforced:\n *\n * - `capabilities.compliance_testing` declared without `complyTest` →\n * `PlatformConfigError` at construction (and a **compile-time error**\n * when `P` is typed with `compliance_testing` non-optional, via\n * `RequiredOptsFor<P>`).\n * - `complyTest` supplied without `capabilities.compliance_testing` →\n * `PlatformConfigError` at construction (runtime defense-in-depth).\n *\n * To enforce the invariant at compile time when building the platform\n * as an object literal, wrap it with `definePlatformWithCompliance`:\n * TypeScript will then require `compliance_testing` on the platform\n * and `complyTest` on opts together.\n *\n * @public\n */\n complyTest?: ComplyControllerConfig;\n\n /**\n * Single-pool shortcut: pass a `pg.Pool` (or any `PgQueryable`) and the\n * framework wires `idempotency` + `ctxMetadata` + `taskRegistry`\n * internally with sensible defaults. One connection, three concerns.\n *\n * Adopters who pass any of `idempotency` / `ctxMetadata` / `taskRegistry`\n * explicitly keep override priority — the explicit values win, and the\n * pool fills only the unset ones.\n *\n * Run `getAllAdcpMigrations({ taskRegistryNamespace })` once per database to create the three\n * required tables (idempotency cache, ctx-metadata cache, task registry).\n *\n * @example\n * ```ts\n * import { Pool } from 'pg';\n * import {\n * createAdcpServerFromPlatform,\n * getAllAdcpMigrations,\n * } from '@adcp/sdk/server';\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const taskRegistryNamespace = 'tenant:my-agent';\n * await pool.query(getAllAdcpMigrations({ taskRegistryNamespace }));\n *\n * const server = createAdcpServerFromPlatform(myPlatform, {\n * name: 'my-agent',\n * version: '1.0.0',\n * pool, // wires all three persistence stores\n * taskRegistryNamespace,\n * });\n * ```\n *\n * **Memory-only deployment:** omit `pool` entirely. Framework defaults to\n * in-memory backends for all three (fine for dev / single-process; not\n * suitable for cluster).\n */\n pool?: PgQueryable;\n\n /**\n * Ctx-metadata store. Wire to enable the v6.1 `ctx_metadata` round-trip\n * cache: publishers attach opaque platform-specific blobs to any returned\n * resource (`{ product_id, ctx_metadata: { gam: {...} } }`); the framework\n * persists by `(account.id, kind, id)` and threads back into\n * `ctx.ctxMetadata` on subsequent calls referencing the same ID.\n *\n * Memory backend (`memoryCtxMetadataStore()`) for dev / single-process.\n * Postgres (`pgCtxMetadataStore(pool)`) for cluster — silent ctx_metadata\n * loss after rolling restart on memory backend produces \"package not\n * found\" errors that look like publisher bugs and run for weeks.\n *\n * @example\n * ```ts\n * import { Pool } from 'pg';\n * import {\n * createAdcpServerFromPlatform,\n * createCtxMetadataStore,\n * pgCtxMetadataStore,\n * getCtxMetadataMigration,\n * } from '@adcp/sdk/server';\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * await pool.query(getCtxMetadataMigration());\n *\n * const ctxMetadata = createCtxMetadataStore({ backend: pgCtxMetadataStore(pool) });\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * name: 'My Adapter',\n * version: '1.0.0',\n * ctxMetadata,\n * });\n * ```\n *\n * @see docs/proposals/decisioning-platform-v6-1-ctx-metadata.md\n */\n ctxMetadata?: CtxMetadataStore;\n\n /**\n * Opinionated media-buy store that satisfies the seller spec contract for\n * `targeting_overlay` echo: persist `packages[].targeting_overlay` from\n * `create_media_buy`, echo it on `get_media_buys`, deep-merge across\n * `update_media_buy` without dropping prior `property_list` /\n * `collection_list` references.\n *\n * Wire to honor the\n * `schemas/cache/<v>/media-buy/get-media-buys-response.json` contract\n * without each adapter persisting + merging by hand. Sellers claiming\n * `property-lists` / `collection-lists` MUST echo the persisted refs;\n * `mediaBuyStore` is the framework-side way to do it.\n *\n * Backed by any `AdcpStateStore` — `InMemoryStateStore` for dev,\n * `PostgresStateStore` for production. Failures are logged and swallowed\n * (auto-echo MUST NOT break a successful seller response).\n *\n * @example\n * ```ts\n * import {\n * createAdcpServerFromPlatform,\n * createMediaBuyStore,\n * InMemoryStateStore,\n * } from '@adcp/sdk/server';\n *\n * const stateStore = new InMemoryStateStore();\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * mediaBuyStore: createMediaBuyStore({ store: stateStore }),\n * });\n * ```\n */\n mediaBuyStore?: MediaBuyStore;\n\n /**\n * Proposal lifecycle ledger — wires the v1.5 ProposalManager dispatch\n * seams. When supplied alongside `platform.proposalManager`, the\n * framework drives the full lifecycle:\n *\n * - `getProducts` / refine responses persist `proposals[]` as DRAFT\n * records (with typed recipes pulled from\n * `Product.implementation_config`).\n * - `refine[i].action: 'finalize'` entries are intercepted before\n * dispatch; the manager's `finalizeProposal` is called and the\n * proposal is committed via the store.\n * - `createMediaBuy` requests carrying `proposal_id` are validated\n * against expiry + capability overlap, the proposal is reserved\n * (atomic CAS `COMMITTED → CONSUMING`), and `ctx.recipes` is\n * hydrated from the record. Adapter success → `CONSUMING →\n * CONSUMED`; adapter throw → rollback to `COMMITTED`.\n * - `updateMediaBuy` / `getMediaBuyDelivery` hydrate `ctx.recipes`\n * via the reverse-index `getByMediaBuyId`.\n *\n * Backed by any {@link ProposalStore} — `InMemoryProposalStore` for\n * dev / single-process; adopters wire their own durable backings for\n * production. Without this option (and/or without\n * `platform.proposalManager`), the v1 path runs unchanged.\n */\n proposalStore?: import('../proposal').ProposalStore;\n\n /**\n * Allow `push_notification_config.url` to point at loopback / private-IP\n * destinations. Default is `false` — the framework's request-ingest\n * validator rejects loopback (`localhost`, `127.0.0.0/8`, `::1`),\n * RFC 1918 / CGNAT / link-local ranges, and IPv4-mapped IPv6 forms\n * targeting any of those, since accepting them at production webhook\n * endpoints is a SSRF / cloud-metadata exfiltration path.\n *\n * Set `true` for sandbox / local-testing deployments where\n * adopter-controlled receivers (storyboard webhook receivers, pytest\n * httptest fixtures) bind to `127.0.0.1:<ephemeral>`. The flag bypasses\n * ONLY the private-range branch — malformed-URL, non-http(s) scheme,\n * and the `http://` reject (separately gated by NODE_ENV / the\n * `ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS` env) all still fire.\n *\n * Adopters typically scope this themselves on `NODE_ENV !== 'production'`\n * or a sandbox env flag — the framework doesn't auto-enable it because\n * the safe default is \"reject private destinations.\" When the flag is\n * `true` AND `NODE_ENV` is unset / `'production'`, the framework emits\n * a one-shot console.warn at construction calling out the relaxation.\n */\n allowPrivateWebhookUrls?: boolean;\n\n /**\n * When `true`, throw `PlatformConfigError` at construction if any\n * specialism declared in `capabilities.specialisms[]` is missing a\n * platform method matching one of its required tools (per the manifest's\n * `SPECIALISM_REQUIRED_TOOLS`). Default `false` — the framework emits a\n * `console.warn` for each missing method instead, so adopters mid-\n * implementation aren't blocked on incomplete specialism coverage.\n *\n * Recommended for production CI builds: catches \"claimed sales-non-\n * guaranteed but forgot to implement getProducts\" before the deploy.\n * Recommended off in dev / sandbox where adopters are iterating.\n *\n * Tracked: adcp-client#1299 (manifest adoption stage 3).\n */\n strictSpecialismValidation?: boolean;\n\n /**\n * @deprecated Ignored under AdCP 3.2. Synchronous terminal responses MUST\n * remain silent on the task-webhook channel; only an async task lifecycle\n * may publish later status observations.\n */\n autoEmitCompletionWebhooks?: boolean;\n\n // ---------------------------------------------------------------------\n // Custom-handler escape hatch (incremental migration seam)\n // ---------------------------------------------------------------------\n //\n // The inherited `mediaBuy` / `creative` / `accounts` / `eventTracking` /\n // `signals` / `governance` / `brandRights` / `sponsoredIntelligence`\n // / `testController` keys (from `AdcpServerConfig`) accept raw\n // handler-style entries for tools the v6 platform doesn't yet model.\n //\n // **Merge semantics**: platform-derived handlers WIN per-key. Adopter-\n // supplied handlers fill gaps for un-wired tools (`getMediaBuys`,\n // `listCreativeFormats`, `providePerformanceFeedback`, `reportUsage`,\n // `syncEventSources`, `logEvent`, `getAccountFinancials`, content-\n // standards CRUD, etc.).\n //\n // Lets adopters with established handler-style adapters migrate\n // incrementally — move sales / audiences / signals to the v6 platform\n // shape today, keep custom handlers wired for tools whose specialism\n // interfaces are deferred to v1.1+ / rc.1 (event-tracking, catalog,\n // financials, content-standards, creative-review, brand-rights).\n //\n // createAdcpServerFromPlatform(platform, {\n // name: 'Adapter', version: '1.0.0',\n // legacyHandlers: { mediaBuy: {\n // // platform.sales already wires get_products / create / update /\n // // sync_creatives / get_media_buy_delivery; fill the rest:\n // getMediaBuys: async (params, ctx) => myDb.queryBuys(params),\n // providePerformanceFeedback: async (params, ctx) => ack(params),\n // } },\n // eventTracking: {\n // // platform.audiences wires sync_audiences; fill the trio:\n // syncEventSources: async (params, ctx) => ...,\n // logEvent: async (params, ctx) => ...,\n // syncCatalogs: async (params, ctx) => ...,\n // },\n // });\n}\n\n/**\n * Derives the opts type for `createAdcpServerFromPlatform` based on whether\n * the platform declares `capabilities.compliance_testing`.\n *\n * When `P` carries a non-optional `compliance_testing` block (e.g. because\n * the caller used `definePlatformWithCompliance`), this resolves to\n * `CreateAdcpServerFromPlatformOptions & { complyTest: ComplyControllerConfig }`,\n * making `complyTest` required. For all other platform shapes the resolved\n * type is the plain `CreateAdcpServerFromPlatformOptions` — no change.\n *\n * Both directions of the mismatch are still caught at runtime by the\n * `PlatformConfigError` check in `createAdcpServerFromPlatform` as\n * defense-in-depth for untyped callers.\n *\n * @public\n */\nexport type RequiredOptsFor<P extends DecisioningPlatform<any, any>> = P extends {\n capabilities: { compliance_testing: ComplianceTestingCapabilities };\n}\n ? CreateAdcpServerFromPlatformOptions & { complyTest: ComplyControllerConfig }\n : CreateAdcpServerFromPlatformOptions;\n\n/**\n * Adcp server returned by `createAdcpServerFromPlatform`. Adds task-state\n * accessors on top of the standard `AdcpServer` so test harnesses (and the\n * forthcoming `tasks/get` wire handler) can inspect lifecycle.\n */\nexport interface DecisioningAdcpServer extends AdcpServer {\n /**\n * Read the current lifecycle state for a HITL task. Returns `null` if the\n * `taskId` is unknown or the account/principal scope does not match.\n *\n * Async to accommodate storage-backed task registries\n * (`createPostgresTaskRegistry`); the in-memory impl resolves synchronously.\n */\n getTaskState<TResult = unknown>(taskId: string, scope: TaskRegistryScope): Promise<TaskRecord<TResult> | null>;\n /** Administrative/test access; null when task_id is ambiguous across scopes. Never expose to buyer traffic. */\n getTaskStateUnsafe<TResult = unknown>(taskId: string): Promise<TaskRecord<TResult> | null>;\n /**\n * Await any in-flight background completion for `taskId` (HITL handoff\n * function still running). Resolves immediately if the task is terminal\n * or has no registered background. Used by tests + the `tasks/get` wire\n * path for deterministic settlement.\n */\n awaitTask(taskId: string, scope: TaskRegistryScope): Promise<void>;\n /** Administrative/test wait across all scopes with this task_id. Never expose to buyer traffic. */\n awaitTaskUnsafe(taskId: string): Promise<void>;\n /**\n * Per-server status-change bus. Delegates to the same internal bus the\n * framework uses for MCP Resources subscription projection.\n *\n * Use `server.statusChange.publish(...)` in tests to push events scoped\n * to this specific server instance — avoids contaminating sibling servers\n * that share the module-level `activeBus` when running multiple servers\n * in the same process. Production webhook/cron code that does not hold a\n * server reference keeps calling the module-level `publishStatusChange(...)`.\n *\n * **Projection wiring contract** (rc.1): when the MCP Resources subscription\n * projection commit lands, the projector MUST fan-in from BOTH this\n * per-server bus AND the module-level `activeBus`. Anchoring the subscriber\n * to only one source silently makes the other call site inert in production\n * — adopters who scope to `server.statusChange.publish(...)` for tenant\n * isolation must still reach buyer-facing subscriptions, and webhook/cron\n * code calling module-level `publishStatusChange(...)` must too.\n */\n statusChange: StatusChangeBus;\n}\n\n// Use `DecisioningPlatform<any, any>` for the generic constraint. The default\n// `TCtxMeta = Record<string, unknown>` doesn't accept adopter metadata interfaces\n// without an index signature (e.g., `interface MyMeta { brand_id: string }`),\n// which is a needless friction point — adopter metadata is opaque to the\n// framework, so we don't need to constrain it here.\nexport function createAdcpServerFromPlatform<P extends DecisioningPlatform<any, any>>(\n platform: P &\n RequiredPlatformsFor<P['capabilities']['specialisms'][number]> &\n RequiredCapabilitiesFor<P['capabilities']['specialisms'][number]>,\n opts: RequiredOptsFor<P>\n): DecisioningAdcpServer {\n // Runtime-only compatibility for pre-13 JavaScript/config objects. The\n // public type exposes these raw handler groups only under legacyHandlers;\n // retaining the hidden fallback avoids turning a type migration into an\n // abrupt wire-support break for untyped deployments.\n const runtimeLegacyOptions = opts as typeof opts & Partial<LegacyDecisioningHandlerGroups>;\n const legacyHandlers: LegacyDecisioningHandlerGroups = {\n mediaBuy: opts.legacyHandlers?.mediaBuy ?? runtimeLegacyOptions.mediaBuy,\n creative: opts.legacyHandlers?.creative ?? runtimeLegacyOptions.creative,\n governance: opts.legacyHandlers?.governance ?? runtimeLegacyOptions.governance,\n brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights,\n };\n validatePlatform(platform, {\n creative: legacyHandlers.creative,\n campaignGovernance: legacyHandlers.governance,\n brandRights: legacyHandlers.brandRights,\n });\n\n // Specialism→required-tools coverage check (adcp-client#1299).\n //\n // For each specialism declared in `capabilities.specialisms[]`, verify the\n // platform exposes a method matching every tool the manifest's\n // `SPECIALISM_REQUIRED_TOOLS` lists for that specialism. Catches the\n // common adopter mistake of declaring `'sales-non-guaranteed'` while\n // forgetting to implement `getProducts` / `createMediaBuy` / etc. —\n // would otherwise surface as a runtime error when a buyer actually\n // calls the missing tool.\n //\n // Default behavior is console.warn — strictSpecialismValidation: true\n // escalates to a thrown `PlatformConfigError`. The check is method-\n // presence-anywhere on the platform (not method-on-specific-field) so\n // adopters with non-standard layouts (e.g., a single mega-platform vs.\n // the conventional sales/creative/accounts split) aren't false-positively\n // flagged.\n {\n const specialisms = (platform.capabilities as { specialisms?: readonly string[] }).specialisms;\n const effectiveSpecialismSurface = {\n ...platform,\n mediaBuy: legacyHandlers.mediaBuy,\n creative: platform.creative ?? legacyHandlers.creative,\n governance: legacyHandlers.governance,\n brandRights: platform.brandRights ?? legacyHandlers.brandRights,\n };\n const issues = validateSpecialismRequiredTools(effectiveSpecialismSurface, specialisms);\n if (issues.length > 0) {\n const messages = issues.map(formatSpecialismIssue);\n if (opts.strictSpecialismValidation === true) {\n throw new PlatformConfigError(\n `Platform missing methods for ${issues.length} specialism-required tool(s). ` +\n `Strict mode (\\`strictSpecialismValidation: true\\`) treats this as fatal.\\n` +\n messages.map(m => ` - ${m}`).join('\\n')\n );\n }\n // eslint-disable-next-line no-console\n for (const message of messages) console.warn(message);\n }\n }\n\n // Compliance-testing capability/adapter consistency.\n //\n // Two failure modes the framework refuses to ship:\n // 1. Capability declared, no adapter — discovery field projects to\n // `get_adcp_capabilities` but the wire tool has no implementation\n // behind it. Conformance harnesses would dispatch and crash.\n // 2. Adapter wired, capability not declared — discovery field is\n // missing from `get_adcp_capabilities` so buyers / harnesses can't\n // tell the agent supports compliance testing.\n //\n // Both throw at construction with `PlatformConfigError`. Adopters who\n // want one without the other are doing it wrong; the right escape hatch\n // is to set `compliance_testing.scenarios = []` (a noop block, but the\n // spec disallows empty `scenarios` so this should never come up in\n // practice — included only to make the constraint explicit).\n const capHasComplianceTesting = platform.capabilities.compliance_testing != null;\n const optsHasComplyTest = opts.complyTest != null;\n if (capHasComplianceTesting && !optsHasComplyTest) {\n throw new PlatformConfigError(\n `capabilities.compliance_testing is declared but opts.complyTest is missing. ` +\n `Either supply complyTest (the ComplyControllerConfig adapter set) or remove ` +\n `the compliance_testing capability block — the framework refuses to advertise ` +\n `comply_test_controller without an implementation.`\n );\n }\n if (optsHasComplyTest && !capHasComplianceTesting) {\n throw new PlatformConfigError(\n `opts.complyTest is supplied but capabilities.compliance_testing is not declared. ` +\n `Add 'compliance_testing: {}' to your platform.capabilities — the framework needs ` +\n `the discovery block to project comply_test_controller scenarios on get_adcp_capabilities. ` +\n `Scenarios auto-derive from your supplied adapters; explicit 'scenarios: [...]' is optional.`\n );\n }\n\n // Footgun guard for `allowPrivateWebhookUrls` — same DEV_ALLOWLIST\n // inversion pattern as other production guards. Adopters\n // intentionally relaxing the SSRF gate for sandbox testing aren't\n // doing anything wrong; production deployments that flip this on\n // accidentally are. Warn on construction when the flag is true AND\n // NODE_ENV is unset / 'staging' / 'prod' / 'live' AND no explicit\n // ack env. Keeps the relaxation usable for real local-test setups\n // without letting it sneak into production.\n if (opts.allowPrivateWebhookUrls === true) {\n const env = process.env.NODE_ENV;\n const isDevOrTest = env === 'test' || env === 'development';\n const ack = process.env.ADCP_DECISIONING_ALLOW_PRIVATE_WEBHOOK_URLS === '1';\n if (!isDevOrTest && !ack) {\n // eslint-disable-next-line no-console\n console.warn(\n '[adcp/decisioning] allowPrivateWebhookUrls: true relaxes the loopback / private-IP ' +\n 'guard on push_notification_config.url. NODE_ENV is not test/development and ' +\n 'ADCP_DECISIONING_ALLOW_PRIVATE_WEBHOOK_URLS is not set — accepting private ' +\n 'destinations in production is a SSRF / cloud-metadata exfiltration path. ' +\n 'For sandbox/local testing, scope this on your own NODE_ENV check.'\n );\n }\n }\n\n if (opts.taskWebhookEmitter && process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'development') {\n throw new PlatformConfigError(\n 'taskWebhookEmitter is test/development-only under AdCP 3.2. Production task webhooks must use the ' +\n 'framework webhooks configuration so durable delivery binding, retry-horizon advertisement, signing, ' +\n 'and retired delivery-ID tombstones are enforced.'\n );\n }\n\n // Pool shortcut: when `opts.pool` is wired and a specific store/registry\n // is NOT explicitly set, derive that store from pool with sensible\n // defaults. Explicit per-store opts always win — this is \"fill the gaps,\"\n // not \"override what the adopter passed.\"\n const pooledIdempotency: IdempotencyStore | undefined =\n opts.pool && opts.idempotency === undefined ? createIdempotencyStore({ backend: pgBackend(opts.pool) }) : undefined;\n const pooledCtxMetadata: CtxMetadataStore | undefined =\n opts.pool && opts.ctxMetadata === undefined\n ? createCtxMetadataStore({ backend: pgCtxMetadataStore(opts.pool) })\n : undefined;\n if (opts.pool && opts.taskRegistry === undefined && opts.taskRegistryNamespace === undefined) {\n throw new PlatformConfigError(\n 'taskRegistryNamespace is required when opts.pool supplies the task registry. ' +\n 'Use the same trusted namespace with getAllAdcpMigrations({ taskRegistryNamespace }) or ' +\n 'getDecisioningTaskRegistryMigration({ namespace }).'\n );\n }\n const pooledTaskRegistry: TaskRegistry | undefined =\n opts.pool && opts.taskRegistry === undefined\n ? createPostgresTaskRegistry({ pool: opts.pool, namespace: opts.taskRegistryNamespace! })\n : undefined;\n\n // Effective resolved values. Explicit > pooled > default.\n const effectiveIdempotency: IdempotencyStore | 'disabled' | undefined = opts.idempotency ?? pooledIdempotency;\n const effectiveCtxMetadata: CtxMetadataStore | undefined = opts.ctxMetadata ?? pooledCtxMetadata;\n const taskRegistry = opts.taskRegistry ?? pooledTaskRegistry ?? buildDefaultTaskRegistry();\n if (taskRegistry.scopeVersion !== 1) {\n throw new PlatformConfigError(\n 'taskRegistry.scopeVersion must be 1. Migrate custom registries to the account/principal-scoped TaskRegistry signatures before use.'\n );\n }\n const baseBus = opts.statusChangeBus ?? createInMemoryStatusChangeBus();\n const taskWebhookEmit = opts.taskWebhookEmitter?.emit;\n\n // Wrap the status-change bus so every publish fires onStatusChangePublish.\n // Subscribers / recent-buffer behavior pass through unchanged — the wrap\n // is only for the publish side. Hook-throw is caught + logged so adopter\n // telemetry mistakes don't break event delivery.\n const observability = opts.observability;\n const statusChangeBus: StatusChangeBus = observability?.onStatusChangePublish\n ? wrapBusWithObservability(baseBus, observability)\n : baseBus;\n const fwLogger = opts.logger ?? DEFAULT_FRAMEWORK_LOGGER;\n const mergeOpts = { mode: opts.mergeSeam ?? 'warn', logger: fwLogger };\n\n // Project per-domain capability blocks declared on the platform onto\n // get_adcp_capabilities via createAdcpServer's `overrides.media_buy`\n // deep-merge seam. Adopters declare audience_targeting /\n // conversion_tracking / content_standards / supported_optimization_metrics\n // / frequency_capping on `platform.capabilities`; the framework wires\n // the deep-merge so buyers see the discovery fields without an opaque\n // custom get_adcp_capabilities tool (which the framework refuses anyway).\n //\n // Each rich block also forces the corresponding `media_buy.features.*`\n // boolean to `true`. Buyers gating on `features.audience_targeting`\n // (which the framework auto-derives as `false` by default) would\n // otherwise skip the rich block sitting next to it.\n //\n // `supported_optimization_metrics` (adcp#4669) and `frequency_capping`\n // (adcp#4670) are AdCP 3.1 additions. They have no corresponding\n // `features.*` boolean — buyers gate on presence of the block itself.\n const at = platform.capabilities.audience_targeting;\n const ct = platform.capabilities.conversion_tracking;\n const cs = platform.capabilities.content_standards;\n const explicitSom = platform.capabilities.supported_optimization_metrics;\n const derivedSom =\n explicitSom == null && platform.capabilities.productCatalog != null\n ? rollupOptimizationMetricsFromProducts(platform.capabilities.productCatalog)\n : undefined;\n const somCandidate = explicitSom ?? derivedSom;\n // Empty arrays are an explicit \"no seller-level rollup to advertise\" signal,\n // not a malformed capability. Omit the wire field so buyers do not see an\n // empty support list as a positive 3.1 metric-optimization declaration.\n const som = somCandidate != null && somCandidate.length > 0 ? somCandidate : undefined;\n const fc = platform.capabilities.frequency_capping;\n const targeting = platform.capabilities.targeting\n ? normalizeTargetingCapabilities(platform.capabilities.targeting)\n : undefined;\n const hasSalesPlatform =\n platform.sales != null || platform.mediaBuyLifecycle != null || platform.proposalManager != null;\n const supportsProposals =\n platform.capabilities.supportsProposals ??\n (platform.proposalManager != null ||\n platform.mediaBuyLifecycle?.requestProposals != null ||\n platform.mediaBuyLifecycle?.refineProposals != null\n ? true\n : hasSalesPlatform\n ? false\n : undefined);\n const hasMediaBuyProjection =\n hasSalesPlatform ||\n at != null ||\n ct != null ||\n cs != null ||\n som != null ||\n fc != null ||\n targeting != null ||\n supportsProposals !== undefined;\n // App `version` / capability `build_version` are deployment metadata and\n // never negotiate protocol behavior. Only the configured AdCP schema pin\n // determines whether this server may advertise the 3.1 feature bit (3.2+\n // makes canonical creatives part of the release contract itself).\n const configuredAdcpVersion = opts.adcpVersion ?? ADCP_VERSION;\n const configuredRelease = parseAdcpRelease(configuredAdcpVersion);\n if (!configuredRelease) {\n throw new PlatformConfigError(\n `Configured AdCP version '${configuredAdcpVersion}' is not a valid release identifier`\n );\n }\n for (const advertisedVersion of platform.capabilities.supported_versions ?? []) {\n const advertisedRelease = parseAdcpRelease(advertisedVersion);\n if (!advertisedRelease) {\n throw new PlatformConfigError(\n `capabilities.supported_versions contains invalid release identifier '${advertisedVersion}'`\n );\n }\n if (compareAdcpReleases(advertisedRelease, configuredRelease) > 0) {\n throw new PlatformConfigError(\n `capabilities.supported_versions advertises AdCP ${advertisedVersion}, newer than the configured server schema ${configuredAdcpVersion}`\n );\n }\n }\n const canonicalCreativeCapability = supportsCanonicalCreativeCapability(configuredAdcpVersion);\n // createAdcpServerFromPlatform is the modern, canonical SDK boundary and\n // advertises canonicalCreatives for every capable release. In transitional\n // 3.1, concrete legacy request fields still select the legacy projection;\n // an otherwise ambiguous read follows the capability the server advertises.\n const defaultCreativeWireMode = canonicalCreativeCapability ? 'canonical' : 'legacy';\n const mediaBuyOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['media_buy']>> = {\n ...(hasSalesPlatform && {\n buying_modes: supportsProposals ? (['brief', 'refine'] as const) : (['brief'] as const),\n }),\n ...(at != null && { audience_targeting: at }),\n ...(ct != null && { conversion_tracking: ct }),\n ...(cs != null && { content_standards: cs }),\n ...(som != null && { supported_optimization_metrics: som }),\n ...(fc != null && { frequency_capping: fc }),\n ...(targeting != null && { execution: { targeting } }),\n ...(supportsProposals !== undefined && { supports_proposals: supportsProposals }),\n features: {\n ...(canonicalCreativeCapability && { canonical_creatives: true }),\n ...(at != null && { audience_targeting: true }),\n ...(ct != null && { conversion_tracking: true }),\n ...(cs != null && { content_standards: true }),\n },\n };\n\n if (process.env.NODE_ENV !== 'production') {\n if (explicitSom != null && explicitSom.length > 0) {\n fwLogger.info(\n `[adcp/decisioning] using explicit media_buy.supported_optimization_metrics override (${explicitSom.length} metric${explicitSom.length === 1 ? '' : 's'}).`\n );\n } else if (derivedSom != null) {\n fwLogger.info(\n `[adcp/decisioning] derived media_buy.supported_optimization_metrics from productCatalog (${derivedSom.length} metric${derivedSom.length === 1 ? '' : 's'}).`\n );\n }\n }\n\n // Brand-protocol capability projection. Adopters who declare\n // `capabilities.brand` get the block projected via `overrides.brand`.\n // When `BrandRightsPlatform` is supplied, `rights: true` is auto-\n // derived (the framework knows the wire tools are available); adopter-\n // declared `right_types` / `available_uses` / `generation_providers` /\n // `description` ride the deep-merge.\n const adopterBrand = platform.capabilities.brand;\n const hasBrandRightsImpl = platform.brandRights != null;\n const hasBrandProjection = adopterBrand != null || hasBrandRightsImpl;\n const brandOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['brand']>> = {\n ...(hasBrandRightsImpl && { rights: true }),\n ...adopterBrand,\n };\n\n // Account-mode capability projection. Two redundant adopter signals\n // resolve into the same wire bit:\n // - `capabilities.requireOperatorAuth: true` — explicit override\n // - `accounts.resolution: 'explicit'` — derived from the account-store\n // model (operators authenticate independently with the seller; the\n // buyer discovers accounts via `list_accounts`, NOT `sync_accounts`).\n // Either, taken alone, projects to `account.require_operator_auth: true`.\n // The conformance storyboard runner reads this bit at step time and\n // grades `sync_accounts` steps as `'not_applicable'` (rather than the\n // misleading `'missing_tool'`) for explicit-mode adopters who correctly\n // don't implement that tool. See storyboard runner.ts account-mode gate.\n //\n // `supportedBillings` projects onto the parallel `account.supported_billing`\n // wire field — buyers pre-flight check whether the seller bills the\n // operator (retail-media model) or the buying agent (pass-through). Without\n // the projection, retail-media adopters that declared `['operator']` saw\n // their buyers default-route to agent-billed flows.\n const requireOperatorAuth = platform.capabilities.requireOperatorAuth ?? platform.accounts.resolution === 'explicit';\n const supportedBillings = platform.capabilities.supportedBillings;\n const hasAccountProjection = requireOperatorAuth === true || (supportedBillings?.length ?? 0) > 0;\n // Schema requires `supported_billing` (minItems: 1) whenever the account\n // block is emitted. Default to ['agent'] when adopters don't declare —\n // matches the documented platform interface default at\n // `capabilities.ts:130` (\"Defaults to ['agent'] when omitted\"). v6 was\n // dropping the field on undefined which failed schema validation; v5's\n // `?? []` would also fail (minItems: 1). 'agent' (agent consolidates\n // billing) is the least-surprising default for non-media-buy specialisms.\n // An adopter passing supportedBillings: [] also lands in the default\n // branch — the closed enum has no semantic meaning for empty, and\n // emitting an empty array would fail schema regardless.\n const accountOverrides: Partial<NonNullable<GetAdCPCapabilitiesResponse['account']>> = {\n ...(requireOperatorAuth === true && { require_operator_auth: true }),\n ...(hasAccountProjection && {\n supported_billing: supportedBillings?.length ? [...supportedBillings] : ['agent'],\n }),\n };\n\n const autoSeedStore: Map<string, Map<string, unknown>> | undefined =\n opts.complyTest != null &&\n platform.sales?.getProducts != null &&\n !opts.testController &&\n !opts.complyTest.seed?.product &&\n !opts.complyTest.seed?.pricing_option\n ? new Map<string, Map<string, unknown>>()\n : undefined;\n\n const complyTestForProjection: ComplyControllerConfig | undefined =\n opts.complyTest != null && autoSeedStore != null\n ? {\n ...opts.complyTest,\n seed: {\n ...opts.complyTest.seed,\n // Projection advertises auto-seed scenarios through the normal\n // complyTest surface; makeAutoSeedBridge handles the real writes.\n product: opts.complyTest.seed?.product ?? (() => undefined),\n pricing_option: opts.complyTest.seed?.pricing_option ?? (() => undefined),\n },\n }\n : opts.complyTest;\n\n // Compliance-testing scenarios projection. Adopters who claim the\n // `compliance_testing` capability AND wire `complyTest` adapters\n // expect buyers to discover which scenarios they implement via\n // `get_adcp_capabilities.compliance_testing.scenarios`. Without\n // projection the wire response carried an empty `compliance_testing: {}`\n // block, the comply-track runner emitted a warning on every call,\n // and adopters saw an actionable-looking message pointing at\n // something they'd already done correctly. Auto-derive scenario names\n // from the wired adapters; let an explicit\n // `capabilities.compliance_testing.scenarios` override the\n // auto-derivation when adopters want to advertise a subset.\n const declaredCT = platform.capabilities.compliance_testing;\n const wiredComplyTest = complyTestForProjection;\n const hasComplianceTestingProjection = declaredCT != null && wiredComplyTest != null;\n const complianceTestingOverrides: NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']> | undefined =\n hasComplianceTestingProjection\n ? {\n scenarios: declaredCT.scenarios ? [...declaredCT.scenarios] : deriveScenariosFromAdapters(wiredComplyTest),\n }\n : undefined;\n\n // Forward specialisms declared on the platform into the inner createAdcpServer\n // config. `capabilities` is omitted from CreateAdcpServerFromPlatformOptions so\n // there is no other forwarding path — without this, createAdcpServer's boot-time\n // guards always see an empty specialisms list and throw when signedRequests is wired.\n const platformSpecialisms = platform.capabilities.specialisms ?? [];\n const hasSpecialisms = platformSpecialisms.length > 0;\n // The signed-requests guard in createAdcpServer (lines 3125 + 3145) requires both\n // `capabilities.specialisms` including 'signed-requests' AND `capabilities.request_signing.\n // supported === true`. DecisioningCapabilities has no request_signing field, so synthesize\n // the minimal block from the specialism claim — supported:true is implied by claiming it.\n const claimsSignedSpecialism = platformSpecialisms.includes('signed-requests' as never);\n const hasOverridesProjection =\n hasMediaBuyProjection || hasBrandProjection || hasAccountProjection || hasComplianceTestingProjection;\n\n // Adopter-declared passthrough fields (issue #2199). DecisioningCapabilities\n // exposes a subset of AdcpCapabilitiesConfig that wasn't previously reachable\n // through definePlatform; forward them so adopters can declare not-supported\n // feature blocks, creative-capability flags, account-shape additions,\n // deep-merge overrides, and release-precision supported_versions without\n // dropping to the lower-level createAdcpServer API.\n //\n // Precedence per the brief on #2199:\n // - features: adopter base; auto-derived audience_targeting /\n // conversion_tracking / content_standards booleans take\n // precedence (handled downstream by applyCapabilityOverrides\n // on the inner createAdcpServer call — the framework's\n // media_buy override is applied AFTER capConfig.features\n // lays down the base).\n // - account: adopter base; existing requireOperatorAuth /\n // supportedBilling projections overlay through the\n // per-domain account override below.\n // - overrides: adopter-declared overrides merged before framework's\n // per-domain blocks so framework-derived blocks remain\n // authoritative on the keys the projection engine handles.\n // This framework canonicalizes every creative before adopter handlers run,\n // but the feature bit exists only in canonical-capable protocol schemas.\n // Strip an adopter claim on a 3.0 pin instead of leaking a future feature\n // into a legacy capability response.\n const { canonicalCreatives: _adopterCanonicalCreatives, ...adopterFeatureBase } =\n platform.capabilities.features ?? {};\n void _adopterCanonicalCreatives;\n const adopterFeatures = {\n ...adopterFeatureBase,\n ...(canonicalCreativeCapability && { canonicalCreatives: true }),\n };\n const adopterCreative = platform.capabilities.creative;\n const adopterAccount = platform.capabilities.account;\n const adopterExtensionsSupported = platform.capabilities.extensions_supported;\n const adopterCapabilityExt = platform.capabilities.ext;\n const adopterOverrides = platform.capabilities.overrides;\n const adopterSupportedVersions = platform.capabilities.supported_versions;\n const hasOverridesObject = hasOverridesProjection || adopterOverrides !== undefined;\n\n const projectedCapabilitiesConfig = {\n ...(hasSpecialisms && {\n specialisms: [...platformSpecialisms] as NonNullable<GetAdCPCapabilitiesResponse['specialisms']>,\n }),\n ...(claimsSignedSpecialism && { request_signing: { supported: true as const } }),\n ...((hasMediaBuyProjection || Object.keys(adopterFeatureBase).length > 0) && {\n features: adopterFeatures,\n }),\n ...(adopterCreative !== undefined && { creative: adopterCreative }),\n ...(adopterAccount !== undefined && { account: adopterAccount }),\n ...(adopterExtensionsSupported !== undefined && {\n extensions_supported: [...adopterExtensionsSupported],\n }),\n ...(adopterCapabilityExt !== undefined && { ext: adopterCapabilityExt }),\n ...(adopterSupportedVersions !== undefined && {\n supported_versions: [...adopterSupportedVersions],\n }),\n ...(hasOverridesObject && {\n overrides: {\n ...(adopterOverrides ?? {}),\n ...(hasMediaBuyProjection\n ? { media_buy: mergeCapabilityOverride(adopterOverrides?.media_buy, mediaBuyOverrides) }\n : adopterOverrides?.media_buy !== undefined && { media_buy: adopterOverrides.media_buy }),\n ...(hasBrandProjection && {\n brand: mergeCapabilityOverride(adopterOverrides?.brand, brandOverrides),\n }),\n ...(hasAccountProjection && {\n account: mergeCapabilityOverride(adopterOverrides?.account, accountOverrides),\n }),\n ...(hasComplianceTestingProjection &&\n complianceTestingOverrides != null && { compliance_testing: complianceTestingOverrides }),\n },\n }),\n };\n\n // Per-server `ctxFor` closure; threads the effective ctx-metadata store\n // (explicit > pooled > none) into `buildRequestContext` so handlers see\n // `ctx.ctxMetadata` as an account-scoped accessor. Multi-tenant hosts\n // (TenantRegistry) get one closure per server, so per-tenant store\n // routing is preserved.\n const ctxFor = makeCtxFor(effectiveCtxMetadata);\n const platformProposalNegotiation = buildProposalNegotiationHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor\n );\n if (platformProposalNegotiation && opts.proposalNegotiation) {\n throw new PlatformConfigError(\n 'Configure refine_proposals through platform.mediaBuyLifecycle or opts.proposalNegotiation, not both'\n );\n }\n\n // Construction-time warn: when the default `resolveIdempotencyPrincipal`\n // is used (no explicit hook), established tools retain the SDK 13 chain:\n // ctx.authInfo.clientId → ctx.sessionKey → ctx.account.id → undefined\n // Compact media-buy mutations instead require a stable authenticated\n // principal below; they never fall through to session/account identity.\n // The `account.id` fallback collapses unauthenticated buyers into one\n // shared idempotency namespace per account — fine for single-tenant\n // deployments where every buyer authenticates, dangerous for multi-\n // tenant hosts serving unauthenticated traffic over a shared\n // account_id. Gate via the dev-allowlist pattern: warn unless\n // NODE_ENV ∈ {test, development} OR the operator explicitly acks via\n // ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL=1.\n if (opts.resolveIdempotencyPrincipal === undefined) {\n const env = process.env.NODE_ENV;\n const inDevAllowlist = env === 'test' || env === 'development';\n const acked = process.env.ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL === '1';\n if (!inDevAllowlist && !acked) {\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] resolveIdempotencyPrincipal not explicitly wired. ` +\n `Default falls through: authInfo.clientId → sessionKey → account.id → undefined. ` +\n `The account.id fallback collapses unauthenticated buyers into one shared idempotency ` +\n `namespace per account. SAFE for single-tenant deployments where every buyer ` +\n `authenticates; UNSAFE for multi-tenant hosts serving unauthenticated traffic over a ` +\n `shared account_id. Wire \\`authenticate\\` on serve() (verifyApiKey / verifyIntrospection) ` +\n `OR pass an explicit \\`resolveIdempotencyPrincipal\\` in opts. ` +\n `Set ADCP_DECISIONING_ALLOW_ACCOUNT_ID_PRINCIPAL=1 to silence this warning.`\n );\n }\n }\n\n // Auto-seed: when the platform has a `getProducts` catalog and the adopter\n // wired `complyTest` without explicit product/pricing seed adapters and\n // without a `testController` bridge, the framework provides default\n // in-memory seed adapters. The bridge makes seeded products visible in\n // sandbox `get_products` responses. `autoSeedStore` is computed before\n // capability projection so `seed_product` / `seed_pricing_option` are also\n // advertised when the framework wires them on the adopter's behalf.\n\n const config: AdcpServerConfig<Account> = {\n ...opts,\n requireCompactMutationAccountScope: true,\n taskRegistry,\n ...(autoSeedStore != null && { testController: makeAutoSeedBridge(autoSeedStore) }),\n ...(projectedCapabilitiesConfig != null && { capabilities: projectedCapabilitiesConfig }),\n // Buyer-agent registry (Phase 1 of #1269). Threaded through from the\n // platform so the v5 dispatcher can call `agentRegistry.resolve()` on\n // every request and populate `ctx.agent`. When the platform omits the\n // field, the v5 surface stays unchanged.\n //\n // Precedence: this spread runs AFTER `...opts`, so `platform.agentRegistry`\n // wins over any `opts.agentRegistry` an adopter passes via the v5 escape\n // hatch. Same convention as the `idempotency` spread below — the platform\n // is the authoritative v6 surface; opts is a low-level escape hatch.\n ...(platform.agentRegistry !== undefined && { agentRegistry: platform.agentRegistry }),\n // Server-level `instructions` (closes #1312). Same precedence pattern as\n // `agentRegistry` above — platform-declared instructions win over the\n // v5 `opts.instructions` escape hatch when both are present, so v6\n // adopters can colocate platform facts / decision policy with the rest\n // of their platform declaration.\n ...(platform.instructions !== undefined && { instructions: platform.instructions }),\n ...(platform.onInstructionsError !== undefined && { onInstructionsError: platform.onInstructionsError }),\n // Pool-derived stores override the spread above when adopters supplied\n // `pool` but no explicit per-store opt. Explicit values still win.\n ...(effectiveIdempotency !== undefined && { idempotency: effectiveIdempotency }),\n // Preserve the SDK 13 principal namespace for established tools so a\n // retry spanning a rolling 13→14 deployment still finds its durable\n // idempotency entry. The new compact lifecycle uses credential-kind\n // namespacing and refuses session/account fallbacks, preventing\n // cross-credential collisions without reopening a duplicate-buy window\n // on create_media_buy/update_media_buy. Explicit adopter resolvers still\n // win for every tool.\n resolveIdempotencyPrincipal:\n opts.resolveIdempotencyPrincipal ??\n ((ctx, _params, toolName) =>\n COMPACT_MEDIA_BUY_MUTATION_TOOLS.has(toolName)\n ? authenticatedPrincipalFor(ctx)\n : (ctx.authInfo?.clientId ?? ctx.sessionKey ?? ctx.account?.id ?? undefined)),\n resolveAccount: async (ref, ctx) => {\n const start = Date.now();\n let resolved = false;\n let resolvedAccountId: string | undefined;\n try {\n // Enforce the JSDoc contract documented at `AccountStore.resolution`:\n // implicit-mode and derived-mode platforms refuse inline `account_id`\n // references. Implicit: buyers call sync_accounts first, then the\n // framework resolves from the auth principal. Derived: single-tenant;\n // the principal alone identifies the tenant. The brand+operator union\n // arm is permitted (implicit's sync_accounts onboarding flow); only\n // the `{ account_id }` arm is refused. Closes adcp-client#1364\n // (implicit) and adcp-client#1468 (derived).\n refuseInlineAccountIdWhenForbidden(platform.accounts.resolution, ref);\n const account = await platform.accounts.resolve(ref, toResolveCtx(ctx, ctx.toolName, ctx.input));\n resolved = account != null;\n resolvedAccountId = account?.id;\n return account;\n } catch (err) {\n if (err instanceof AccountNotFoundError) return null;\n throw err;\n } finally {\n safeFire(\n observability?.onAccountResolve,\n {\n tool: ctx.toolName,\n durationMs: Date.now() - start,\n resolved,\n fromAuth: false,\n ...(resolvedAccountId !== undefined && { accountId: resolvedAccountId }),\n },\n 'onAccountResolve',\n fwLogger\n );\n }\n },\n // Auth-derived path: framework calls this for tools whose wire request\n // doesn't carry an `account` field (`provide_performance_feedback`,\n // `list_creative_formats`, `tasks_get`). The platform's resolver runs\n // with `undefined` ref + `authInfo` available — adopters of any\n // `resolution` mode can return a non-null Account here:\n //\n // - `'derived'` — return the singleton.\n // - `'implicit'` — look up by `ctx.authInfo.clientId`.\n // - `'explicit'` — also handle the `undefined` ref branch by\n // looking up via `ctx.authInfo.clientId` (or whichever principal\n // field your auth wires). The framework calls this resolver\n // regardless of declared `resolution` mode; only adopters who\n // intentionally don't model these tools return null.\n //\n // A `null` return is legal — handler runs with `ctx.account`\n // undefined. Appropriate for tools that don't need tenant scoping\n // (publisher-wide format catalogs).\n resolveAccountFromAuth: async ctx => {\n const start = Date.now();\n let resolved = false;\n let resolvedAccountId: string | undefined;\n try {\n const account = await platform.accounts.resolve(undefined, toResolveCtx(ctx, ctx.toolName, ctx.input));\n resolved = account != null;\n resolvedAccountId = account?.id;\n return account;\n } catch (err) {\n if (err instanceof AccountNotFoundError) return null;\n throw err;\n } finally {\n safeFire(\n observability?.onAccountResolve,\n {\n tool: ctx.toolName,\n durationMs: Date.now() - start,\n resolved,\n fromAuth: true,\n ...(resolvedAccountId !== undefined && { accountId: resolvedAccountId }),\n },\n 'onAccountResolve',\n fwLogger\n );\n }\n },\n // Merge: platform-derived handlers WIN per-key over adopter-supplied\n // custom handlers. Adopter handlers fill gaps for tools the v6 platform\n // doesn't yet model (content-standards CRUD, sync_event_sources, etc.).\n // See `CreateAdcpServerFromPlatformOptions` JSDoc for the migration-seam\n // contract.\n mediaBuy: mergeMediaBuyHandlers(\n legacyHandlers.mediaBuy,\n buildMediaBuyHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n effectiveCtxMetadata,\n opts.mediaBuyStore,\n opts.proposalStore,\n opts.legacyCreativeFormatConverter,\n opts.legacyCreativeFormatResolver,\n {\n timeoutMs: legacyFormatResolverLimit(\n opts.legacyCreativeFormatResolverTimeoutMs,\n DEFAULT_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS,\n 'legacyCreativeFormatResolverTimeoutMs',\n MAX_LEGACY_FORMAT_RESOLVER_TIMEOUT_MS\n ),\n concurrency: legacyFormatResolverLimit(\n opts.legacyCreativeFormatResolverConcurrency,\n DEFAULT_LEGACY_FORMAT_RESOLVER_CONCURRENCY,\n 'legacyCreativeFormatResolverConcurrency',\n MAX_LEGACY_FORMAT_RESOLVER_CONCURRENCY\n ),\n },\n opts.canonicalFormatLegacyResolver,\n defaultCreativeWireMode\n ),\n 'mediaBuy',\n mergeOpts,\n defaultCreativeWireMode\n ),\n proposalNegotiation: platformProposalNegotiation ?? opts.proposalNegotiation,\n creative: mergeHandlers(\n legacyHandlers.creative,\n buildCreativeHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n opts.legacyCreativeFormatConverter,\n opts.canonicalFormatLegacyResolver,\n defaultCreativeWireMode\n ),\n 'creative',\n mergeOpts\n ),\n eventTracking: mergeHandlers(\n opts.eventTracking,\n buildEventTrackingHandlers(platform, ctxFor),\n 'eventTracking',\n mergeOpts\n ),\n signals: mergeHandlers(\n opts.signals,\n buildSignalsHandlers(\n platform,\n taskRegistry,\n taskWebhookEmit,\n observability,\n fwLogger,\n {\n allowPrivateWebhookUrls: opts.allowPrivateWebhookUrls === true,\n autoEmitCompletionWebhooks: opts.autoEmitCompletionWebhooks === true,\n },\n ctxFor,\n effectiveCtxMetadata\n ),\n 'signals',\n mergeOpts\n ),\n sponsoredIntelligence: mergeHandlers(\n opts.sponsoredIntelligence,\n buildSponsoredIntelligenceHandlers(platform, ctxFor, effectiveCtxMetadata, fwLogger),\n 'sponsoredIntelligence',\n mergeOpts\n ),\n governance: mergeHandlers(\n legacyHandlers.governance,\n buildGovernanceHandlers(platform, ctxFor),\n 'governance',\n mergeOpts\n ),\n accounts: mergeHandlers(opts.accounts, buildAccountHandlers(platform, ctxFor), 'accounts', mergeOpts),\n brandRights: mergeHandlers(\n legacyHandlers.brandRights,\n buildBrandRightsHandlers(platform, ctxFor, effectiveCtxMetadata, fwLogger),\n 'brandRights',\n mergeOpts\n ),\n customTools: (() => {\n // MCP tool names cannot contain `/`, so expose the AdCP work-status\n // polling surface under the MCP-safe `tasks_get` alias only. A2A keeps\n // using the transport-native `tasks/get` method name on its own path.\n const tasksGetTool = buildTasksGetTool(\n platform,\n taskRegistry,\n platform.agentRegistry,\n fwLogger,\n opts.resolveSessionKey,\n opts.credentialPolicy\n );\n return {\n ...opts.customTools,\n tasks_get: tasksGetTool,\n };\n })(),\n };\n\n const server = createAdcpServer(config);\n const mcp = getSdkServer(server);\n type McpExtra = { authInfo?: ResolvedAuthInfo } | undefined;\n\n const resolveComplyBuyerAgent = async (\n extra: McpExtra,\n input?: Readonly<Record<string, unknown>>\n ): Promise<BuyerAgent | undefined> => {\n if (platform.agentRegistry === undefined) return undefined;\n try {\n const inboundCredential = extra?.authInfo?.extra?.credential;\n const credential =\n extra?.authInfo?.credential ?? (inboundCredential as ResolvedAuthInfo['credential'] | undefined);\n const resolved = await platform.agentRegistry.resolve({\n ...(credential !== undefined && { credential }),\n ...(extra?.authInfo?.extra !== undefined && { extra: extra.authInfo.extra }),\n ...(input !== undefined && { input }),\n });\n if (resolved == null) return undefined;\n if (!Object.isFrozen(resolved)) {\n if (resolved.billing_capabilities instanceof Set) {\n Object.freeze(resolved.billing_capabilities);\n }\n Object.freeze(resolved);\n }\n return resolved;\n } catch (err) {\n fwLogger.warn?.('Buyer-agent registry resolution failed during comply controller visibility check', {\n error: redactCredentialPatterns(err instanceof Error ? err.message : String(err)),\n });\n return undefined;\n }\n };\n\n const resolveComplyControllerVisible = async (\n extra: McpExtra,\n toolName?: string,\n input?: Readonly<Record<string, unknown>>\n ): Promise<boolean> => {\n const agent = await resolveComplyBuyerAgent(extra, input);\n let principalAccount: Account | null = null;\n try {\n principalAccount = await platform.accounts.resolve(\n undefined,\n toResolveCtx(\n {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n },\n toolName,\n input\n )\n );\n } catch {\n principalAccount = null;\n }\n\n recordResolvedAccountMode(principalAccount);\n\n if (isSandboxOrMockAccount(principalAccount)) return true;\n\n if (process.env.ADCP_SANDBOX === '1') {\n if (hasObservedLiveMode()) {\n throw new Error(\n 'comply_test_controller: ADCP_SANDBOX=1 is set but this process has resolved at least one ' +\n 'live-mode account from platform.accounts.resolve. Remove ADCP_SANDBOX from your prod ' +\n 'environment; gate the controller via mode: \"sandbox\" on resolved sandbox accounts instead. ' +\n 'See docs/proposals/lifecycle-state-and-sandbox-authority.md.'\n );\n }\n return true;\n }\n\n return false;\n };\n\n if (hasComplianceTestingProjection) {\n setToolVisibilityResolver(server, ({ toolName, authInfo, input }) => {\n if (toolName !== 'comply_test_controller') return true;\n return resolveComplyControllerVisible(authInfo === undefined ? undefined : { authInfo }, toolName, input);\n });\n }\n\n if (mcp != null && hasComplianceTestingProjection) {\n const wrappedCapabilities = wrapRegisteredToolHandler(mcp, 'get_adcp_capabilities', async (orig, args, extra) => {\n const response = await orig(args, extra);\n if (\n await resolveComplyControllerVisible(\n extra as McpExtra,\n 'get_adcp_capabilities',\n args as Readonly<Record<string, unknown>>\n )\n ) {\n return response;\n }\n if (response == null || typeof response !== 'object') return response;\n\n const structured = (response as { structuredContent?: unknown }).structuredContent;\n if (structured == null || typeof structured !== 'object') return response;\n if (!Object.hasOwn(structured, 'compliance_testing')) return response;\n\n const nextStructured = { ...(structured as Record<string, unknown>) };\n delete nextStructured['compliance_testing'];\n return { ...(response as Record<string, unknown>), structuredContent: nextStructured };\n });\n if (!wrappedCapabilities) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap get_adcp_capabilities for comply_test_controller visibility. ' +\n 'The MCP SDK registered-tool internals may have changed.'\n );\n }\n }\n\n // Wire `comply_test_controller` if the adopter supplied adapters.\n // `createComplyController` builds the tool definition + handler + raw\n // dispatch. The framework registers the tool itself (bypassing\n // `controller.register(server)`) so the sandbox-authority gate can\n // resolve the calling account through `platform.accounts.resolve`\n // BEFORE dispatching — under no circumstances should the controller\n // operate on a `live`-mode account, regardless of what the caller\n // claims on the wire. See `docs/proposals/lifecycle-state-and-sandbox-authority.md`\n // for the full three-mode design and #1435 phase 2.\n if (opts.complyTest != null) {\n let complyConfig = opts.complyTest;\n\n if (autoSeedStore != null) {\n // Inject auto-seed adapters for `seed_product` and `seed_pricing_option`\n // when the adopter didn't wire explicit ones. Explicit adapters win — the\n // spread only fills the undefined slots.\n //\n // **Namespace key: raw `account.account_id`.** The adapter does NOT call\n // `platform.accounts.resolve` even though that would seem symmetric with\n // the bridge's `ctx.account?.id` read — calling resolve here without\n // `authInfo` (which `ComplyControllerContext` doesn't expose) lets a\n // caller spoof `account.account_id: 'victim'` and have a non-validating\n // resolver write seeds into the victim's resolved namespace. Raw id is\n // the safe choice: a caller can only write to their own claimed id, and\n // the sandboxGate already filters non-sandbox traffic.\n //\n // **Trade-off.** Adopters whose resolver maps `account_id` to a distinct\n // internal id (e.g., `acc_1` → `tenant_a:acc_1`) will see seeded fixtures\n // disappear — the adapter writes to `acc_1`, the bridge reads\n // `tenant_a:acc_1`, no match. That's a documented limitation, not a\n // security issue: silent test loss, not cross-tenant pollution. The\n // architectural fix (widen `ComplyControllerContext` to expose the\n // framework-resolved account so writes match reads even under mapping\n // resolvers) is tracked at #1216. Mapping-resolver adopters wire\n // explicit seed adapters today.\n const explicitSeed = opts.complyTest.seed ?? {};\n const autoSeed = { ...explicitSeed };\n\n if (!explicitSeed.product) {\n autoSeed.product = async (params, ctx) => {\n const accountId = readAutoSeedAccountId(ctx.input);\n if (accountId == null) {\n fwLogger.warn(\n '[adcp/auto-seed] seed_product fired without `account.account_id`; dropping write. ' +\n 'Verify the request envelope carries an account ref and the sandboxGate is configured correctly.',\n { product_id: params.product_id }\n );\n return;\n }\n autoSeedStoreFor(autoSeedStore, accountId).set(params.product_id, {\n ...params.fixture,\n product_id: params.product_id,\n });\n };\n }\n\n if (!explicitSeed.pricing_option) {\n autoSeed.pricing_option = async (params, ctx) => {\n const accountId = readAutoSeedAccountId(ctx.input);\n if (accountId == null) {\n fwLogger.warn(\n '[adcp/auto-seed] seed_pricing_option fired without `account.account_id`; dropping write. ' +\n 'Verify the request envelope carries an account ref and the sandboxGate is configured correctly.',\n { product_id: params.product_id, pricing_option_id: params.pricing_option_id }\n );\n return;\n }\n const accountStore = autoSeedStoreFor(autoSeedStore, accountId);\n const existing = accountStore.get(params.product_id) as Record<string, unknown> | undefined;\n const pricingOption = { ...params.fixture, pricing_option_id: params.pricing_option_id };\n const existingOptions = Array.isArray(\n (existing as { pricing_options?: unknown[] } | undefined)?.pricing_options\n )\n ? (existing as { pricing_options: unknown[] }).pricing_options\n : [];\n const filtered = existingOptions.filter(\n (p): p is Record<string, unknown> =>\n p != null &&\n typeof p === 'object' &&\n (p as Record<string, unknown>).pricing_option_id !== params.pricing_option_id\n );\n accountStore.set(params.product_id, {\n ...(existing ?? { product_id: params.product_id }),\n pricing_options: [...filtered, pricingOption],\n });\n };\n }\n\n complyConfig = { ...opts.complyTest, seed: autoSeed };\n }\n\n const controller = createComplyController(complyConfig);\n\n // Manual registration with framework-side sandbox-authority gate. See\n // top-of-block rationale and `docs/proposals/lifecycle-state-and-sandbox-authority.md`.\n //\n // Trust boundary: the gate consults the *resolved* account from\n // `platform.accounts.resolve`, NOT a buyer-supplied claim like\n // `account.sandbox === true` on the wire. The resolver is the only\n // thing that names the account's mode; the gate refuses dispatch when\n // mode is `live` (or the resolver fails to produce an account, modulo\n // the narrow fallbacks below).\n //\n // Fallback paths (deprecated):\n // - `account.sandbox === true` admits only for unresolved target-account\n // refs after a sandbox/mock principal has already passed the discovery\n // visibility gate. A buyer wire claim never overrides a resolved live\n // account and is never used for principal visibility.\n // - `process.env.ADCP_SANDBOX === '1'` admits the principal visibility\n // check and target dispatch for legacy conformance deployments. It\n // fails closed if the same process has ever resolved an explicit\n // `mode: 'live'` account from the resolver: that pairing is a\n // misconfiguration (env var should be unset on prod) and leaving it\n // open re-exposes the live principal we just gated against.\n //\n // `list_scenarios` is exempt from the target-account gate once the\n // principal can see the controller. Read-only and reveals nothing beyond\n // which scenarios the adopter advertised in capabilities.\n if (mcp == null) {\n // Non-MCP server — fall back to the controller's own registration so\n // adopters wiring a custom transport keep the v5 behavior. The gate is\n // an MCP-side concern; A2A and other transports are wired separately.\n controller.register(server);\n } else {\n // Permit a top-level `account` field on the wire so the gate can read\n // the buyer's account ref. The canonical AdCP shape strips it (account\n // routes through `context.account`), but adopters' storyboard fixtures\n // commonly send it at the top level — `TOOL_INPUT_SHAPE`'s JSDoc in\n // `src/lib/server/test-controller.ts` documents this extension as the\n // supported escape hatch.\n //\n // Schema is the full canonical `AccountReference` per\n // `schemas/cache/3.0.6/core/account-ref.json`: oneOf\n // { account_id } — explicit accounts\n // { brand, operator, sandbox? } — implicit accounts\n // Modeled here as a single object with all four fields optional so\n // either arm passes; resolvers narrow on the shape at dispatch.\n // `brand` content is `unknown()` because the inner `brand-ref.json`\n // shape is itself a oneOf and resolvers (not the gate) validate it.\n // Top-level `.strict()` still blocks unknown keys at the framework\n // boundary so a buyer can't stuff `__proto__` / arbitrary payloads\n // into adopters' resolvers.\n const gatedInputSchema = {\n ...controller.toolDefinition.inputSchema,\n account: z\n .object({\n account_id: z.string().min(1).optional(),\n brand: z.unknown().optional(),\n operator: z.string().optional(),\n sandbox: z.boolean().optional(),\n })\n .strict()\n .optional(),\n };\n\n mcp.registerTool(\n controller.toolDefinition.name,\n {\n description: controller.toolDefinition.description,\n inputSchema: gatedInputSchema,\n },\n (async (input: Record<string, unknown>, extra: { authInfo?: ResolvedAuthInfo } | undefined) => {\n if (!(await resolveComplyControllerVisible(extra, 'comply_test_controller', input))) {\n throw new McpError(ErrorCode.MethodNotFound, 'Method not found');\n }\n\n // Probe exempt — capability discovery, no state mutation.\n if (input.scenario === 'list_scenarios') {\n return controller.handle(input);\n }\n\n // Read account ref from top-level (extended shape) or from\n // `context.account` (canonical AdCP routing). First non-null wins.\n const refFromTop = input.account as AccountReference | undefined;\n const refFromContext = (input.context as { account?: AccountReference } | undefined)?.account;\n const accountRef = refFromTop ?? refFromContext;\n\n let resolvedAccount: Account | null = null;\n try {\n const agent = await resolveComplyBuyerAgent(extra, input);\n resolvedAccount = await platform.accounts.resolve(\n accountRef,\n toResolveCtx(\n {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n },\n 'comply_test_controller',\n input\n )\n );\n } catch {\n // Resolver failures fall through to the wire-ref / env fallbacks.\n // Treat as \"no account resolved\" — fail-closed by default unless a\n // fallback admits.\n }\n\n // Record the resolved account's explicit mode (if any). Used by the\n // env-fallback fail-closed guard below.\n recordResolvedAccountMode(resolvedAccount);\n\n const accountIsSandbox = resolvedAccount != null && isSandboxOrMockAccount(resolvedAccount);\n // Spec-defined fallback for the unresolved-account path: read\n // `sandbox: true` off the wire `AccountReference` (per\n // `core/account-ref.json`). Only consulted when the resolver\n // returned `null` — if the resolver names the account, the\n // resolver wins. The buyer's wire claim never overrides a\n // resolved live account.\n const refSandbox = (accountRef as { sandbox?: unknown } | undefined)?.sandbox === true;\n const envSandbox = process.env.ADCP_SANDBOX === '1';\n\n const wouldAdmitOnlyViaEnv = envSandbox && !accountIsSandbox && !(resolvedAccount == null && refSandbox);\n\n // Fail-closed guard on the env fallback. If the env var is the only\n // signal that would admit AND this process has ever resolved an\n // explicit `mode: 'live'` account from the resolver, the env is\n // misconfigured. Refuse loudly so operators notice, instead of\n // silently downgrading the gate for live principals.\n if (wouldAdmitOnlyViaEnv && hasObservedLiveMode()) {\n throw new Error(\n 'comply_test_controller: ADCP_SANDBOX=1 is set but this process has resolved at least one ' +\n 'live-mode account from platform.accounts.resolve. Remove ADCP_SANDBOX from your prod ' +\n 'environment; gate the controller via mode: \"sandbox\" on resolved sandbox accounts instead. ' +\n 'See docs/proposals/lifecycle-state-and-sandbox-authority.md.'\n );\n }\n\n const allowed = accountIsSandbox || (resolvedAccount == null && refSandbox) || envSandbox;\n\n if (!allowed) {\n // Refuse with the standard AdCP permission code once the\n // sandbox/mock principal can see the controller but the target\n // account is live or unresolved. Live principals never reach\n // this branch: they get MCP method-not-found above.\n //\n // `context` and `ext` are open-object on the request schema, so a\n // hostile caller could stuff arbitrarily large payloads. Self-\n // reflection only (no cross-tenant amplifier), but we cap at\n // 8 KiB serialized to bound the response body — anything larger\n // gets dropped, mirroring a missing field rather than echoing\n // garbage.\n const ECHO_BYTE_CAP = 8 * 1024;\n const safeEcho = (value: unknown): Record<string, unknown> | undefined => {\n if (value == null || typeof value !== 'object') return undefined;\n try {\n if (JSON.stringify(value).length > ECHO_BYTE_CAP) return undefined;\n return value as Record<string, unknown>;\n } catch {\n return undefined;\n }\n };\n const requestContext = safeEcho((input as { context?: unknown }).context);\n const requestExt = safeEcho((input as { ext?: unknown }).ext);\n const response = adcpError('PERMISSION_DENIED', {\n message:\n 'comply_test_controller requires a sandbox or mock target account; ' +\n 'resolved target account is live or unresolved.',\n recovery: 'terminal',\n details: {\n scope: 'sandbox-gate',\n tool: 'comply_test_controller',\n reason: 'sandbox-or-mock-required',\n },\n });\n if (requestContext !== undefined || requestExt !== undefined) {\n const structured = response.structuredContent as Record<string, unknown>;\n if (requestContext !== undefined) structured['context'] = requestContext;\n if (requestExt !== undefined) structured['ext'] = requestExt;\n response.content = [{ type: 'text', text: JSON.stringify(structured) }];\n }\n return response;\n }\n\n return controller.handle(input);\n }) as Parameters<typeof mcp.registerTool>[2]\n );\n\n const wrappedToolsCall = wrapSdkRequestHandler(mcp, 'tools/call', async (orig, req, extra) => {\n const params = (req.params ?? {}) as { name?: unknown; arguments?: unknown };\n if (params.name === 'comply_test_controller') {\n const input =\n params.arguments != null && typeof params.arguments === 'object'\n ? (params.arguments as Readonly<Record<string, unknown>>)\n : undefined;\n if (!(await resolveComplyControllerVisible(extra as McpExtra, 'comply_test_controller', input))) {\n throw new McpError(ErrorCode.MethodNotFound, 'Method not found');\n }\n }\n return orig(req, extra);\n });\n if (!wrappedToolsCall) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap MCP tools/call for comply_test_controller visibility. ' +\n 'The MCP SDK request-handler internals may have changed.'\n );\n }\n\n const wrappedToolsList = wrapSdkRequestHandler(mcp, 'tools/list', async (orig, req, extra) => {\n const response = await orig(req, extra);\n const input =\n req.params != null && typeof req.params === 'object'\n ? (req.params as Readonly<Record<string, unknown>>)\n : undefined;\n if (await resolveComplyControllerVisible(extra as McpExtra, undefined, input)) return response;\n if (response == null || typeof response !== 'object') return response;\n const tools = (response as { tools?: unknown }).tools;\n if (!Array.isArray(tools)) return response;\n return {\n ...(response as Record<string, unknown>),\n tools: tools.filter(tool => (tool as { name?: unknown } | null)?.name !== 'comply_test_controller'),\n };\n });\n if (!wrappedToolsList) {\n throw new Error(\n 'createAdcpServerFromPlatform: failed to wrap MCP tools/list for comply_test_controller visibility. ' +\n 'The MCP SDK request-handler internals may have changed.'\n );\n }\n }\n }\n\n return Object.assign(server, {\n getTaskState: async <TResult = unknown>(\n taskId: string,\n scope: TaskRegistryScope\n ): Promise<TaskRecord<TResult> | null> => {\n const record = await taskRegistry.getTask<TResult>(taskId, scope);\n return record && taskRecordMatchesScope(record, scope) ? record : null;\n },\n getTaskStateUnsafe: <TResult = unknown>(taskId: string): Promise<TaskRecord<TResult> | null> =>\n taskRegistry._getTaskUnsafe<TResult>(taskId),\n awaitTask: (taskId: string, scope: TaskRegistryScope): Promise<void> => taskRegistry.awaitTask(taskId, scope),\n awaitTaskUnsafe: (taskId: string): Promise<void> => taskRegistry._awaitTaskUnsafe(taskId),\n statusChange: statusChangeBus,\n });\n}\n\n// ---------------------------------------------------------------------------\n// `tasks_get` polling tool — buyer-facing wire path for HITL task lifecycle\n// ---------------------------------------------------------------------------\n\n/**\n * Custom tool exposing a scoped `taskRegistry.getTask(taskId, scope)` over the wire so\n * buyer agents can poll HITL task state. Snake-case `tasks_get` (MCP tool\n * names disallow `/`) approximates the spec's `tasks/get` method.\n *\n * Native MCP `tasks/get` integration via the SDK's experimental\n * `registerToolTask` path lands in v6.1 — that registers HITL tools\n * (`create_media_buy`, `sync_creatives`) as MCP task tools and the SDK\n * handles the protocol-level `tasks/get` natively. Until then, this\n * custom tool is the buyer-facing polling surface.\n *\n * **Tenant scoping.** The handler resolves both the trusted account and\n * authenticated owner scope before the registry read. Postgres-backed\n * deployments additionally isolate each server/tenant through the registry\n * namespace configured by `taskRegistryNamespace`.\n */\nfunction buildTasksGetTool<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n agentRegistry: BuyerAgentRegistry | undefined,\n logger: AdcpLogger,\n resolveSessionKey: AdcpServerConfig['resolveSessionKey'] | undefined,\n credentialPolicy: CredentialPolicy | undefined\n) {\n const credentialPolicyPatterns =\n credentialPolicy === undefined || typeof credentialPolicy === 'string' ? undefined : credentialPolicy.patterns;\n const credentialPolicyError = (\n args: Record<string, unknown>,\n extra: { authInfo?: ResolvedAuthInfo } | undefined\n ): AdcpErrorResponse | undefined => {\n if (credentialPolicy === undefined) return undefined;\n const effectivePolicy = resolveCredentialPolicyForTool(credentialPolicy, 'tasks_get');\n if (effectivePolicy !== 'lax') {\n const hits = scanArgsForCredentials(args, credentialPolicyPatterns);\n const blockedPaths =\n typeof effectivePolicy === 'object' ? hits.filter(p => !effectivePolicy.allow.includes(p)) : hits;\n if (blockedPaths.length > 0) {\n return adcpError('PERMISSION_DENIED', {\n message:\n 'Request args carry credential-shaped keys. Credentials must arrive on authInfo, not in the request body.',\n recovery: 'correctable',\n details: { scope: 'credentials', credential_paths: blockedPaths },\n });\n }\n }\n if (\n typeof credentialPolicy !== 'string' &&\n credentialPolicy.scanAuthInfo === true &&\n extra?.authInfo?.extra !== null &&\n extra?.authInfo?.extra !== undefined &&\n typeof extra.authInfo.extra === 'object'\n ) {\n const authInfoHits = scanArgsForCredentials(extra.authInfo.extra, credentialPolicyPatterns);\n if (authInfoHits.length > 0) {\n try {\n logger.warn?.('credentialPolicy: authInfo.extra carries credential-shaped keys', {\n tool: 'tasks_get',\n paths: authInfoHits.map(p => `authInfo.extra.${p}`),\n });\n } catch {\n // Ignore logger failures on the rejection path.\n }\n return adcpError('PERMISSION_DENIED', {\n message:\n 'Request authentication context carries credential-shaped keys. Configure your authenticator to keep credentials off authInfo.extra.',\n recovery: 'terminal',\n details: { scope: 'credentials' },\n });\n }\n }\n return undefined;\n };\n\n const inputShape = {\n // Cap task_id length: framework-issued task ids are\n // `task_<UUIDv4>` = 41 chars. Cap at 128 so a malicious buyer can't\n // hand us megabytes of string for a parameterized read query.\n task_id: z\n .string()\n .min(1)\n .max(128)\n .describe('Task identifier returned in the submitted envelope of a HITL tool call.'),\n // Full canonical `AccountReference` per `core/account-ref.json`:\n // `oneOf({ account_id }, { brand, operator, sandbox? })`. Modeled as\n // a single object with all four fields optional so either arm\n // passes; the resolver narrows on shape at dispatch. `brand` content\n // is `unknown()` because the inner `brand-ref.json` shape is itself\n // a oneOf and the resolver validates it. Top-level `.strict()`\n // blocks unknown keys at the framework boundary.\n account: z\n .object({\n account_id: z.string().min(1).optional(),\n brand: z.unknown().optional(),\n operator: z.string().optional(),\n sandbox: z.boolean().optional(),\n })\n .strict()\n .optional()\n .describe(\n 'Optional account reference for tenant scoping. Either AccountReference arm is accepted: ' +\n '`{account_id}` for explicit accounts or `{brand, operator, sandbox?}` for implicit accounts.'\n ),\n include_result: z\n .boolean()\n .optional()\n .describe('Include a canonical terminal artifact for completed, failed, or rejected tasks.'),\n };\n return {\n description:\n 'Call this when you receive `{ status: \"submitted\", task_id }` from create_media_buy ' +\n 'or sync_creatives — pass the same `task_id` plus your `account` to retrieve the ' +\n 'terminal lifecycle state. Returns the spec-flat tasks-get-response shape ' +\n '(`status`, `result` on completed, `error: { code, message }` on failed). ' +\n \"Snake-case substitute for the spec's `tasks/get` method (MCP tool names disallow \" +\n '`/`); native MCP method dispatch lands in v6.1. Webhook delivery is the push-based ' +\n 'alternative when the buyer set `push_notification_config` on the original request.',\n title: 'Get Task State',\n inputSchema: inputShape,\n annotations: { readOnlyHint: true },\n // Handler receives the MCP RequestHandlerExtra as second arg — carries\n // the caller's `authInfo` extracted by `serve({ authenticate })`. Thread\n // it through `accounts.resolve(ref, ctx)` so adopters' `'explicit'`-mode\n // resolvers can authorize the resolution against the principal — without\n // this, an attacker passing `{ account: { account_id: 'tenant_B' } }`\n // gets tenant B's account back from a naive `findById(ref.account_id)`\n // resolver and reads tenant B's task. Same threading as the regular\n // `resolveAccount` dispatch flow in `create-adcp-server.ts:2380-2398`.\n handler: async (\n args: { task_id: string; account?: { account_id?: string }; include_result?: boolean },\n extra: { authInfo?: ResolvedAuthInfo }\n ) => {\n const policyError = credentialPolicyError(args as Record<string, unknown>, extra);\n if (policyError) return policyError;\n const ref = args.account;\n if (extra?.authInfo) {\n const inboundCredential = extra.authInfo.extra?.credential;\n if (inboundCredential !== undefined && extra.authInfo.credential === undefined) {\n extra.authInfo.credential = inboundCredential as ResolvedAuthInfo['credential'];\n }\n }\n // Resolve the buyer agent (when an `agentRegistry` is configured) so\n // adopters' `accounts.resolve` impl sees `ctx.agent` — same contract as\n // every other AccountStore method. Bypasses the dispatcher's\n // resolution-and-status-enforcement seam at\n // `create-adcp-server.ts:2748-2832` deliberately:\n //\n // - **Status enforcement is intentionally skipped on tasks_get\n // polls.** A buyer agent suspended AFTER kicking off an HITL task\n // must still be able to learn the task's terminal state — refusing\n // the poll would strand work with no visibility. Hard-cutoff\n // sellers implement that policy inside their `accounts.resolve`\n // or downstream by reading `ctx.agent.status` themselves.\n // - **Registry failures are surfaced as SERVICE_UNAVAILABLE.** The\n // task owner scope may have been persisted as `agent:${agent_url}`;\n // falling back to credential/session/account scope on a transient\n // registry outage would turn a valid task into a false 404.\n let agent: BuyerAgent | undefined;\n if (agentRegistry !== undefined) {\n try {\n const resolved = await agentRegistry.resolve({\n ...(extra?.authInfo?.credential !== undefined && { credential: extra.authInfo.credential }),\n ...(extra?.authInfo?.extra !== undefined && { extra: extra.authInfo.extra }),\n input: args,\n });\n if (resolved != null) {\n // Mirror the dispatcher's freeze contract: lock the resolved\n // record (and `billing_capabilities` Set if present) so adopter\n // code cannot mutate shared registry state across requests.\n // See `create-adcp-server.ts:2762-2779` for the full rationale.\n if (!Object.isFrozen(resolved)) {\n if (resolved.billing_capabilities instanceof Set) {\n Object.freeze(resolved.billing_capabilities);\n }\n Object.freeze(resolved);\n }\n agent = resolved;\n }\n } catch (err) {\n logger.error?.('Buyer-agent registry resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', {\n message: 'Buyer-agent registry resolution failed',\n });\n }\n }\n const resolveCtx = {\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n toolName: 'tasks_get',\n ...(agent !== undefined && { agent }),\n };\n let resolvedAccountId: string | undefined;\n let resolvedAccount: Account | undefined;\n if (ref) {\n refuseInlineAccountIdWhenForbidden(platform.accounts.resolution, ref as AccountReference);\n try {\n const resolved = await platform.accounts.resolve(ref as AccountReference, resolveCtx);\n if (resolved) {\n resolvedAccountId = resolved.id;\n resolvedAccount = resolved;\n }\n } catch (err) {\n if (!(err instanceof AccountNotFoundError)) {\n logger.error?.('Account resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Account resolution failed' });\n }\n }\n if (!resolvedAccountId) {\n return adcpError('ACCOUNT_NOT_FOUND', {\n message: 'The specified account does not exist',\n field: 'account',\n });\n }\n } else {\n try {\n const resolved = await platform.accounts.resolve(undefined, resolveCtx);\n if (resolved) {\n resolvedAccountId = resolved.id;\n resolvedAccount = resolved;\n }\n } catch (err) {\n if (!(err instanceof AccountNotFoundError)) {\n logger.error?.('Auth-derived account resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Account resolution failed' });\n }\n }\n }\n let sessionKey: string | undefined;\n if (resolveSessionKey !== undefined) {\n try {\n sessionKey = await resolveSessionKey({\n toolName: 'tasks_get' as AdcpServerToolName,\n params: args,\n ...(resolvedAccount !== undefined && { account: resolvedAccount }),\n ...(agent !== undefined && { agent }),\n });\n } catch (err) {\n logger.error?.('Session key resolution failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', {\n message: 'Session key resolution failed',\n });\n }\n }\n\n if (resolvedAccountId === undefined) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n const ownerCtx: HandlerContext<Account> = {\n store: {} as HandlerContext<Account>['store'],\n ...(extra?.authInfo !== undefined && { authInfo: extra.authInfo }),\n ...(agent !== undefined && { agent }),\n ...(sessionKey !== undefined && { sessionKey }),\n account: resolvedAccount ?? ({ id: resolvedAccountId } as Account),\n };\n const expectedOwnerScope = taskOwnerScopeFor(ownerCtx, resolvedAccountId);\n\n let record;\n try {\n record = await taskRegistry.getTask(args.task_id, {\n accountId: resolvedAccountId,\n ownerScope: expectedOwnerScope,\n });\n } catch (err) {\n logger.error?.('Task registry read failed during tasks_get poll', {\n error: err instanceof Error ? err.message : String(err),\n });\n return adcpError('SERVICE_UNAVAILABLE', { message: 'Task registry read failed' });\n }\n if (record == null) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n if (\n !taskRecordMatchesScope(record, {\n accountId: resolvedAccountId,\n ownerScope: expectedOwnerScope,\n })\n ) {\n return adcpError('REFERENCE_NOT_FOUND', {\n message: `Task ${args.task_id} not found`,\n field: 'task_id',\n });\n }\n // Spec shape: `tasks-get-response.json` requires task_id, task_type,\n // status, created_at, updated_at, protocol. Optional: completed_at\n // (terminal states), error (failed tasks — top-level, NOT inside\n // result), result (success-arm body for completed tasks),\n // has_webhook (whether buyer wired push_notification_config).\n const payload: Record<string, unknown> = {\n task_id: record.taskId,\n task_type: record.tool,\n status: record.status,\n protocol: protocolForTool(record.tool),\n has_webhook: record.hasWebhook === true,\n created_at: record.createdAt,\n updated_at: record.updatedAt,\n };\n // Terminal states get `completed_at` per spec (covers completed,\n // failed, canceled). The framework writes terminal-state transitions\n // by stamping `updated_at`, so the two coincide today.\n if (record.status === 'completed' || record.status === 'failed' || record.status === 'canceled') {\n payload.completed_at = record.updatedAt;\n }\n if (record.statusMessage) payload.message = record.statusMessage;\n if (\n args.include_result === true &&\n (record.status === 'completed' || record.status === 'failed' || record.status === 'rejected') &&\n record.result !== undefined\n ) {\n payload.result = record.result;\n }\n if (record.status === 'failed' && record.error) {\n // Spec shape: top-level `error: { code, message, details? }` —\n // matches `tasks-get-response.json`'s required `code` + `message`\n // shape with optional `details` carrying a flattened structured-error\n // tail (`recovery`, `field`, `suggestion`, `retry_after`) plus safe\n // adopter-supplied detail fields.\n const { code, message, details: safeDetails, ...tail } = sanitizeStructuredAdcpError(record.error);\n const details =\n safeDetails !== null &&\n safeDetails !== undefined &&\n typeof safeDetails === 'object' &&\n !Array.isArray(safeDetails)\n ? { ...tail, ...(safeDetails as Record<string, unknown>) }\n : safeDetails !== undefined\n ? { ...tail, details: safeDetails }\n : tail;\n payload.error = {\n code,\n message,\n ...(Object.keys(details).length > 0 && { details }),\n };\n }\n return {\n content: [{ type: 'text' as const, text: `Task ${record.taskId} status: ${record.status}` }],\n structuredContent: payload,\n };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Handler merge — incremental migration seam\n// ---------------------------------------------------------------------------\n\n/**\n * Merge adopter-supplied custom handlers with platform-derived handlers.\n * Platform-derived wins per-key when both define the same handler; adopter\n * handlers fill any gaps. Returns `undefined` when neither side has any\n * handlers (so the framework knows the domain is unrouted and can omit it\n * from `tools/list`).\n *\n * Used to bridge the gap between v6 specialism interfaces (which model the\n * stable v1.0 surface) and adopter codebases that need to dispatch\n * tools the platform shape doesn't cover yet (getMediaBuys,\n * listCreativeFormats, providePerformanceFeedback, reportUsage,\n * sync_event_sources, log_event, content-standards CRUD, etc.).\n *\n * **Collision detection.** When a custom-supplied handler would be\n * shadowed by a platform-derived one (i.e., the framework added native\n * coverage for a tool the adopter previously filled via the merge seam),\n * the resolver logs a warning by default. Tells adopters to migrate the\n * custom logic into the platform method. Adopters who genuinely want\n * the custom logic to win can pass `mergeSeam: 'silent'` to skip the\n * warning, `'strict'` to throw a `PlatformConfigError`, or `'log-once'`\n * to suppress duplicate warnings across multiple server constructions\n * in the same process (multi-tenant deployments, hot-reload dev).\n */\ntype MergeSeamMode = 'warn' | 'log-once' | 'silent' | 'strict';\n\n// Module-level dedupe set for `'log-once'` mode. Keyed on\n// `${domain}|${sortedColliders}` so two constructions hitting the same\n// collision pattern only log once across the lifetime of the process.\n// Cleared via `_resetMergeSeamDedupe()` in tests.\nconst mergeSeamLoggedKeys = new Set<string>();\n\n/** @internal — reset the log-once dedupe set. Tests only. */\nexport function _resetMergeSeamDedupe(): void {\n mergeSeamLoggedKeys.clear();\n}\n\nfunction mergeHandlers<T extends object>(\n custom: T | undefined,\n platform: T | undefined,\n domain: string,\n opts: { mode: MergeSeamMode; logger: AdcpLogger }\n): T | undefined {\n if (!custom && !platform) return undefined;\n if (!custom) return platform;\n if (!platform) return custom;\n\n if (opts.mode !== 'silent') {\n const collisions: string[] = [];\n for (const key of Object.keys(platform)) {\n if (key in (custom as Record<string, unknown>)) collisions.push(key);\n }\n if (collisions.length > 0) {\n // Sort for stable dedupe key — same collision set logs the same key\n // regardless of declaration order across constructions.\n const dedupeKey = `${domain}|${[...collisions].sort().join(',')}`;\n const shouldLog = opts.mode !== 'log-once' || !mergeSeamLoggedKeys.has(dedupeKey);\n\n const message =\n `[adcp/decisioning] opts.legacyHandlers.${domain}.{${collisions.join(', ')}} ` +\n `${collisions.length === 1 ? 'is' : 'are'} shadowed by platform-derived handlers. ` +\n `The merge seam is for tools the platform doesn't model yet — once a tool has a native ` +\n `platform method, move the logic there and remove the opts override.`;\n\n if (opts.mode === 'strict') {\n throw new PlatformConfigError(message);\n }\n if (shouldLog) {\n opts.logger.warn(message);\n if (opts.mode === 'log-once') mergeSeamLoggedKeys.add(dedupeKey);\n }\n }\n }\n\n return { ...custom, ...platform };\n}\n\n/**\n * Native media-buy methods operate on the canonical platform surface, while\n * the explicitly named `legacyHandlers` surface is the adopter's raw-wire\n * compatibility escape hatch. For the three lifecycle methods that can echo\n * package selectors, route an actually negotiated legacy request to that raw\n * handler when both implementations are present. Canonical requests continue\n * to use the native platform method, and strict merge-seam collision checking\n * remains unchanged.\n */\nfunction mergeMediaBuyHandlers(\n custom: MediaBuyHandlers<Account> | undefined,\n platform: MediaBuyHandlers<Account> | undefined,\n domain: string,\n opts: { mode: MergeSeamMode; logger: AdcpLogger },\n fallbackWireMode: 'canonical' | 'legacy'\n): MediaBuyHandlers<Account> | undefined {\n const merged = mergeHandlers(custom, platform, domain, opts);\n if (!custom || !platform || !merged) return merged;\n\n const routed = { ...merged } as Record<string, unknown>;\n for (const key of ['createMediaBuy', 'updateMediaBuy', 'getMediaBuys'] as const) {\n const customHandler = (custom as Record<string, unknown>)[key];\n const platformHandler = (platform as Record<string, unknown>)[key];\n if (typeof customHandler !== 'function' || typeof platformHandler !== 'function') continue;\n routed[key] = (...args: unknown[]) => {\n const ctx = args[1] as HandlerContext<Account> | undefined;\n if (ctx && creativeWireModeForRequest(ctx, fallbackWireMode, args[0]) === 'legacy') {\n return Reflect.apply(customHandler, custom, args);\n }\n return Reflect.apply(platformHandler, platform, args);\n };\n }\n return routed as MediaBuyHandlers<Account>;\n}\n\n// ---------------------------------------------------------------------------\n// Observability hook plumbing\n// ---------------------------------------------------------------------------\n\n/**\n * Fire an observability callback with throw-safe semantics — both sync\n * throws AND rejected promises are caught + logged so a buggy span/metric\n * callback never breaks dispatch. The framework does NOT await the\n * callback; if you need async tracer work, do it inside the callback and\n * the framework will not hold the dispatch path waiting for it.\n */\n/**\n * Derive scenario names from a wired `ComplyControllerConfig` adapter\n * set. Each adapter slot maps to one wire scenario name. Order is\n * stable (force → simulate) so adopter wire-fixture snapshots don't\n * churn between releases. Used by the projection seam to populate\n * `get_adcp_capabilities.compliance_testing.scenarios` when the adopter\n * doesn't supply an explicit subset.\n *\n * `list_scenarios` itself is implicit and is not advertised.\n */\nfunction deriveScenariosFromAdapters(\n cfg: ComplyControllerConfig\n): NonNullable<NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']> {\n const out: Array<NonNullable<NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']>[number]> =\n [];\n if (cfg.force?.creative_status) out.push('force_creative_status');\n if (cfg.force?.account_status) out.push('force_account_status');\n if (cfg.force?.media_buy_status) out.push('force_media_buy_status');\n if (cfg.force?.session_status) out.push('force_session_status');\n if (cfg.force?.create_media_buy_arm) out.push('force_create_media_buy_arm');\n if (cfg.force?.task_completion) out.push('force_task_completion');\n if (cfg.force?.creative_purge) out.push('force_creative_purge');\n if (cfg.simulate?.delivery) out.push('simulate_delivery');\n if (cfg.simulate?.budget_spend) out.push('simulate_budget_spend');\n if (cfg.seed?.account) out.push('seed_account');\n if (cfg.seed?.product) out.push('seed_product');\n if (cfg.seed?.pricing_option) out.push('seed_pricing_option');\n if (cfg.seed?.creative) out.push('seed_creative');\n if (cfg.seed?.plan) out.push('seed_plan');\n if (cfg.seed?.media_buy) out.push('seed_media_buy');\n if (cfg.seed?.creative_format) out.push('seed_creative_format');\n if (cfg.seed?.measurement_catalog) out.push('seed_measurement_catalog');\n if (cfg.queryUpstreamTraffic) out.push('query_upstream_traffic');\n if (cfg.queryProvenanceAuditObservations) out.push('query_provenance_audit_observations');\n if (cfg.force?.upstream_unavailable) out.push('force_upstream_unavailable');\n return out;\n}\n\nfunction safeFire<T>(fn: ((arg: T) => unknown) | undefined, arg: T, hookName: string, logger: AdcpLogger): void {\n if (!fn) return;\n let result: unknown;\n try {\n result = fn(arg);\n } catch (err) {\n logger.warn(\n `[adcp/decisioning] observability hook ${hookName} threw — telemetry callbacks must never throw. ` +\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n return;\n }\n // Catch rejected promises from accidentally-async callbacks. Without\n // this an `async () => { throw ... }` hook would surface as\n // UnhandledPromiseRejection and on `--unhandled-rejections=strict`\n // would crash the process. `Promise.resolve()` coerces both real\n // promises and user-land thenables (a thenable returning sync values\n // is wrapped, a true Promise is returned as-is) — safer than the\n // duck-typed `typeof .catch === 'function'` check.\n if (result !== undefined && result !== null) {\n Promise.resolve(result).catch((err: unknown) => {\n logger.warn(\n `[adcp/decisioning] observability hook ${hookName} returned a rejected promise — ` +\n `telemetry callbacks must never reject. ` +\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n });\n }\n}\n\n/**\n * Wrap a `StatusChangeBus` so every publish fires `onStatusChangePublish`\n * after the underlying bus persists the event. Subscribers + recent-buffer\n * pass through; only the publish side is observed.\n */\nfunction wrapBusWithObservability(bus: StatusChangeBus, observability: DecisioningObservabilityHooks): StatusChangeBus {\n return {\n publish<TPayload>(eventOpts: PublishStatusChangeOpts<TPayload>): void {\n bus.publish(eventOpts);\n if (observability.onStatusChangePublish) {\n try {\n observability.onStatusChangePublish({\n accountId: eventOpts.account_id,\n resourceType: eventOpts.resource_type,\n resourceId: eventOpts.resource_id,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] observability hook onStatusChangePublish threw: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n },\n subscribe: bus.subscribe.bind(bus),\n recent: bus.recent.bind(bus),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Default task registry — gated by NODE_ENV\n// ---------------------------------------------------------------------------\n\n/**\n * Build the default in-memory task registry, gated by NODE_ENV.\n *\n * The in-memory registry loses task state on process restart — fine for\n * tests and local dev, NOT fine for production. Gate via allowlist:\n * `NODE_ENV` must be `'test'` or `'development'`, OR the operator must\n * explicitly opt in via `ADCP_DECISIONING_ALLOW_INMEMORY_TASKS=1`.\n *\n * Pattern follows `feedback_node_env_allowlist.md`: never compare\n * `=== 'production'` (production may unset NODE_ENV entirely); always\n * allowlist the safe modes.\n */\n/**\n * Combined DDL for all framework persistence tables: idempotency cache,\n * ctx-metadata cache, and decisioning task registry. Run once per database\n * during deployment / boot. Idempotent — safe to re-run.\n *\n * Use with the `pool` shortcut on `createAdcpServerFromPlatform`:\n *\n * ```ts\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const taskRegistryNamespace = 'tenant:my-agent';\n * await pool.query(getAllAdcpMigrations({ taskRegistryNamespace }));\n *\n * createAdcpServerFromPlatform(myPlatform, {\n * name: '...', version: '...',\n * pool,\n * taskRegistryNamespace,\n * });\n * ```\n *\n * Adopters who don't use the `pool` shortcut should call the per-store\n * migration helpers (`getIdempotencyMigration`, `getCtxMetadataMigration`,\n * `getDecisioningTaskRegistryMigration`) only for the stores they wire.\n *\n * @public\n */\nexport function getAllAdcpMigrations(options: { taskRegistryNamespace: string }): string {\n if (!options) {\n throw new PlatformConfigError(\n 'getAllAdcpMigrations requires { taskRegistryNamespace }; use a stable, trusted deployment or tenant namespace.'\n );\n }\n return [\n getIdempotencyMigration(),\n getCtxMetadataMigration(),\n getDecisioningTaskRegistryMigration({ namespace: options.taskRegistryNamespace }),\n ].join('\\n\\n');\n}\n\nfunction buildDefaultTaskRegistry(): TaskRegistry {\n const env = process.env.NODE_ENV;\n const safe = env === 'test' || env === 'development';\n const ack = process.env.ADCP_DECISIONING_ALLOW_INMEMORY_TASKS === '1';\n if (!safe && !ack) {\n throw new Error(\n 'createAdcpServerFromPlatform: in-memory task registry refused outside ' +\n '{NODE_ENV=test, NODE_ENV=development}. Production deployments need a ' +\n 'durable task registry — pick one of:\\n' +\n ' 1. (Recommended) Pass `taskRegistry: createPostgresTaskRegistry({ pool, namespace: tenantId })` ' +\n 'to keep HITL tasks across restarts. See `@adcp/sdk/server/decisioning` ' +\n 'for `getDecisioningTaskRegistryMigration({ namespace })` — run it once against your DB.\\n' +\n ' 2. Pass `taskRegistry: createInMemoryTaskRegistry()` explicitly if you ' +\n 'accept that in-flight tasks are lost on process restart. The explicit ' +\n 'pass-in is the contract — saying \"yes I want in-memory in production\" ' +\n 'in code is the right shape.\\n' +\n ' 3. ADCP_DECISIONING_ALLOW_INMEMORY_TASKS=1 env flag is the ops escape ' +\n 'hatch (same effect as #2 but config-only); prefer #2 in adopter code.'\n );\n }\n return createInMemoryTaskRegistry();\n}\n\n// ---------------------------------------------------------------------------\n// Sync vs HITL dispatch\n// ---------------------------------------------------------------------------\n\ntype SubmittedEnvelope = {\n status: 'submitted';\n task_id: string;\n};\n\n/**\n * Mid-request token refresh hook config (#1145 Gap 2). When `refresh.fn`\n * is defined and the platform method throws `AdcpError` with a\n * recovery-correctable auth code (`AUTH_REQUIRED` from 3.0.x sellers, or\n * `AUTH_MISSING` from 3.1+ sellers), `projectSync` refreshes the account's\n * token via the hook, mutates or creates `account.authInfo`, and retries the\n * platform method ONCE. `AUTH_INVALID` is terminal — credentials were\n * presented and rejected — so we deliberately do NOT refresh on it (auto-\n * retry against an SSO endpoint on a revoked token is the retry-storm\n * pattern adcp#3730 split the code to prevent). If the refresh hook itself\n * throws, projects to legacy-compatible `AUTH_REQUIRED` with\n * `recovery: 'correctable'` so existing buyers re-link via their UI flow.\n *\n * Parameterized over `TCtxMeta` (#1168) so adopters' refresh hooks see\n * typed `account.ctx_metadata` rather than `unknown`. Default `unknown`\n * preserves backward compat for call sites that don't thread the\n * adopter's metadata shape through.\n */\ninterface RefreshConfig<TCtxMeta = unknown> {\n account: Account<TCtxMeta>;\n fn?: (account: Account<TCtxMeta>, reason: 'auth_required') => Promise<{ token: string; expiresAt?: number }>;\n}\n\nfunction cloneAccountForRequest<TCtxMeta>(account: Account<TCtxMeta>): Account<TCtxMeta> {\n try {\n return structuredClone(account);\n } catch (cause) {\n const publicError = new AdcpError('CONFIGURATION_ERROR', {\n message: 'Resolved account is not safely cloneable for request-local auth refresh.',\n recovery: 'terminal',\n });\n (publicError as Error & { cause?: unknown }).cause = cause;\n throw publicError;\n }\n}\n\n/** Auth codes that signal \"credentials missing, refresh and retry once.\" */\nconst REFRESHABLE_AUTH_CODES: ReadonlySet<string> = new Set(['AUTH_REQUIRED', 'AUTH_MISSING']);\n\n/**\n * Run a platform method with reactive token refresh on missing-credential\n * auth codes (`AUTH_REQUIRED` on 3.0.x sellers, `AUTH_MISSING` on 3.1+).\n * Without a refresh fn (or no `refresh` at all) this passes the call\n * through. With one, catches the refreshable code, calls `refresh.fn`,\n * mutates or creates `account.authInfo` (including `expiresAt` when\n * returned), and retries the inner call exactly once.\n *\n * `AUTH_INVALID` is intentionally NOT refreshed — it's terminal by\n * spec (credentials presented and rejected); refreshing creates the\n * SSO retry-storm pattern adcp#3730 split the code to prevent.\n *\n * Failure modes:\n * - Refresh hook throws → re-throw legacy-compatible `AUTH_REQUIRED` with\n * `recovery: 'correctable'` so the buyer re-links via their UI.\n * - Retried call throws a refreshable auth code again → bubble out\n * (don't refresh a second time).\n */\nasync function runWithTokenRefresh<TCtxMeta, T>(\n fn: () => Promise<T>,\n refresh: RefreshConfig<TCtxMeta> | undefined\n): Promise<T> {\n if (!refresh?.fn) return fn();\n try {\n return await fn();\n } catch (err) {\n if (!(err instanceof AdcpError) || !REFRESHABLE_AUTH_CODES.has(err.code)) {\n throw err;\n }\n let refreshed: { token: string; expiresAt?: number };\n try {\n refreshed = await refresh.fn(refresh.account, 'auth_required');\n } catch (cause) {\n // Refresh-fn exception text is intentionally NOT echoed on the wire\n // — upstream identity-provider error messages routinely embed\n // refresh-token prefixes, internal hostnames, OAuth provider error\n // codes, and stack-trace fragments. Adopters log details server-\n // side; the buyer gets a fixed message + correctable recovery\n // signaling they need to re-authorize.\n const publicError = new AdcpError('AUTH_REQUIRED', {\n message: 'Token refresh failed; re-authentication required',\n recovery: 'correctable',\n });\n (publicError as Error & { cause?: unknown }).cause = cause;\n throw publicError;\n }\n // `authInfo` became optional in #1286. A 3.1-native AUTH_MISSING can mean\n // the upstream request had no usable credential at all, so attach the\n // freshly minted OAuth-style token even when the resolver omitted\n // account.authInfo.\n const authInfo = refresh.account.authInfo ?? { kind: 'oauth' as const };\n authInfo.token = refreshed.token;\n if (refreshed.expiresAt !== undefined) {\n authInfo.expiresAt = refreshed.expiresAt;\n }\n refresh.account.authInfo = authInfo;\n return fn();\n }\n}\n\n/**\n * Project a sync platform call onto the wire dispatch shape. `AdcpError`\n * throws → wire `adcp_error` envelope; other thrown errors bubble to the\n * framework's `SERVICE_UNAVAILABLE` mapping.\n *\n * When `refresh` is provided and the call throws a refreshable auth code, the\n * framework calls `refresh.fn(refresh.account, 'auth_required')`, updates\n * `account.authInfo`, and retries the platform method once.\n */\nasync function projectSync<TResult, TWire, TCtxMeta = unknown>(\n fn: () => Promise<TResult>,\n mapResult: (r: TResult) => TWire,\n refresh?: RefreshConfig<TCtxMeta>\n): Promise<TWire | AdcpErrorResponse> {\n try {\n const result = await runWithTokenRefresh(fn, refresh);\n if (_extractResponseSummaryEntry(result)) {\n throw new TypeError('withResponseSummary is supported only for synchronous getProducts results');\n }\n const wire = mapResult(result as TResult);\n // Single-chokepoint runtime strip: ctx_metadata MUST NEVER cross to the\n // buyer. Defense-in-depth (compile-time WireShape<T> + runtime walk).\n // Mutates `wire` in place — every handler builds a fresh response per\n // call so mutation is safe. Runs BEFORE the framework wraps in envelope\n // / caches in idempotency, so cached replays stay clean too.\n //\n // implementation_config strip: same pattern. Recipes ride on\n // Product.implementation_config server-side (typed contract between\n // ProposalManager and DecisioningPlatform via ctx.recipes) but are\n // opaque-to-buyer. The wire schema is `additionalProperties: true`\n // so the field is technically legal — but recipes carry upstream\n // identifiers (network codes, line-item template ids, ad-unit ids,\n // GAM line-item priority) that leak topology to buyers. Strip\n // before the response leaves the dispatcher.\n if (wire != null && typeof wire === 'object') {\n stripCtxMetadata(wire as Record<string, unknown>);\n stripImplementationConfig(wire as Record<string, unknown>);\n }\n return wire;\n } catch (err) {\n if (err instanceof AdcpError) {\n return adcpError(err.code, {\n message: err.message,\n recovery: err.recovery,\n ...(err.field !== undefined && { field: err.field }),\n ...(err.suggestion !== undefined && { suggestion: err.suggestion }),\n ...(err.retry_after !== undefined && { retry_after: err.retry_after }),\n ...(err.details !== undefined && { details: err.details }),\n });\n }\n // AccountNotFoundError is documented as throwable only from\n // AccountStore.resolve(); but adopters new to the framework\n // sometimes throw it from a specialism method body. Project to\n // ACCOUNT_NOT_FOUND so the wire envelope is right either way —\n // closes the silent-SERVICE_UNAVAILABLE foot-gun the security\n // review flagged. Adopters are still encouraged to handle account\n // not-found inside resolve() (canonical) — this is a guardrail.\n if (err instanceof AccountNotFoundError) {\n return adcpError('ACCOUNT_NOT_FOUND', {\n message: 'Account not found',\n field: 'account',\n });\n }\n throw err;\n }\n}\n\n/**\n * HITL dispatch: allocate task, return submitted envelope to buyer\n * immediately, run the handoff function in background. Method's return\n * value becomes terminal `result`; throws become terminal `error`.\n *\n * **Webhook delivery on terminal state.** When the buyer passed\n * `push_notification_config: { url, token? }` in the request and the host\n * wired `webhooks` on `serve()`, the framework emits a signed RFC 9421\n * webhook to that URL on terminal state with the task lifecycle payload.\n * Buyers don't need to poll — they receive completion via push. Polling via\n * `server.getTaskState(taskId, scope)` continues to work for harnesses + the\n * forthcoming wire-level `tasks/get`.\n */\ninterface DispatchHitlOpts {\n tool: string;\n accountId: string;\n ownerScope?: string;\n pushNotificationUrl?: string;\n pushNotificationToken?: string;\n pushNotificationOperationId?: string;\n servedAdcpVersion?: string;\n emitWebhook?: HandlerContext<Account>['emitWebhook'];\n observability?: DecisioningObservabilityHooks;\n logger: AdcpLogger;\n /** @deprecated Ignored; retained internally during the SDK 14 compatibility window. */\n autoEmitCompletion?: boolean;\n}\n\nfunction taskOwnerScopeFor(ctx: HandlerContext<Account>, accountId: string): string {\n if (ctx.sessionKey !== undefined) return `session:${ctx.sessionKey}`;\n if (ctx.agent?.agent_url) return `agent:${ctx.agent.agent_url}`;\n const credential = ctx.authInfo?.credential;\n if (credential?.kind === 'http_sig') return `http_sig:${credential.agent_url}`;\n if (credential?.kind === 'oauth') return `oauth:${credential.client_id}`;\n if (credential?.kind === 'api_key') return `api_key:${credential.key_id}`;\n if (typeof ctx.authInfo?.clientId === 'string' && ctx.authInfo.clientId.length > 0) {\n return `client:${ctx.authInfo.clientId}`;\n }\n return `account:${accountId}`;\n}\n\nfunction authenticatedPrincipalFor(ctx: HandlerContext<Account>): string | undefined {\n if (ctx.agent?.agent_url) return `agent:${ctx.agent.agent_url}`;\n const credential = ctx.authInfo?.credential;\n if (credential?.kind === 'http_sig') return `http_sig:${credential.agent_url}`;\n if (credential?.kind === 'oauth') return `oauth:${credential.client_id}`;\n if (credential?.kind === 'api_key') return `api_key:${credential.key_id}`;\n if (typeof ctx.authInfo?.clientId === 'string' && ctx.authInfo.clientId.length > 0) {\n return `client:${ctx.authInfo.clientId}`;\n }\n return undefined;\n}\n\nfunction hasPushNotificationConfig(params: unknown): boolean {\n return (\n params != null &&\n typeof params === 'object' &&\n (params as { push_notification_config?: unknown }).push_notification_config !== undefined\n );\n}\n\nfunction rejectHandRolledSubmitted(result: unknown): void {\n // Catch the most common LLM-scaffolded mistake: hand-rolling a\n // `{status: 'submitted', task_id: '...'}` envelope instead of returning\n // `ctx.handoffToTask(fn)`. The framework owns the submitted envelope —\n // adopters either return the sync-success arm or a TaskHandoff marker.\n // A bare submitted-shape return here would slip past dispatch and fail\n // response-schema validation downstream with a generic shape error;\n // pointing at the right SDK primitive up-front saves the debug round-trip.\n if (\n result != null &&\n typeof result === 'object' &&\n (result as { status?: unknown }).status === 'submitted' &&\n 'task_id' in (result as object)\n ) {\n throw new Error(\n `Specialism handler returned a hand-rolled \\`{status: 'submitted', task_id}\\` ` +\n `envelope. The framework owns the submitted envelope — return ` +\n `\\`ctx.handoffToTask(async (taskCtx) => { ... })\\` from the handler ` +\n `and the framework will issue the task_id, persist the handoff, and ` +\n `wrap the wire envelope. Returning a bare submitted shape skips the ` +\n `task registry and the buyer ends up polling a task_id the framework ` +\n `never registered.`\n );\n }\n}\n\nconst RETURNED_ERROR_ARM_KEYS = new Set(['errors', 'context', 'ext', 'success', 'conflicting_standards_id']);\n\n/** Match only a pure generated Error arm, never a success payload carrying advisory errors. */\nfunction isReturnedErrorArm(value: unknown): value is { errors: unknown[]; context?: unknown; ext?: unknown } {\n if (value == null || typeof value !== 'object') return false;\n const record = value as Record<string, unknown>;\n if (!Array.isArray(record.errors) || 'status' in record) return false;\n return Object.keys(record).every(key => RETURNED_ERROR_ARM_KEYS.has(key));\n}\n\n/**\n * Route a unified-shape return value: if it's a `TaskHandoff` marker,\n * dispatch through `dispatchHitl`; otherwise pass through the sync\n * projection.\n *\n * Adopter return type is `Success | TaskHandoff<Success>`. Each\n * specialism dispatcher uses this helper so all four call sites\n * (`createMediaBuy`, `updateMediaBuy`, `sales.syncCreatives`,\n * `creative.syncCreatives`)\n * route through a single seam — closes round-6 CR-1 (drift across\n * near-identical `isTaskHandoff` branches).\n *\n * `project` shapes both arms identically — for `syncCreatives`,\n * `rows → { creatives: rows }`; for `createMediaBuy`, identity.\n */\nasync function routeIfHandoff<TInner, TWire>(\n taskRegistry: TaskRegistry,\n opts: DispatchHitlOpts,\n result: TInner | TaskHandoff<TInner>,\n project: (inner: TInner) => TWire | Promise<TWire>\n): Promise<TWire | SubmittedEnvelope> {\n const rejectResponseSummary = (value: unknown): void => {\n if (_extractResponseSummaryEntry(value)) {\n throw new TypeError('withResponseSummary is supported only for synchronous getProducts results');\n }\n };\n if (isTaskHandoff<TInner>(result)) {\n const entry = _extractHandoffEntry(result);\n if (!entry) {\n // Forgery — adopter constructed something with the brand symbol\n // but didn't go through ctx.handoffToTask. Treat as a sync\n // success arm with an empty body (caller-supplied projection\n // shapes the result; this branch is defensive).\n rejectResponseSummary(result);\n return await project(result as unknown as TInner);\n }\n const { fn: taskFn, options } = entry;\n return dispatchHitl(\n taskRegistry,\n opts,\n async taskId => {\n const inner = await taskFn(\n buildHandoffContext(taskRegistry, taskId, {\n accountId: opts.accountId,\n ownerScope: opts.ownerScope ?? `account:${opts.accountId}`,\n })\n );\n rejectResponseSummary(inner);\n return await project(inner);\n },\n options?.task_id\n );\n }\n rejectHandRolledSubmitted(result);\n rejectResponseSummary(result);\n return await project(result);\n}\n\nasync function dispatchHitl<TResult>(\n taskRegistry: TaskRegistry,\n opts: DispatchHitlOpts,\n taskFn: (taskId: string) => Promise<TResult>,\n overrideTaskId?: string\n): Promise<SubmittedEnvelope> {\n const createStart = Date.now();\n const { taskId } = await taskRegistry.create({\n tool: opts.tool,\n accountId: opts.accountId,\n ownerScope: opts.ownerScope ?? `account:${opts.accountId}`,\n hasWebhook: opts.pushNotificationUrl !== undefined,\n ...(overrideTaskId !== undefined && { overrideTaskId }),\n });\n safeFire(\n opts.observability?.onTaskCreate,\n {\n tool: opts.tool,\n taskId,\n accountId: opts.accountId,\n durationMs: Date.now() - createStart,\n },\n 'onTaskCreate',\n opts.logger\n );\n const taskStart = Date.now();\n\n // Single helper for the four `onTaskTransition` fire sites.\n const fireTransition = (status: 'completed' | 'failed', errorCode?: string): void => {\n safeFire(\n opts.observability?.onTaskTransition,\n {\n taskId,\n tool: opts.tool,\n accountId: opts.accountId,\n status,\n durationMs: Date.now() - taskStart,\n ...(errorCode !== undefined && { errorCode }),\n },\n 'onTaskTransition',\n opts.logger\n );\n };\n\n // Three failure surfaces:\n // 1. taskFn throws → record failure → emit failed webhook\n // 2. taskFn succeeds but registry write fails (DB outage) → log only;\n // do NOT emit webhook (buyer doesn't know task succeeded), do NOT\n // try to fail() the task (taskFn DID succeed; mismatch would\n // mislead operator reconciliation)\n // 3. taskFn fails AND registry fail-write also fails → log only;\n // do not emit webhook (registry state is inconsistent)\n //\n // Webhook delivery is gated on the registry write succeeding so the\n // buyer's view (via webhook OR getTaskState) is always consistent.\n const completion: Promise<void> = (async () => {\n const registryScope = {\n accountId: opts.accountId,\n ownerScope: opts.ownerScope ?? `account:${opts.accountId}`,\n };\n let result: TResult | undefined;\n let taskFnError: unknown;\n try {\n result = await taskFn(taskId);\n } catch (err) {\n taskFnError = err;\n }\n\n if (taskFnError === undefined) {\n // Success path. Strip wire-only-server fields BEFORE the registry\n // write so every downstream consumer (tasks/get polling at\n // line 1826, emitTaskWebhook below at line 2493, idempotency\n // replays of the Submitted envelope) inherits a clean payload.\n // Mirrors the same chokepoint pattern projectSync uses for the\n // sync arm. Without this strip, ctx_metadata + implementation_config\n // ride to the buyer via the HITL completion path even though the\n // sync path is clean — surfaced by security review on PR #1562.\n if (result != null && typeof result === 'object') {\n stripCtxMetadata(result as Record<string, unknown>);\n stripImplementationConfig(result as Record<string, unknown>);\n }\n try {\n await taskRegistry.complete(taskId, registryScope, result as TResult);\n } catch (registryErr) {\n opts.logger.error(\n `[adcp/decisioning] task ${taskId} (${opts.tool}) completed but registry write failed — ` +\n `manual reconciliation required. Webhook not emitted; buyer state will diverge until resolved. ` +\n `Error type: ${registryErr instanceof Error ? 'Error' : typeof registryErr}`\n );\n fireTransition('failed', 'REGISTRY_WRITE_FAILED');\n return;\n }\n fireTransition('completed');\n await emitTaskWebhook(opts, {\n task: { task_id: taskId, status: 'completed', result },\n });\n return;\n }\n\n // Failure path\n const structured = sanitizeStructuredAdcpError(\n taskFnError instanceof AdcpError\n ? taskFnError.toStructuredError()\n : {\n code: 'SERVICE_UNAVAILABLE' as const,\n recovery: 'transient' as const,\n message: 'Task failed',\n }\n );\n const failureArtifact = { errors: [structured] };\n try {\n await taskRegistry.fail(taskId, registryScope, structured, failureArtifact);\n } catch (registryErr) {\n opts.logger.error(\n `[adcp/decisioning] task ${taskId} (${opts.tool}) failed AND registry fail-write also failed — ` +\n `manual reconciliation required. Webhook not emitted. ` +\n `Task error code: ${structured.code}; registry error type: ${registryErr instanceof Error ? 'Error' : typeof registryErr}`\n );\n fireTransition('failed', 'REGISTRY_WRITE_FAILED');\n return;\n }\n fireTransition('failed', structured.code);\n await emitTaskWebhook(opts, {\n task: { task_id: taskId, status: 'failed', result: failureArtifact, error: structured },\n });\n })();\n taskRegistry._registerBackground(\n taskId,\n { accountId: opts.accountId, ownerScope: opts.ownerScope ?? `account:${opts.accountId}` },\n completion\n );\n\n return { status: 'submitted', task_id: taskId };\n}\n\n/**\n * AdCP wire spec puts task / status / context fields on the webhook envelope\n * top level (`mcp-webhook-payload.json`); the success / failure body lives on\n * `result`. This helper builds that shape from the v6 task lifecycle data.\n *\n * Spec requires top-level: `idempotency_key`, `task_id`, `task_type`, `status`,\n * `timestamp`, `operation_id`. Optional: `protocol`, `context_id`, `message`,\n * `result`. We add `validation_token` (echoed from\n * `push_notification_config.token`) outside the spec but consistent with the\n * intent — receivers that don't expect it ignore the extra property.\n *\n * The webhook emitter replaces the placeholder `idempotency_key` with the\n * immutable key bound to its SDK-local `delivery_id`. The payload's\n * `operation_id` remains independent task correlation and can span multiple\n * lifecycle observations, each with a distinct delivery id/key.\n */\nfunction buildTaskWebhookPayload(\n opts: DispatchHitlOpts,\n taskId: string,\n status: TaskStatus,\n artifact: { result?: unknown; error?: AdcpStructuredError }\n): Record<string, unknown> {\n const idempotencyKey = randomUUID();\n const payload: Record<string, unknown> = {\n idempotency_key: idempotencyKey,\n operation_id: resolveWebhookPayloadOperationId(opts, taskId),\n task_id: taskId,\n task_type: opts.tool,\n status,\n timestamp: new Date().toISOString(),\n protocol: protocolForTool(opts.tool),\n };\n // Spec doesn't define a wire field name for the echoed token. Buyers\n // pass `push_notification_config.token` on the request; we echo it back\n // under the same name `token` so receivers verifying via the request\n // field can find it. (Earlier preview drops named this `validation_token`\n // — that wasn't spec-aligned and won't be picked up by buyers wiring\n // against the spec request shape.)\n if (opts.pushNotificationToken !== undefined) {\n payload.token = opts.pushNotificationToken;\n }\n // `result` is the AdCP async-response-data union — for completed it's\n // the success-arm body; for failed it carries `errors: AdcpStructuredError[]`\n // alongside the empty success shape.\n if (status === 'completed' && artifact.result !== undefined) {\n payload.result = artifact.result;\n }\n if (status === 'failed' && artifact.error !== undefined) {\n payload.result = artifact.result ?? { errors: [artifact.error] };\n payload.message = artifact.error.message;\n }\n return payload;\n}\n\nfunction resolveWebhookPayloadOperationId(opts: DispatchHitlOpts, taskId: string): string {\n if (opts.pushNotificationOperationId === undefined && isAdcpVersionAtLeast(opts.servedAdcpVersion, '3.2.0-beta.5')) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'push_notification_config.operation_id is required for webhook delivery',\n field: 'push_notification_config.operation_id',\n });\n }\n // Older negotiated bundles predate buyer-supplied operation IDs. Preserve\n // their stable compatibility value without allowing beta.5+ to synthesize.\n return opts.pushNotificationOperationId ?? `${opts.tool}.${taskId}`;\n}\n\nfunction resolveWebhookDeliveryId(opts: DispatchHitlOpts, taskId: string): string {\n return `task-webhook:${opts.accountId}:${opts.tool}:${taskId}`;\n}\n\n// `protocolForTool` and `SPEC_WEBHOOK_TASK_TYPES` are exported from\n// `protocol-for-tool.ts` — see import at top of file.\n\nasync function emitTaskWebhook(\n opts: DispatchHitlOpts,\n source: { task: { task_id: string; status: 'completed' | 'failed'; result?: unknown; error?: AdcpStructuredError } }\n): Promise<void> {\n if (!opts.emitWebhook || !opts.pushNotificationUrl) return;\n const taskId = source.task.task_id;\n // Spec gate: `enums/task-type.json` is a closed 20-value enum at AdCP\n // 3.0 GA. Spec-validating receivers reject envelopes with a non-spec\n // `task_type` value. The framework dispatches a wider tool surface\n // than the spec-listed task types — for those, skip webhook delivery\n // (adopters surface long-running state via `publishStatusChange`\n // instead). Tracking spec issue to widen the enum.\n if (!SPEC_WEBHOOK_TASK_TYPES.has(opts.tool)) {\n opts.logger.warn(\n `[adcp/decisioning] task webhook for ${taskId} (${opts.tool}) skipped — ` +\n `tool not in spec task-type enum (closed 20-value set per enums/task-type.json). ` +\n `Use publishStatusChange for long-running ${opts.tool} state.`\n );\n return;\n }\n const wirePayload = buildTaskWebhookPayload(opts, taskId, source.task.status, {\n ...(source.task.result !== undefined && { result: source.task.result }),\n ...(source.task.error !== undefined && { error: source.task.error }),\n });\n const start = Date.now();\n let success = false;\n let errorMessages: string[] | undefined;\n let errorCode: string | undefined;\n try {\n const result = await opts.emitWebhook({\n url: opts.pushNotificationUrl,\n payload: wirePayload,\n delivery_id: resolveWebhookDeliveryId(opts, taskId),\n });\n success = result?.delivered === true;\n if (result && Array.isArray(result.errors) && result.errors.length > 0) {\n errorMessages = result.errors;\n errorCode = bucketWebhookError(result.errors[0] ?? '');\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errorMessages = [msg];\n errorCode = bucketWebhookError(msg);\n // Webhook failures don't fail the task — registry already records the\n // terminal state. URL redacted from log to avoid leaking buyer-supplied\n // attacker-controllable values into operator log aggregators.\n opts.logger.warn(\n `[adcp/decisioning] task webhook for ${taskId} (${opts.tool}, status=${source.task.status}) ` + `failed: ${msg}`\n );\n } finally {\n safeFire(\n opts.observability?.onWebhookEmit,\n {\n taskId,\n tool: opts.tool,\n status: source.task.status,\n url: opts.pushNotificationUrl,\n success,\n durationMs: Date.now() - start,\n ...(errorCode && { errorCode }),\n ...(errorMessages && { errorMessages }),\n },\n 'onWebhookEmit',\n opts.logger\n );\n }\n}\n\n/**\n * Bucket a free-text webhook error into a metric-tag-safe code. Matches\n * `DecisioningObservabilityHooks.onWebhookEmit.errorCode` documented enum\n * (`'TIMEOUT'`, `'CONNECTION_REFUSED'`, `'HTTP_4XX'`, `'HTTP_5XX'`,\n * `'SIGNATURE_FAILURE'`, `'UNKNOWN'`). Adopters tag DD/Prom by the bucket;\n * `errorMessages` carries the raw text for log adopters.\n */\nfunction bucketWebhookError(msg: string): string {\n const lower = msg.toLowerCase();\n if (lower.includes('timeout') || lower.includes('etimedout')) return 'TIMEOUT';\n if (lower.includes('econnrefused') || lower.includes('connection refused')) return 'CONNECTION_REFUSED';\n if (lower.includes('signature') || lower.includes('rfc 9421')) return 'SIGNATURE_FAILURE';\n // Find ALL 3-digit HTTP-status-shaped tokens. Take the LARGEST one —\n // operator triage cares about the most-severe status, not the\n // left-most occurrence. Fixes \"upstream 502 (proxy received 401)\"\n // which would mis-bucket as HTTP_4XX under a first-match policy.\n // 3xx is included because signed webhook delivery never follows redirects, so\n // a redirecting endpoint is a real (and common) misconfiguration that would\n // otherwise bucket as UNKNOWN and stay invisible in operator dashboards.\n const matches = lower.match(/\\b[345]\\d\\d\\b/g);\n if (matches && matches.length > 0) {\n const codes = matches.map(m => parseInt(m, 10));\n const max = Math.max(...codes);\n if (max >= 500) return 'HTTP_5XX';\n if (max >= 400) return 'HTTP_4XX';\n return 'HTTP_REDIRECT';\n }\n return 'UNKNOWN';\n}\n\n// ---------------------------------------------------------------------------\n// Specialism → handler-map adapters\n// ---------------------------------------------------------------------------\n\n/**\n * Per-server `ctxFor` builder. `createAdcpServerFromPlatform` constructs\n * one closure per server (capturing `opts.ctxMetadata` if wired) and\n * threads it into each handler-builder. Handler bodies invoke\n * `ctxFor(ctx, params)` at request time to derive the per-call\n * `RequestContext`. The `params` argument is the un-destructured wire\n * envelope; it lands on `RequestContext.input` so platform methods can\n * read request fields the typed signature doesn't model (`assignments[]`\n * on `sync_creatives`, `delete_missing` on `sync_audiences`, etc.).\n */\ntype CtxForFn = (\n handlerCtx: HandlerContext<Account>,\n input?: Readonly<Record<string, unknown>>\n) => RequestContext<Account>;\n\nfunction makeCtxFor(ctxMetadataStore?: CtxMetadataStore): CtxForFn {\n return (handlerCtx, input) => buildRequestContext(handlerCtx, ctxMetadataStore, input);\n}\n\n/**\n * Project a framework `HandlerContext` / `RequestContext` to the public\n * `ResolveContext` shape passed to every `AccountStore` method\n * (`resolve`, `upsert`, `list`, `reportUsage`, `getAccountFinancials`).\n *\n * Single source of truth for the threading shape: when `ResolveContext`\n * gains a new field, update this function and every account-method call\n * site picks it up. The alternative (inline literals at each call site)\n * is what produced the original asymmetric `agent` gap on `reportUsage`\n * and `getAccountFinancials` — fixed by routing all six framework call\n * sites through here.\n *\n * `toolName` is supplied per call site (handlers hardcode their tool\n * name; the dispatcher's `resolveAccount` / `resolveAccountFromAuth`\n * paths read it off `RequestContext.toolName`). Spread guards keep\n * `authInfo` / `agent` keys absent rather than `undefined` — adopters\n * can use `'authInfo' in ctx` as a presence check.\n */\nfunction toResolveCtx(\n ctx: { authInfo?: ResolvedAuthInfo; agent?: BuyerAgent },\n toolName: string | undefined,\n input?: Readonly<Record<string, unknown>>\n): ResolveContext {\n return {\n ...(ctx.authInfo !== undefined && { authInfo: ctx.authInfo }),\n ...(toolName !== undefined && { toolName }),\n ...(ctx.agent != null && { agent: ctx.agent }),\n ...(input != null && { input }),\n };\n}\n\n/**\n * Auto-store helper. After a publisher returns resources from a discovery\n * tool (`getProducts`, `getMediaBuys`, etc.), persist each resource's wire\n * shape (minus `ctx_metadata`) alongside the publisher's `ctx_metadata`\n * blob. Subsequent calls referencing the same id by string can be hydrated\n * (publisher sees the full resource as `req.packages[i].product`).\n *\n * Failures are logged + swallowed — auto-store must NEVER break a\n * successful response.\n */\nasync function autoStoreResources(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n kind: ResourceKind,\n resources: readonly unknown[] | undefined,\n idField: string,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId || !resources) return;\n let skippedMissingId = 0;\n for (const r of resources) {\n if (r == null || typeof r !== 'object') continue;\n const obj = r as Record<string, unknown>;\n const id = obj[idField];\n if (typeof id !== 'string' || id.length === 0) {\n // The id field is wire-required on every resource the framework\n // auto-stores (e.g. `signal_agent_segment_id` on a signal,\n // `product_id` on a product). Silently skipping leaves buyers with\n // no way to reference the resource on a downstream mutating call —\n // a strong indicator the handler returned a misshaped response.\n skippedMissingId++;\n continue;\n }\n const ctxMeta = obj['ctx_metadata'];\n // Strip ctx_metadata from the resource before storing — round-trip\n // restores it on hydration. Keeping a pristine wire copy in `resource`.\n const {\n ctx_metadata: _stripped,\n [STORED_LEGACY_FORMAT_ROUTES]: _reservedRouteMetadata,\n ...wireResource\n } = obj as Record<string, unknown>;\n void _stripped;\n void _reservedRouteMetadata;\n const legacyFormatRoutes = kind === 'product' ? captureStoredLegacyFormatRoutes(obj) : undefined;\n if (legacyFormatRoutes) wireResource[STORED_LEGACY_FORMAT_ROUTES] = legacyFormatRoutes;\n try {\n // Use `setResource` (not `setEntry`) so a publisher's prior\n // `ctx.ctxMetadata.set(kind, id, blob)` is preserved when the\n // publisher returns the resource WITHOUT `ctx_metadata` inline.\n // Auto-store should never clobber adopter-managed state.\n await store.setResource(accountId, kind, id, wireResource, ctxMeta);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store ${kind} ${id} failed: ${msg}`);\n }\n }\n if (skippedMissingId > 0) {\n logger.warn(\n `[adcp/decisioning] auto-store skipped ${skippedMissingId} ${kind} ` +\n `record(s) missing required '${idField}' — buyers will not be able ` +\n `to reference these resources on a subsequent mutating call.`\n );\n }\n}\n\n/**\n * Persist `packages[].targeting_overlay` from a successful\n * `create_media_buy`. Called from the createMediaBuy projection so the\n * persistence applies to both the sync arm and the HITL completion arm\n * (the projection runs after the handoff fn resolves).\n *\n * Failures are logged + swallowed: a successful seller response must\n * never be turned into an error by the auto-echo plumbing.\n */\nasync function persistTargetingOverlayFromCreate(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n request: unknown,\n result: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n if (result == null || typeof result !== 'object') return;\n try {\n await store.persistFromCreate(\n accountId,\n request as CreateMediaBuyInputForStore,\n result as CreateMediaBuyResultForStore\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.persistFromCreate failed: ${msg}`);\n }\n}\n\n/**\n * Apply an `update_media_buy` patch to the persisted media-buy store.\n * Per-field merge inside `targeting_overlay`: omitted keeps prior,\n * present-non-null replaces, present-null clears.\n *\n * Failures are logged + swallowed for the same reason as the create\n * path — the seller's update succeeded; auto-merge is best-effort.\n */\nasync function persistTargetingOverlayFromUpdate(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n mediaBuyId: string,\n patch: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n try {\n await store.mergeFromUpdate(accountId, mediaBuyId, patch as UpdateMediaBuyInputForStore);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.mergeFromUpdate failed: ${msg}`);\n }\n}\n\n/**\n * Backfill missing `packages[].targeting_overlay` on a `get_media_buys`\n * response from the persisted store. Mutates the response. Packages the\n * seller already echoed are left alone.\n *\n * Failures are logged + swallowed: a partial-echo response is strictly\n * better than a hard error wiping out the seller's correctly-returned\n * media-buy data.\n */\nasync function backfillTargetingOverlay(\n store: MediaBuyStore | undefined,\n accountId: string | undefined,\n result: unknown,\n logger: AdcpLogger\n): Promise<void> {\n if (!store || !accountId) return;\n if (result == null || typeof result !== 'object') return;\n try {\n await store.backfill(accountId, result as GetMediaBuysResultForStore);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] mediaBuyStore.backfill failed: ${msg}`);\n }\n}\n\n/**\n * Auto-hydrate helper. Before invoking a publisher's mutating handler,\n * walk the request's resource references and attach the full wire\n * resource (including `ctx_metadata`) to each. Mutates the request in\n * place — adds an extra typed field alongside the original id.\n *\n * For `createMediaBuy`: walks `req.packages`, hydrates each with\n * `pkg.product = { ...resource, ctx_metadata }` keyed by `pkg.product_id`.\n *\n * Failures are logged + swallowed; the publisher still receives the\n * un-hydrated request and can fall back to its own DB.\n */\nasync function hydratePackagesWithProducts(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n packages: unknown[] | undefined,\n logger: AdcpLogger,\n legacyFormatConverter: LegacyFormatConverter | undefined\n): Promise<void> {\n if (!store || !accountId || !packages || packages.length === 0) return;\n const refs: Array<{ kind: 'product'; id: string }> = [];\n for (const pkg of packages) {\n if (pkg == null || typeof pkg !== 'object') continue;\n const productId = (pkg as Record<string, unknown>)['product_id'];\n if (typeof productId === 'string' && productId.length > 0) {\n refs.push({ kind: 'product', id: productId });\n }\n }\n if (refs.length === 0) return;\n let entries: ReadonlyMap<string, { value: unknown; resource?: unknown }>;\n try {\n entries = await store.bulkGetEntries(accountId, refs);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-hydrate bulkGet failed: ${msg}`);\n return;\n }\n for (const pkg of packages) {\n if (pkg == null || typeof pkg !== 'object') continue;\n const productId = (pkg as Record<string, unknown>)['product_id'];\n if (typeof productId !== 'string') continue;\n const entry = entries.get(`product:${productId}`);\n if (!entry?.resource || typeof entry.resource !== 'object') continue;\n let hydrated: Record<string, unknown>;\n try {\n const storedResource = entry.resource as Record<string, unknown>;\n const { [STORED_LEGACY_FORMAT_ROUTES]: storedLegacyFormatRoutes, ...resource } = storedResource;\n hydrated = asCanonicalSemanticServerRequest(resource, 'hydrate_product', legacyFormatConverter) as Record<\n string,\n unknown\n >;\n restoreStoredLegacyFormatRoutes(hydrated, storedLegacyFormatRoutes);\n } catch {\n logger.warn(\n `[adcp/decisioning] auto-hydrate product:${productId} skipped: stored creative format has no canonical representation`\n );\n continue;\n }\n if (entry.value !== null && entry.value !== undefined) {\n hydrated['ctx_metadata'] = entry.value;\n }\n Object.defineProperty(hydrated, '__adcp_hydrated__', {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n // Non-enumerable: see hydrateSingleResource for rationale (no leak via\n // JSON.stringify / spread / Object.entries; direct access works).\n Object.defineProperty(pkg, 'product', {\n value: hydrated,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n}\n\n/**\n * Auto-hydrate one resource referenced by id at the top level of a request.\n *\n * Generalization of {@link hydratePackagesWithProducts} for verbs whose\n * primary resource lives directly on the request body (`update_media_buy`,\n * `provide_performance_feedback`, `activate_signal`, `acquire_rights`).\n * Walks the store for `(kind, id)`, attaches `target[attachField] =\n * { ...resource, ctx_metadata }` when the entry has a wire resource.\n *\n * ## Error contract on missing references\n *\n * **Misses are silent. The handler runs anyway with `target[attachField]`\n * undefined.** This is deliberate — the framework cache is a *hint*, not\n * the source of truth. A miss can mean any of:\n *\n * 1. The buyer never called the discovery verb in this session (cold\n * start, fresh tenant). Hydration is purely additive context; the\n * publisher's own DB is authoritative for whether the id exists.\n * 2. The cache evicted (TTL, LRU). Same: publisher's DB stays the\n * source of truth.\n * 3. The buyer truly referenced an unknown id. The publisher SHOULD\n * reject this — see the handler-side guard pattern below.\n *\n * Adopters who want strict existence checks (option 1: framework throws\n * `PRODUCT_NOT_FOUND` / `MEDIA_BUY_NOT_FOUND` and the handler never runs)\n * implement that check inside the handler:\n *\n * ```ts\n * updateMediaBuy: async (id, patch, ctx) => {\n * // Hydration miss + DB miss = unknown to this seller.\n * if (!patch.media_buy && !(await db.findMediaBuy(id))) {\n * throw new MediaBuyNotFoundError({ message: `media_buy ${id} not found` });\n * }\n * // ...\n * }\n * ```\n *\n * The framework cannot distinguish (1)/(2) from (3) without consulting the\n * publisher's DB, which is exactly what the handler does. Erroring at the\n * framework layer would force every adopter to manage cache warmth or\n * pre-load every media_buy into the cache before serving traffic — wrong\n * default for a hint-based cache.\n *\n * ## Field semantics on the hydrated value\n *\n * The attached field is **non-enumerable** so accidental serialization\n * (`JSON.stringify(req)`, spread `{...req}`, `Object.entries(req)`)\n * doesn't leak the publisher's `ctx_metadata` blob into request-side audit\n * sinks. Direct property access (`req.media_buy.ctx_metadata`) still\n * works; the field is invisible only to enumeration-based serializers.\n *\n * Hydrated fields carry a `__adcp_hydrated__: true` non-enumerable marker\n * so handler authors and middleware can disambiguate \"publisher passed it\"\n * from \"framework attached it\" — the field is **advisory context only**;\n * the wire contract is defined by the spec request fields, not by what\n * the SDK happens to attach.\n *\n * Store-fetch failures (Postgres unavailable, etc.) are logged + swallowed.\n * Hydration must NEVER break a successful dispatch — same posture as a\n * cache miss.\n */\nasync function hydrateSingleResource(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n kind: ResourceKind,\n id: string | undefined,\n attachField: string,\n target: unknown,\n logger: AdcpLogger,\n legacyFormatConverter?: LegacyFormatConverter\n): Promise<void> {\n if (!store || !accountId || !id || target == null || typeof target !== 'object') return;\n let entry: { value: unknown; resource?: unknown } | undefined;\n try {\n entry = await store.getEntry(accountId, kind, id);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-hydrate ${kind}:${id} failed: ${msg}`);\n return;\n }\n if (!entry?.resource || typeof entry.resource !== 'object') return;\n let hydrated: Record<string, unknown>;\n if (legacyFormatConverter !== undefined || kind === 'media_buy' || kind === 'package' || kind === 'creative') {\n try {\n hydrated = asCanonicalSemanticServerRequest(entry.resource, `hydrate_${kind}`, legacyFormatConverter) as Record<\n string,\n unknown\n >;\n } catch {\n logger.warn(\n `[adcp/decisioning] auto-hydrate ${kind}:${id} skipped: stored creative format has no canonical representation`\n );\n return;\n }\n } else {\n hydrated = { ...(entry.resource as Record<string, unknown>) };\n }\n if (entry.value !== null && entry.value !== undefined) {\n hydrated['ctx_metadata'] = entry.value;\n }\n Object.defineProperty(hydrated, '__adcp_hydrated__', {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n // Attach as non-enumerable so JSON.stringify(req), spread {...req}, and\n // Object.entries(req) do NOT carry the publisher's ctx_metadata blob into\n // log lines, audit sinks, or replay payloads. Direct access (req.foo)\n // still works.\n Object.defineProperty(target, attachField, {\n value: hydrated,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Spec `x-entity` annotation → SDK `ResourceKind`. The SDK only hydrates\n * resource kinds it has a backing store for; unmapped entities (e.g.\n * `vendor_pricing_option`, `governance_plan`) are gracefully skipped.\n *\n * The annotation acts as a renaming-firewall: if the spec renames\n * `media_buy_id` → `mediabuy_id`, the `x-entity: \"media_buy\"` tag travels\n * with the field and the codegen step in `scripts/generate-entity-hydration.ts`\n * picks up the new field name automatically — no SDK code change required.\n *\n * Adding a new `ResourceKind` for hydration is a coordinated change: add\n * it to `ResourceKind` (in `ctx-metadata/store.ts`) and to this map.\n */\n/** @internal Exported for the coverage test in `test/lib/x-entity-hydration.test.js`. */\nexport const ENTITY_TO_RESOURCE_KIND: Readonly<Record<string, ResourceKind>> = {\n media_buy: 'media_buy',\n package: 'package',\n creative: 'creative',\n audience: 'audience',\n // Spec quirk: `signal_activation_id` is a SEPARATE entity from `signal`\n // (per AdCP `core/x-entity-types.json` — the activation handle is\n // scoped to the issuing signals agent, not interchangeable with the\n // catalog's `signal_id`). The SDK collapses them onto the existing\n // `signal` ResourceKind for backward-compat: adopters already seed\n // the cache keyed by `signal_agent_segment_id` under `kind: 'signal'`.\n // Splitting `signal_activation` to its own ResourceKind would orphan\n // those entries. Tracked upstream — file an `adcp` issue if/when this\n // collapse causes confusion.\n signal_activation_id: 'signal',\n rights_grant: 'rights_grant',\n property_list: 'property_list',\n collection_list: 'collection_list',\n account: 'account',\n product: 'product',\n // SI session lifecycle, hydrated on `si_send_message` /\n // `si_terminate_session` from the entry the framework auto-stores after\n // `si_initiate_session`. See `buildSponsoredIntelligenceHandlers`.\n si_session: 'si_session',\n};\n\n/**\n * `x-entity` values the SDK does NOT hydrate today — graceful skip rather\n * than failure. Entries here are documented intentional skips so a future\n * code reader can distinguish \"we forgot to map this\" from \"the SDK\n * doesn't model this kind.\"\n *\n * The codegen-derived `TOOL_ENTITY_FIELDS` map carries every `x-entity`\n * the spec emits on dispatchable tools (webhook-only payloads like\n * `creative_approval` are filtered out at codegen time); this allowlist\n * + `ENTITY_TO_RESOURCE_KIND` together must cover the full set,\n * enforced by a test (`test/lib/x-entity-hydration.test.js`) that\n * imports both.\n *\n * @internal Exported for the coverage test; not part of the public API.\n */\nexport const INTENTIONALLY_UNHYDRATED_ENTITIES: ReadonlySet<string> = new Set([\n 'vendor_pricing_option', // Scoped to issuing vendor agent; adopters seed pricing context themselves.\n 'governance_plan', // No SDK ResourceKind yet; campaign-governance follow-up.\n 'governance_check', // Transient request envelope; not stored.\n 'event_source', // No SDK ResourceKind yet.\n 'offering', // SI offering catalog; correlation handled by brand-side `offering_token`, not framework hydration.\n 'rights_holder_brand', // Read-through `get_brand_identity`; not separately stored.\n 'advertiser_brand', // Same as above.\n 'transformer', // Creative build capability catalog entry; no ctx-metadata ResourceKind yet.\n 'build_variant', // Build lineage/refinement handle; no ctx-metadata ResourceKind yet.\n 'task', // Protocol task reconciliation id; task registry handles lookup, not ctx_metadata hydration.\n 'proposal', // ProposalStore owns proposal lifecycle/CAS; ctx-metadata hydration would bypass those controls.\n 'governance_adjustment', // Durable governance receipt identifier; no SDK ResourceKind/store yet.\n 'governance_outcome', // Durable governance receipt identifier; no SDK ResourceKind/store yet.\n 'seller_adjustment', // Seller-authored adjustment reference; resolved by governance workflows, not ctx metadata.\n]);\n\n/**\n * Per-tool, per-field destination property name for hydrated resources.\n *\n * The hydrator's default is to derive the destination from the field name\n * by stripping the `_id` suffix (e.g. `media_buy_id` → attach as\n * `params.media_buy`). Three cases need explicit overrides because their\n * historical attach-fields don't match that convention — adopters already\n * read these in handler code and a rename would be wire-visible behavior:\n *\n * - `acquire_rights.rights_id` → `params.rights` (NOT `rights_grant`).\n * Predates the entity-driven hydrator. Kept for backward-compat.\n * - `activate_signal.signal_agent_segment_id` → `params.signal`\n * (NOT `signal_agent_segment` — `_id` suffix isn't on the boundary\n * the convention strips).\n * - `update_rights.rights_id` → `params.rights_grant` (NOT `rights`).\n * Diverges from `acquire_rights`'s historical `params.rights` because\n * the wire payloads model different things — acquire takes an\n * offering selection, update modifies an existing grant.\n *\n * Other tools either follow the convention (`update_media_buy`,\n * `provide_performance_feedback`) or don't currently have hydration\n * registered (the unmapped `x-entity` skips above).\n */\nconst HYDRATION_ATTACH_FIELD_OVERRIDES: Readonly<Record<string, Readonly<Record<string, string>>>> = {\n acquire_rights: { rights_id: 'rights' },\n activate_signal: { signal_agent_segment_id: 'signal' },\n update_rights: { rights_id: 'rights_grant' },\n};\n\nfunction deriveAttachField(toolName: string, field: string): string {\n const override = HYDRATION_ATTACH_FIELD_OVERRIDES[toolName]?.[field];\n if (override) return override;\n // Default: strip the `_id` suffix so `media_buy_id` → `media_buy`,\n // `creative_id` → `creative`, etc. This is the convention every existing\n // hydration call site followed before the schema-driven refactor.\n return field.endsWith('_id') ? field.slice(0, -3) : field;\n}\n\n/**\n * Schema-driven auto-hydration for a tool's request payload.\n *\n * Walks the codegen-derived `TOOL_ENTITY_FIELDS` table for the named tool,\n * looks up each spec-tagged identifier on `params`, maps the `x-entity`\n * annotation to a `ResourceKind`, and attaches the resolved record at the\n * conventional destination field. Replaces the four hand-rolled\n * `hydrateSingleResource` call sites that hardcoded `(field_name, kind)`\n * pairs and were vulnerable to a silent break under a future spec rename\n * (protocol-expert review of #1086 → tracked as #1109).\n */\nasync function hydrateForTool(\n store: CtxMetadataStore | undefined,\n accountId: string | undefined,\n toolName: string,\n params: unknown,\n logger: AdcpLogger,\n legacyFormatConverter?: LegacyFormatConverter\n): Promise<void> {\n if (!store || !accountId || params == null || typeof params !== 'object') return;\n const fields = TOOL_ENTITY_FIELDS[toolName];\n if (!fields || fields.length === 0) return;\n const paramsRecord = params as Record<string, unknown>;\n for (const { field, xEntity } of fields) {\n const id = paramsRecord[field];\n if (typeof id !== 'string' || id.length === 0) continue;\n const kind = ENTITY_TO_RESOURCE_KIND[xEntity];\n if (!kind) continue; // Unknown entity — graceful skip; don't break unknown verbs.\n const attachField = deriveAttachField(toolName, field);\n await hydrateSingleResource(store, accountId, kind, id, attachField, params, logger, legacyFormatConverter);\n }\n}\n\n/**\n * Extract the buyer's push-notification webhook config from a request body\n * and validate the URL + token against SSRF / replay primitives.\n *\n * AdCP wire requests for HITL tools carry `push_notification_config: { url,\n * token? }`. The buyer-supplied URL is attacker-controllable — without\n * validation, a buyer with `create_media_buy` access can force the agent\n * process to POST signed payloads to internal admin endpoints, AWS metadata\n * (`http://169.254.169.254/`), or RFC 1918 private ranges. Validation\n * gates here:\n *\n * 1. **Scheme**: `https://` only in production; `http://` allowed when\n * `NODE_ENV` ∈ {test, development} OR the operator opts in via\n * `ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS=1`. Same allowlist pattern as\n * the in-memory task registry.\n * 2. **Host**: rejects IP-literals targeting RFC 1918 private ranges\n * (10/8, 172.16/12, 192.168/16), link-local (169.254/16, fe80::/10),\n * loopback (127/8, ::1), CGNAT (100.64/10), and unspecified addresses\n * (0.0.0.0, ::). Rejects bare hostnames `localhost` / `0`.\n * 3. **Token shape**: rejects tokens longer than 255 chars or containing\n * control characters. Tokens past 255 chars combined with a malicious\n * URL would inflate webhook payload size; control characters break log\n * redaction.\n *\n * Adopters who need stricter rules (host allowlist) can re-validate\n * inside their `taskWebhookEmitter` impl. Adopters needing to relax for\n * legitimate internal-network test setups use the env-var ack.\n *\n * **DNS rebinding caveat.** This validator only inspects the literal\n * hostname/IP in the URL. A buyer registers `https://rebind.attacker.com/`\n * whose A-record returns `8.8.8.8` at validate time and `127.0.0.1` /\n * `169.254.169.254` at fetch time bypasses this layer. The framework's\n * own `serve({ webhooks })`-wired emitter (RFC 9421-signed delivery via\n * `WebhookManager`) re-resolves the host at fetch time and DOES NOT\n * pin-and-bind to the validate-time IP. Adopters wiring a custom\n * `taskWebhookEmitter` SHOULD pin the resolved IP at validate time and\n * connect to that specific IP, OR run all webhook delivery through a\n * forward proxy with an egress allowlist. Tracking issue:\n * `adcp-client#TBD` for framework-side pin-and-bind.\n *\n * On rejection, throws `AdcpError('INVALID_REQUEST', { field })` so the\n * buyer sees the bad config at the request boundary. Previous silent-skip\n * posture lost buyer visibility.\n */\nfunction extractPushConfig(\n params: unknown,\n _logger: AdcpLogger,\n opts: { allowPrivateWebhookUrls?: boolean } = {}\n): { url?: string; token?: string; operationId?: string } {\n if (!params || typeof params !== 'object') return {};\n const cfg = (params as { push_notification_config?: unknown }).push_notification_config;\n if (!cfg || typeof cfg !== 'object') return {};\n const cfgObj = cfg as { url?: unknown; token?: unknown; operation_id?: unknown };\n const rawUrl = cfgObj.url;\n const rawToken = cfgObj.token;\n const rawOperationId = cfgObj.operation_id;\n\n let url: string | undefined;\n if (typeof rawUrl === 'string') {\n const validation = validatePushNotificationUrl(rawUrl, { allowPrivate: opts.allowPrivateWebhookUrls === true });\n if (!validation.ok) {\n // Fail fast: buyers thought they wired push and never saw it under\n // the previous silent-skip posture. Rejecting upfront with\n // `INVALID_REQUEST` and `field: 'push_notification_config.url'`\n // surfaces the problem at the request boundary so buyers can fix\n // their config before relying on webhooks. Buyers can still poll\n // via `tasks_get` if they need a fallback path.\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.url rejected: ${validation.reason}`,\n field: 'push_notification_config.url',\n });\n }\n url = rawUrl;\n }\n\n let token: string | undefined;\n if (typeof rawToken === 'string') {\n const validation = validatePushNotificationToken(rawToken);\n if (!validation.ok) {\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.token rejected: ${validation.reason}`,\n field: 'push_notification_config.token',\n });\n }\n token = rawToken;\n }\n\n let operationId: string | undefined;\n if (Object.prototype.hasOwnProperty.call(cfgObj, 'operation_id')) {\n if (typeof rawOperationId !== 'string') {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'push_notification_config.operation_id rejected: operation_id must be a string',\n field: 'push_notification_config.operation_id',\n });\n }\n const validation = validatePushNotificationOperationId(rawOperationId);\n if (!validation.ok) {\n throw new AdcpError('INVALID_REQUEST', {\n message: `push_notification_config.operation_id rejected: ${validation.reason}`,\n field: 'push_notification_config.operation_id',\n });\n }\n operationId = rawOperationId;\n }\n\n return {\n ...(url !== undefined && { url }),\n ...(token !== undefined && { token }),\n ...(operationId !== undefined && { operationId }),\n };\n}\n\ninterface UrlValidationResult {\n ok: boolean;\n reason?: string;\n}\n\nfunction validatePushNotificationUrl(rawUrl: string, opts: { allowPrivate?: boolean } = {}): UrlValidationResult {\n let parsed: URL;\n try {\n parsed = new URL(rawUrl);\n } catch {\n return { ok: false, reason: 'malformed URL' };\n }\n\n const allowHttp =\n process.env.NODE_ENV === 'test' ||\n process.env.NODE_ENV === 'development' ||\n process.env.ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS === '1';\n\n if (parsed.protocol === 'http:' && !allowHttp) {\n return {\n ok: false,\n reason: 'http:// scheme not allowed (use https:// or set ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS=1)',\n };\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { ok: false, reason: `unsupported scheme \"${parsed.protocol}\" (only http: / https:)` };\n }\n\n // Adopter-set flag bypasses ONLY the private-IP / loopback rejection.\n // Malformed-URL and scheme checks above always fire — the relaxation\n // is scoped to \"let sandbox webhook receivers bind to loopback\" not\n // \"trust everything.\" See CreateAdcpServerFromPlatformOptions.\n if (opts.allowPrivate === true) {\n return { ok: true };\n }\n\n // Node's `URL.hostname` returns IPv6 literals WITH brackets — so\n // `https://[::1]/` yields `[::1]`. Strip them so our IPv6 checks below\n // can match the unbracketed form. (`URL.host` includes the port, which\n // we don't want here.)\n let host = parsed.hostname.toLowerCase();\n if (host.startsWith('[') && host.endsWith(']')) {\n host = host.slice(1, -1);\n }\n if (host === '' || host === 'localhost' || host === '0') {\n return { ok: false, reason: `host \"${host}\" rejected (loopback / unspecified)` };\n }\n\n // Note on IPv4 alternate forms (integer `2130706433`, hex `0x7f000001`,\n // octal `0177.0.0.1`): Node's WHATWG URL parser canonicalizes all of\n // these to dotted-decimal before we see `parsed.hostname`. So\n // `https://2130706433/` arrives here with host `127.0.0.1` and falls\n // through to the dotted-decimal range check below. Defense-in-depth\n // alternate-form regex rejectors are not needed at this layer.\n\n // IPv4 dotted-decimal check\n const ipv4Match = host.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (ipv4Match) {\n const a = Number(ipv4Match[1]);\n const b = Number(ipv4Match[2]);\n if (a === 10) return { ok: false, reason: 'RFC 1918 private range 10/8 rejected' };\n if (a === 127) return { ok: false, reason: 'loopback range 127/8 rejected' };\n if (a === 0) return { ok: false, reason: 'unspecified range 0/8 rejected' };\n if (a === 169 && b === 254) return { ok: false, reason: 'link-local 169.254/16 rejected (cloud metadata)' };\n if (a === 172 && b >= 16 && b <= 31) return { ok: false, reason: 'RFC 1918 private range 172.16/12 rejected' };\n if (a === 192 && b === 168) return { ok: false, reason: 'RFC 1918 private range 192.168/16 rejected' };\n if (a === 100 && b >= 64 && b <= 127) return { ok: false, reason: 'CGNAT range 100.64/10 rejected' };\n if (a >= 224) return { ok: false, reason: 'multicast / reserved range rejected' };\n }\n\n // IPv6 literal check — Node strips brackets so we match unbracketed forms.\n // A hostname containing `:` is an IPv6 literal (DNS hostnames disallow `:`).\n if (host.includes(':')) {\n // Loopback + unspecified — exact match\n if (host === '::1') return { ok: false, reason: 'IPv6 loopback ::1 rejected' };\n if (host === '::') return { ok: false, reason: 'IPv6 unspecified :: rejected' };\n // Link-local fe80::/10 — match strict prefix `fe80:` (not just `fe80`)\n if (host.startsWith('fe80:')) {\n return { ok: false, reason: 'IPv6 link-local fe80::/10 rejected' };\n }\n // Unique-local fc00::/7 — match strict prefix `fc` or `fd` followed\n // by exactly one more hex char (so fc00:, fcab:, fd00:, fdef:) and\n // then `:`. Old check `host.startsWith('fc')` would match the\n // hostname-not-IP `fc-cdn.example.com`; since IPv6 hostnames always\n // contain `:`, restrict to literals where char[2] is hex + `:`.\n if (/^f[cd][0-9a-f]{2}:/.test(host)) {\n return { ok: false, reason: 'IPv6 unique-local fc00::/7 rejected' };\n }\n // IPv4-mapped IPv6 — `::ffff:127.0.0.1` or `::ffff:7f00:0001`. Either\n // form: extract the embedded IPv4 (if dotted) or the last 32 bits and\n // re-run the IPv4 range checks. Simpler: reject any `::ffff:` prefix\n // pointing to a private IPv4 by recursive validation.\n const v4MappedMatch = host.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (v4MappedMatch) {\n const inner = v4MappedMatch[1];\n const innerCheck = validatePushNotificationUrl(`http://${inner}/`);\n if (!innerCheck.ok) {\n return { ok: false, reason: `IPv4-mapped IPv6 ${host}: ${innerCheck.reason}` };\n }\n }\n // Hex IPv4-mapped form (`::ffff:7f00:0001`): match the 32-bit\n // suffix and convert to dotted form for re-check.\n const v4MappedHexMatch = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (v4MappedHexMatch) {\n const high = parseInt(v4MappedHexMatch[1]!, 16);\n const low = parseInt(v4MappedHexMatch[2]!, 16);\n const dotted = `${(high >> 8) & 0xff}.${high & 0xff}.${(low >> 8) & 0xff}.${low & 0xff}`;\n const innerCheck = validatePushNotificationUrl(`http://${dotted}/`);\n if (!innerCheck.ok) {\n return { ok: false, reason: `IPv4-mapped IPv6 ${host}: ${innerCheck.reason}` };\n }\n }\n }\n\n return { ok: true };\n}\n\nconst TOKEN_MAX_LENGTH = 255;\nconst TOKEN_CONTROL_CHAR_RE = /[\\x00-\\x1f\\x7f]/;\nconst PUSH_OPERATION_ID_RE = /^[A-Za-z0-9_.:-]{1,255}$/;\n\nfunction validatePushNotificationToken(token: string): UrlValidationResult {\n if (token.length === 0) {\n return { ok: false, reason: 'token is empty' };\n }\n if (token.length > TOKEN_MAX_LENGTH) {\n return { ok: false, reason: `token longer than ${TOKEN_MAX_LENGTH} chars` };\n }\n if (TOKEN_CONTROL_CHAR_RE.test(token)) {\n return { ok: false, reason: 'token contains control characters' };\n }\n return { ok: true };\n}\n\nfunction validatePushNotificationOperationId(operationId: string): UrlValidationResult {\n if (!PUSH_OPERATION_ID_RE.test(operationId)) {\n return { ok: false, reason: `operation_id must match ${PUSH_OPERATION_ID_RE.source}` };\n }\n return { ok: true };\n}\n\nfunction buildProposalNegotiationHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn\n): ProposalNegotiationHandlers<Account> | undefined {\n const lifecycle = platform.mediaBuyLifecycle;\n if (!lifecycle?.refineProposals) return undefined;\n if (!lifecycle.proposalRefinement) {\n throw new PlatformConfigError(\n 'mediaBuyLifecycle.refineProposals requires mediaBuyLifecycle.proposalRefinement capability metadata'\n );\n }\n\n return {\n capabilities: lifecycle.proposalRefinement,\n resolveScope: ctx => {\n const accountId = ctx.account?.id;\n if (!accountId) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'refine_proposals requires an authenticated account scope',\n recovery: 'correctable',\n });\n }\n const principalId = authenticatedPrincipalFor(ctx);\n if (!principalId) {\n throw new AdcpError('AUTH_REQUIRED', {\n message: 'refine_proposals requires an authenticated buyer principal',\n recovery: 'correctable',\n });\n }\n return { tenant_id: accountId, account_id: accountId, principal_id: principalId };\n },\n refineProposals: async (params, ctx) => {\n const request = params as unknown as Readonly<Record<string, unknown>>;\n const reqCtx = ctxFor(ctx, request);\n if (!reqCtx.account?.id) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'refine_proposals requires an authenticated account scope',\n recovery: 'correctable',\n });\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(request, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await lifecycle.refineProposals!(params, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'refine_proposals',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n value => value\n );\n },\n value => value\n );\n },\n };\n}\n\nfunction buildMediaBuyHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n mediaBuyStore: MediaBuyStore | undefined,\n proposalStore: import('../proposal').ProposalStore | undefined,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n legacyFormatResolver: LegacyFormatResolver | undefined,\n legacyFormatResolverOptions: { timeoutMs: number; concurrency: number },\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n creativeWireMode: 'canonical' | 'legacy'\n): MediaBuyHandlers<Account> | undefined {\n const sales = platform.sales;\n const lifecycle = platform.mediaBuyLifecycle;\n const getMediaBuyDelivery = lifecycle?.getMediaBuyDelivery ?? sales?.getMediaBuyDelivery;\n const getMediaBuys = lifecycle?.getMediaBuys ?? sales?.getMediaBuys;\n const proposalManager = (platform as { proposalManager?: import('../proposal').ProposalManager }).proposalManager;\n // Without a legacy sales surface, compact lifecycle, or proposal manager,\n // there's nothing to dispatch.\n if (!sales && !lifecycle && !proposalManager) return undefined;\n\n const dispatchCompactMutation = async <TResult>(\n tool: string,\n params: Readonly<Record<string, unknown>>,\n ctx: HandlerContext<Account>,\n invoke: (reqCtx: RequestContext<Account>) => Promise<TResult | TaskHandoff<TResult>>\n ) => {\n return projectSync(\n async () => {\n if (ctx.authInfo === undefined && ctx.agent === undefined) {\n throw new AdcpError('AUTH_MISSING', {\n message: `${tool} requires an authenticated buyer principal`,\n recovery: 'correctable',\n });\n }\n const accountId = ctx.account?.id;\n if (!accountId) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: `${tool} requires a resolved account scope`,\n recovery: 'correctable',\n });\n }\n const principalId = authenticatedPrincipalFor(ctx);\n if (!principalId) {\n throw new AdcpError('AUTH_MISSING', {\n message: `${tool} requires an authenticated buyer principal`,\n recovery: 'correctable',\n });\n }\n const callerMutationScope = Object.freeze({\n tenant_id: accountId,\n account_id: accountId,\n principal_id: principalId,\n });\n const reqCtx = ctxFor({ ...ctx, callerMutationScope }, params);\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await invoke(reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool,\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n value => value\n );\n },\n value => value\n );\n };\n\n // Core lifecycle methods are optional on the SalesPlatform interface\n // (#1341) — the per-specialism mapping in `RequiredPlatformsFor<S>`\n // enforces \"you claimed `sales-non-guaranteed`, therefore you must\n // implement getProducts\" at the type level, while specialisms whose\n // upstream owns bidding (`sales-social`) skip them entirely. The\n // dispatcher mirrors that with conditional spreads — we don't register\n // a wire handler when the platform method is absent, so the merge seam\n // (`opts.legacyHandlers.mediaBuy.X`) can supply it OR the framework returns\n // `METHOD_NOT_FOUND` from `tools/list` for the unsupported tool.\n return {\n ...(lifecycle?.listProducts && {\n listProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listProducts']>>) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => lifecycle.listProducts!(params, reqCtx),\n value => value\n );\n },\n }),\n ...(lifecycle?.requestProposals && {\n requestProposals: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['requestProposals']>>\n ) =>\n dispatchCompactMutation('request_proposals', params, ctx, reqCtx =>\n lifecycle.requestProposals!(params, reqCtx)\n ),\n }),\n ...(lifecycle?.declineProposals && {\n declineProposals: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['declineProposals']>>\n ) =>\n dispatchCompactMutation('decline_proposals', params, ctx, reqCtx =>\n lifecycle.declineProposals!(params, reqCtx)\n ),\n }),\n ...(lifecycle?.buyProducts && {\n buyProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['buyProducts']>>) =>\n dispatchCompactMutation('buy_products', params, ctx, reqCtx => lifecycle.buyProducts!(params, reqCtx)),\n }),\n ...(lifecycle?.acceptProposal && {\n acceptProposal: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['acceptProposal']>>) =>\n dispatchCompactMutation('accept_proposal', params, ctx, reqCtx => lifecycle.acceptProposal!(params, reqCtx)),\n }),\n ...(lifecycle?.controlMediaBuy && {\n controlMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['controlMediaBuy']>>\n ) =>\n dispatchCompactMutation('control_media_buy', params, ctx, reqCtx => lifecycle.controlMediaBuy!(params, reqCtx)),\n }),\n ...((sales?.getProducts || proposalManager) && {\n getProducts: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getProducts']>>) => {\n const responseWireMode = creativeWireModeForRequest(\n ctx,\n creativeWireMode,\n params as Readonly<Record<string, unknown>>\n );\n const canonicalParams = asCanonicalGetProductsRequest(params as unknown as Record<string, unknown>);\n const reqCtx = ctxFor(ctx, params as Readonly<Record<string, unknown>>);\n // v1.5 seam: intercept refine[i].action='finalize' before\n // dispatching to the manager / sales. When the framework\n // commits the proposal inline, project the response directly.\n if (proposalManager && proposalStore) {\n const intercept = await maybeInterceptFinalize({\n request: canonicalParams,\n manager: proposalManager,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (intercept.kind === 'intercepted') {\n // Unified sync-or-HITL dispatch. routeIfHandoff runs\n // `intercept.project` inline for sync `FinalizeProposalSuccess`\n // returns and inside the background task for HITL handoffs.\n // Same machinery createMediaBuy / syncCreatives use — finalize\n // inherits the framework's task-lifecycle guarantees.\n //\n // **Known gap (HITL only)**: if the buyer calls tasks/cancel\n // while the adopter's handoff fn is still mid-run, the\n // framework marks the task cancelled but `intercept.project`\n // (which fires when the handoff fn resolves) still runs\n // store.commit. The committed proposal then sits in the\n // store with no buyer-facing task to retrieve it. Same gap\n // exists for createMediaBuy HITL today (see comment in\n // `sales.createMediaBuy` body re: CONSUMING reservation\n // cleanup). Mitigations: the proposal expires via the\n // 7-day eviction window in `InMemoryProposalStore`, and\n // production durable stores can implement a sweep against\n // the task registry to release stale committed-but-\n // unretrievable proposals. Closing the gap end-to-end\n // requires propagating an AbortSignal into the projection\n // — framework-level work tracked separately, not finalize-\n // specific.\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const out = await routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_products',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n intercept.result,\n intercept.project\n );\n return out as never;\n }\n }\n return projectSync(\n async () => {\n const buyingMode = (params as { buying_mode?: string }).buying_mode;\n if (buyingMode === 'wholesale' && hasPushNotificationConfig(params)) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_products buying_mode=wholesale is synchronous and does not support push_notification_config; use incomplete[] for partial feed results.',\n field: 'push_notification_config',\n recovery: 'correctable',\n });\n }\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n // Pick dispatch target: ProposalManager (when wired) takes\n // ownership of get_products; sales is the v1 fallback.\n // Refine routing per Python's _select_proposal_method:\n // refine_products iff buying_mode='refine' AND\n // capabilities.refine AND the manager implements it.\n type GetProductsPayload = import('../specialisms/sales').GetProductsPayload;\n type GetProductsHandlerResult = import('../specialisms/sales').GetProductsHandlerResult;\n let result: GetProductsHandlerResult;\n if (proposalManager) {\n const useRefine =\n buyingMode === 'refine' &&\n proposalManager.capabilities.refine === true &&\n typeof proposalManager.refineProducts === 'function';\n result = useRefine\n ? await proposalManager.refineProducts!(canonicalParams, reqCtx as never)\n : await proposalManager.getProducts(canonicalParams, reqCtx as never);\n } else {\n result = (await sales!.getProducts!(canonicalParams, reqCtx)) as GetProductsHandlerResult;\n }\n const summarized = _extractResponseSummaryEntry<GetProductsPayload>(result);\n if (\n summarized &&\n (isTaskHandoff(summarized.payload) || _extractResponseSummaryEntry(summarized.payload) !== undefined)\n ) {\n throw new TypeError('withResponseSummary may wrap only a synchronous getProducts payload');\n }\n const resultForRouting = summarized?.payload ?? result;\n const projectProducts = async (terminalResult: GetProductsPayload) => {\n const preparedProjection = preparePerProductProjectionCatalogs(terminalResult, legacyFormatConverter);\n const requestLegacyFormatConverter = await resolveLegacyProductFormats(\n preparedProjection.response,\n preparedProjection.converter,\n legacyFormatResolver,\n {\n ...(ctx.servedAdcpVersion !== undefined && { servedAdcpVersion: ctx.servedAdcpVersion }),\n ...(reqCtx.account?.id !== undefined && { accountId: reqCtx.account.id }),\n ...(ctx.signal !== undefined && { signal: ctx.signal }),\n ...legacyFormatResolverOptions,\n }\n );\n const canonicalResult = asCanonicalProductResponse(\n preparedProjection.response,\n requestLegacyFormatConverter\n );\n // Auto-store products: persist each Product's wire shape +\n // ctx_metadata so subsequent createMediaBuy / updateMediaBuy\n // calls referencing product_id can hydrate the full Product\n // automatically (publisher sees `req.packages[i].product`).\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'product',\n (canonicalResult as { products?: readonly unknown[] })?.products,\n 'product_id',\n logger\n );\n // v1.5 seam: persist proposals[] as DRAFT records (with\n // typed recipes pulled from Product.implementation_config)\n // so subsequent finalize / create_media_buy can hydrate.\n // Read recipes from the adopter's original semantic result,\n // before wire sanitization turns Set-backed capability overlap\n // into transport-safe data. Recipes are internal state and never\n // cross the buyer-facing response boundary.\n if (proposalStore) {\n await maybePersistDraftAfterGetProducts({\n response: terminalResult as unknown as import('../proposal').ProposalGetProductsPayload,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n }\n const wireResponse = asProductResponseForWire(\n canonicalResult,\n responseWireMode,\n canonicalFormatLegacyResolver,\n shouldEmitTransitionalDualCreativeWire(ctx.servedAdcpVersion, params)\n ) as unknown as import('../../../types/tools.generated').GetProductsResponse;\n return summarized\n ? productsResponse(\n wireResponse as unknown as Parameters<typeof productsResponse>[0],\n summarized.summary\n )\n : wireResponse;\n };\n const isHandoff = isTaskHandoff<GetProductsPayload>(resultForRouting);\n if (buyingMode === 'wholesale' && isHandoff) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_products buying_mode=wholesale must return synchronously; use incomplete[] for partial feed results.',\n field: 'buying_mode',\n recovery: 'correctable',\n });\n }\n if (!isHandoff && push.url === undefined) {\n rejectHandRolledSubmitted(resultForRouting);\n return projectProducts(resultForRouting as GetProductsPayload);\n }\n const accountId = reqCtx.account?.id;\n if (accountId === undefined) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'Async get_products and push_notification_config require account-scoped discovery.',\n field: 'account',\n recovery: 'correctable',\n });\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_products',\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n resultForRouting as GetProductsPayload | TaskHandoff<GetProductsPayload>,\n projectProducts\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.createMediaBuy && {\n createMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['createMediaBuy']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(\n ctx,\n creativeWireMode,\n params as Readonly<Record<string, unknown>>\n );\n params = asCanonicalSemanticServerRequest(params, 'create_media_buy', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params as Readonly<Record<string, unknown>>);\n // Auto-hydrate: walk `params.packages`, attach the full Product object\n // (including `ctx_metadata`) at `pkg.product`. Publisher reads\n // `pkg.product.format_ids`, `pkg.product.ctx_metadata?.gam?.ad_unit_ids`\n // directly — no separate lookup, no boilerplate.\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { packages?: unknown[] })?.packages,\n logger,\n legacyFormatConverter\n );\n // v1.5 seam: when the request carries a proposal_id, reserve\n // the proposal (atomic CAS COMMITTED → CONSUMING), validate\n // expiry + capability overlap, hydrate ctx.recipes. The\n // adapter runs against the reservation; finalize_consumption\n // (success) or release_consumption (failure) closes it out.\n let reservation: ReservedProposal<ProposalRecipe> | null = null;\n if (proposalStore) {\n reservation = await maybeReserveProposalForCreateMediaBuy({\n request: params as { proposal_id?: string; packages?: ReadonlyArray<unknown> } & Record<string, unknown>,\n manager: proposalManager,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (reservation) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = reservation.recipes;\n }\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n let result: Awaited<ReturnType<NonNullable<typeof sales.createMediaBuy>>>;\n try {\n result = await sales!.createMediaBuy!(params as unknown as CanonicalCreateMediaBuyRequest, reqCtx);\n } catch (err) {\n // Adapter rejected — roll back the reservation so the buyer\n // can retry without PROPOSAL_NOT_COMMITTED blocking them.\n if (reservation && proposalStore) {\n await releaseProposalReservation({\n store: proposalStore,\n record: reservation,\n logger,\n });\n }\n throw err;\n }\n if (isReturnedErrorArm(result)) {\n // A returned domain Error arm is a failed create, not a\n // successful proposal consumption or sync-completion webhook.\n // Restore the proposal so the corrected request can retry.\n if (reservation && proposalStore) {\n await releaseProposalReservation({\n store: proposalStore,\n record: reservation,\n logger,\n });\n }\n return asSemanticServerResponseForWire(\n result,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n // Inline-success path: promote CONSUMING → CONSUMED with the\n // adapter's media_buy_id. HITL handoff: the proposal stays\n // CONSUMING until the handoff completes — wiring the\n // post-completion commit hook is a v1.6 follow-up; for now\n // adopters using HITL accept the reservation lingers until\n // eviction. Most adopters use inline create_media_buy.\n if (reservation && proposalStore && !isTaskHandoff(result)) {\n const mediaBuyId = (result as { media_buy_id?: string }).media_buy_id;\n if (mediaBuyId) {\n await finalizeProposalConsumption({\n store: proposalStore,\n record: reservation,\n mediaBuyId,\n });\n }\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'create_media_buy',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n async r => {\n await persistTargetingOverlayFromCreate(mediaBuyStore, reqCtx.account?.id, params, r, logger);\n return asSemanticServerResponseForWire(\n r,\n 'create_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.updateMediaBuy && {\n updateMediaBuy: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['updateMediaBuy']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'update_media_buy', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n // `media_buy_id` is required on the wire schema, but `validation: 'off'`\n // mode skips the schema parse — guard at the seam so platform code can\n // trust the value rather than re-checking. Also catches buyers calling\n // with the param missing under an off-spec server config.\n const { media_buy_id } = params;\n if (!media_buy_id) {\n return adcpError('INVALID_REQUEST', {\n message: 'update_media_buy requires media_buy_id',\n field: 'media_buy_id',\n });\n }\n // Auto-hydrate: attach the full MediaBuy (wire shape + ctx_metadata)\n // at `req.media_buy`. Publisher reads `req.media_buy.ctx_metadata?.gam`\n // directly — no separate lookup. Misses are silent; publisher falls\n // back to its own DB. Schema-driven via `x-entity` (#1109).\n await hydrateForTool(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'update_media_buy',\n params,\n logger,\n legacyFormatConverter\n );\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { packages?: unknown[] }).packages,\n logger,\n legacyFormatConverter\n );\n await hydratePackagesWithProducts(\n ctxMetadataStore,\n reqCtx.account?.id,\n (params as { new_packages?: unknown[] }).new_packages,\n logger,\n legacyFormatConverter\n );\n // v1.5 seam: hydrate ctx.recipes via reverse-index so the adapter's\n // updateMediaBuy can apply the same recipe that drove createMediaBuy.\n // Re-validates capability overlap on any packages-shaped patch\n // (Resolutions §5).\n if (proposalStore) {\n const record = await maybeHydrateRecipesForMediaBuyId({\n mediaBuyId: media_buy_id,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n packages: (params as { packages?: ReadonlyArray<unknown> }).packages,\n });\n if (record) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = record.recipes;\n }\n }\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await sales!.updateMediaBuy!(\n media_buy_id,\n params as unknown as CanonicalUpdateMediaBuyRequest,\n reqCtx\n );\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'update_media_buy',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n async r => {\n // A TaskHandoff marker is not acceptance of the patch. Apply\n // the local overlay only when the sync call or background\n // task completes and the result is projected to the wire.\n await persistTargetingOverlayFromUpdate(\n mediaBuyStore,\n reqCtx.account?.id,\n media_buy_id,\n params,\n logger\n );\n return asSemanticServerResponseForWire(\n r,\n 'update_media_buy',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n }\n );\n },\n r => r\n );\n },\n }),\n\n ...(sales?.syncCreatives && {\n syncCreatives: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['syncCreatives']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'sync_creatives', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n const creatives = (params.creatives ?? []) as CanonicalSyncCreativeAsset[];\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await sales.syncCreatives!(creatives, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'sync_creatives',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n rows =>\n asSemanticServerResponseForWire(\n { creatives: rows.map(normalizeRowErrors) },\n 'sync_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n r => r\n );\n },\n }),\n\n ...(getMediaBuyDelivery && {\n getMediaBuyDelivery: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getMediaBuyDelivery']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n // v1.5 seam: hydrate ctx.recipes for delivery reads. Per\n // Resolutions §5, recipe-driven delivery aggregation needs the\n // same recipe view the originating createMediaBuy used.\n if (proposalStore) {\n const ids = (params as { media_buy_ids?: readonly string[] }).media_buy_ids;\n // The wire shape uses `media_buy_ids[]`; hydrate from the first id\n // when present (per-buy recipe lookup; if buyer queries multiple\n // ids, the adapter is responsible for per-id recipe routing).\n const firstId = Array.isArray(ids) && ids.length > 0 ? ids[0] : undefined;\n if (firstId) {\n const record = await maybeHydrateRecipesForMediaBuyId({\n mediaBuyId: firstId,\n store: proposalStore,\n ctx: reqCtx as unknown as { account: { id: string } },\n });\n if (record) {\n (reqCtx as unknown as { recipes?: ReadonlyMap<string, ProposalRecipe> }).recipes = record.recipes;\n }\n }\n }\n return projectSync(\n async () => {\n const result = await getMediaBuyDelivery(asValidatedDomainRequest(params), reqCtx);\n warnIfTruncatedMultiIdResponse(\n 'getMediaBuyDelivery',\n 'media_buy_ids',\n (params as { media_buy_ids?: readonly string[] }).media_buy_ids,\n (result as { media_buy_deliveries?: readonly unknown[] })?.media_buy_deliveries,\n logger\n );\n return asSemanticServerResponseForWire(\n result,\n 'get_media_buy_delivery',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n },\n actuals => actuals\n );\n },\n }),\n\n // Optional methods — return UNSUPPORTED_FEATURE when the platform omits\n // them. Adopters that haven't migrated to the v6 platform interface for\n // these specific tools can still pass raw handlers via opts.legacyHandlers.mediaBuy\n // (merge seam) — the merge runs AFTER buildMediaBuyHandlers, so opts\n // handlers fill in for the methods this platform omits.\n // `getMediaBuys` is REQUIRED at the type level, but we keep a runtime\n // guard for the merge-seam migration path: legacy adopters wire it via\n // `opts.legacyHandlers.mediaBuy.getMediaBuys` rather than on the platform interface.\n // Once the migration completes (every adopter implements it natively),\n // this conditional spreads can collapse — but for now, omitting the\n // platform-derived handler when absent lets `mergeHandlers` pick up the\n // adopter's custom handler from `opts.legacyHandlers.mediaBuy` instead of throwing\n // `sales.getMediaBuys is not a function`.\n ...(getMediaBuys && {\n getMediaBuys: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['getMediaBuys']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await getMediaBuys(asValidatedDomainRequest(params), reqCtx);\n warnIfTruncatedMultiIdResponse(\n 'getMediaBuys',\n 'media_buy_ids',\n (params as { media_buy_ids?: readonly string[] }).media_buy_ids,\n (result as { media_buys?: readonly unknown[] })?.media_buys,\n logger\n );\n const canonicalResult = asCanonicalSemanticServerResponse(\n result,\n 'get_media_buys',\n legacyFormatConverter,\n canonicalFormatLegacyResolver\n );\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'media_buy',\n (canonicalResult as { media_buys?: readonly unknown[] })?.media_buys,\n 'media_buy_id',\n logger\n );\n const wireResult =\n responseWireMode === 'canonical'\n ? attachCanonicalFormatWireRefs(canonicalResult, canonicalFormatLegacyResolver, 'get_media_buys')\n : asSemanticServerResponseForWire(\n result,\n 'get_media_buys',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n await backfillTargetingOverlay(mediaBuyStore, reqCtx.account?.id, wireResult, logger);\n return wireResult;\n },\n r => r\n );\n },\n }),\n ...(sales?.providePerformanceFeedback && {\n providePerformanceFeedback: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['providePerformanceFeedback']>>\n ) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'provide_performance_feedback', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.media_buy` from the prior createMediaBuy /\n // getMediaBuys store entry, plus `req.creative` when the buyer\n // scoped feedback to a specific creative, plus `req.package`\n // when scoped to a package. All three are optional hydration\n // targets — adopters who only care about the feedback payload\n // itself can ignore them. Schema-driven via `x-entity` (#1109);\n // package hydration is additive vs the prior hardcoded version\n // (silent no-op when packages aren't seeded).\n await hydrateForTool(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'provide_performance_feedback',\n params,\n logger,\n legacyFormatConverter\n );\n return projectSync(\n () => sales!.providePerformanceFeedback!(asValidatedDomainRequest(params), reqCtx),\n result =>\n asSemanticServerResponseForWire(\n result,\n 'provide_performance_feedback',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n }),\n ...(sales?.listCreativeFormatsLegacy && {\n listCreativeFormats: async (\n ...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listCreativeFormats']>>\n ) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales!.listCreativeFormatsLegacy!(params, reqCtx),\n r => r\n );\n },\n }),\n ...(sales?.listCreatives && {\n listCreatives: async (...[params, ctx]: Parameters<NonNullable<MediaBuyHandlers<Account>['listCreatives']>>) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const canonicalParams = asCanonicalListCreativesRequest(\n params as unknown as Record<string, unknown>,\n legacyFormatConverter,\n responseWireMode\n );\n const reqCtx = ctxFor(ctx, canonicalParams);\n return projectSync(\n async () => {\n const result = await sales!.listCreatives!(canonicalParams, reqCtx);\n const canonicalResult = asSemanticServerResponseForWire(\n result,\n 'list_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n warnIfTruncatedMultiIdResponse(\n 'listCreatives',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (canonicalResult as { creatives?: readonly unknown[] })?.creatives,\n logger\n );\n return canonicalResult as unknown as import('../../../types/tools.generated').ListCreativesResponse;\n },\n r => r\n );\n },\n }),\n } as unknown as MediaBuyHandlers<Account>;\n}\n\n/**\n * Project an adopter `buildCreative` return value into the wire response\n * shape. Handles the five legal adopter shapes per `BuildCreativeReturn`:\n *\n * - Already-shaped Single envelope (`creative_manifest` field present) →\n * passthrough. Adopter set `sandbox` / `expires_at` / `preview` themselves.\n * - Already-shaped Multi envelope (`creative_manifests` field present) →\n * passthrough. Same metadata-controlled case for multi-format requests.\n * - Already-shaped multiplicity envelope (`creatives` field present) →\n * passthrough. Used for best-of-N, variant-axis, and catalog fan-out.\n * - Bare array → wrap as `{ creative_manifests: <array> }` (multi, no metadata).\n * - Plain `CreativeManifest` → wrap as `{ creative_manifest: <obj> }`\n * (single, no metadata).\n *\n * The discriminator order matters: check shaped envelopes first so an\n * adopter that returned `{ creative_manifest, sandbox: true }` (a Single\n * envelope) doesn't get re-wrapped into\n * `{ creative_manifest: { creative_manifest, sandbox: true } }`. Same\n * concern applies symmetrically for Multi.\n */\nfunction projectBuildCreativeReturn(\n ret: unknown\n): BuildCreativeSuccess | BuildCreativeMultiSuccess | BuildCreativeVariantSuccess {\n if (ret != null && typeof ret === 'object' && !Array.isArray(ret)) {\n if ('creatives' in ret) return ret as BuildCreativeVariantSuccess;\n if ('creative_manifest' in ret) return ret as BuildCreativeSuccess;\n if ('creative_manifests' in ret) return ret as BuildCreativeMultiSuccess;\n }\n if (Array.isArray(ret)) {\n return { creative_manifests: ret as CreativeManifest[] };\n }\n return { creative_manifest: ret as CreativeManifest };\n}\n\nfunction buildCreativeHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n legacyFormatConverter: LegacyFormatConverter | undefined,\n canonicalFormatLegacyResolver: CanonicalFormatLegacyResolver | undefined,\n creativeWireMode: 'canonical' | 'legacy'\n): CreativeHandlers<Account> | undefined {\n const creative = platform.creative;\n if (!creative) return undefined;\n\n return {\n buildCreative: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => creative.buildCreativeLegacy(asValidatedDomainRequest(params), reqCtx),\n ret => projectBuildCreativeReturn(ret)\n );\n },\n\n previewCreative: async (params, ctx) => {\n const canonicalHandler =\n 'previewCreative' in creative ? (creative as CreativeBuilderPlatform).previewCreative : undefined;\n const legacyHandler =\n 'previewCreativeLegacy' in creative ? (creative as CreativeBuilderPlatform).previewCreativeLegacy : undefined;\n const usesLegacyFormatId =\n params.format_id != null ||\n (Array.isArray(params.requests) && params.requests.some(request => request.format_id != null));\n\n if (usesLegacyFormatId && legacyHandler == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'preview_creative: this creative platform does not support legacy format_id preview requests. ' +\n 'Use target_capability_id, creative_id, or creative_manifest with the canonical previewCreative handler.',\n });\n }\n if (canonicalHandler == null && legacyHandler == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'preview_creative: this creative platform did not implement previewCreative. ' +\n 'Add `previewCreative(req, ctx)` to your CreativeBuilderPlatform / CreativeAdServerPlatform literal.',\n });\n }\n const reqCtx = ctxFor(ctx, params);\n if (usesLegacyFormatId || canonicalHandler == null) {\n return projectSync(\n () => legacyHandler!(params, reqCtx),\n preview => preview\n );\n }\n return projectSync(\n () => canonicalHandler(params as CanonicalPreviewCreativeRequest, reqCtx),\n preview => preview\n );\n },\n\n // No-account tool — `list_creative_formats` request schema doesn't carry\n // `account`. The framework's `resolveAccountFromAuth` runs and accepts a\n // null return; the platform method receives `ctx.account` possibly\n // undefined per `NoAccountCtx`. Wired identically on both\n // `CreativeBuilderPlatform` and `CreativeAdServerPlatform`.\n listCreativeFormats: async (params, ctx) => {\n if (!('listCreativeFormatsLegacy' in creative) || creative.listCreativeFormatsLegacy == null) {\n return adcpError('UNSUPPORTED_FEATURE', {\n message:\n 'list_creative_formats: this creative platform did not implement listCreativeFormatsLegacy. ' +\n 'Add `listCreativeFormatsLegacy(req, ctx)` to your CreativeBuilderPlatform / CreativeAdServerPlatform literal, ' +\n 'or delegate via `capabilities.creative_agents`.',\n });\n }\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => (creative as CreativeBuilderPlatform).listCreativeFormatsLegacy!(params, reqCtx),\n r => r\n );\n },\n\n // Only register sync_creatives when the platform actually implements it.\n // Unconditionally returning UNSUPPORTED_FEATURE would advertise the tool in\n // tools/list and trigger the buyer retry-policy (two wasted round-trips) for\n // platforms that never supported it. Mirrors the conditional pattern used by\n // buildAccountHandlers — see comment at line 4544.\n ...(creative.syncCreatives != null && {\n syncCreatives: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n params = asCanonicalSemanticServerRequest(params, 'sync_creatives', legacyFormatConverter);\n const reqCtx = ctxFor(ctx, params);\n const creatives = (params.creatives ?? []) as CanonicalSyncCreativeAsset[];\n return projectSync(\n async () => {\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await creative.syncCreatives!(creatives, reqCtx);\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'sync_creatives',\n accountId: reqCtx.account.id,\n ownerScope: taskOwnerScopeFor(ctx, reqCtx.account.id),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n rows =>\n asSemanticServerResponseForWire(\n { creatives: rows.map(normalizeRowErrors) },\n 'sync_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n )\n );\n },\n r => r\n );\n },\n }),\n\n // Ad-server-specialism methods. Only CreativeAdServerPlatform declares\n // listCreatives and getCreativeDelivery. Registering unconditional stubs\n // would advertise these tools in tools/list for CreativeBuilderPlatform\n // adopters, misleading buyer agents and triggering UNSUPPORTED_FEATURE on\n // every call. Only emit handlers when the platform method is present.\n ...('listCreatives' in creative &&\n (creative as CreativeAdServerPlatform).listCreatives != null && {\n listCreatives: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const canonicalParams = asCanonicalListCreativesRequest(\n params as unknown as Record<string, unknown>,\n legacyFormatConverter,\n responseWireMode\n );\n const reqCtx = ctxFor(ctx, canonicalParams);\n return projectSync(\n async () => {\n const result = await (creative as CreativeAdServerPlatform).listCreatives(canonicalParams, reqCtx);\n const canonicalResult = asSemanticServerResponseForWire(\n result,\n 'list_creatives',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n );\n warnIfTruncatedMultiIdResponse(\n 'listCreatives',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (canonicalResult as { creatives?: readonly unknown[] })?.creatives,\n logger\n );\n return canonicalResult as unknown as import('../../../types/tools.generated').ListCreativesResponse;\n },\n r => r\n );\n },\n }),\n\n ...('getCreativeDelivery' in creative &&\n (creative as CreativeAdServerPlatform).getCreativeDelivery != null && {\n getCreativeDelivery: async (params, ctx) => {\n const responseWireMode = creativeWireModeForRequest(ctx, creativeWireMode, params);\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await (creative as CreativeAdServerPlatform).getCreativeDelivery(\n asValidatedDomainRequest(params),\n reqCtx\n );\n warnIfTruncatedMultiIdResponse(\n 'getCreativeDelivery',\n 'creative_ids',\n (params as { creative_ids?: readonly string[] }).creative_ids,\n (result as { creative_deliveries?: readonly unknown[] })?.creative_deliveries,\n logger\n );\n return asSemanticServerResponseForWire(\n result,\n 'get_creative_delivery',\n legacyFormatConverter,\n canonicalFormatLegacyResolver,\n responseWireMode\n ) as unknown as import('../../../types/tools.generated').GetCreativeDeliveryResponse;\n },\n r => r\n );\n },\n }),\n };\n}\n\nfunction buildEventTrackingHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): EventTrackingHandlers<Account> | undefined {\n const audiences = platform.audiences;\n const sales = platform.sales;\n // Retail-media adopters (sales-catalog-driven) implement sync_catalogs /\n // log_event / sync_event_sources on `SalesPlatform`. The wire spec routes\n // these through the `event-tracking` framework category so the handlers\n // land on `EventTrackingHandlers` regardless of which specialism owns\n // them on the platform side.\n if (!audiences && !sales) return undefined;\n\n const handlers: EventTrackingHandlers<Account> = {};\n\n if (audiences) {\n handlers.syncAudiences = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n const audienceList = (params.audiences ?? []) as Audience[];\n return projectSync(\n () => audiences.syncAudiences(audienceList, reqCtx),\n rows => ({ audiences: rows })\n );\n };\n }\n\n if (sales?.syncCatalogs) {\n handlers.syncCatalogs = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.syncCatalogs!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (sales?.logEvent) {\n handlers.logEvent = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.logEvent!(params, reqCtx),\n r => r\n );\n };\n }\n\n if (sales?.syncEventSources) {\n handlers.syncEventSources = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => sales.syncEventSources!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n return Object.keys(handlers).length > 0 ? handlers : undefined;\n}\n\nfunction buildSignalsHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n taskRegistry: TaskRegistry,\n taskWebhookEmit: NonNullable<HandlerContext<Account>['emitWebhook']> | undefined,\n observability: DecisioningObservabilityHooks | undefined,\n logger: AdcpLogger,\n pushOpts: { allowPrivateWebhookUrls: boolean; autoEmitCompletionWebhooks: boolean },\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined\n): SignalsHandlers<Account> | undefined {\n const signals = platform.signals;\n if (!signals) return undefined;\n return {\n getSignals: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const discoveryMode = (params as { discovery_mode?: string }).discovery_mode;\n if (discoveryMode === 'wholesale' && hasPushNotificationConfig(params)) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_signals discovery_mode=wholesale is synchronous and does not support push_notification_config; use incomplete[] for partial feed results.',\n field: 'push_notification_config',\n recovery: 'correctable',\n });\n }\n const push = extractPushConfig(params, logger, {\n allowPrivateWebhookUrls: pushOpts.allowPrivateWebhookUrls,\n });\n const result = await signals.getSignals(asValidatedDomainRequest(params), reqCtx);\n const projectSignals = async (terminalResult: import('../specialisms/signals').GetSignalsPayload) => {\n // signal_ids is `SignalID[]` (`{source, data_provider_domain, id}`\n // objects), not bare strings — but the helper's truncation-detection\n // is purely length-based, so the object element type is irrelevant.\n warnIfTruncatedMultiIdResponse(\n 'getSignals',\n 'signal_ids',\n (params as { signal_ids?: readonly unknown[] }).signal_ids,\n (terminalResult as { signals?: readonly unknown[] })?.signals,\n logger\n );\n // Auto-store signals so subsequent activate_signal can hydrate\n // `req.signal` from the publisher's prior catalog entry.\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'signal',\n (terminalResult as { signals?: readonly unknown[] })?.signals,\n 'signal_agent_segment_id',\n logger\n );\n return terminalResult;\n };\n const isHandoff = isTaskHandoff<import('../specialisms/signals').GetSignalsPayload>(result);\n if (discoveryMode === 'wholesale' && isHandoff) {\n throw new AdcpError('INVALID_REQUEST', {\n message:\n 'get_signals discovery_mode=wholesale must return synchronously; use incomplete[] for partial feed results.',\n field: 'discovery_mode',\n recovery: 'correctable',\n });\n }\n if (!isHandoff && push.url === undefined) {\n rejectHandRolledSubmitted(result);\n return projectSignals(result as import('../specialisms/signals').GetSignalsPayload);\n }\n const accountId = reqCtx.account?.id;\n if (accountId === undefined) {\n throw new AdcpError('INVALID_REQUEST', {\n message: 'Async get_signals and push_notification_config require account-scoped discovery.',\n field: 'account',\n recovery: 'correctable',\n });\n }\n return routeIfHandoff(\n taskRegistry,\n {\n tool: 'get_signals',\n accountId,\n ownerScope: taskOwnerScopeFor(ctx, accountId),\n pushNotificationUrl: push.url,\n pushNotificationToken: push.token,\n pushNotificationOperationId: push.operationId,\n servedAdcpVersion: ctx.servedAdcpVersion,\n emitWebhook: taskWebhookEmit ?? ctx.emitWebhook,\n autoEmitCompletion: pushOpts.autoEmitCompletionWebhooks,\n observability,\n logger,\n },\n result,\n projectSignals\n );\n },\n r => r\n );\n },\n activateSignal: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.signal` from the prior getSignals store entry —\n // publisher reads pricing options, agent segment id, ctx_metadata\n // directly without the buyer round-tripping the full signal object.\n // Schema-driven via `x-entity` (#1109): `signal_agent_segment_id`\n // carries `x-entity: \"signal_activation_id\"`, mapped to ResourceKind\n // `signal`; attached at `params.signal` per the override table.\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'activate_signal', params, logger);\n return projectSync(\n () => signals.activateSignal(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n };\n}\n\n/**\n * Adapt `SponsoredIntelligencePlatform` (v6 platform-specialism shape) onto the v5\n * `SponsoredIntelligenceHandlers` handler-bag the dispatcher consumes.\n *\n * Auto-store on `initiateSession`: stash a session record keyed by\n * `session_id` under `ResourceKind: 'si_session'`. The framework's\n * schema-driven hydrator (TOOL_ENTITY_FIELDS for `si_send_message` /\n * `si_terminate_session`) attaches that record at `params.session` on\n * subsequent calls so the platform reads transcript context from\n * `req.session` without manual `ctx.store.get`.\n *\n * Hydrate on `sendMessage` / `terminateSession`: schema-driven\n * `hydrateForTool` reads `params.session_id`, looks up the stored\n * session, and attaches at `params.session`.\n */\nfunction buildSponsoredIntelligenceHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n logger: AdcpLogger\n): SponsoredIntelligenceHandlers<Account> | undefined {\n const si = platform.sponsoredIntelligence;\n if (!si) return undefined;\n return {\n getOffering: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => si.getOffering(params, reqCtx),\n r => r\n );\n },\n initiateSession: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await si.initiateSession(asValidatedDomainRequest(params), reqCtx);\n // Auto-store the session record so subsequent `sendMessage` /\n // `terminateSession` calls hydrate `req.session` without a\n // manual lookup. Stored payload preserves the bits the brand\n // engine needs to resume context across turns: identity\n // consent, offering scoping, negotiated capabilities,\n // placement provenance, and any media-buy linkage. The full\n // request intent is stored alongside so brand handlers can\n // re-read what the user originally asked for. Production\n // brand engines that own transcript state in their own\n // backend can ignore this and read from their own store —\n // see SponsoredIntelligencePlatform JSDoc.\n if (ctxMetadataStore && reqCtx.account?.id) {\n const sessionId = (result as { session_id?: unknown })?.session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n const reqRec = params as unknown as Record<string, unknown>;\n const resRec = result as unknown as Record<string, unknown>;\n const sessionRecord = {\n session_id: sessionId,\n // Request-side scoping the brand engine needs across turns.\n intent: reqRec.intent,\n offering_id: reqRec.offering_id,\n offering_token: reqRec.offering_token,\n placement: reqRec.placement,\n media_buy_id: reqRec.media_buy_id,\n identity: reqRec.identity,\n supported_capabilities: reqRec.supported_capabilities,\n // Response-side state.\n negotiated_capabilities: resRec.negotiated_capabilities,\n session_status: resRec.session_status,\n session_ttl_seconds: resRec.session_ttl_seconds,\n };\n try {\n await ctxMetadataStore.setResource(reqCtx.account.id, 'si_session', sessionId, sessionRecord);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store si_session ${sessionId} failed: ${msg}`);\n }\n }\n }\n return result;\n },\n r => r\n );\n },\n sendMessage: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.session` from the stored si_session record. The\n // schema-driven hydrator reads `params.session_id` and attaches the\n // stored session at `params.session` (via the `_id` → strip\n // convention; `session_id` → `session`).\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'si_send_message', params, logger);\n return projectSync(\n () => si.sendMessage(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n terminateSession: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'si_terminate_session', params, logger);\n return projectSync(\n async () => {\n const result = await si.terminateSession(params, reqCtx);\n // Persist `acp_handoff` and terminal `session_status` onto the\n // stored session record so a re-terminate replay (which is\n // naturally idempotent on `session_id` per the spec) hydrates\n // the same handoff payload via `req.session` without the\n // adopter having to remember to write through. Honors the\n // platform interface JSDoc contract:\n // \"Re-terminating a closed session MUST return the same\n // payload, including any acp_handoff block.\"\n if (ctxMetadataStore && reqCtx.account?.id) {\n const sessionId = (params as { session_id?: unknown })?.session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n const resRec = result as unknown as Record<string, unknown>;\n try {\n const existing = await ctxMetadataStore.getEntry(reqCtx.account.id, 'si_session', sessionId);\n const merged = {\n ...((existing?.resource as Record<string, unknown>) ?? { session_id: sessionId }),\n session_status: resRec.session_status,\n acp_handoff: resRec.acp_handoff,\n follow_up: resRec.follow_up,\n terminated: resRec.terminated,\n };\n await ctxMetadataStore.setResource(reqCtx.account.id, 'si_session', sessionId, merged);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`[adcp/decisioning] auto-store si_session ${sessionId} on terminate failed: ${msg}`);\n }\n }\n }\n return result;\n },\n r => r\n );\n },\n };\n}\n\nfunction buildBrandRightsHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn,\n ctxMetadataStore: CtxMetadataStore | undefined,\n logger: AdcpLogger\n): BrandRightsHandlers<Account> | undefined {\n const br = platform.brandRights;\n if (!br) return undefined;\n return {\n getBrandIdentity: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => br.getBrandIdentity(params, reqCtx),\n r => r\n );\n },\n getRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n async () => {\n const result = await br.getRightsLegacy(asValidatedDomainRequest(params), reqCtx);\n // Auto-store rights offerings so subsequent acquire_rights can\n // hydrate `req.rights` (pricing_options + ctx_metadata) without\n // a separate publisher lookup.\n await autoStoreResources(\n ctxMetadataStore,\n reqCtx.account?.id,\n 'rights_grant',\n (result as { rights?: readonly unknown[] })?.rights,\n 'rights_id',\n logger\n );\n return result;\n },\n r => r\n );\n },\n // `acquire_rights` has 3 native wire-spec arms (Acquired / PendingApproval /\n // Rejected) handled by the platform directly. No framework task envelope —\n // adopters return the spec-defined arm. Async delivery for the\n // PendingApproval arm rides the buyer's `push_notification_config` webhook\n // (the spec doesn't define a polling tool for `acquire_rights`).\n acquireRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n // Auto-hydrate `req.rights` from the prior getRights catalog entry.\n // Publisher reads selected pricing option + ctx_metadata directly.\n // Schema-driven via `x-entity` (#1109); destination field stays at\n // `params.rights` per the override table — historical, predates\n // the entity-driven hydrator and `updateRights`'s convention of\n // `params.rights_grant`. Adopters already read this field, so a\n // rename would be wire-visible behavior.\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'acquire_rights', params, logger);\n return projectSync(\n () => br.acquireRightsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n // `update_rights` modifies an existing grant. The framework hydrates\n // the grant record from `req.rights_id` so the implementation reads\n // the resolved state from `ctx.store` (or as `params.rights_grant`\n // — see field-name divergence note on `acquireRights` above; this\n // tool attaches under `rights_grant` because the wire payload has\n // no `rights` field). Schema-driven via `x-entity` (#1109). Async\n // delivery — when the change requires rights-holder counter-\n // signature — rides the buyer's `push_notification_config` webhook;\n // the immediate response carries `implementation_date: null` to\n // signal pending state.\n updateRights: async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n await hydrateForTool(ctxMetadataStore, reqCtx.account?.id, 'update_rights', params, logger);\n return projectSync(\n () => br.updateRightsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n },\n };\n}\n\nfunction buildGovernanceHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): GovernanceHandlers<Account> | undefined {\n const cg = platform.campaignGovernance;\n const pl = platform.propertyLists;\n const cl = platform.collectionLists;\n const cs = platform.contentStandards;\n if (!cg && !pl && !cl && !cs) return undefined;\n\n const handlers: GovernanceHandlers<Account> = {};\n\n if (cg) {\n handlers.checkGovernance = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.checkGovernance(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.syncPlans = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.syncPlans(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.reportPlanOutcome = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.reportPlanOutcome(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getPlanAuditLogs = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cg.getPlanAuditLogs(params, reqCtx),\n r => r\n );\n };\n }\n\n if (pl) {\n handlers.createPropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.createPropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updatePropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.updatePropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getPropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.getPropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.listPropertyLists = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.listPropertyLists(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.deletePropertyList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => pl.deletePropertyList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (cl) {\n handlers.createCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.createCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updateCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.updateCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.getCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.getCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.listCollectionLists = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.listCollectionLists(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.deleteCollectionList = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cl.deleteCollectionList(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n\n if (cs) {\n handlers.listContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.listContentStandardsLegacy(params, reqCtx),\n r => r\n );\n };\n handlers.getContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getContentStandardsLegacy(params, reqCtx),\n r => r\n );\n };\n handlers.createContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.createContentStandardsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.updateContentStandards = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.updateContentStandardsLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.calibrateContent = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.calibrateContentLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n handlers.validateContentDelivery = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.validateContentDeliveryLegacy(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n if (cs.getMediaBuyArtifactsLegacy) {\n handlers.getMediaBuyArtifacts = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getMediaBuyArtifactsLegacy!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n if (cs.getCreativeFeaturesLegacy) {\n handlers.getCreativeFeatures = async (params, ctx) => {\n const reqCtx = ctxFor(ctx, params);\n return projectSync(\n () => cs.getCreativeFeaturesLegacy!(asValidatedDomainRequest(params), reqCtx),\n r => r\n );\n };\n }\n }\n\n return handlers;\n}\n\ntype SyncAccountsEntry = AccountReference & {\n account?: AccountReference;\n brand?: BrandReference;\n operator?: string;\n billing?: BillingParty;\n payment_terms?: PaymentTerms;\n billing_entity?: unknown;\n};\n\ntype SyncAccountsPolicyResult = {\n acceptedEntries: SyncAccountsEntry[];\n acceptedParams: Record<string, unknown>;\n failedRows: Map<number, SyncAccountsResultRow>;\n};\n\nconst BILLING_VALUES: readonly BillingParty[] = ['operator', 'agent', 'advertiser'];\n\nfunction isBillingParty(value: unknown): value is BillingParty {\n return typeof value === 'string' && (BILLING_VALUES as readonly string[]).includes(value);\n}\n\nfunction isPaymentTerms(value: unknown): value is PaymentTerms {\n return typeof value === 'string';\n}\n\nfunction supportedBillingsFor(platform: DecisioningPlatform<any, any>): readonly BillingParty[] {\n const configured = platform.capabilities.supportedBillings;\n return configured?.length ? configured : ['agent'];\n}\n\nfunction entryBrandOperator(entry: SyncAccountsEntry): { brand: BrandReference; operator: string } | undefined {\n if (entry.brand !== undefined && typeof entry.operator === 'string') {\n return { brand: entry.brand, operator: entry.operator };\n }\n const account = entry.account;\n if (\n account !== undefined &&\n 'brand' in account &&\n account.brand !== undefined &&\n 'operator' in account &&\n typeof account.operator === 'string'\n ) {\n return { brand: account.brand as BrandReference, operator: account.operator };\n }\n return undefined;\n}\n\nfunction entryHasAccountId(entry: SyncAccountsEntry): boolean {\n if (refAccountId(entry) !== undefined) return true;\n return entry.account !== undefined && refAccountId(entry.account) !== undefined;\n}\n\nfunction failedSyncAccountRow(entry: SyncAccountsEntry, error: AdcpStructuredError): SyncAccountsResultRow {\n const key = entryBrandOperator(entry);\n if (key === undefined) {\n throw new AdcpError(error.code, {\n message: error.message,\n recovery: error.recovery,\n ...(error.field !== undefined && { field: error.field }),\n ...(error.suggestion !== undefined && { suggestion: error.suggestion }),\n ...(error.retry_after !== undefined && { retry_after: error.retry_after }),\n ...(error.details !== undefined && { details: error.details }),\n });\n }\n return {\n brand: key.brand,\n operator: key.operator,\n action: 'failed',\n status: 'rejected',\n errors: [error],\n };\n}\n\nfunction buildBillingNotSupportedError(opts: {\n requestedBilling: BillingParty;\n supportedBillings?: readonly BillingParty[];\n exposeCapabilityScope: boolean;\n}): AdcpStructuredError {\n return new AdcpError('BILLING_NOT_SUPPORTED', {\n message: `Billing value \"${opts.requestedBilling}\" is not supported for this account sync request.`,\n recovery: 'correctable',\n field: 'accounts[].billing',\n ...(opts.exposeCapabilityScope && opts.supportedBillings !== undefined\n ? { details: { scope: 'capability', supported_billing: [...opts.supportedBillings] } }\n : {}),\n }).toStructuredError();\n}\n\nfunction buildBillingNotPermittedError(\n agent: BuyerAgent,\n requestedBilling: BuyerAgentBillingMode\n): AdcpStructuredError {\n const fallback = suggestBilling(agent.billing_capabilities, requestedBilling);\n return new AdcpError('BILLING_NOT_PERMITTED_FOR_AGENT', {\n message: `Billing value \"${requestedBilling}\" is not permitted for this buyer agent.`,\n recovery: 'correctable',\n field: 'accounts[].billing',\n details: {\n rejected_billing: requestedBilling,\n ...(fallback !== undefined && { suggested_billing: fallback }),\n },\n }).toStructuredError();\n}\n\nfunction enforceSyncAccountsCommercialPolicy<P extends DecisioningPlatform<any, any>>(\n platform: P,\n params: Record<string, unknown>,\n resolveCtx: ResolveContext\n): SyncAccountsPolicyResult {\n const entries = ((params.accounts as unknown[]) ?? []) as SyncAccountsEntry[];\n const supportedBillings = supportedBillingsFor(platform);\n const supportedPaymentTerms = platform.capabilities.supportedPaymentTerms;\n const failedRows = new Map<number, SyncAccountsResultRow>();\n const acceptedEntries: SyncAccountsEntry[] = [];\n\n entries.forEach((entry, index) => {\n const hasBillableFields =\n entry.billing !== undefined || entry.payment_terms !== undefined || entry.billing_entity !== undefined;\n if (hasBillableFields && entryBrandOperator(entry) === undefined && !entryHasAccountId(entry)) {\n throw new AdcpError('BRAND_REQUIRED', {\n message: 'Billable account sync entries require a brand reference or account_id.',\n recovery: 'correctable',\n field: `accounts[${index}].brand`,\n });\n }\n\n let failure: AdcpStructuredError | undefined;\n if (isBillingParty(entry.billing)) {\n if (!supportedBillings.includes(entry.billing)) {\n failure = buildBillingNotSupportedError({\n requestedBilling: entry.billing,\n supportedBillings,\n exposeCapabilityScope: true,\n });\n } else if (platform.agentRegistry !== undefined && resolveCtx.agent === undefined) {\n failure = buildBillingNotSupportedError({\n requestedBilling: entry.billing,\n exposeCapabilityScope: false,\n });\n } else if (resolveCtx.agent !== undefined && !resolveCtx.agent.billing_capabilities.has(entry.billing)) {\n failure = buildBillingNotPermittedError(resolveCtx.agent, entry.billing);\n }\n }\n\n if (\n failure === undefined &&\n supportedPaymentTerms !== undefined &&\n supportedPaymentTerms.length > 0 &&\n isPaymentTerms(entry.payment_terms) &&\n !supportedPaymentTerms.includes(entry.payment_terms)\n ) {\n failure = new AdcpError('PAYMENT_TERMS_NOT_SUPPORTED', {\n message: `Payment terms \"${entry.payment_terms}\" are not supported for this account sync request.`,\n recovery: 'correctable',\n field: `accounts[${index}].payment_terms`,\n }).toStructuredError();\n }\n\n if (failure !== undefined) {\n failedRows.set(index, failedSyncAccountRow(entry, failure));\n } else {\n acceptedEntries.push(entry);\n }\n });\n\n return {\n acceptedEntries,\n acceptedParams: { ...params, accounts: acceptedEntries },\n failedRows,\n };\n}\n\nfunction buildAccountHandlers<P extends DecisioningPlatform<any, any>>(\n platform: P,\n ctxFor: CtxForFn\n): AccountHandlers<Account> {\n const accounts = platform.accounts;\n\n // Only emit framework-derived handlers for methods the platform actually\n // implements. Emitting an UNSUPPORTED_FEATURE stub for an undefined\n // method shadows adopter-supplied `opts.accounts.{syncAccounts,listAccounts}`\n // fillers under the merge seam (platform-derived wins per-key), so the\n // adopter's working handler silently never runs. This pattern matches the\n // gating already used for `reportUsage` / `getAccountFinancials` below.\n // Adopters who claim sync_accounts / list_accounts capability without\n // implementing `accounts.upsert` / `accounts.list` AND without supplying a\n // merge-seam override get framework's \"tool not registered\" path —\n // closer to the truth than a fabricated UNSUPPORTED_FEATURE envelope.\n const handlers: AccountHandlers<Account> = {};\n\n if (accounts.upsert) {\n handlers.syncAccounts = async (params, ctx) => {\n const resolveCtx = toResolveCtx(ctx, 'sync_accounts', params);\n const policy = enforceSyncAccountsCommercialPolicy(platform, params as Record<string, unknown>, resolveCtx);\n const dispatchCtx =\n policy.failedRows.size === 0 ? resolveCtx : toResolveCtx(ctx, 'sync_accounts', policy.acceptedParams);\n return projectSync(\n () =>\n policy.acceptedEntries.length > 0\n ? accounts.upsert!(policy.acceptedEntries as AccountReference[], dispatchCtx)\n : Promise.resolve([]),\n rows => {\n if (rows.length !== policy.acceptedEntries.length) {\n throw new Error(\n `sync_accounts accounts.upsert returned ${rows.length} ${\n rows.length === 1 ? 'row' : 'rows'\n } for ${policy.acceptedEntries.length} accepted account ${\n policy.acceptedEntries.length === 1 ? 'entry' : 'entries'\n }`\n );\n }\n if (policy.failedRows.size === 0) {\n return { accounts: rows.map(toWireSyncAccountRow) };\n }\n const combined: SyncAccountsResultRow[] = [];\n let acceptedIndex = 0;\n const originalCount = ((params.accounts as unknown[]) ?? []).length;\n for (let index = 0; index < originalCount; index += 1) {\n const failed = policy.failedRows.get(index);\n if (failed !== undefined) {\n combined.push(failed);\n } else {\n combined.push(rows[acceptedIndex] as SyncAccountsResultRow);\n acceptedIndex += 1;\n }\n }\n return { accounts: combined.map(toWireSyncAccountRow) };\n }\n );\n };\n }\n\n if (accounts.syncGovernance) {\n handlers.syncGovernance = async (params, ctx) => {\n const entries = params.accounts as SyncGovernanceRequest['accounts'];\n const resolveCtx = toResolveCtx(ctx, 'sync_governance', params);\n return projectSync(\n () => accounts.syncGovernance!(entries, resolveCtx),\n rows => ({ accounts: rows.map(toWireSyncGovernanceRow) })\n );\n };\n }\n\n if (accounts.list) {\n handlers.listAccounts = async (params, ctx) => {\n const filter = params as Parameters<NonNullable<typeof accounts.list>>[0];\n const resolveCtx = toResolveCtx(ctx, 'list_accounts', params);\n // Wrap in projectSync so adopter `throw new AdcpError('PERMISSION_DENIED', ...)`\n // from the list impl projects to the structured wire envelope rather\n // than falling through to the framework's `SERVICE_UNAVAILABLE` mapping.\n //\n // Wire shape: 3.0 + 3.1 `list-accounts-response` model pagination via a\n // `pagination` block referencing `core/pagination-response.json`\n // (`has_more` required, `cursor` present only when `has_more=true`).\n // Emitting top-level `next_cursor` — the shape shipped before this fix —\n // was schema-invisible (`additionalProperties: true` on the response) but\n // silently failed the `pagination_integrity_list_accounts` storyboard's\n // `field_value pagination.has_more: true` + `field_present pagination.cursor`\n // assertions for every adopter, regardless of `CursorPage` output.\n // See adcontextprotocol/adcp#5723 for the reproduction from a 3.1 seller.\n return projectSync(\n () => accounts.list!(filter, resolveCtx),\n page => ({\n status: 'completed' as const,\n accounts: page.items.map(toWireAccount),\n pagination: {\n has_more: page.nextCursor != null,\n ...(page.nextCursor != null && { cursor: page.nextCursor }),\n ...(page.totalCount !== undefined && { total_count: page.totalCount }),\n },\n })\n );\n };\n }\n\n if (accounts.reportUsage) {\n handlers.reportUsage = async (params, ctx) => {\n const resolveCtx = toResolveCtx(ctx, 'report_usage', params);\n return projectSync(\n () => accounts.reportUsage!(asValidatedDomainRequest(params), resolveCtx),\n r => r\n );\n };\n }\n\n if (accounts.getAccountFinancials) {\n handlers.getAccountFinancials = async (params, ctx) => {\n // Resolve the account first so `ctx.account` is populated when the\n // platform method runs. Adopters fronting an upstream platform read\n // tokens / upstream IDs off `ctx.account.ctx_metadata` without\n // having to re-resolve from `params.account`.\n const resolveCtx = toResolveCtx(ctx, 'get_account_financials', params);\n const accountRef = asValidatedDomainRequest<AccountReference | undefined>(params.account);\n refuseInlineAccountIdWhenForbidden(accounts.resolution, accountRef);\n const resolved = await accounts.resolve(accountRef, resolveCtx);\n if (!resolved) {\n throw new AdcpError('ACCOUNT_NOT_FOUND', {\n message: 'Account not found',\n recovery: 'terminal',\n });\n }\n // Request-local clone: refreshToken mutates account.authInfo before the\n // retry. Never write refreshed credentials onto a resolver-owned object;\n // adopters sometimes cache Account rows between requests.\n const account = cloneAccountForRequest(resolved);\n const toolCtx = { ...resolveCtx, account };\n return projectSync(\n () => accounts.getAccountFinancials!(asValidatedDomainRequest(params), toolCtx),\n r => r,\n accounts.refreshToken ? { account, fn: accounts.refreshToken.bind(accounts) } : undefined\n );\n };\n }\n\n return handlers;\n}\n\n// ────────────────────────────────────────────────────────────\n// Auto-seed helpers (catalog-backed comply sandbox; issue #1091)\n// ────────────────────────────────────────────────────────────\n\n// Auto-seed namespace key extractor. Used by both the write side (the\n// `seed.product` / `seed.pricing_option` adapter closures injected\n// inline in the auto-seed wiring) and the read side (`makeAutoSeedBridge`\n// when `ctx.account?.id` is absent — i.e., the framework didn't\n// pre-resolve the account on a custom dispatcher path).\n//\n// Write-side rationale: the adapter cannot reach the framework-resolved\n// `ctx.account.id` (the comply-controller's `ComplyControllerContext`\n// only exposes `{ input }`), and calling `platform.accounts.resolve`\n// here without `authInfo` would let a caller spoof `account.account_id`\n// and write into another tenant's resolved namespace. The architectural\n// fix (widen `ComplyControllerContext` to surface the resolved account)\n// is tracked at #1216 — until then, raw id is the secure choice.\nfunction readAutoSeedAccountId(input: Record<string, unknown>): string | undefined {\n const account = input.account;\n if (account == null || typeof account !== 'object') return undefined;\n const id = (account as { account_id?: unknown }).account_id;\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n}\n\nfunction autoSeedStoreFor(store: Map<string, Map<string, unknown>>, accountId: string): Map<string, unknown> {\n let inner = store.get(accountId);\n if (inner == null) {\n inner = new Map<string, unknown>();\n store.set(accountId, inner);\n }\n return inner;\n}\n\n// Build a `TestControllerBridge` over the per-account auto-seed store. The\n// bridge filters seeded products by the resolved account so multi-tenant\n// servers (TenantRegistry-fronted, or single-tenant with multiple sandbox\n// accounts) never leak fixtures across tenants. Reads\n// `ctx.account?.id` first (set by `resolveAccount` at request time) and\n// falls back to `ctx.input.account.account_id` when no resolver is wired.\nfunction makeAutoSeedBridge(store: Map<string, Map<string, unknown>>): TestControllerBridge<unknown> {\n return {\n getSeededProducts: ctx => {\n const resolved = (ctx.account as { id?: unknown } | undefined)?.id;\n const accountId =\n typeof resolved === 'string' && resolved.length > 0 ? resolved : readAutoSeedAccountId(ctx.input);\n if (accountId == null) return [];\n const inner = store.get(accountId);\n if (inner == null || inner.size === 0) return [];\n const products: Product[] = [];\n for (const [productId, fixture] of inner.entries()) {\n const merged = mergeSeedProduct(\n {},\n {\n ...(fixture && typeof fixture === 'object' ? (fixture as Partial<Product>) : {}),\n product_id: productId,\n }\n );\n products.push(merged as Product);\n }\n return products;\n },\n };\n}\n"],"mappings":"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","names":["import_async_outcome","import_types","converter","cloned","value","clonedRefs"]}
|