Repository navigation
chore: release package (rc) - #2912
Merged
Merged
Conversation
|
Ladon does not review bot-authored PRs. |
aao-ipr-bot
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 14, 2026 17:35
34e5c36 to
9062872
Compare
bokelley
marked this pull request as draft
September 14, 2026 17:38
Contributor
Release hold — coordinated rc.4 adoption incompleteThis Changesets PR now includes the #2911 reporting contract fix after main advanced to Keep this PR Draft with auto-merge off. Do not merge or publish yet:
Release requires fresh human maintainer review of the resulting combined package, terminal exact CI/package verification, and explicit coordinated publication authorization. This hold does not revert #2911 or claim a source regression. |
aao-ipr-bot
Bot
force-pushed
the
changeset-release/main
branch
from
September 14, 2026 18:07
9062872 to
1be6b25
Compare
This was referenced Sep 14, 2026
aao-ipr-bot
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 14, 2026 18:51
1be6b25 to
2a85915
Compare
This was referenced Sep 14, 2026
aao-ipr-bot
Bot
force-pushed
the
changeset-release/main
branch
4 times, most recently
from
September 15, 2026 02:07
3e7c56c to
2c344b2
Compare
bokelley
marked this pull request as ready for review
September 15, 2026 02:15
aao-ipr-bot
Bot
force-pushed
the
changeset-release/main
branch
from
September 15, 2026 02:15
2c344b2 to
1712166
Compare
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
mainis currently in pre mode so this branch has prereleases rather than normal releases. If you want to exit prereleases, runchangeset pre exitonmain.Releases
@adcp/sdk@14.0.0-rc.37
Major Changes
5582908: Breaking (correction inside the unreleased v14):
AccountStore.resolution: 'derived'is now an upstream-managed account-id namespace, matching the account-reference model settled in adcp#5062. The previous wire semantics were inverted and unusable for the adapters the mode exists for — buyers who calledlist_accountsgot ids that every subsequent call rejected.Wire contract:
{ account_id }is the durable reference for'derived'and is now accepted (it was refused withINVALID_REQUEST); the{ brand, operator }natural-key arm is now refused withINVALID_REQUEST(field: 'account.brand') and alist_accountssuggestion.list_accountsis required for'derived'—createAdcpServerFromPlatformthrowsPlatformConfigErrorwhen neitheraccounts.listnoropts.accounts.listAccountsis wired. It is the discovery contract for a namespace the agent doesn't own; credential-bound singletons expose one row.sync_accountsis not categorically blocked: natural-key provisioning entries fail per-row withUNSUPPORTED_PROVISIONING, natural-key references fail per-row withINVALID_REQUEST, andaccount: { account_id }settings-update entries pass through.'derived'resolution projectsaccount.require_operator_auth: trueonget_adcp_capabilities, like a declared'explicit'.Tenant-isolation hardening (
'derived'only):accounts.resolvemust verify buyer-supplied ids; the framework backstops it — a resolved account whoseidisn't the one the buyer named is refused withACCOUNT_NOT_FOUND(with a dev-mode warning), so an un-migrated resolver that ignoresreffails closed instead of cross-serving.sync_accountsandsync_governanceentries — the two account references that never passed throughaccounts.resolve— are now resolved against the caller's reachable set before any write, on both the platform and merge-seam wirings.comply_test_controllersandbox gate no longer accepts a wiresandbox: trueclaim alongside anaccount_idthe resolver refused.API:
createDerivedAccountStoreverifies buyer-suppliedaccount_idagainst what the caller's credential can reach (fail closed →ACCOUNT_NOT_FOUND), auto-selects the account on ref-less tools only when exactly one is reachable, and wires a filtered, pagedlist_accounts. NewlistAccounts/lookupAccountoptions support credentials that reach many accounts;toAccountkeeps its signature for the single-account case.AccountResolutionMode/CanonicalAccountResolutionModetypes and thenormalizeAccountResolution(),isAccountResolutionMode(),refHasNaturalKey()helpers. An unrecognizedresolutionvalue is now aPlatformConfigErrorrather than silently inheriting another mode's enforcement. No alias spelling is introduced —'derived'stays the single name.Migration: 13 → 14 § derived account resolution. Fixes decisioning: rework 'derived' resolution mode — upstream-managed roster (Meta/Snap/AudioStack), invert account_id rejection #1647 and createDerivedAccountStore: factory + docs only cover single-tenant; multi-tenant derived needs a path to list_accounts #1628.
Minor Changes
ecf1c74: Adopt the signed AdCP 3.2.0-rc.3 schema and compliance bundles as the default wire release.
Moving the pin activates the
content_mismatchconsumer status and its closedmismatch_codeacross the publishedReportingConsumerStatusSchema/SyncReportingStatusRequestSchemaexports and the seller ledger's consumer-status types.The machinery that keeps those two in step with the bundle landed separately in fix(reporting): preserve canonical consumer status contracts #2911,
which derives both the ledger statement type and the Zod conditional arms from the pinned
schema; this pin is what supplies the rc.3 arms it reads. Verified: the regenerated
validator requires the obligation id, the revision id, the recomputed
observed_revision_content_sha256, andmismatch_codeforcontent_mismatch, forbidsfailure_codethere, and forbidsmismatch_codeon the four pre-existing statuses.rc.3 also publishes
core/media-buy-available-action-id.json, so the generatedupdate_media_buydispatch table gains the structured-onlyupdate_media_buy_frequency_capaction and itsfrequency_capfield binding. Media-buypreflight already resolved that binding from the generated table, so the shared
media-buy frequency cap becomes dispatchable with no adopter change.
3.2 prereleases remain exact pins: rc.3 replaces rc.2 in
COMPATIBLE_ADCP_VERSIONSandonly the current prerelease's schema bundle ships. Pin
adcpVersion: '3.2-rc'to followwhichever 3.2 release candidate a given SDK build carries.
d4d6780: Return correctable
ACCOUNT_REQUIREDwhen an account-scoped server operation omitsaccountand authentication cannot select one, including compact lifecycle mutations, async discovery, and task polling. Buyer retry policy re-discovers the account before retrying. Buyer-supplied unknown, unauthorized, or mismatched account references continue to return terminalACCOUNT_NOT_FOUND.46eb301: Accept the pinned AdCP 3.2 proposal-refinement frequency-cap, outcome-target,
and acceptance-context fields in buyer preflight, including remove-only shared
frequency-cap revisions, fail closed on invalid or contradictory cap removal,
and publicly expose their exact schema-derived supporting types.
dd96794: Export the protocol-authored AdCP 3.2.0-rc.3 universal principal and reporting-core storyboards with immutable provenance and drift-checked loaders.
5591b93: Bound transport-diagnostics body capture and observer flushing so observability cannot stall request completion. Preserve postal-country fallback validation for countries outside the registered system list, add whole-operation cancellation to
validateAdAgents, and expose client-scoped capability evidence priming for applications that already perform a trusted preflight. Add generated release upgrade guidance and a compiling thin existing-platform integration recipe.39b0714: Expose the standalone proposal commercial-terms verifier through
@adcp/sdk/negotiation/verificationwith ESM/CJS types. Fail closed on unsupported schema keywords, cross-bundle references, and changed validation contracts throughout the commercial-terms schema graph. Preserve digest-first exhaustive comparison and legacy opaque contract-reference behavior, and document runtime schema coupling and upstream shim retirement.Enforce schema-declared targeting disjointness, geographic label membership, language-tag grammar, and IANA timezone annotations before comparing terms, with validators isolated from ordinary SDK schema validation. Pin extensible-enum annotations while preserving explicit enum membership for binding snapshots.
3a5edd3: Add account change webhook normalization, branded advisory/checkpoint cursor types, and an acknowledged async drain with snapshot bootstrap and structured CURSOR_EXPIRED recovery. Expose the existing change-feed declaration in normalized capabilities and provide a subscriber-preserving account notification registration builder. Include packed MCP schema/type regressions, training-seller integration and runner support for persistent account-change webhook observations and an adopter migration guide. Durable storage, projection transactions and subscription runtime remain adopter/server responsibilities.
537f193: Implement the AdCP 3.2.0-rc.3 Reliable Reporting consumer-status hardening in the seller ledger.
content_mismatchprojection. The fifth consumer status conflicts with a healthy/complete sellerprojection like the other negative statuses and is immediately
action_required. It is acontract-fact disagreement naming the exact bytes the consumer read, never a measurement dispute.
Stale-
receivedgrace. Areceivedstatement made stale only by a seller restatement nowprojects the caller-scoped view as
delayed— withwait_for_retry— until a bounded re-readdeadline, then
action_required. The deadline is thecreated_atof the first revision thatsuperseded the one the consumer named plus the generation's
delivery_sla, falling back toautomated_recovery_window_secondswhen that SLA is zero. Later restatements supersede laterrevisions and cannot restart it. Previously every conflict escalated immediately.
Escalation.
createReportingStatusHandleracceptsconsumerMismatchEscalation(
escalationSeconds+operationsContact, mirroring the capability block's both-or-neither rule).Past
opened_atplus that window an open mismatch becomesaction_requiredwith acontact_*action naming the diagnosed party;
wait_for_retryandrepair_accessdo not survive the boundary,and escalation takes precedence over an open grace window.
Issue lifecycle. Issues emit
opened_at, fixed at first emission and carried unchanged acrossre-emission and across the
delayed→action_requiredtransition under one stableissue_id. Itis derived from immutable ledger facts, not the read time, so polling cannot reset the escalation
clock.
issue_state(open/acknowledged) andexternal_refare optional and now validated atthe response boundary.
projectReportingConsumerStatusMismatchV1is exported so a custom store canreuse the exact projection.
obligation_counts.consumer_status_pending. Emitted on the summary view whenever a consumerprincipal is resolved. Counts obligations past
expected_atplus the recovery window with an emptystatus chain for the caller. Never a health input; overlaps the health counts rather than
partitioning them.
Reserved
authoritative_party.assertSupportedReportingAuthoritativePartyrefuses'consumer'withUNSUPPORTED_FEATUREinstead of coercing it to'seller', andinstallConfigurationapplies it before any other validation. Call it fromsync_accountstoo.The lifecycle harness (
examples/reliable-reporting-lifecycle) gains arestate_after_receivedprobe operation mirroring the comply controller's: it restates only against the revision the caller
currently reports as
received, returnsstale_received_grace_deadline, and is convergent on repeat.Cross-tenant fix. A persisted
CONSUMER_STATUS_MISMATCHissue is no longer republished. Theissue store is keyed by obligation and carries no consumer dimension, so echoing a persisted one
handed every other consumer on that obligation the causing
reporting_status_id, itsopened_at(another tenant's exact ingest timing), and any
external_refticket key. The projection recomputesthe mismatch from the caller's own current leaf on every read, so the persisted copy was redundant
as well as unsafe. Retired (
resolved/waived) issues are dropped from the projection ratherthan emitted with the state elided.
Health-filter fix.
PostgresReportingLedgerStoreapplies thehealthquery filter whilebuilding the snapshot, and it carried a second copy of the mismatch rule that hardcoded
action_required. With rc.3'sdelayedgrace window that made a stale-receivedobligationunreachable under every filter — excluded from the snapshot when the caller asked for
delayed,dropped by the handler when they asked for
action_required. Both now call one shared projection in./health, and the store acceptsconsumerMismatchEscalationso the two cannot disagree.opened_atis now the later of the first supersession and the causing statement'srecorded_at; abuyer that posts
receivednaming an already-superseded revision no longer gets an issue datedbefore the seller could have observed it, which with a short escalation window would have been born
already escalated. Grace and escalation comparisons use the ledger's exact instant comparators
instead of
Date.parse, which floors sub-millisecond fractions and returnsNaNfor the leapseconds this module accepts. Persisted issues preserve their
openedAtacross re-upsert, andHISTORY_UNAVAILABLEis anchored to its period rather than the read time.UnsupportedReportingFeatureErrorextendsAdcpErrorso the framework maps it toUNSUPPORTED_FEATURE/terminal; as a plainErrorit would have been projected toSERVICE_UNAVAILABLE/transient, telling the buyer to retry the request it refuses.assertSupportedReportingAuthoritativePartyis exported from the package root, rejects awrong-shaped argument instead of silently passing, treats an explicit
nullas a request ratherthan absence, and reports buyer-supplied values as bounded structured details.
consumerMismatchEscalationis validated at wiring time —NaNsilently disabled escalation and anegative window escalated everything.
reportingConsumerStatusCapabilityV1(escalation)projects the same option into the capabilitydocument's
consumer_mismatch_escalation_seconds+operations_contact, so the advertised windowand the window the reads enforce come from one value and cannot drift.
Ingest rejects a
content_mismatchagainst a superseded revision.expected_periodmakes it"valid only against a revision the seller currently requires for that period", but existence,
account ownership, obligation membership, and a matching content digest are all satisfiable by a
long-superseded revision — so a buyer could dispute stale bytes and pin its own caller-scoped view
at
action_required, which the seller may then not clear while that statement is the leaf.Deciding currency needs the sibling revision set, so
ReportingConsumerStatusLedgerStoregains anoptional
listRevisionMetadata;ReportingLedgerStoreimplementors are already covered throughlistRevisions. A store that can do neither now rejectscontent_mismatchrather thanaccepting a statement it cannot validate — the other four statuses are unaffected, and
content_mismatchis new in rc.3 so no existing adapter regresses.consumer_status_pendingnow starts strictly after the deadline, since the duty is to post "nolater than" it. A negative-status issue's
opened_attakes the later of the statement'srecorded_atand the earliest qualifying revision, so a statement filed during a seller outage nolonger surfaces on recovery already past its escalation boundary. And
createReportingStatusHandlerinheritsconsumerMismatchEscalationfrom the store and throws on adisagreement, so a health-filtered periods read cannot contradict the summary.
ecf1c74: Add request-only Targeting Input helpers for the AdCP 3.2 null-clear semantics (DR-0020) and stop
createMediaBuyStorefrom persisting a clear command.resolveTargetingInput,applyTargetingInput, andhasTargetingClearsare exported from the rootand
@adcp/sdk/server. They project between the request-only Targeting Input — where a dimension maybe
nullto suppress a product default on create or clear stored state on update — and the strictTargeting Overlay used by discovery criteria, accepted commercial snapshots, mutation responses, and
package readback, which must not contain
null.Two fixes in
createMediaBuyStore, both reachable only once rc.3 makes the nullable input typesreal:
persistFromCreatefell back to the request overlay verbatim when the seller's response didnot echo one, and the
new_packagesarm ofmergeFromUpdateassigned the incoming overlay directly.Either path could write a
nullclear command into durable state, whichbackfillwould then echointo a
get_media_buysresponse whose schema forbids null. Both now resolve clears away, and a patchthat clears the last surviving dimension drops the tracked overlay instead of persisting
{}.The store's
CreateMediaBuyInputForStore/UpdateMediaBuyInputForStoreinput types widen from thestrict overlay to the request shape, so passing a real
create_media_buy/update_media_buypayload typechecks. Persisted and echoed values remain strict.
Codegen fix:
TargetingOverlayInput.device_platformand.device_typewere emitted as the scalarDevicePlatform/DeviceTypeenums instead of arrays.core/targeting-input.jsonreaches thosedimensions through a JSON-pointer
$refintocore/targeting.json#/properties/<dimension>, and foran array with no
titleof its own json-schema-to-typescript names the result after the items'canonical
$ref. Both types now match the wire.Patch Changes
content_mismatch. Derive ledger wire fields and status-specific validation from the pinned schema, and, when regenerated from those bundles, retainmismatch_codethrough ingest and readback and verify the consumed revision binding for content mismatches. Existing statuses remain supported; the protocol version pin and release process are unchanged.