Context
While building a multi-tenant + multi-specialism hello adapter for @adcp/sdk (branch adcontextprotocol/adcp-client@bokelley/hello-adapters-gov-rights, tracking issue adcp-client#1387) and running it through protocol expert review, several spec-level gaps surfaced. Three already filed individually: #3892 (rights_grant_id storyboard capture), #3913 (storyboard runner context seeding), #3914 (GOVERNANCE_DENIED storyboard convention). This is the meta-issue for the rest.
Items
Wire schema gaps
Storyboard runner
Spec-repo CI
Cross-references
Context
While building a multi-tenant + multi-specialism hello adapter for
@adcp/sdk(branchadcontextprotocol/adcp-client@bokelley/hello-adapters-gov-rights, tracking issue adcp-client#1387) and running it through protocol expert review, several spec-level gaps surfaced. Three already filed individually: #3892 (rights_grant_id storyboard capture), #3913 (storyboard runner context seeding), #3914 (GOVERNANCE_DENIED storyboard convention). This is the meta-issue for the rest.Items
Wire schema gaps
Add
account: AccountReferencetoAcquireRightsRequest. Every governance-aware brand agent needs operator+brand to look up the account-scoped governance binding. The brand-rights compliance storyboard already sendsaccount: { brand, operator }inacquire_rights_denied's sample request, but the schema doesn't define it — so the framework strips/ignores it for account resolution and adapters fall back toreq.buyer.domain(which is the brand, not the buyer's account). Same shape every other governance-aware tool already has.Add optional
plan_idtoSyncGovernanceRequest.accounts[].governance_agents[]. The wire request binds a governance agent URL to an account but doesn't reference which plan that agent is authoritative for. Adopters today invent conventions ("first plan wins", "active plan") because the wire is silent. Explicitplan_idremoves the guesswork and matches how brand agents actually consult governance onacquire_rights.Doc-comment clarification on
GOVERNANCE_DENIEDplacement.error-code.jsonsays it means "registered governance agent denied the transaction" — but is the canonical wire shape (a)AcquireRightsRejectedwithreasonreferencing the denial, or (b) thrownAdcpErrorprojected asadcp_error.code: GOVERNANCE_DENIED, or (c)AcquireRightsError.errors[].code: GOVERNANCE_DENIED? Different storyboards interpret differently (brand_rights/governance_denied storyboard:expect_error: code: GOVERNANCE_DENIEDis non-spec —AcquireRightsRejectedis the canonical denial shape #3914 documents one mismatch). Suggest spec doc-comment: prefer Rejected arm for adopter-controlled denial; reserve thrown error for governance-call FAILURE (timeout / unreachable / config error), parallel toGOVERNANCE_UNAVAILABLE.Broaden
estimated_impressionsMUST. Spec atacquire-rights-request.json:64requiresestimated_impressionsonly when the request carries an intent-phasegovernance_contextAND CPM pricing. But governance-aware brand agents that bind viasync_governance(not via inlinegovernance_contexttoken) STILL need to project CPM spend — and "implementer-chosen defaults are non-conformant" per the same spec note. Resolution: any governance-aware CPM projection requiresestimated_impressions, not just intent-phase context-token flows. Otherwise adopters either invent non-conformant defaults or block compliance scenarios that reasonable buyer flows produce.Loosen
^https://URL pattern for cross-agent dial-out URLs in dev. The schema rejectshttp://localhost:3003/mcpas agovernance_agent_urleven when the storyboard runner is invoked with--allow-http. Hello adapters demonstrating cross-agent integration locally need a way to register a dev-mode URL. Suggest:^(https://|http://(localhost|127\.0\.0\.1)(:[0-9]+)?(/.*)?$). Same fix benefits webhook URLs and any*_urlfield used for cross-agent calls.Storyboard runner
--default-agentCLI flag. Thedefault_agentstoryboard YAML field landed via Storyboard schema: per-storyboarddefault_agentfield for multi-agent runner routing #3894, butbin/adcp.js storyboard rundoesn't accept a CLI override. Cross-specialism storyboards (governance + brand-rights, governance + media-buy) can't be tested against a multi-specialism agent without per-stepagent:annotations. Companion to storyboard runner: no way to seed$context.governance_agent_urlfor fullstoryboard runmode #3913 (no--contextfor full runs).Spec-repo CI
expect_error.codeandcontext_outputs.pathresolve to fields/codes the spec schemas define. Therights_grant_id(brand-rights storyboard capturesrights_grant_idfrom acquire_rights — spec field isrights_id#3892) andGOVERNANCE_DENIED(brand_rights/governance_denied storyboard:expect_error: code: GOVERNANCE_DENIEDis non-spec —AcquireRightsRejectedis the canonical denial shape #3914) bugs were both "storyboard authored a non-spec opinion" — adopter-friendly tests caught real regressions but only after they'd shipped. CI gate that walks the storyboard cache and validates every assertion against the spec schema definitions would catch this class of drift at storyboard-author time, not at adopter-validation time.Cross-references
rights_grant_idfrom acquire_rights — spec field isrights_id#3892 (rights_grant_id capture in brand-rights storyboard), storyboard runner: no way to seed$context.governance_agent_urlfor fullstoryboard runmode #3913 (runner context seeding), brand_rights/governance_denied storyboard:expect_error: code: GOVERNANCE_DENIEDis non-spec —AcquireRightsRejectedis the canonical denial shape #3914 (GOVERNANCE_DENIED storyboard convention)