feat(skills): hoist call-adcp-agent + bundle skills/ into protocol tarball#3097
Merged
feat(skills): hoist call-adcp-agent + bundle skills/ into protocol tarball#3097
Conversation
…rball
Make `skills/call-adcp-agent/SKILL.md` the canonical buyer-side wire-contract
skill in the adcp main repo (was @adcp/client-only). Bundle skills/ into the
versioned protocol tarball so all SDKs (JS/Python/Go) consume one source of
truth — version-pinned, Sigstore-verified, no manual copy. Wire it through
Addie via frontmatter-driven skill loading, with cross-cutting rules
consolidated into a single search preamble. Add canonical docs page at
docs/protocol/calling-an-agent.mdx.
Also fixes two pre-existing prod bugs surfaced along the way:
- Dockerfile didn't COPY /app/skills (loader silently returned empty for ALL
adcp-* skills in production)
- Skill loader's relative-path traversal landed at /skills (root) in prod
layout. Replaced with a candidate-list resolver that handles dev, prod, and
CWD layouts.
Tested live via docker compose: authenticated Addie now surfaces the correct
oneOf variants ({account_id} OR {brand:{domain}, operator}) where anonymous
tier hallucinated account_name+account_email.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 25, 2026
Merged
Closed
bokelley
added a commit
to adcontextprotocol/adcp-client
that referenced
this pull request
Apr 25, 2026
scripts/sync-schemas.ts now extracts protocol-managed skills (call-adcp-agent
plus the six per-protocol skills: adcp-{brand,creative,governance,media-buy,
si,signals}) from /protocol/<version>.tgz alongside schemas and compliance.
Manifest-driven and per-name: only directories enumerated in
manifest.contents.skills are overwritten. SDK-local skills (build-seller-agent,
build-creative-agent, the legacy adcp CLI skill, etc.) stay untouched.
Filters out nested schemas/ subdirs from each per-protocol skill — the spec
repo bundles them for self-contained agent consumption, but @adcp/client
already has the canonical schemas in schemas/cache/<version>/, so re-copying
would duplicate ~1.4MB per protocol with no functional gain.
Adds an ADCP_BASE_URL env override (defaults to https://adcontextprotocol.org)
so CI / local dev can point sync at a fake CDN for testing.
The buyer-side call-adcp-agent skill is now sourced from the spec repo
(adcontextprotocol/adcp#3097) rather than maintained as a local copy —
version-pinned to ADCP_VERSION, Sigstore-verified via the same cosign path
as schemas, no manual sync.
Tested end-to-end against a local CDN serving a release-built tarball: all
seven protocol-managed skills extracted; SDK-local skills (adcp/, build-*)
untouched; nested schemas/ subdirs filtered (1 file per skill, ~80K total
vs. 1.4MB+ per protocol unfiltered).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 25, 2026
Closed
Closed
Merged
bokelley
added a commit
that referenced
this pull request
Apr 25, 2026
… in call-adcp-agent (#3125) * fix(skills): re-cut 3.0.0 tarball with skills + discovery-first paths Two fixes filed against the upstream skill hoist (#3097): #3116 — Production /protocol/3.0.0.tgz was built 2026-04-22, before #3097 hoisted skills/ into the bundle. SDK consumers pinned to ADCP_VERSION=3.0.0 extracted zero skills, so the JS-side companion sync (adcp-client#965) shipped dormant. Rebuild dist/protocol/3.0.0.tgz with skills/ + manifest.contents.skills enumerated, preserving adcp_version: "3.0.0" so no SDK pin bumps are needed. Stale cosign sidecars (.sig + .crt) removed because they bind to the old content's SHA. Sync verification (verifyCosignSignature in @adcp/client) falls back to checksum-only trust on 404 — graceful, logs "ℹ️ No cosign sidecars for v3.0.0 (checksum-only trust)". Re-signing requires the release.yml workflow identity (cosign keyless OIDC bound to the workflow run); next CI release dispatch will regenerate sidecars. #3117 — call-adcp-agent SKILL.md and docs/protocol/calling-an-agent.mdx both hardcoded `dist/schemas/<adcp-version>/bundled/...` (the spec-repo source layout). SDK consumers see schemas at `schemas/cache/<version>/bundled/` (@adcp/client) or other SDK-specific locations; the canonical text pointed agents at a directory that didn't exist for them. Fixed with discovery-first phrasing across four call sites: prefer get_schema(), fall back to "your SDK's schema cache", let the loader find the path. Don't hardcode anything. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(skills): expert-review cleanups — residual path drift + clearer comms Address feedback from pre-merge review on PR #3125: - **SKILL.md:28 (Discovery chain step 4)** — collapse to mirror the cleaner docs/protocol/calling-an-agent.mdx phrasing. Drops the "Don't hardcode a path" repetition and tightens the SDK-list ordering. - **SKILL.md:247 (If you get stuck)** — was repeating the SDK-path enumeration nearly verbatim from step 4. Replace with a reference to step 4 plus a terminal action ("ask the developer or fall back to get_schema()") so agents without an SDK loader don't stall. - **SKILL.md:255 (Related)** — was still hardcoding spec-repo + @adcp/client paths after the lead rewrite. Replace with reference to Discovery chain step 4. - **Changeset body** — explicitly call out the new SHA-256 at the same URL (so cached-digest consumers refresh) and the temporary cosign-sidecar absence (so Sigstore-verification consumers know to expect the 404). Adds a CDN-cache-invalidation checklist for the post-merge deploy. Tarball regenerated to pick up the SKILL.md text changes; new sha256 committed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * pivot to 3.0.1 patch release per pre-merge expert review Restores immutability of /protocol/3.0.0.tgz (and its cosign sidecars) and switches the changeset to a `patch: adcontextprotocol` bump so the next release.yml run will produce 3.0.1.tgz with skills/ properly bundled and freshly signed under the workflow identity. Net effect of this PR after the pivot: - skills/call-adcp-agent/SKILL.md — discovery-first phrasing across four call sites (closes #3117 once 3.0.1 ships, since the canonical content rides in the new bundle) - docs/protocol/calling-an-agent.mdx — sister content fix - .changeset/3.0.1-skills-bundle-and-path-fix.md — patch bump entry that triggers the changesets release flow on merge Once 3.0.1.tgz lands at /protocol/3.0.1.tgz with skills bundled (closes #3116), SDKs can bump ADCP_VERSION from 3.0.0 to 3.0.1 to receive the canonical skills via their existing sync flow. JS-side wiring is in adcp-client#965; Python and Go follow-ups in adcp-client-python#274 and adcp-go#91. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
skills/call-adcp-agent/SKILL.md— agent-facing buyer-side wire contract (idempotency replay, accountoneOfvariants, asyncstatus:'submitted'polling,adcp_error.issues[]recovery). Hoisted from@adcp/client@5.17.0and made canonical here so all SDKs (@adcp/client,adcpPython,adcp-go) consume one source of truth.scripts/build-protocol-tarball.cjsnow bundlesskills/into the published/protocol/<version>.tgz. SDKs already pull this tarball at sync time for schemas and compliance — version-pinned, Sigstore-verified, no manual copy.manifest.json.contents.skillsis an enumerated list so SDK sync scripts can pick out skill names without re-walking the tree.adcp-{brand,creative,governance,media-buy,si,signals}) gain a one-line pointer at the top deferring cross-cutting rules tocall-adcp-agent.docs/protocol/calling-an-agent.mdx— human-readable canonical narrative form, registered indocs.jsonand cited from the SKILL.md (and back).loadSkillDocsis now frontmatter-driven (filters byname: adcp-*ortype: cross-cutting) instead of hardcoding directory names. Cross-cutting rules live in a singleBUYER_RULES_PREAMBLEinjected at the top of every search response.call_adcp_task's tool description trims to the two non-negotiable rules (idempotency_keyreplay +issues[].variants[]recovery). Failure-path output appends a recovery hint pointing atissues[].Dockerfilewas missingCOPY /app/skills— skill loader silently returned empty for ALLadcp-*skills in production./skills(root) in prod (dist/) layout. Replaced withresolveSkillsDir()candidate-list (works in dev, prod, and CWD layouts; exported and unit-tested).tests/addie/buyer-skill-wiring.test.tslock down skill content, frontmatter version pin, loader resolution, search preamble injection, and tool description shape. Pre-commit hook ran 832 tests + typecheck — all passed.Live test
Spun up
docker compose up, logged in asadmindev user, asked Addie:She called
ask_about_adcp_task, citedskills/call-adcp-agent/SKILL.mdas the source, and gave all five buyer rules verbatim — including the correctoneOfvariants{account_id}OR{brand:{domain}, operator}. Anonymous tier (no AdCP tools exposed) had hallucinatedaccount_name+account_email. The wiring is real.Pre-PR review
Five experts in parallel — agentic-product-architect, docs-expert, prompt-engineer, dx-expert, code-reviewer. Addressed all "must-fix" + most "should-fix" feedback before commit.
Test plan
npx vitest run tests/addie/— 414 passing (was 402 before, +12 from new wiring tests + dropped scope tests)npx tsc --project server/tsconfig.json --noEmit— cleannpm run test:unit && npm run typecheck) — 832 tests passedask_about_adcp_tasknpm run build:protocol-tarball— verifiedadcp-latest/skills/call-adcp-agent/SKILL.mdis in the tarball; manifest enumerates skillsFollow-ups (not in this PR)
skills/from the tarball at sync time:@adcp/clientscripts/sync-schemas.tsadcp-client-pythonequivalentadcp-goequivalent@adcp/client/skills/call-adcp-agent/..mdxpages (e.g.docs/media-buy/task-reference/create_media_buy.mdx) to the canonical idempotency_key list rather than redefining inline.🤖 Generated with Claude Code