agentsclimarketplace

Build governance agent

Skill adcontextprotocol/adcp-client/skills/build-governance-agent

Use when building an AdCP governance agent — campaign governance (spending authority, approval/denial), property/collection lists for brand safety, or content standards for creative compliance.From its SKILL.md

Install
npx -y skills add adcontextprotocol/adcp-client --skill build-governance-agent

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.1 KB, as published. Nobody here has run it

Build a Governance Agent

A governance agent enforces policy on the buy side. It evaluates spending authority, maintains property and collection lists, and defines content standards. There is no dedicated hello_governance_adapter_*.ts yet — this skill collapses against the seller adapter pattern and the documented tool surface.

Pick your fork target

SpecialismStatusFork thisStoryboard
governance-spend-authoritystablehello_seller_adapter_multi_tenant.ts — campaignGovernance blockgovernance_spend_authority
governance-delivery-monitorstableSame; add phase: 'delivery' branch on checkGovernancegovernance_delivery_monitor
property-listsstablehello_seller_adapter_multi_tenant.ts — propertyLists blockproperty_lists
collection-listsstableSame shape as property-lists; add IMDb/Gracenote/EIDR resolutionplaceholder
content-standardsstableAdd contentStandards domain group via defineContentStandardsPlatformplaceholder
measurement-verificationpreviewv3.1 placeholder. Baseline only.placeholder

The multi-tenant adapter is the canonical fork target — it implements campaignGovernance (sync_plans, check_governance, report_plan_outcome, get_plan_audit_logs), propertyLists (CRUD + validate_property_delivery), and brandRights against a per-tenant in-memory store with full tenant isolation via createTenantStore.

What to delete if you're single-specialism

Forking the multi-tenant adapter for a single specialism? Delete these blocks first — leaning on stable symbol names rather than line numbers (the adapter evolves; greppable identifiers don't):

A single-specialism governance-spend-authority adopter (an in-house policy engine, IAS, DoubleVerify) deletes:

  • The brandRights = defineBrandRightsPlatform({ ... }) block (the entire brand-rights surface)
  • The propertyLists = definePropertyListsPlatform({ ... }) block if you don't claim property-lists
  • The private async enforceGovernance(...) helper and the interface GovernanceBinding — these belong to brandRights cross-specialism dispatch, not to standalone governance
  • Per-tenant brands / rights Maps on TenantState (no brand-rights catalog to seed)

A single-specialism property-lists adopter mirrors this: keep the propertyLists block; delete campaignGovernance, brandRights, enforceGovernance, the brand/rights Maps, and the governanceBindings map.

Keep: the accounts / createTenantStore block (translates to single-tenant by passing one tenant entry — needed for tenant isolation), agentRegistry, the specialism block(s) you claim, getTenant(ctx) resolution. Don't keep enforceGovernance if you also delete brandRights — the helper has no caller and wires a non-existent governance binding.

For content-standards and collection-lists, no worked fork target ships yet — wire defineContentStandardsPlatform / defineCollectionListsPlatform from @adcp/sdk/server against the multi-tenant scaffolding.

For exact response shapes, error codes, and optional fields, docs/llms.txt is the canonical reference.

When to use this skill

  • User wants to enforce campaign governance, property lists, collection lists, or content standards
  • User describes themselves as a brand-safety vendor (IAS, DoubleVerify), policy engine (OPA/Cerbos), or compliance platform
  • User mentions check_governance, validate_property_delivery, validate_content_delivery

Not this skill:

  • Selling inventory while consuming governance signals → skills/build-seller-agent/ (governance-aware seller track)
  • Brand identity / rights licensing → skills/build-brand-rights-agent/
  • Audience sync (despite the name overlap) → skills/build-seller-agent/ (audience-sync track)

Cross-cutting rules

Every governance agent hits the cross-cutting rules in ../cross-cutting.md. The high-traffic ones for governance (deep-linked to the rule):

  • idempotency_key on sync_plans, sync_governance, report_plan_outcome, create_property_list / update_property_list / delete_property_list, create_collection_list / update_collection_list / delete_collection_list, create_content_standards / update_content_standards / calibrate_content
  • Resolve-then-authorize — byte-equivalent errors on property_list_id / collection_list_id / plan_id cross-tenant lookups
  • Account resolution — createTenantStore for multi-tenant policy hubs

One governance-specific rule on top:

comply_test_controller is required

Both governance_spend_authority and property_lists storyboards seed fixtures via comply_test_controller.seed_plan / seed_property_list before running the business-logic phases. Register via createComplyController({ sandboxGate, seed: { plan, property_list, collection_list, content_standards } }) and call controller.register(server) — same pattern as the seller adapter wires for media-buy seeding. The gate must derive authority from server-controlled authentication or resolved account state, never from a caller-supplied sandbox marker.

Without the test controller, every business-logic step skips with missing_test_controller and the track "passes" vacuously — the grader treats vacuous green as fail. Wire it on day one.

Specialism deltas at a glance

governance-spend-authority — check_governance evaluates the request's binding against the Plan's budget.total, human_review_required, and custom_policies. Returns one of approved / conditions / denied. The Plan model is the source of truth: read sync_plans / get_plan to materialize the spending authority, then check the inbound binding against it.

governance-delivery-monitor — check_governance with phase: 'delivery' + delivery_metrics. Compute drift vs Plan's budget.reallocation_threshold; return BUDGET_DRIFT_EXCEEDED findings when delivery exceeds the threshold.

property-lists — tool family property_list_* (create, read, update, delete, list). validate_property_delivery returns full violations[] (publisher property not in the inclusion list, or hit the exclusion list). Property identity is {agent_url, id} — buyers fetch lists by reference, not by inline copy.

collection-lists — program-level brand safety (shows, series, podcasts) identified by platform-independent IDs: IMDb (movies/TV), Gracenote (TV/audio metadata), EIDR (entertainment industry standard). Mirrors property-lists CRUD plus collection resolution.

content-standards — policies[] is an array of { policy_id, enforcement, policy, policy_categories?, channels? }. validate_content_delivery uses records[].artifact (not creative_id). Re-read policies per call so standards_version_change events don't serve stale policy.

measurement-verification — v3.1 placeholder (empty phases). Pass universal + governance baseline only. Advertise the capability for discoverability.

Validate locally

# Run the fork-matrix gate (tsc strict)
npm run compliance:fork-matrix -- --test-name-pattern="hello-seller-adapter-multi-tenant"

# Run your forked agent against the matching storyboard
adcp storyboard run http://127.0.0.1:3003/mcp governance_spend_authority \
  --bearer "$ADCP_AUTH_TOKEN" --include-bundles --json

# Property-lists track
adcp storyboard run http://127.0.0.1:3003/mcp property_lists \
  --bearer "$ADCP_AUTH_TOKEN" --include-bundles --json

The fork-matrix gate is the three-gate contract from docs/guides/EXAMPLE-TEST-CONTRACT.md. The multi-tenant adapter currently runs the strict-tsc gate only (no governance / brand-rights mock-server today); storyboard-grader gates land alongside the next mock-server family.

For deeper validation: docs/guides/VALIDATE-YOUR-AGENT.md.

Common shape gotchas

policies[] is { policy_id, enforcement, policy, ... } — a wrapped policy, not a bare string. validate_content_delivery keys on records[].artifact, not creative_id. Property identity is {agent_url, id} (a PropertyId), not a bare string. check_governance response uses decision: 'approved' | 'conditions' | 'denied' — not boolean. See ../SHAPE-GOTCHAS.md.

Migration notes

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.