Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .changeset/reporting-subscription-beta3-engine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
'@adcp/sdk': minor
'@adcp/reporting-storage': minor
---

Reporting subscriptions (experimental `media_buy.reporting_subscriptions`): the coverage function, engine, principal runtime, ledger and managed delivery follow the AdCP 3.3.0-beta.3 rules. All 120 canonical coverage vectors pass.

- **Flights and cancellation (adcp#8617, #8618).** A buy's stop time uses `cancellation_effective_at`, the delivery stop under a cancellation, when present. Flight values at each period's end come from the buy's wire `flight_history`. **Breaking:** the non-wire `prior_flights` coverage input and `ReportingSubscriptionPriorFlightV1` are removed. Pass `flight_history` (`ReportingSubscriptionFlightHistoryEntryV1`) from `get_media_buys` instead.
- **Billing stubs (adcp#8617).** A cutover onto a billing feed whose schedule has no boundary at E owes `[E, first boundary)` as one stub period. Owed rows, grouped obligations, ledger obligations and the wire `reporting_obligation` carry `stub: true`.
- **Re-grants (adcp#8618).** The grant journal serves `authorization.regranted_at` on `list_accounts` and `sync_accounts` for a chain that continued past a loss of authority. **Breaking:**
- `engine.observeGrants` now returns `{ authorized_at, regranted_at? }` per account.
- The host account fact's `granted_at` is renamed `regranted_at`, the wire name.
- **Sticky resolution (adcp#8619).** Each package resolves once per (buy, version), at the later of `accepted_at` and `confirmed_at`, among the offerings available then. It keeps that resolution until the offering is withdrawn. New: `resolveReportingSubscriptionPackageV1`. The managed path reads each package's `reporting_delivery_offering_ids` snapshot from `get_media_buys`.
- **Admission (adcp#8619).** Under `max_accounts`, admission is sticky and ordered by `authorized_at`, then `account_id`. Accounts with another open exception keep their place. A deactivation releases its slots.
- **Membership in place (adcp#8619).** Adding or removing `account_ids`, or changing `exclude_account_ids`, keeps the version. The engine records each edit per account as an `excluded_by_buyer` interval. Changing the scope kind or `operator_domains` still needs a new version, and `client.reporting.subscribe` auto-versions accordingly.
- **Several feeds per purpose (adcp#8619).**
- Pacing and analytics allow several subscriptions per account and purpose. Where two resolve one offering for a package, the lower `subscription_id` owes it, and the other records a package-level `overridden` exception.
- Billing stays one per account at a scope level, and must use `match: exact` with `dimensions`.
- **`destination_overrides` (adcp#8619).**
- Each override is validated.
- The readback carries `destination_override_refs`.
- Managed delivery binds each account to its routed destination and template. New: `reportingSubscriptionDestinationForAccount`, plus `ReliableReportingSubscriptionBindingInputV1.destination`.
- **Paged readback (adcp#8619).**
- Lists of any length are kept.
- The response lists 1,000 accounts inline, each list with its total.
- `get_principal` `reporting_subscription_page` pages `accounts_with_exceptions`, `accounts_unauthorized` and `prior_versions`.
- `onReadbackOverflow` and `readback_overflow` are deprecated and never report.
- **Partial grants (adcp#8619).** With subscriptions, `sync_reporting_status` (SDK service) and `sync_reporting_receipts` (`@adcp/reporting-storage` service) refuse a task that the account's `authorization.allowed_tasks` leaves out with `SCOPE_INSUFFICIENT`. New: `assertReportingTaskGrantedV1`.
- **Delivered rows (adcp#8619).** Creating a service with subscriptions refuses a managed-delivery offering whose `reporting_profile.primary_keys` omit `account_id`.
- **Period arithmetic (adcp#8622).**
- Each local date's first instant is always a boundary of a sub-daily local schedule, so `PT24H` equals `P1D` where midnight doesn't exist.
- Reactivation resumes at the later of the reactivation instant and the end of the last period owed before the deactivation.
- **Account requests (adcp#8620).** `accounts.ensure` outcomes carry the request's `resolution`, `effective_at` and `not_carried_over`. The account's money terms are on `account`.
18 changes: 18 additions & 0 deletions .changeset/reporting-subscription-beta3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@adcp/sdk': minor
---

**Beta-channel break:** this SDK advertises and negotiates only the AdCP `3.3-beta.3` preview and no longer packages or advertises `3.3-beta.2`. A buyer or seller still on beta.2 (SDK 17.0.0-beta.10) will not select the 3.3 preview with this release; the pair negotiates a shared stable release (3.2.7, 3.1.31 or 3.0.25) instead. Upgrade both sides together to keep exercising 3.3 preview features. An explicit `adcpVersion: '3.3.0-beta.2'` pin now fails with a configuration error.

Adopt the signed AdCP 3.3.0-beta.3 bundle, replacing 3.3.0-beta.2. Public types, Zod schemas, tool metadata and the packaged compliance corpus are regenerated from the beta.3 release.

- Every 3.3 task response composes the protocol envelope (adcp#8547): `status` is required on every response, and the generated response types no longer restate envelope fields.
- Account requests (adcp#8620): resolved `matched`/`created` records carry `account` with its money terms, an `updated` money change carries `effective_at`, and a change that `created` a separate account carries `not_carried_over`.
- Experimental live creative updates: `creative.live_updates` types, `CREATIVE_LIVE_UPDATE_UNSUPPORTED`, and the `creative.staged_update_changed` notification type, which joins `ACCOUNT_NOTIFICATION_TYPES`.
- Reporting subscriptions: `authorization.regranted_at` joins the account authorization fields (`toWireAccount` and `windDownGrant` keep it); media buys carry `cancellation_effective_at` and `flight_history`, packages `reporting_delivery_offering_ids`, offerings `available_from`/`withdrawn_at`, billing obligations `stub`, and `subscription_coverage[].status` is served as `inactive` with `deactivated_at`. Readbacks list at most 16 `prior_versions` and carry `prior_versions_count`, `accounts_with_exceptions_count` and `accounts_unauthorized_count`. A subscription response served without a negotiated release uses the pinned release, as in the Python SDK.

**Removed from `@adcp/sdk/reporting/advanced`:** the hand-modelled wire types `ReportingDeliveryOfferingWithDimensionsV1`, `ReportingSubscriptionCoverageWithOfferingsV1`, `ReportingSubscriptionExclusionEntryV1`, `ReportingSubscriptionGapV1`, `ReportingSubscriptionInactiveIntervalV1`, `ReportingSubscriptionStateWithIntervalsV1` and `ReportingSubscriptionTimezoneCutoverV1`. The generated `ReportingDeliveryOffering`, `ReportingSubscriptionCoverage` and `ReportingSubscriptionState` carry every field; `ReportingSubscriptionOfferingV1` is now an alias of `ReportingDeliveryOffering`.

Codegen follows the beta.3 envelope layout: the `request_proposals`, `refine_proposals` and `decline_proposals` submitted arms keep `status: 'submitted'` and the required `task_id` (folded from `core/task-submitted.json`), and generated Zod response schemas keep the `adcp_version`, `adcp_major_version`, `task_id` and `message` constraints they inherit through the composed envelopes.

A terminal task webhook's `result` is the task's full response, so on 3.1+ it now carries the task `status` (`completed` or `rejected`) like a synchronous response, and a media-buy lifecycle value a platform returned in `status` moves to `media_buy_status`, as on the synchronous path. A 3.2 `list_products` / `decline_proposals` result and a 3.0 result are left as returned.
2 changes: 1 addition & 1 deletion ADCP_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.0-beta.2
3.3.0-beta.3
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ npm run generate-zod-schemas # Generate runtime validation

### Wire-version compat (v3 SDK ↔ legacy sellers)

The SDK speaks one AdCP major (`ADCP_VERSION` in `src/lib/version.ts`, currently `3.3.0-beta.2`) on its public surface and adapts to legacy sellers underneath. AdCP 2 support has been removed following its August 1, 2026 end of life. Maintained AdCP 3 compatibility and the policy for future major-version support are documented in [`docs/development/WIRE-VERSION-COMPAT.md`](https://github.com/adcontextprotocol/adcp-client/blob/main/docs/development/WIRE-VERSION-COMPAT.md). Touch that doc whenever you add to `src/lib/adapters/legacy/`, `src/lib/types/v*-*/`, or `schemas/cache/<version>/`.
The SDK speaks one AdCP major (`ADCP_VERSION` in `src/lib/version.ts`, currently `3.3.0-beta.3`) on its public surface and adapts to legacy sellers underneath. AdCP 2 support has been removed following its August 1, 2026 end of life. Maintained AdCP 3 compatibility and the policy for future major-version support are documented in [`docs/development/WIRE-VERSION-COMPAT.md`](https://github.com/adcontextprotocol/adcp-client/blob/main/docs/development/WIRE-VERSION-COMPAT.md). Touch that doc whenever you add to `src/lib/adapters/legacy/`, `src/lib/types/v*-*/`, or `schemas/cache/<version>/`.

## Testing Strategies

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ AdCP operations are **distributed and asynchronous by default**. An agent might:

```bash
npm install @adcp/sdk # 16.x, AdCP 3.2
npm install @adcp/sdk@beta # 17.x beta, AdCP 3.3.0-beta.2 (development/staging)
npm install @adcp/sdk@beta # 17.x beta, AdCP 3.3.0-beta.3 (development/staging)
npm install @adcp/sdk@adcp-3.1 # 13.x, maintained AdCP 3.1 line
npm install @adcp/sdk@adcp-3.0 # 7.11.x, AdCP 3.0
```

SDK 17 beta adopts the signed AdCP `3.3.0-beta.2` bundle and includes the breaking
SDK 17 beta adopts the signed AdCP `3.3.0-beta.3` bundle and includes the breaking
HTML-markup `display_tag` mapping. See the [beta release notes](./docs/releases/17.0.0-beta.0.md)
and [16 β†’ 17 migration guide](./docs/migration-16-to-17.md). Keep production on SDK 16.

Expand Down
2 changes: 1 addition & 1 deletion bin/adcp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2079,7 +2079,7 @@ RUN OPTIONS (full assessment):
--storyboards IDS Comma-separated storyboard/bundle IDs to run
--compliance-version VERSION
Select a compliance cache version, e.g. 3.1.31 or
3.3.0-beta.2. The runner uses this cache for
3.3.0-beta.3. The runner uses this cache for
storyboard resolution and wire-version defaults. When
--test-kit points into a compliance cache, its version is
selected automatically; an explicit mismatch is rejected.
Expand Down
39 changes: 7 additions & 32 deletions docs/TYPE-SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AdCP Type Summary

> Generated at: 2026-10-30
> Generated at: 2026-10-31
> @adcp/sdk v17.0.0-beta.10

Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
Expand Down Expand Up @@ -575,7 +575,7 @@ Request parameters for get_task_status, the 3.
_Request:_
```
{
task_id: string // required
task_id: Task Id // required
account: Account Ref
include_history: boolean
include_result: boolean
Expand All @@ -586,10 +586,8 @@ _Request:_
_Response (success branch):_
```
{
task_id: string // required
task_type: Task Type // required
protocol: Adcp Protocol // required
status: Task Status // required
created_at: string // required
updated_at: string // required
completed_at: string
Expand Down Expand Up @@ -684,6 +682,7 @@ Read caller-scoped connection configuration, version, and destination setup stat
_Request:_
```
{
reporting_subscription_page: object
context: Context
}
```
Expand Down Expand Up @@ -998,12 +997,10 @@ _Response (success branch):_
products: Canonical Product[] // required
feed_version: string // required
cache_scope: 'public' | 'account' // required
adcp_version: string
collections: Response Collection[]
next_cursor: string
pricing_version: string
incomplete: object[]
replayed: 'true'
context: Context
}
```
Expand Down Expand Up @@ -1038,7 +1035,6 @@ _Response (success branch):_
proposals: object[] // required
opportunities: object[] // required
next_cursor: string
replayed: 'true'
context: Context
}
```
Expand Down Expand Up @@ -1069,7 +1065,6 @@ _Response (success branch):_
collections_version: string // required
cache_scope: 'public' | 'account' // required
pagination: Pagination Response
replayed: 'true'
context: Context
}
```
Expand Down Expand Up @@ -1102,16 +1097,13 @@ _Response (success branch):_
outcome: 'proposed' // required
proposals: Canonical Proposal[] // required
products: Canonical Product[] // required
adcp_version: string
collections: Response Collection[]
incomplete: object[]
targeting_resolution: Get Products Targeting Resolution
later_proposals: Later Proposals State
status: 'completed'
message: string
errors: Error[]
context: Context
replayed: 'true'
status: 'completed'
}
```

Expand All @@ -1138,13 +1130,10 @@ _Response (success branch):_
{
results: union[] // required
products: Canonical Product[] // required
adcp_version: string
collections: Response Collection[]
status: 'completed'
message: string
errors: Error[]
context: Context
replayed: 'true'
status: 'completed'
}
```

Expand All @@ -1170,10 +1159,9 @@ _Response (success branch):_
```
{
results: object[] // required
message: string
errors: Error[]
context: Context
replayed: 'true'
status: 'completed'
}
```

Expand Down Expand Up @@ -1289,7 +1277,6 @@ _Response (success branch):_
available_actions: Canonical Media Buy Action[]
warnings: Warning[]
context: Context
replayed: 'true'
}
```

Expand Down Expand Up @@ -1688,7 +1675,6 @@ _Response (success branch):_
outcome: 'recorded' // required
issue: Media Buy Issue // required
context: Context
replayed: boolean
}
```

Expand Down Expand Up @@ -1716,7 +1702,6 @@ _Response (success branch):_
outcome: 'found' // required
issue: Media Buy Issue // required
context: Context
replayed: boolean
}
```

Expand Down Expand Up @@ -2100,7 +2085,7 @@ _Request:_
include_webhook_activity: boolean
webhook_activity_limit: integer
account: Account Ref
fields: ('creative_id' | 'name' | 'format_id' | 'format_kind' | 'format_option_ref' | 'assets' | 'status' | 'created_date' | 'updated_date' | 'tags' | 'provenance' | 'rights' | 'rights_attestation_evaluations' | 'localization' | 'localization_unavailable' | 'assignments' | 'snapshot' | 'items' | 'variables' | 'concept' | 'pricing_options')[]
fields: ('creative_id' | 'name' | 'format_id' | 'format_kind' | 'format_option_ref' | 'assets' | 'status' | 'created_date' | 'updated_date' | 'tags' | 'provenance' | 'rights' | 'rights_attestation_evaluations' | 'localization' | 'localization_unavailable' | 'assignments' | 'snapshot' | 'items' | 'variables' | 'concept' | 'pricing_options' | 'staged_update')[]
context: Context
}
```
Expand Down Expand Up @@ -2268,7 +2253,6 @@ _Response (success branch):_
{
list: Property List // required
auth_token: string // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2297,7 +2281,6 @@ _Response (success branch):_
```
{
list: Property List // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2372,7 +2355,6 @@ _Response (success branch):_
{
deleted: boolean // required
list_id: string // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2400,7 +2382,6 @@ _Response (success branch):_
{
list: Collection List // required
auth_token: string // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2429,7 +2410,6 @@ _Response (success branch):_
```
{
list: Collection List // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2504,7 +2484,6 @@ _Response (success branch):_
{
deleted: boolean // required
list_id: string // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2727,7 +2706,6 @@ _Response (success branch):_
```
{
plans: object[] // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2762,7 +2740,6 @@ _Response (success branch):_
delivery_period_state: 'open' | 'closed'
findings: object[]
plan_summary: object
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2800,7 +2777,6 @@ _Response (success branch):_
amount: object // required
headroom_restored: number // required
plan_summary: object // required
replayed: boolean
context: Context
}
```
Expand Down Expand Up @@ -2878,7 +2854,6 @@ _Response (success branch):_
mode: Governance Mode
runtime_attestation_evaluations: Attestation Evaluation[]
runtime_attestation_binding_digest: string
governance_context: string
context: Context
}
```
Expand Down
6 changes: 3 additions & 3 deletions docs/development/WIRE-VERSION-COMPAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ from `@adcp/sdk/v2/projection`. These advisories remain outside the wire JSON.

```text
schemas/cache/
β”œβ”€β”€ 3.3.0-beta.2/ # primary SDK pin
β”œβ”€β”€ 3.3.0-beta.3/ # primary SDK pin
β”œβ”€β”€ 3.2.7/ # maintained stable release
β”œβ”€β”€ 3.1.31/ # maintained stable release
β”œβ”€β”€ 3.0.25/ # maintained stable release
Expand All @@ -88,11 +88,11 @@ schemas/cache/

Run `npm run sync-schemas:all` to refresh the primary and maintained bundles. Run `npm run generate-types:all` to regenerate public types, then `npm run build:lib` to build and copy supported schemas into the package. `copy-schemas-to-dist.ts` excludes retired AdCP 2 caches even when present locally. `check-publish-protocol-artifacts.mjs` checks the published schema inventory and rejects retired type exports.

The v17 beta primary pin is the signed AdCP 3.3.0-beta.2 bundle; it replaces 3.3.0-beta.1, which is no longer packaged or advertised. Stable SDK 16 remains on AdCP 3.2.7. The beta retains stable AdCP 3.2.7, 3.1.31 and 3.0.25 bundles for negotiation, schema projection and compliance runs.
The v17 beta primary pin is the signed AdCP 3.3.0-beta.3 bundle; it replaces 3.3.0-beta.2, which is no longer packaged or advertised. Stable SDK 16 remains on AdCP 3.2.7. The beta retains stable AdCP 3.2.7, 3.1.31 and 3.0.25 bundles for negotiation, schema projection and compliance runs.

Compliance pins select exact fixture bytes, unlike same-minor wire schema aliases. SDK 16.5.0 packages the 3.2.7 corpus; when upgrading from SDK 16.4.0, update explicit `--compliance-version 3.2.5` flags to `3.2.7`. A development pin of `3.2.6` must likewise advance. Retain the matching historical SDK if a run requires that older corpus. The maintained 3.1.31 and 3.0.25 corpora remain packaged.

Build tooling also understands exact AdCP 3.3.0 `beta.N` and `rc.N` pins. Such a build retains maintained AdCP 3.0, 3.1, and 3.2 GA aliases through 3.2.7 while advertising only the selected prerelease, without a moving beta/RC-family alias. SDK 17 selects the exact 3.3.0-beta.2 preview. The stable v16 compatibility list continues to advertise only AdCP 3.2 and earlier.
Build tooling also understands exact AdCP 3.3.0 `beta.N` and `rc.N` pins. Such a build retains maintained AdCP 3.0, 3.1, and 3.2 GA aliases through 3.2.7 while advertising only the selected prerelease, without a moving beta/RC-family alias. SDK 17 selects the exact 3.3.0-beta.3 preview. The stable v16 compatibility list continues to advertise only AdCP 3.2 and earlier.

Conformance validates current and unversioned response payloads without synthesizing task status. The existing status-optional compatibility shim applies only to explicitly declared AdCP 3.0 payloads, and never to status-free compact tools. Closed response schemas admit only the canonical version-envelope fields alongside their declared task fields; other root restrictions and nested-body constraints remain enforced.

Expand Down
Loading
Loading