@adcp/sdk 15.7.0 → 15.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/lib/core/SingleAgentClient.d.mts +14 -0
  2. package/dist/lib/core/SingleAgentClient.d.ts +14 -0
  3. package/dist/lib/core/SingleAgentClient.js +138 -54
  4. package/dist/lib/core/SingleAgentClient.mjs +141 -54
  5. package/dist/lib/core/agent-discovery-cache.d.mts +2 -0
  6. package/dist/lib/core/agent-discovery-cache.d.ts +2 -0
  7. package/dist/lib/core/creative-schema-support.d.mts +3 -0
  8. package/dist/lib/core/creative-schema-support.d.ts +3 -0
  9. package/dist/lib/core/creative-schema-support.js +113 -0
  10. package/dist/lib/core/creative-schema-support.mjs +89 -0
  11. package/dist/lib/core/product-cache.js +4 -3
  12. package/dist/lib/core/product-cache.mjs +4 -3
  13. package/dist/lib/reporting/ledger/handler.d.mts +10 -3
  14. package/dist/lib/reporting/ledger/handler.d.ts +10 -3
  15. package/dist/lib/reporting/ledger/handler.js +17 -4
  16. package/dist/lib/reporting/ledger/handler.mjs +17 -4
  17. package/dist/lib/reporting/ledger/managed.d.mts +3 -1
  18. package/dist/lib/reporting/ledger/managed.d.ts +3 -1
  19. package/dist/lib/reporting/ledger/managed.js +4 -1
  20. package/dist/lib/reporting/ledger/managed.mjs +4 -1
  21. package/dist/lib/reporting/ledger/postgres.d.mts +87 -0
  22. package/dist/lib/reporting/ledger/postgres.d.ts +87 -0
  23. package/dist/lib/reporting/ledger/postgres.js +314 -13
  24. package/dist/lib/reporting/ledger/postgres.mjs +314 -13
  25. package/dist/lib/reporting/ledger/row-storage.d.mts +23 -0
  26. package/dist/lib/reporting/ledger/row-storage.d.ts +23 -0
  27. package/dist/lib/reporting/ledger/row-storage.js +56 -0
  28. package/dist/lib/reporting/ledger/row-storage.mjs +56 -0
  29. package/dist/lib/reporting/ledger/types.d.mts +26 -0
  30. package/dist/lib/reporting/ledger/types.d.ts +26 -0
  31. package/dist/lib/reporting/service/index.d.mts +33 -3
  32. package/dist/lib/reporting/service/index.d.ts +33 -3
  33. package/dist/lib/reporting/service/index.js +20 -2
  34. package/dist/lib/reporting/service/index.mjs +20 -2
  35. package/dist/lib/reporting/service/maintenance.d.mts +20 -1
  36. package/dist/lib/reporting/service/maintenance.d.ts +20 -1
  37. package/dist/lib/reporting/service/maintenance.js +25 -2
  38. package/dist/lib/reporting/service/maintenance.mjs +25 -2
  39. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  40. package/dist/lib/testing/storyboard/request-builder.js +14 -16
  41. package/dist/lib/testing/storyboard/request-builder.mjs +14 -16
  42. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  43. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  44. package/dist/lib/types/schemas.generated.js +2542 -2542
  45. package/dist/lib/types/schemas.generated.mjs +2542 -2542
  46. package/dist/lib/v2/projection/creative-delivery.d.mts +22 -0
  47. package/dist/lib/v2/projection/creative-delivery.d.ts +22 -0
  48. package/dist/lib/v2/projection/creative-delivery.js +92 -0
  49. package/dist/lib/v2/projection/creative-delivery.mjs +91 -0
  50. package/dist/lib/v2/projection/legacy-metadata.d.mts +6 -3
  51. package/dist/lib/v2/projection/legacy-metadata.d.ts +6 -3
  52. package/dist/lib/v2/projection/legacy-metadata.js +17 -0
  53. package/dist/lib/v2/projection/legacy-metadata.mjs +15 -0
  54. package/dist/lib/validation/bidding-policy.js +1 -1
  55. package/dist/lib/validation/bidding-policy.mjs +1 -1
  56. package/dist/lib/validation/budget-allocation.js +1 -1
  57. package/dist/lib/validation/budget-allocation.mjs +1 -1
  58. package/dist/lib/validation/get-products-request.js +3 -3
  59. package/dist/lib/validation/get-products-request.mjs +3 -3
  60. package/dist/lib/validation/sync-creatives.js +9 -13
  61. package/dist/lib/validation/sync-creatives.mjs +9 -13
  62. package/dist/lib/version.d.mts +3 -3
  63. package/dist/lib/version.d.ts +3 -3
  64. package/dist/lib/version.js +3 -3
  65. package/dist/lib/version.mjs +3 -3
  66. package/docs/TYPE-SUMMARY.md +2 -2
  67. package/docs/ZOD-SCHEMAS.md +11 -1
  68. package/docs/guides/CREATIVE-DELIVERY.md +16 -0
  69. package/docs/guides/REPORTING-LEDGER-CUTOVER.md +405 -0
  70. package/docs/guides/REPORTING-LEDGER.md +130 -0
  71. package/docs/guides/REPORTING-OPERATIONS.md +12 -0
  72. package/docs/llms.txt +3 -2
  73. package/docs/migration-14.x-rc-worksheet.md +4 -4
  74. package/package.json +1 -1
@@ -233,6 +233,14 @@ empty revision association. A deployment with per-tenant workers should pass
233
233
  the resolved `account_id` to both `planObligations()` and `runWorker()`;
234
234
  omitting it intentionally runs a deployment-wide worker.
235
235
 
236
+ ### Already running your own ledger tables?
237
+
238
+ Do not dual-write, and do not migrate data. Cut over at a period boundary: the
239
+ SDK ledger produces and serves new periods, and your old tables become
240
+ read-only behind the optional `legacyRevisionReader`, which answers exact
241
+ `get_media_buy_delivery` reads only for revisions the SDK ledger does not hold.
242
+ See [Cutting over to the SDK reporting ledger](REPORTING-LEDGER-CUTOVER.md).
243
+
236
244
  ### Migrating an existing manual lifecycle
237
245
 
238
246
  Keep the same `PostgresReportingLedgerStore` and run the same
@@ -373,6 +381,22 @@ await store.readyRowStorage();
373
381
  segment, never a raw account ID. Override `keyTemplate` with the placeholders
374
382
  in `REPORTING_ROW_KEY_PLACEHOLDERS`; templates must include
375
383
  `{content_sha256}` and `{chunk_index}`.
384
+ Enabling snapshot compaction additionally requires `{revision_key}` (see
385
+ [Compacting superseded snapshots](#compacting-superseded-snapshots-opt-in)).
386
+ - A custom `keyTemplate` without `{account_key}` and `{revision_key}` can map
387
+ row sets from different obligations or accounts with identical chunk content
388
+ (an adjustment's digest covers its rows alone) to one object, which the
389
+ second writer adopts. Every delete path (period retirement, compaction and
390
+ the intent sweep) therefore skips an object while a live row set outside the
391
+ operation still references the same binding, key and native version, or an
392
+ open write intent created it. The reference check and the delete run in one
393
+ transaction under a per-object advisory lock, and a commit that adopts an
394
+ existing object takes the same lock, re-reads the object and holds the lock
395
+ until its chunk rows commit. A delete that wins the lock makes the adopting
396
+ commit fail with `STATE_UNAVAILABLE` (the writer re-uploads once its intent
397
+ lapses); a commit that wins is seen by the delete, which skips. A skipped
398
+ object is deleted by the retirement, compaction or sweep of the last row set
399
+ that referenced it, so it is not leaked.
376
400
  - An upload runs only while the obligation lease still covers
377
401
  `writeDeadlineMilliseconds` plus five seconds. A fenced write intent records
378
402
  every object the upload created, and the ledger commit closes the intent in
@@ -546,6 +570,111 @@ because the retired obligations no longer exist.
546
570
  always sweeps abandoned row uploads and expired cursor snapshots and
547
571
  checkpoints, and retires periods when retention is enabled.
548
572
 
573
+ ### Compacting superseded snapshots (opt-in)
574
+
575
+ > **Do not enable this in production before the next eligible AdCP minor after
576
+ > November 20, 2026.** Until then the published protocol still describes
577
+ > superseded snapshots as preserved. The option is off by default, and
578
+ > retaining the whole chain, as the ledger does by default, stays conformant.
579
+
580
+ [adcontextprotocol/adcp#8100](https://github.com/adcontextprotocol/adcp/pull/8100)
581
+ separates the two things `status_retention_days` covers. **Metadata** for every
582
+ revision stays queryable for the whole window. **Content** (the rows) is owed
583
+ only for the revisions a buyer is likely to read, so a seller that publishes a
584
+ snapshot every 15 minutes need not keep thousands of full snapshots per period.
585
+
586
+ The window runs from the revision's `created_at`. Once a later revision names it
587
+ in `supersedes_reporting_revision_id`, it runs from that successor's
588
+ `created_at` instead. Within its window the seller must keep content readable
589
+ by exact read when the revision is:
590
+
591
+ - (a) the current, unsuperseded revision of its slice, which includes every
592
+ official revision;
593
+ - (b) the revision the current revision supersedes;
594
+ - (c) a superseded snapshot inside its recovery grace, `max(automated recovery
595
+ window, one hour)` after its successor's `created_at`;
596
+ - (d) named, for the requesting caller, by that caller's own reporting receipt
597
+ in any status, or by its current consumer status statement with status
598
+ `received`, `unreadable` or `content_mismatch`.
599
+
600
+ Any other superseded snapshot may be compacted to metadata only. An exact read
601
+ of a compacted revision returns the same nondisclosing `REFERENCE_NOT_FOUND` as
602
+ an unknown ID. A revision in (a) to (d) whose content cannot be served is
603
+ `SERVICE_UNAVAILABLE` (`REVISION_UNREADABLE`), never not-found.
604
+
605
+ ```ts
606
+ // Core-only service
607
+ createReliableReportingService({
608
+ // ...
609
+ maintenance: { compaction: { enabled: true, limit: 100 } },
610
+ });
611
+
612
+ // Production service
613
+ await createPostgresReliableReportingProductionService({
614
+ // ...
615
+ compaction: { enabled: true, limit: 100 },
616
+ });
617
+
618
+ // Or call the store directly
619
+ await store.compactSupersededSnapshots({
620
+ statusRetentionDays: 30,
621
+ automatedRecoveryWindowSeconds: 3600,
622
+ limit: 100,
623
+ });
624
+ ```
625
+
626
+ Both options take `{ enabled: true; limit?: number }` (default `limit` 100 per
627
+ pass) and reuse the service's `statusRetentionDays` and
628
+ `automatedRecoveryWindowSeconds`. The maintenance task is named
629
+ `snapshot compaction`.
630
+
631
+ A snapshot is compacted only when all of these hold:
632
+
633
+ - A later revision supersedes it, and it is not the revision the current
634
+ revision supersedes. Current and official revisions are never compacted.
635
+ - Its recovery grace has passed: `max(automatedRecoveryWindowSeconds, 3600)`
636
+ seconds since its successor's `created_at`.
637
+ - No caller is owed it. The check spans every caller: a receipt in any status
638
+ (current or superseded), or a current `received`, `unreadable` or
639
+ `content_mismatch` consumer status statement, from any caller keeps the
640
+ revision while its window (`statusRetentionDays` from its successor's
641
+ `created_at`) is open. After that window nothing is owed any more.
642
+ - The obligation holds no live worker lease, no Managed Delivery
643
+ materialization of that revision is still `pending`, and no live change-feed
644
+ consumer (updated within `maxFeedHoldDays`) has yet to pass that revision's
645
+ change row. This is the same hold retirement applies, narrowed to the
646
+ revision.
647
+ - It has rows. A revision with no rows has nothing to reclaim.
648
+
649
+ Compaction drops row content only. The revision header, its manifest and every
650
+ metadata listing stay, and `listRevisionMetadata` and the status views keep
651
+ listing it. `listRevisions`, which hydrates rows, omits compacted revisions.
652
+ The `revision` view of `get_reporting_status` for a compacted revision answers
653
+ as an unavailable lookup, like an exact read.
654
+
655
+ It uses the same three resumable phases as retirement. Under the account lock it
656
+ re-checks eligibility and marks the row set `pruning` (reads answer as expired;
657
+ no new revision can share its chunks). It then deletes external objects at their
658
+ recorded versions through the fenced delete path, skipping any object a row set
659
+ that is not being pruned still references. Finally it deletes the chunk
660
+ manifest and any PostgreSQL chunk body nothing else uses, and marks the row set
661
+ `pruned`. A crash after the first phase leaves a `pruning` row set that the next
662
+ pass finishes. Chunks shared by byte-identical revisions survive until the last
663
+ revision referencing them is compacted.
664
+
665
+ Compaction records no change-feed row: the revision's metadata did not change,
666
+ and a sink still catching up holds the revision back (above).
667
+
668
+ Compaction requires every object row binding's `keyTemplate` to include
669
+ `{revision_key}` (the default template does). Deletes now skip objects another
670
+ row set still references (see [Object storage](#object-storage-bindings)),
671
+ so this is defense in depth rather than the only guard: with `{revision_key}`
672
+ no two revisions ever name the same object, so compaction never depends on the
673
+ reference check. The SDK fails closed: `createReliableReportingService` and
674
+ `createPostgresReliableReportingProductionService` throw at construction when
675
+ compaction is enabled and a binding's template omits `{revision_key}`, and
676
+ `compactSupersededSnapshots` throws the same error before deleting anything.
677
+
549
678
  ### Core-only setup with row storage, change feed and retention
550
679
 
551
680
  You do not need the production service (managed delivery, notifications and
@@ -611,6 +740,7 @@ Tasks, in order:
611
740
  | `row upload sweep` | always | Resolves abandoned object uploads (100 per pass); no-op without row storage. |
612
741
  | `change-feed pruning` | when `maintenance.changeFeed` is set | `pruneChanges` with `changeRetentionDays` and `maxFeedHoldDays`. |
613
742
  | `retention` | when `maintenance.retention.enabled` is `true` | `retireExpiredPeriods` with the service's `statusRetentionDays` and the feed's `maxFeedHoldDays`. |
743
+ | `snapshot compaction` | when `maintenance.compaction.enabled` is `true` | `compactSupersededSnapshots` with the service's `statusRetentionDays` and `automatedRecoveryWindowSeconds` (see [Compacting superseded snapshots](#compacting-superseded-snapshots-opt-in)). |
614
744
 
615
745
  Notes:
616
746
 
@@ -120,6 +120,15 @@ service runs for you. See
120
120
  `status_retention_days` is the window you intend to keep. Retirement deletes
121
121
  rows and ledger records for whole periods and cannot be undone. Keep backups
122
122
  for any longer audit requirement.
123
+ 7. **Snapshot compaction (optional).** Off by default; enable `compaction`
124
+ (`maintenance.compaction` on the Core-only service) only to reclaim the
125
+ content of superseded snapshots. Do not enable it in production before the
126
+ next eligible AdCP minor after November 20, 2026, when the protocol takes
127
+ compaction into effect. Roll it out after retention, with a small `limit`,
128
+ and watch the `snapshot compaction` task's `failed` IDs. See
129
+ [Compacting superseded snapshots](REPORTING-LEDGER.md#compacting-superseded-snapshots-opt-in)
130
+ for the rule and what it keeps. Compaction cannot be undone; backups hold
131
+ any longer evidence.
123
132
 
124
133
  Alert on these row-storage signals:
125
134
 
@@ -127,6 +136,9 @@ Alert on these row-storage signals:
127
136
  normal, and buyers see `SERVICE_UNAVAILABLE` for the affected revision.
128
137
  - A growing count of `adcp_reporting_row_write_intents` in `sweeping` state,
129
138
  or `sweepRowWriteIntents` reporting failures. Provider deletes are failing.
139
+ - The `snapshot compaction` task reporting `failed` revisions. Provider deletes
140
+ are failing; the revisions stay `pruning` (reads already answer not-found) and
141
+ the next pass resumes them.
130
142
  - `retireExpiredPeriods` returning `failed` IDs. Usually a binding was removed
131
143
  from configuration while revisions still reference it; keep retired bindings
132
144
  configured.
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
- > Generated at: 2026-10-09
4
- > Library: @adcp/sdk v15.7.0
3
+ > Generated at: 2026-10-11
4
+ > Library: @adcp/sdk v15.8.0
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
  > Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
@@ -2140,6 +2140,7 @@ These docs are available locally in the repo and hosted at https://adcontextprot
2140
2140
  | Conformance (property-based fuzzing) | docs/guides/CONFORMANCE.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/CONFORMANCE.md) |
2141
2141
  | Reporting source executor (seller adapters) | docs/guides/REPORTING-SOURCE-EXECUTOR.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-SOURCE-EXECUTOR.md) |
2142
2142
  | Seller reporting ledger | docs/guides/REPORTING-LEDGER.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-LEDGER.md) |
2143
+ | Reporting ledger cutover from custom tables | docs/guides/REPORTING-LEDGER-CUTOVER.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-LEDGER-CUTOVER.md) |
2143
2144
  | Buyer reporting reconciliation | docs/guides/REPORTING-RECONCILIATION.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-RECONCILIATION.md) |
2144
2145
  | Reliable Reporting production operations | docs/guides/REPORTING-OPERATIONS.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/REPORTING-OPERATIONS.md) |
2145
2146
  | Validate your agent (5-command checklist) | docs/guides/VALIDATE-YOUR-AGENT.md | [link](https://adcontextprotocol.github.io/adcp-client/guides/VALIDATE-YOUR-AGENT.md) |
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
11
11
 
12
12
  | Fact | Value |
13
13
  | --- | --- |
14
- | Exact npm package | `@adcp/sdk@15.7.0` |
15
- | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@15.7.0 dist.integrity` |
14
+ | Exact npm package | `@adcp/sdk@15.8.0` |
15
+ | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@15.8.0 dist.integrity` |
16
16
  | Node.js runtime | `^20.19.0 || >=22.12.0` |
17
17
  | Default AdCP wire release | `3.2.3` |
18
18
  | Maintained wire releases | `v2.5`, `v2.6`, `v3`, `3.0.0`, `3.0`, `3.0.1`, `3.0.2`, `3.0.3`, `3.0.4`, `3.0.5`, `3.0.6`, `3.0.7`, `3.0.8`, `3.0.9`, `3.0.10`, `3.0.11`, `3.0.12`, `3.0.13`, `3.0.14`, `3.0.15`, `3.0.16`, `3.0.17`, `3.0.18`, `3.0.19`, `3.0.20`, `3.0.21`, `3.0.22`, `3.0.23`, `3.0.24`, `3.0.25`, `3.1.0`, `3.1`, `3.1.1`, `3.1.2`, `3.1.3`, `3.1.4`, `3.1.5`, `3.1.6`, `3.1.7`, `3.1.8`, `3.1.9`, `3.1.10`, `3.1.11`, `3.1.12`, `3.1.13`, `3.1.14`, `3.1.15`, `3.1.16`, `3.1.17`, `3.1.18`, `3.1.19`, `3.1.20`, `3.1.21`, `3.1.22`, `3.1.23`, `3.1.24`, `3.2.1`, `3.2`, `3.2.2`, `3.2.3` |
@@ -21,8 +21,8 @@ below as the publication/deployment gate.
21
21
  Install exact production inputs rather than a moving range or dist-tag:
22
22
 
23
23
  ```bash
24
- npm install --save-exact '@adcp/sdk@15.7.0'
25
- npm view '@adcp/sdk@15.7.0' dist.integrity
24
+ npm install --save-exact '@adcp/sdk@15.8.0'
25
+ npm view '@adcp/sdk@15.8.0' dist.integrity
26
26
  ```
27
27
 
28
28
  ### Required and optional peers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "15.7.0",
3
+ "version": "15.8.0",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",