Summary
AdCP 3.0 has no protocol-level mechanism for a buyer to stop using a signal mid-campaign once it has been activated to a destination. The existing activate_signal task accepts action: "deactivate" (schema signals/activate-signal-request.json) but:
- No published agent in the live AdCP directory implements it (verified via federation probe against the live registry)
- The semantics of "deactivate this signal everywhere" vs. "deactivate this specific activation" are undefined
- Buyer-triggered revocation carries no reason code, no authorization scope, no async-safe state machine, and no audit trail
- The only alternatives today are manual out-of-band destination action (untraceable) or producer-set
validity_period (not buyer-triggered, not implemented in any 3.0.x adapter)
This is a clean greenfield gap: no existing GH issue, no in-flight RFC, no working-group thread covering this surface (verified prior-art check, May 2026).
Proposed primitive: revoke_activation
A new task in the signals domain. Design constraints:
- Async-by-default — revocations may require producer-side propagation to downstream platforms; synchronous response is not realistic
- Reason-coded — reason enum covers compliance, campaign-end, budget-exhausted, policy-violation, producer-request, and test (minimum viable set; open for extension)
- Reason-scoped authorization — not every caller can invoke every reason code (e.g.
producer-request may only be callable by the producing agent; policy-violation requires governance context)
- Reuses existing AdCP infrastructure end-to-end — async polling via
tasks/get, webhook delivery using the existing signed-webhook contract, no new transport / auth / persistence / envelope
- Additive only — agents that don't implement
revoke_activation degrade to today's behavior; no breaking change to activate_signal
Request sketch
{
"task": "revoke_activation",
"idempotency_key": "<uuid>",
"signal_agent_segment_id": "<segment-id>",
"activation_ref": "<activation-idempotency-key | all>",
"destinations": ["<destination-id>"],
"reason": "compliance | campaign-end | budget-exhausted | policy-violation | producer-request | test",
"effective_at": "<ISO-8601 | null>",
"context": {}
}
activation_ref: "all" targets all active destinations for the segment. A specific key targets a single activation, enabling per-activation revocation without disturbing siblings.
State machine (proposed)
pending → propagating → revoked | failed
Webhook event: signal.revocation.completed / signal.revocation.failed
Open questions for working-group triage (§14 of full proposal)
- Producer-initiated revocation routing — sibling tool on the buyer agent, or direct call from producer to buyer agents? What's the right topology?
- Cascade semantics — when a signal feeds an activation chain, does revoking the root propagate? Proposal default: explicit per-task only for v1.
- Pricing reconciliation — mid-billing-period revocation creates a partial-use window. In scope for protocol (e.g. a
revoked_at timestamp on the activation record), or out of scope?
effective_at scheduling — who is responsible for running the timer for future-dated revocations? Caller, producer, or platform?
- Privacy-budget restoration — when clean-room signals are revoked, should the protocol signal that budget is restorable? How?
Full proposal
Detailed spec (17 sections — request + response schemas, state machine, reason code enum, authorization matrix, worked example, conformance storyboard, test plan):
https://github.com/EvgenyAndroid/adcp-signals-adaptor/blob/master/docs/SPEC_PROPOSAL_REVOKE_ACTIVATION.md
Target milestone
3.1 minor — additive, no breaking changes, testable in <10 conformance storyboards.
Prior art
None found. activate_signal action: "deactivate" exists in schema but is semantically underspecified and unimplemented. This proposal supersedes the deactivate discriminator or can be defined as its normative complement.
Suggested labels
domain:signals, kind:proposal, priority:high
Summary
AdCP 3.0 has no protocol-level mechanism for a buyer to stop using a signal mid-campaign once it has been activated to a destination. The existing
activate_signaltask acceptsaction: "deactivate"(schemasignals/activate-signal-request.json) but:validity_period(not buyer-triggered, not implemented in any 3.0.x adapter)This is a clean greenfield gap: no existing GH issue, no in-flight RFC, no working-group thread covering this surface (verified prior-art check, May 2026).
Proposed primitive:
revoke_activationA new task in the signals domain. Design constraints:
producer-requestmay only be callable by the producing agent;policy-violationrequires governance context)tasks/get, webhook delivery using the existing signed-webhook contract, no new transport / auth / persistence / enveloperevoke_activationdegrade to today's behavior; no breaking change toactivate_signalRequest sketch
{ "task": "revoke_activation", "idempotency_key": "<uuid>", "signal_agent_segment_id": "<segment-id>", "activation_ref": "<activation-idempotency-key | all>", "destinations": ["<destination-id>"], "reason": "compliance | campaign-end | budget-exhausted | policy-violation | producer-request | test", "effective_at": "<ISO-8601 | null>", "context": {} }activation_ref: "all"targets all active destinations for the segment. A specific key targets a single activation, enabling per-activation revocation without disturbing siblings.State machine (proposed)
pending → propagating → revoked | failedWebhook event:
signal.revocation.completed/signal.revocation.failedOpen questions for working-group triage (§14 of full proposal)
revoked_attimestamp on the activation record), or out of scope?effective_atscheduling — who is responsible for running the timer for future-dated revocations? Caller, producer, or platform?Full proposal
Detailed spec (17 sections — request + response schemas, state machine, reason code enum, authorization matrix, worked example, conformance storyboard, test plan):
https://github.com/EvgenyAndroid/adcp-signals-adaptor/blob/master/docs/SPEC_PROPOSAL_REVOKE_ACTIVATION.md
Target milestone
3.1 minor — additive, no breaking changes, testable in <10 conformance storyboards.
Prior art
None found.
activate_signalaction: "deactivate"exists in schema but is semantically underspecified and unimplemented. This proposal supersedes the deactivate discriminator or can be defined as its normative complement.Suggested labels
domain:signals,kind:proposal,priority:high