Skip to content

v5.15.0

Choose a tag to compare

@github-actions github-actions released this 24 Apr 11:06
· 1420 commits to main since this release
d4da34c

Minor Changes

  • 6c1d5d0: resolveAccount now receives auth context, checkGovernance parses 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. Previously authInfo was 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 the authInfo that serve({ authenticate }) would populate, so resolveAccount and handler tests cover auth-sensitive paths without spinning up HTTP. Never mount this behind an HTTP route — extras.authInfo bypasses authenticate.

    checkGovernance now extracts from structuredContent or content[0].text before 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 MCP CallToolResult envelope rather than spreading the payload at the root. The single-agent JSDoc example no longer references a fabricated ctx.account.governanceAgentUrl field — it now shows the real sync_governance → Account.governance_agents[] flow.

    Multi-agent governance helper is deferred pending spec resolution on adcontextprotocol/adcp#3010 — sync_governance allows up to 10 governance agents per account but the check_governance request and the protocol envelope only thread a single governance_context per lifecycle. The SDK will ship an aggregation helper once the spec picks an interpretation.

    Skill docs. skills/build-seller-agent/SKILL.md gains an Alternative Transports section covering the createAdcpServer().connect(transport) pattern — multi-host HTTP on a single process and stdio — for cases where serve()'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 $ref resolution

    ensureCoreLoaded pre-registered only core/ and enums/ 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.json threw can'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 — covering core/, enums/, pricing-options/,
    error-details/, extensions/, and every flat-tree domain's sibling
    building blocks. Tool request/response files stay lazy-compiled so
    relaxResponseRoot still applies to response variants.

    Blast radius is broader than storyboards. The same getValidator is
    wired into strict-mode request/response validation
    (AdcpClient({ strict: true }), createAdcpServer default validation,
    validateOutgoingRequest / validateIncomingResponse, the dispatcher
    middleware, and TaskExecutor). 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_buy enricher: fixture-per-package precedence

    The 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_buy kept the prior builder-authoritative precedence.
    Storyboards that authored explicit product_id / pricing_option_id /
    bid_price on packages[0] had those values overridden by the first
    discovered product's pricing_options[0] — e.g. a seller's
    pinnacle_news_video_premium_pricing_0 replaced the fixture's
    cpm_guaranteed, failing create-buy with INVALID_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_price synthesis 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 with product_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_signal as "same pattern". The
    enricher is not FIXTURE_AWARE — the outer merge lets the storyboard's
    $context.first_signal_pricing_option_id overlay the enricher's pick,
    and both resolve from the same signals[0].pricing_options[0]. The
    mismatch reporters saw (po_prism_abandoner_cpm sent,
    po_prism_cart_cpm accepted) traces to seller catalog inconsistency
    between get_signals and activate_signal, not SDK synthesis.
    Follow-up in #870: have the storyboard runner emit a hint when a
    response's available: 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.