v5.15.0
Minor Changes
-
6c1d5d0:
resolveAccountnow receives auth context,checkGovernanceparses MCP envelope shapes correctly, and the seller skill documents alternative transports.resolveAccount(ref, ctx)now receives{ toolName, authInfo }. Adapters that front an upstream platform API (Snap, Meta, TikTok, retail media networks) need the caller's OAuth token to look up the upstream account. PreviouslyauthInfowas only available inside handlers, forcing resolvers to return a thin stub and re-resolve the platform account on every handler call. Single-arg resolvers (async (ref) => ...) remain valid — TypeScript allows a shorter parameter list.dispatchTestRequest(request, { authInfo }). Test harnesses can simulate theauthInfothatserve({ authenticate })would populate, soresolveAccountand handler tests cover auth-sensitive paths without spinning up HTTP. Never mount this behind an HTTP route —extras.authInfobypassesauthenticate.checkGovernancenow extracts fromstructuredContentorcontent[0].textbefore falling back to top-level fields. Fixes a latent bug where the helper returned "missing required fields" when the governance agent responded with a conformant MCPCallToolResultenvelope rather than spreading the payload at the root. The single-agent JSDoc example no longer references a fabricatedctx.account.governanceAgentUrlfield — it now shows the realsync_governance→Account.governance_agents[]flow.Multi-agent governance helper is deferred pending spec resolution on adcontextprotocol/adcp#3010 —
sync_governanceallows up to 10 governance agents per account but thecheck_governancerequest and the protocol envelope only thread a singlegovernance_contextper lifecycle. The SDK will ship an aggregation helper once the spec picks an interpretation.Skill docs.
skills/build-seller-agent/SKILL.mdgains an Alternative Transports section covering thecreateAdcpServer().connect(transport)pattern — multi-host HTTP on a single process and stdio — for cases whereserve()'s single-publicUrl-per-process model doesn't fit.
Patch Changes
-
a050729: Two regressions from the 5.14 train (closes #862). Both restore documented
behavior — no new surface, no new policy. 5.14.0 consumers should upgrade
directly to this release; no code changes required.(1) Schema loader: flat-tree domain
$refresolutionensureCoreLoadedpre-registered onlycore/andenums/before AJV
compile. Tool schemas in flat-tree domain directories —governance/,
brand/,property/,collection/,content-standards/,account/,
signals/— ship alongside sibling building-block fragments they$ref,
and those siblings were never registered. First compile of e.g.
governance/sync-plans-request.jsonthrewcan't resolve reference /schemas/3.0.0/governance/audience-constraints.json.The loader now walks every directory outside
bundled/and pre-registers
non-tool JSON fragments — coveringcore/,enums/,pricing-options/,
error-details/,extensions/, and every flat-tree domain's sibling
building blocks. Tool request/response files stay lazy-compiled so
relaxResponseRootstill applies to response variants.Blast radius is broader than storyboards. The same
getValidatoris
wired into strict-mode request/response validation
(AdcpClient({ strict: true }),createAdcpServerdefault validation,
validateOutgoingRequest/validateIncomingResponse, the dispatcher
middleware, andTaskExecutor). Any 5.14.0 server-side adopter running
strict validation on governance/brand/property/signals/collection/
content-standards/account tools was silently throwing on first call;
those paths are fixed by this release too.(2)
create_media_buyenricher: fixture-per-package precedenceThe fixture-authoritative refactor in 5.14 (#816) set every task's
top-level merge to fixture-wins, but the nested-package merge in
create_media_buykept the prior builder-authoritative precedence.
Storyboards that authored explicitproduct_id/pricing_option_id/
bid_priceonpackages[0]had those values overridden by the first
discovered product'spricing_options[0]— e.g. a seller's
pinnacle_news_video_premium_pricing_0replaced the fixture's
cpm_guaranteed, failing create-buy withINVALID_REQUEST.Real seller ids in the fixture now win over discovery. Discovery
still gap-fills when the author omits per-package ids — the
behavior generic single-package storyboards rely on. Auction/CPM
bid_pricesynthesis only fires when the fixture didn't author
one, so bid-floor-boundary tests keep their explicit values.Sentinel placeholders pass through to discovery. The upstream
universal compliance storyboards (adcontextprotocol/adcp:
universal/deterministic-testing.yaml,error-compliance.yaml,
idempotency.yaml,domains/media-buy/state-machine.yaml) ship
packages[0]fixtures withproduct_id: "test-product"and
pricing_option_id: "test-pricing"expecting the runner to
substitute the seller's discovered identifiers. The enricher
recognizes those two literals as sentinels and defers to discovery
when either appears. Real seller ids (cpm_guaranteed,
sports_display_auction, any non-sentinel string) keep winning.If your storyboard wants placeholder-then-discovery semantics for a
new field, author$context.<key>substitution rather than a magic
literal — the intent is explicit at the fixture level and the
sentinel allowlist stays small.Out of scope
Issue #862 also flagged
activate_signalas "same pattern". The
enricher is notFIXTURE_AWARE— the outer merge lets the storyboard's
$context.first_signal_pricing_option_idoverlay the enricher's pick,
and both resolve from the samesignals[0].pricing_options[0]. The
mismatch reporters saw (po_prism_abandoner_cpmsent,
po_prism_cart_cpmaccepted) traces to seller catalog inconsistency
betweenget_signalsandactivate_signal, not SDK synthesis.
Follow-up in #870: have the storyboard runner emit a hint when a
response'savailable:list excludes a context-derived value, so the
reporter-facing symptom stops looking identical to an SDK bug. -
d856e1e: Triage routine now runs a mandatory pre-PR expert review on the diff (code-reviewer + domain expert in parallel) before opening the PR, capped at 2 review→fix iterations. Sign-offs recorded in the PR body.