Skip to content

feat(skills): hoist call-adcp-agent + bundle skills/ into protocol tarball#3097

Merged
bokelley merged 1 commit intomainfrom
bokelley/client-skill-sync
Apr 25, 2026
Merged

feat(skills): hoist call-adcp-agent + bundle skills/ into protocol tarball#3097
bokelley merged 1 commit intomainfrom
bokelley/client-skill-sync

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

  • New skills/call-adcp-agent/SKILL.md — agent-facing buyer-side wire contract (idempotency replay, account oneOf variants, async status:'submitted' polling, adcp_error.issues[] recovery). Hoisted from @adcp/client@5.17.0 and made canonical here so all SDKs (@adcp/client, adcp Python, adcp-go) consume one source of truth.
  • Cross-SDK distribution: scripts/build-protocol-tarball.cjs now bundles skills/ 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.skills is an enumerated list so SDK sync scripts can pick out skill names without re-walking the tree.
  • Per-protocol skills (adcp-{brand,creative,governance,media-buy,si,signals}) gain a one-line pointer at the top deferring cross-cutting rules to call-adcp-agent.
  • New docs/protocol/calling-an-agent.mdx — human-readable canonical narrative form, registered in docs.json and cited from the SKILL.md (and back).
  • Addie wiring: loadSkillDocs is now frontmatter-driven (filters by name: adcp-* or type: cross-cutting) instead of hardcoding directory names. Cross-cutting rules live in a single BUYER_RULES_PREAMBLE injected at the top of every search response. call_adcp_task's tool description trims to the two non-negotiable rules (idempotency_key replay + issues[].variants[] recovery). Failure-path output appends a recovery hint pointing at issues[].
  • Two pre-existing prod bugs fixed along the way:
    • Dockerfile was missing COPY /app/skills — skill loader silently returned empty for ALL adcp-* skills in production.
    • Skill loader's hardcoded relative-path traversal landed at /skills (root) in prod (dist/) layout. Replaced with resolveSkillsDir() candidate-list (works in dev, prod, and CWD layouts; exported and unit-tested).
  • 12 new tests in tests/addie/buyer-skill-wiring.test.ts lock 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 as admin dev user, asked Addie:

"I want to call create_media_buy on test-agent.adcontextprotocol.org. What cross-cutting rules do I need to be aware of as a buyer?"

She called ask_about_adcp_task, cited skills/call-adcp-agent/SKILL.md as the source, and gave all five buyer rules verbatim — including the correct oneOf variants {account_id} OR {brand:{domain}, operator}. Anonymous tier (no AdCP tools exposed) had hallucinated account_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 — clean
  • Pre-commit hook (npm run test:unit && npm run typecheck) — 832 tests passed
  • Live Addie conversation in docker compose — buyer rules surface correctly via ask_about_adcp_task
  • npm run build:protocol-tarball — verified adcp-latest/skills/call-adcp-agent/SKILL.md is in the tarball; manifest enumerates skills

Follow-ups (not in this PR)

  1. SDK-side wire-up to extract skills/ from the tarball at sync time:
    • @adcp/client scripts/sync-schemas.ts
    • adcp-client-python equivalent
    • adcp-go equivalent
  2. Once SDKs pull from canonical, remove the local copy from @adcp/client/skills/call-adcp-agent/.
  3. Per docs-expert: link from per-task .mdx pages (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

…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>
@bokelley bokelley merged commit 49420b1 into main Apr 25, 2026
18 checks passed
@bokelley bokelley deleted the bokelley/client-skill-sync branch April 25, 2026 11:48
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>
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>
@github-actions github-actions Bot mentioned this pull request Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant