@adcp/sdk 14.0.0-rc.37 → 14.0.0-rc.39

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 (622) hide show
  1. package/bin/adcp-storyboard-summary.js +286 -0
  2. package/bin/adcp.js +221 -10
  3. package/dist/lib/conformance/schemaLoader.d.mts +1 -1
  4. package/dist/lib/conformance/schemaLoader.d.ts +1 -1
  5. package/dist/lib/core/AgentClient.d.mts +6 -1
  6. package/dist/lib/core/AgentClient.d.ts +6 -1
  7. package/dist/lib/core/AgentClient.js +9 -0
  8. package/dist/lib/core/AgentClient.mjs +9 -0
  9. package/dist/lib/core/ConversationTypes.d.mts +29 -0
  10. package/dist/lib/core/ConversationTypes.d.ts +29 -0
  11. package/dist/lib/core/SingleAgentClient.d.mts +3 -1
  12. package/dist/lib/core/SingleAgentClient.d.ts +3 -1
  13. package/dist/lib/core/SingleAgentClient.js +9 -1
  14. package/dist/lib/core/SingleAgentClient.mjs +9 -1
  15. package/dist/lib/core/TaskExecutor.d.mts +13 -1
  16. package/dist/lib/core/TaskExecutor.d.ts +13 -1
  17. package/dist/lib/core/TaskExecutor.js +216 -18
  18. package/dist/lib/core/TaskExecutor.mjs +216 -19
  19. package/dist/lib/index.d.mts +5 -2
  20. package/dist/lib/index.d.ts +5 -2
  21. package/dist/lib/index.js +10 -1
  22. package/dist/lib/index.mjs +10 -1
  23. package/dist/lib/media-buy/action-assessment.d.mts +77 -0
  24. package/dist/lib/media-buy/action-assessment.d.ts +77 -0
  25. package/dist/lib/media-buy/action-assessment.js +300 -0
  26. package/dist/lib/media-buy/action-assessment.mjs +284 -0
  27. package/dist/lib/media-buy/action-constraints.d.mts +9 -0
  28. package/dist/lib/media-buy/action-constraints.d.ts +9 -0
  29. package/dist/lib/media-buy/action-constraints.js +170 -0
  30. package/dist/lib/media-buy/action-constraints.mjs +146 -0
  31. package/dist/lib/media-buy/action-contracts.d.mts +40 -0
  32. package/dist/lib/media-buy/action-contracts.d.ts +40 -0
  33. package/dist/lib/media-buy/action-contracts.js +304 -0
  34. package/dist/lib/media-buy/action-contracts.mjs +267 -0
  35. package/dist/lib/media-buy/action-metadata.generated.d.mts +37 -0
  36. package/dist/lib/media-buy/action-metadata.generated.d.ts +37 -0
  37. package/dist/lib/media-buy/action-metadata.generated.js +128 -0
  38. package/dist/lib/media-buy/action-metadata.generated.mjs +101 -0
  39. package/dist/lib/media-buy/action-types.d.mts +106 -0
  40. package/dist/lib/media-buy/action-types.d.ts +106 -0
  41. package/dist/lib/{types/v3-1-beta/tools.generated.js → media-buy/action-types.js} +2 -2
  42. package/dist/lib/media-buy/actions.d.mts +6 -0
  43. package/dist/lib/media-buy/actions.d.ts +6 -0
  44. package/dist/lib/media-buy/actions.js +38 -0
  45. package/dist/lib/media-buy/actions.mjs +9 -0
  46. package/dist/lib/media-buy/available-actions.d.mts +2 -1
  47. package/dist/lib/media-buy/available-actions.d.ts +2 -1
  48. package/dist/lib/media-buy/available-actions.js +4 -3
  49. package/dist/lib/media-buy/available-actions.mjs +4 -3
  50. package/dist/lib/media-buy/compatibility.js +3 -0
  51. package/dist/lib/media-buy/compatibility.mjs +3 -0
  52. package/dist/lib/media-buy/index.d.mts +4 -0
  53. package/dist/lib/media-buy/index.d.ts +4 -0
  54. package/dist/lib/media-buy/index.js +3 -1
  55. package/dist/lib/media-buy/index.mjs +1 -0
  56. package/dist/lib/media-buy/legacy-action-ids.d.mts +1 -0
  57. package/dist/lib/media-buy/legacy-action-ids.d.ts +1 -0
  58. package/dist/lib/media-buy/legacy-action-ids.js +50 -0
  59. package/dist/lib/media-buy/legacy-action-ids.mjs +26 -0
  60. package/dist/lib/media-buy/mutations.d.mts +70 -0
  61. package/dist/lib/media-buy/mutations.d.ts +70 -0
  62. package/dist/lib/media-buy/mutations.js +525 -0
  63. package/dist/lib/media-buy/mutations.mjs +498 -0
  64. package/dist/lib/media-buy/preflight.d.mts +20 -69
  65. package/dist/lib/media-buy/preflight.d.ts +20 -69
  66. package/dist/lib/media-buy/preflight.js +100 -336
  67. package/dist/lib/media-buy/preflight.mjs +111 -333
  68. package/dist/lib/media-buy/targeting-input.d.mts +7 -4
  69. package/dist/lib/media-buy/targeting-input.d.ts +7 -4
  70. package/dist/lib/media-buy/types.d.mts +55 -7
  71. package/dist/lib/media-buy/types.d.ts +55 -7
  72. package/dist/lib/protocols/rawResponseCapture.d.mts +12 -0
  73. package/dist/lib/protocols/rawResponseCapture.d.ts +12 -0
  74. package/dist/lib/protocols/rawResponseCapture.js +33 -3
  75. package/dist/lib/protocols/rawResponseCapture.mjs +32 -3
  76. package/dist/lib/registry/types.generated.d.mts +377 -9
  77. package/dist/lib/registry/types.generated.d.ts +377 -9
  78. package/dist/lib/reporting/content-mismatch.d.mts +126 -0
  79. package/dist/lib/reporting/content-mismatch.d.ts +126 -0
  80. package/dist/lib/reporting/content-mismatch.js +90 -0
  81. package/dist/lib/reporting/content-mismatch.mjs +66 -0
  82. package/dist/lib/reporting/evidence.d.mts +1 -0
  83. package/dist/lib/reporting/evidence.d.ts +1 -0
  84. package/dist/lib/reporting/evidence.js +32 -3
  85. package/dist/lib/reporting/evidence.mjs +31 -3
  86. package/dist/lib/reporting/index.d.mts +3 -1
  87. package/dist/lib/reporting/index.d.ts +3 -1
  88. package/dist/lib/reporting/index.js +3 -0
  89. package/dist/lib/reporting/index.mjs +2 -0
  90. package/dist/lib/reporting/ledger/handler.d.mts +51 -1
  91. package/dist/lib/reporting/ledger/handler.d.ts +51 -1
  92. package/dist/lib/reporting/ledger/handler.js +306 -38
  93. package/dist/lib/reporting/ledger/handler.mjs +304 -37
  94. package/dist/lib/reporting/ledger/health.d.mts +12 -0
  95. package/dist/lib/reporting/ledger/health.d.ts +12 -0
  96. package/dist/lib/reporting/ledger/health.js +15 -2
  97. package/dist/lib/reporting/ledger/health.mjs +13 -1
  98. package/dist/lib/reporting/ledger/index.d.mts +3 -0
  99. package/dist/lib/reporting/ledger/index.d.ts +3 -0
  100. package/dist/lib/reporting/ledger/index.js +7 -1
  101. package/dist/lib/reporting/ledger/index.mjs +3 -0
  102. package/dist/lib/reporting/ledger/lifecycle.d.mts +31 -4
  103. package/dist/lib/reporting/ledger/lifecycle.d.ts +31 -4
  104. package/dist/lib/reporting/ledger/lifecycle.js +244 -37
  105. package/dist/lib/reporting/ledger/lifecycle.mjs +244 -37
  106. package/dist/lib/reporting/ledger/managed-postgres.d.mts +231 -0
  107. package/dist/lib/reporting/ledger/managed-postgres.d.ts +231 -0
  108. package/dist/lib/reporting/ledger/managed-postgres.js +1797 -0
  109. package/dist/lib/reporting/ledger/managed-postgres.mjs +1776 -0
  110. package/dist/lib/reporting/ledger/managed.d.mts +355 -0
  111. package/dist/lib/reporting/ledger/managed.d.ts +355 -0
  112. package/dist/lib/reporting/ledger/managed.js +661 -0
  113. package/dist/lib/reporting/ledger/managed.mjs +633 -0
  114. package/dist/lib/reporting/ledger/notification-activity.d.mts +222 -0
  115. package/dist/lib/reporting/ledger/notification-activity.d.ts +222 -0
  116. package/dist/lib/reporting/ledger/notification-activity.js +1139 -0
  117. package/dist/lib/reporting/ledger/notification-activity.mjs +1110 -0
  118. package/dist/lib/reporting/ledger/postgres.d.mts +161 -1
  119. package/dist/lib/reporting/ledger/postgres.d.ts +161 -1
  120. package/dist/lib/reporting/ledger/postgres.js +1153 -21
  121. package/dist/lib/reporting/ledger/postgres.mjs +1152 -21
  122. package/dist/lib/reporting/ledger/producer.d.mts +8 -0
  123. package/dist/lib/reporting/ledger/producer.d.ts +8 -0
  124. package/dist/lib/reporting/ledger/producer.js +146 -52
  125. package/dist/lib/reporting/ledger/producer.mjs +146 -51
  126. package/dist/lib/reporting/ledger/types.d.mts +358 -1
  127. package/dist/lib/reporting/ledger/types.d.ts +358 -1
  128. package/dist/lib/reporting/ledger/types.js +3 -0
  129. package/dist/lib/reporting/ledger/types.mjs +2 -0
  130. package/dist/lib/reporting/reconciliation.d.mts +362 -2
  131. package/dist/lib/reporting/reconciliation.d.ts +362 -2
  132. package/dist/lib/reporting/reconciliation.js +1051 -7
  133. package/dist/lib/reporting/reconciliation.mjs +1053 -7
  134. package/dist/lib/reporting/service/conformance.d.mts +35 -0
  135. package/dist/lib/reporting/service/conformance.d.ts +35 -0
  136. package/dist/lib/reporting/service/conformance.js +89 -0
  137. package/dist/lib/reporting/service/conformance.mjs +68 -0
  138. package/dist/lib/reporting/service/index.d.mts +182 -0
  139. package/dist/lib/reporting/service/index.d.ts +182 -0
  140. package/dist/lib/reporting/service/index.js +793 -0
  141. package/dist/lib/reporting/service/index.mjs +787 -0
  142. package/dist/lib/reporting/source/index.d.mts +2 -1
  143. package/dist/lib/reporting/source/index.d.ts +2 -1
  144. package/dist/lib/reporting/source/index.js +16 -3
  145. package/dist/lib/reporting/source/index.mjs +12 -1
  146. package/dist/lib/reporting/source/inline.d.mts +88 -1
  147. package/dist/lib/reporting/source/inline.d.ts +88 -1
  148. package/dist/lib/reporting/source/inline.js +1161 -163
  149. package/dist/lib/reporting/source/inline.mjs +1166 -163
  150. package/dist/lib/reporting/source/manifest.js +12 -7
  151. package/dist/lib/reporting/source/manifest.mjs +12 -7
  152. package/dist/lib/reporting/source/source.d.mts +26 -0
  153. package/dist/lib/reporting/source/source.d.ts +26 -0
  154. package/dist/lib/reporting/source/source.js +71 -2
  155. package/dist/lib/reporting/source/source.mjs +65 -1
  156. package/dist/lib/schemas/index.d.mts +22 -1
  157. package/dist/lib/schemas/index.d.ts +22 -1
  158. package/dist/lib/schemas/index.js +7 -0
  159. package/dist/lib/schemas/index.mjs +7 -0
  160. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  161. package/dist/lib/server/create-adcp-server.d.mts +18 -0
  162. package/dist/lib/server/create-adcp-server.d.ts +18 -0
  163. package/dist/lib/server/create-adcp-server.js +52 -2
  164. package/dist/lib/server/create-adcp-server.mjs +52 -2
  165. package/dist/lib/server/decisioning/account.d.mts +1 -1
  166. package/dist/lib/server/decisioning/account.d.ts +1 -1
  167. package/dist/lib/server/decisioning/index.d.mts +1 -0
  168. package/dist/lib/server/decisioning/index.d.ts +1 -0
  169. package/dist/lib/server/decisioning/platform.d.mts +3 -0
  170. package/dist/lib/server/decisioning/platform.d.ts +3 -0
  171. package/dist/lib/server/decisioning/runtime/from-platform.js +88 -10
  172. package/dist/lib/server/decisioning/runtime/from-platform.mjs +88 -10
  173. package/dist/lib/server/decisioning/specialisms/reporting.d.mts +38 -0
  174. package/dist/lib/server/decisioning/specialisms/reporting.d.ts +38 -0
  175. package/dist/lib/{types/v3-1-beta/index.js → server/decisioning/specialisms/reporting.js} +2 -8
  176. package/dist/lib/server/decisioning/specialisms/reporting.mjs +0 -0
  177. package/dist/lib/server/index.d.mts +4 -2
  178. package/dist/lib/server/index.d.ts +4 -2
  179. package/dist/lib/server/index.js +5 -0
  180. package/dist/lib/server/index.mjs +4 -0
  181. package/dist/lib/server/media-buy-action-resolver.d.mts +63 -0
  182. package/dist/lib/server/media-buy-action-resolver.d.ts +63 -0
  183. package/dist/lib/server/media-buy-action-resolver.js +297 -0
  184. package/dist/lib/server/media-buy-action-resolver.mjs +285 -0
  185. package/dist/lib/server/media-buy-actions.d.mts +7 -8
  186. package/dist/lib/server/media-buy-actions.d.ts +7 -8
  187. package/dist/lib/server/media-buy-actions.js +57 -14
  188. package/dist/lib/server/media-buy-actions.mjs +63 -14
  189. package/dist/lib/server/notification-subscriptions/index.d.mts +2 -2
  190. package/dist/lib/server/notification-subscriptions/index.d.ts +2 -2
  191. package/dist/lib/server/notification-subscriptions/index.js +2 -0
  192. package/dist/lib/server/notification-subscriptions/index.mjs +2 -0
  193. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.mts +3 -1
  194. package/dist/lib/server/notification-subscriptions/postgres-runtime.d.ts +3 -1
  195. package/dist/lib/server/notification-subscriptions/postgres-runtime.js +1 -0
  196. package/dist/lib/server/notification-subscriptions/postgres-runtime.mjs +1 -0
  197. package/dist/lib/server/notification-subscriptions/runtime.d.mts +12 -1
  198. package/dist/lib/server/notification-subscriptions/runtime.d.ts +12 -1
  199. package/dist/lib/server/notification-subscriptions/runtime.js +102 -16
  200. package/dist/lib/server/notification-subscriptions/runtime.mjs +101 -16
  201. package/dist/lib/server/notification-subscriptions/types.d.mts +104 -1
  202. package/dist/lib/server/notification-subscriptions/types.d.ts +104 -1
  203. package/dist/lib/server/webhook-emitter.d.mts +40 -5
  204. package/dist/lib/server/webhook-emitter.d.ts +40 -5
  205. package/dist/lib/server/webhook-emitter.js +23 -12
  206. package/dist/lib/server/webhook-emitter.mjs +23 -12
  207. package/dist/lib/storage/interfaces.d.mts +14 -2
  208. package/dist/lib/storage/interfaces.d.ts +14 -2
  209. package/dist/lib/testing/compliance/comply.d.mts +9 -3
  210. package/dist/lib/testing/compliance/comply.d.ts +9 -3
  211. package/dist/lib/testing/compliance/comply.js +158 -3
  212. package/dist/lib/testing/compliance/comply.mjs +159 -4
  213. package/dist/lib/testing/compliance/storyboard-tracks.js +7 -5
  214. package/dist/lib/testing/compliance/storyboard-tracks.mjs +7 -5
  215. package/dist/lib/testing/compliance/summary.js +10 -1
  216. package/dist/lib/testing/compliance/summary.mjs +10 -1
  217. package/dist/lib/testing/index.d.mts +1 -1
  218. package/dist/lib/testing/index.d.ts +1 -1
  219. package/dist/lib/testing/index.js +2 -0
  220. package/dist/lib/testing/index.mjs +3 -1
  221. package/dist/lib/testing/storyboard/agent-routing.d.mts +12 -43
  222. package/dist/lib/testing/storyboard/agent-routing.d.ts +12 -43
  223. package/dist/lib/testing/storyboard/agent-routing.js +75 -13
  224. package/dist/lib/testing/storyboard/agent-routing.mjs +70 -12
  225. package/dist/lib/testing/storyboard/index.d.mts +1 -0
  226. package/dist/lib/testing/storyboard/index.d.ts +1 -0
  227. package/dist/lib/testing/storyboard/index.js +3 -0
  228. package/dist/lib/testing/storyboard/index.mjs +2 -0
  229. package/dist/lib/testing/storyboard/junit.d.mts +1 -1
  230. package/dist/lib/testing/storyboard/junit.d.ts +1 -1
  231. package/dist/lib/testing/storyboard/junit.js +21 -2
  232. package/dist/lib/testing/storyboard/junit.mjs +21 -2
  233. package/dist/lib/testing/storyboard/probes.d.mts +130 -0
  234. package/dist/lib/testing/storyboard/probes.d.ts +130 -0
  235. package/dist/lib/testing/storyboard/probes.js +682 -10
  236. package/dist/lib/testing/storyboard/probes.mjs +683 -3
  237. package/dist/lib/testing/storyboard/request-signing/builder.d.mts +16 -5
  238. package/dist/lib/testing/storyboard/request-signing/builder.d.ts +16 -5
  239. package/dist/lib/testing/storyboard/request-signing/grader.d.mts +44 -1
  240. package/dist/lib/testing/storyboard/request-signing/grader.d.ts +44 -1
  241. package/dist/lib/testing/storyboard/request-signing/grader.js +46 -22
  242. package/dist/lib/testing/storyboard/request-signing/grader.mjs +43 -21
  243. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +86 -11
  244. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +86 -11
  245. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +119 -25
  246. package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +117 -26
  247. package/dist/lib/testing/storyboard/request-signing/synthesize.js +22 -2
  248. package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +22 -2
  249. package/dist/lib/testing/storyboard/runner.d.mts +103 -0
  250. package/dist/lib/testing/storyboard/runner.d.ts +103 -0
  251. package/dist/lib/testing/storyboard/runner.js +1090 -268
  252. package/dist/lib/testing/storyboard/runner.mjs +1096 -261
  253. package/dist/lib/testing/storyboard/seeding.d.mts +4 -1
  254. package/dist/lib/testing/storyboard/seeding.d.ts +4 -1
  255. package/dist/lib/testing/storyboard/seeding.js +55 -24
  256. package/dist/lib/testing/storyboard/seeding.mjs +55 -24
  257. package/dist/lib/testing/storyboard/test-kit.d.mts +37 -3
  258. package/dist/lib/testing/storyboard/test-kit.d.ts +37 -3
  259. package/dist/lib/testing/storyboard/test-kit.js +8 -2
  260. package/dist/lib/testing/storyboard/test-kit.mjs +7 -2
  261. package/dist/lib/testing/storyboard/types.d.mts +132 -10
  262. package/dist/lib/testing/storyboard/types.d.ts +132 -10
  263. package/dist/lib/testing/storyboard/types.js +17 -0
  264. package/dist/lib/testing/storyboard/types.mjs +16 -0
  265. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  266. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  267. package/dist/lib/testing/storyboard/validations.js +16 -0
  268. package/dist/lib/testing/storyboard/validations.mjs +16 -0
  269. package/dist/lib/testing/test-controller.d.mts +1 -1
  270. package/dist/lib/testing/test-controller.d.ts +1 -1
  271. package/dist/lib/types/buy-products.d.ts +71 -6
  272. package/dist/lib/types/control-media-buy.d.ts +25 -11
  273. package/dist/lib/types/core.generated.d.mts +69 -10
  274. package/dist/lib/types/core.generated.d.ts +69 -10
  275. package/dist/lib/types/create-media-buy.d.ts +71 -6
  276. package/dist/lib/types/forward-compat-error-codes.d.mts +7 -6
  277. package/dist/lib/types/forward-compat-error-codes.d.ts +7 -6
  278. package/dist/lib/types/index.d.mts +2 -2
  279. package/dist/lib/types/index.d.ts +2 -2
  280. package/dist/lib/types/schemas.generated.d.ts +8040 -8116
  281. package/dist/lib/types/schemas.generated.js +1074 -309
  282. package/dist/lib/types/schemas.generated.mjs +1068 -309
  283. package/dist/lib/types/tools.generated.d.mts +65 -6
  284. package/dist/lib/types/tools.generated.d.ts +65 -6
  285. package/dist/lib/types/update-media-buy.d.ts +71 -6
  286. package/dist/lib/utils/redact-secrets.d.mts +1 -1
  287. package/dist/lib/utils/redact-secrets.d.ts +1 -1
  288. package/dist/lib/utils/redact-secrets.js +1 -1
  289. package/dist/lib/utils/redact-secrets.mjs +1 -1
  290. package/dist/lib/v2/projection/cache-versions.d.mts +0 -1
  291. package/dist/lib/v2/projection/cache-versions.d.ts +0 -1
  292. package/dist/lib/v2/projection/cache-versions.js +1 -15
  293. package/dist/lib/v2/projection/cache-versions.mjs +1 -14
  294. package/dist/lib/v2/projection/canonical-properties.js +2 -2
  295. package/dist/lib/v2/projection/canonical-properties.mjs +3 -3
  296. package/dist/lib/v2/projection/registry.d.mts +1 -1
  297. package/dist/lib/v2/projection/registry.d.ts +1 -1
  298. package/dist/lib/v2/projection/registry.js +2 -2
  299. package/dist/lib/v2/projection/registry.mjs +3 -3
  300. package/dist/lib/validation/schema-loader.d.mts +9 -1
  301. package/dist/lib/validation/schema-loader.d.ts +9 -1
  302. package/dist/lib/validation/schema-loader.js +65 -8
  303. package/dist/lib/validation/schema-loader.mjs +64 -8
  304. package/dist/lib/version.d.mts +5 -5
  305. package/dist/lib/version.d.ts +5 -5
  306. package/dist/lib/version.js +3 -8
  307. package/dist/lib/version.mjs +3 -8
  308. package/dist/lib/wholesale-feed-sync/index.d.mts +1 -0
  309. package/dist/lib/wholesale-feed-sync/index.d.ts +1 -0
  310. package/dist/lib/wholesale-feed-sync/protocol-types.d.mts +42 -0
  311. package/dist/lib/wholesale-feed-sync/protocol-types.d.ts +42 -0
  312. package/dist/lib/wholesale-feed-sync/protocol-types.js +16 -0
  313. package/dist/lib/wholesale-feed-sync/protocol-types.mjs +0 -0
  314. package/dist/lib/wholesale-feed-sync/sync.d.mts +6 -6
  315. package/dist/lib/wholesale-feed-sync/sync.d.ts +6 -6
  316. package/dist/lib/wholesale-feed-sync/sync.js +3 -1
  317. package/dist/lib/wholesale-feed-sync/sync.mjs +3 -1
  318. package/dist/lib/wholesale-feed-sync/types.d.mts +15 -14
  319. package/dist/lib/wholesale-feed-sync/types.d.ts +15 -14
  320. package/dist/lib/wholesale-feed-sync/webhook-notification.d.mts +7 -5
  321. package/dist/lib/wholesale-feed-sync/webhook-notification.d.ts +7 -5
  322. package/dist/lib/wholesale-feed-sync/webhook-notification.js +45 -0
  323. package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +44 -0
  324. package/docs/CLI.md +1 -1
  325. package/docs/TYPE-SUMMARY.md +118 -4
  326. package/docs/guides/ASYNC-API-REFERENCE.md +62 -1
  327. package/docs/guides/ASYNC-DEVELOPER-GUIDE.md +25 -0
  328. package/docs/guides/ASYNC-DOCUMENTATION-INDEX.md +3 -0
  329. package/docs/guides/BUYER-QUICKSTART-3.2.md +5 -0
  330. package/docs/guides/DURABLE-BUYER-WRITES.md +337 -0
  331. package/docs/guides/EXISTING-PLATFORM.md +80 -1
  332. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +57 -0
  333. package/docs/guides/MEDIA-BUY-ACTION-ASSESSMENT.md +300 -0
  334. package/docs/guides/REPORTING-LEDGER.md +654 -3
  335. package/docs/guides/REPORTING-RECONCILIATION.md +50 -0
  336. package/docs/guides/REPORTING-SOURCE-EXECUTOR.md +63 -1
  337. package/docs/guides/SELLER-QUICKSTART-3.2.md +2 -0
  338. package/docs/guides/VALIDATE-YOUR-AGENT.md +35 -0
  339. package/docs/guides/idempotency-crash-recovery.md +4 -0
  340. package/docs/llms.txt +4 -2
  341. package/docs/migration-14.x-rc-worksheet.md +60 -5
  342. package/docs/migration-7.9-to-7.10.md +7 -5
  343. package/examples/README.md +17 -0
  344. package/examples/durable-buyer-writes/caller.ts +745 -0
  345. package/examples/durable-buyer-writes/worker.ts +240 -0
  346. package/examples/reliable-reporting-service/README.md +100 -0
  347. package/examples/seller-3.2-starter.ts +7 -8
  348. package/examples/targeting-input-existing-platform.ts +153 -0
  349. package/package.json +41 -29
  350. package/skills/build-seller-agent/SKILL.md +2 -0
  351. package/skills/build-seller-agent/specialisms/signed-requests.md +11 -1
  352. package/skills/cross-cutting.md +28 -11
  353. package/compliance/cache/3.1.0-beta.7/domains/brand/index.yaml +0 -160
  354. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  355. package/compliance/cache/3.1.0-beta.7/domains/brand/scenarios/single_side_trust_extension.yaml +0 -454
  356. package/compliance/cache/3.1.0-beta.7/domains/creative/index.yaml +0 -339
  357. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/billing_out_of_band.yaml +0 -153
  358. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  359. package/compliance/cache/3.1.0-beta.7/domains/creative/scenarios/native_in_feed.yaml +0 -543
  360. package/compliance/cache/3.1.0-beta.7/domains/governance/index.yaml +0 -682
  361. package/compliance/cache/3.1.0-beta.7/domains/media-buy/index.yaml +0 -781
  362. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  363. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/available_actions.yaml +0 -565
  364. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  365. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/canonical_formats.yaml +0 -711
  366. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  367. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  368. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  369. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  370. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/creative_reception.yaml +0 -247
  371. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/delivery_reporting.yaml +0 -357
  372. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment.yaml +0 -633
  373. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  374. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  375. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  376. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_approved.yaml +0 -214
  377. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_conditions.yaml +0 -199
  378. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied.yaml +0 -204
  379. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  380. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/invalid_transitions.yaml +0 -289
  381. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  382. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  383. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_accountability.yaml +0 -244
  384. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  385. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  386. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  387. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  388. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  389. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  390. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize.yaml +0 -399
  391. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  392. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  393. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  394. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  395. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  396. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  397. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  398. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/refine_products.yaml +0 -148
  399. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  400. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  401. package/compliance/cache/3.1.0-beta.7/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  402. package/compliance/cache/3.1.0-beta.7/domains/media-buy/state-machine.yaml +0 -442
  403. package/compliance/cache/3.1.0-beta.7/domains/signals/index.yaml +0 -266
  404. package/compliance/cache/3.1.0-beta.7/domains/sponsored-intelligence/index.yaml +0 -256
  405. package/compliance/cache/3.1.0-beta.7/index.json +0 -356
  406. package/compliance/cache/3.1.0-beta.7/protocols/brand/index.yaml +0 -160
  407. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/distributed_brand_resolution.yaml +0 -415
  408. package/compliance/cache/3.1.0-beta.7/protocols/brand/scenarios/single_side_trust_extension.yaml +0 -454
  409. package/compliance/cache/3.1.0-beta.7/protocols/creative/index.yaml +0 -339
  410. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/billing_out_of_band.yaml +0 -153
  411. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +0 -389
  412. package/compliance/cache/3.1.0-beta.7/protocols/creative/scenarios/native_in_feed.yaml +0 -543
  413. package/compliance/cache/3.1.0-beta.7/protocols/governance/index.yaml +0 -682
  414. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/index.yaml +0 -781
  415. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/audience_buy_flow.yaml +0 -380
  416. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/available_actions.yaml +0 -565
  417. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/billing_finality_delivery.yaml +0 -354
  418. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/canonical_formats.yaml +0 -711
  419. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/clicks_buy_flow.yaml +0 -264
  420. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +0 -344
  421. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/create_media_buy_async.yaml +0 -234
  422. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +0 -419
  423. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/creative_reception.yaml +0 -247
  424. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/delivery_reporting.yaml +0 -357
  425. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment.yaml +0 -633
  426. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +0 -800
  427. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/event_dedup_flow.yaml +0 -399
  428. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +0 -309
  429. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_approved.yaml +0 -214
  430. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_conditions.yaml +0 -199
  431. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied.yaml +0 -204
  432. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/governance_denied_recovery.yaml +0 -252
  433. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/invalid_transitions.yaml +0 -289
  434. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_no_match.yaml +0 -148
  435. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/inventory_list_targeting.yaml +0 -276
  436. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_accountability.yaml +0 -244
  437. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +0 -203
  438. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +0 -274
  439. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +0 -500
  440. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow.yaml +0 -428
  441. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +0 -470
  442. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/product_signal_targeting.yaml +0 -373
  443. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize.yaml +0 -399
  444. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +0 -264
  445. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +0 -257
  446. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_audit_observation.yaml +0 -333
  447. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_enforcement.yaml +0 -517
  448. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +0 -294
  449. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/reach_buy_flow.yaml +0 -823
  450. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +0 -360
  451. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/refine_products.yaml +0 -148
  452. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +0 -293
  453. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +0 -307
  454. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +0 -576
  455. package/compliance/cache/3.1.0-beta.7/protocols/media-buy/state-machine.yaml +0 -442
  456. package/compliance/cache/3.1.0-beta.7/protocols/signals/index.yaml +0 -266
  457. package/compliance/cache/3.1.0-beta.7/protocols/sponsored-intelligence/index.yaml +0 -256
  458. package/compliance/cache/3.1.0-beta.7/specialisms/audience-sync/index.yaml +0 -313
  459. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/index.yaml +0 -350
  460. package/compliance/cache/3.1.0-beta.7/specialisms/brand-rights/scenarios/governance_denied.yaml +0 -226
  461. package/compliance/cache/3.1.0-beta.7/specialisms/collection-lists/index.yaml +0 -359
  462. package/compliance/cache/3.1.0-beta.7/specialisms/content-standards/index.yaml +0 -572
  463. package/compliance/cache/3.1.0-beta.7/specialisms/creative-ad-server/index.yaml +0 -409
  464. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/generative-seller.yaml +0 -807
  465. package/compliance/cache/3.1.0-beta.7/specialisms/creative-generative/index.yaml +0 -758
  466. package/compliance/cache/3.1.0-beta.7/specialisms/creative-template/index.yaml +0 -510
  467. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/index.yaml +0 -143
  468. package/compliance/cache/3.1.0-beta.7/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +0 -117
  469. package/compliance/cache/3.1.0-beta.7/specialisms/governance-delivery-monitor/index.yaml +0 -441
  470. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/denied.yaml +0 -221
  471. package/compliance/cache/3.1.0-beta.7/specialisms/governance-spend-authority/index.yaml +0 -330
  472. package/compliance/cache/3.1.0-beta.7/specialisms/property-lists/index.yaml +0 -482
  473. package/compliance/cache/3.1.0-beta.7/specialisms/sales-broadcast-tv/index.yaml +0 -738
  474. package/compliance/cache/3.1.0-beta.7/specialisms/sales-catalog-driven/index.yaml +0 -840
  475. package/compliance/cache/3.1.0-beta.7/specialisms/sales-guaranteed/index.yaml +0 -601
  476. package/compliance/cache/3.1.0-beta.7/specialisms/sales-non-guaranteed/index.yaml +0 -546
  477. package/compliance/cache/3.1.0-beta.7/specialisms/sales-proposal-mode/index.yaml +0 -586
  478. package/compliance/cache/3.1.0-beta.7/specialisms/sales-social/index.yaml +0 -919
  479. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/index.yaml +0 -424
  480. package/compliance/cache/3.1.0-beta.7/specialisms/signal-marketplace/scenarios/governance_denied.yaml +0 -211
  481. package/compliance/cache/3.1.0-beta.7/specialisms/signal-owned/index.yaml +0 -317
  482. package/compliance/cache/3.1.0-beta.7/specialisms/sponsored-intelligence/index.yaml +0 -59
  483. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor-live.yaml +0 -78
  484. package/compliance/cache/3.1.0-beta.7/test-kits/acme-outdoor.yaml +0 -223
  485. package/compliance/cache/3.1.0-beta.7/test-kits/billing-gate-runner.yaml +0 -115
  486. package/compliance/cache/3.1.0-beta.7/test-kits/bistro-oranje.yaml +0 -126
  487. package/compliance/cache/3.1.0-beta.7/test-kits/distributed-brand-runner.yaml +0 -281
  488. package/compliance/cache/3.1.0-beta.7/test-kits/nova-motors.yaml +0 -262
  489. package/compliance/cache/3.1.0-beta.7/test-kits/osei-natural.yaml +0 -126
  490. package/compliance/cache/3.1.0-beta.7/test-kits/parallel-dispatch-runner.yaml +0 -196
  491. package/compliance/cache/3.1.0-beta.7/test-kits/rate-limit-trip-runner.yaml +0 -172
  492. package/compliance/cache/3.1.0-beta.7/test-kits/signed-requests-runner.yaml +0 -155
  493. package/compliance/cache/3.1.0-beta.7/test-kits/single-side-trust-runner.yaml +0 -294
  494. package/compliance/cache/3.1.0-beta.7/test-kits/substitution-observer-runner.yaml +0 -688
  495. package/compliance/cache/3.1.0-beta.7/test-kits/summit-foods.yaml +0 -125
  496. package/compliance/cache/3.1.0-beta.7/test-kits/webhook-receiver-runner.yaml +0 -265
  497. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/001-minimal-plan.json +0 -43
  498. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/002-full-plan.json +0 -217
  499. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/003-bookkeeping-stripped.json +0 -60
  500. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004a-human-review-omitted.json +0 -43
  501. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/004b-human-review-explicit-null.json +0 -49
  502. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005a-policy-categories-order-1.json +0 -53
  503. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/005b-policy-categories-order-2.json +0 -57
  504. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006a-ext-trace-v1.json +0 -49
  505. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/006b-ext-trace-v2.json +0 -53
  506. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/007-unicode-objectives.json +0 -43
  507. package/compliance/cache/3.1.0-beta.7/test-vectors/plan-hash/008-numeric-canonicalization.json +0 -65
  508. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/README.md +0 -220
  509. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/canonicalization.json +0 -241
  510. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/keys.json +0 -60
  511. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/001-no-signature-header.json +0 -24
  512. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/002-wrong-tag.json +0 -26
  513. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/003-expired-signature.json +0 -26
  514. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/004-window-too-long.json +0 -26
  515. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/005-alg-not-allowed.json +0 -26
  516. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/006-missing-covered-component.json +0 -26
  517. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/007-missing-content-digest.json +0 -26
  518. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/008-unknown-keyid.json +0 -26
  519. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +0 -27
  520. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/010-content-digest-mismatch.json +0 -33
  521. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/011-malformed-header.json +0 -27
  522. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/012-missing-expires-param.json +0 -26
  523. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/013-expires-le-created.json +0 -27
  524. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/014-missing-nonce-param.json +0 -27
  525. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/015-signature-invalid.json +0 -28
  526. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/016-replayed-nonce.json +0 -35
  527. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/017-key-revoked.json +0 -38
  528. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +0 -28
  529. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/019-signature-without-signature-input.json +0 -26
  530. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/020-rate-abuse.json +0 -34
  531. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +0 -31
  532. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/022-multi-valued-content-type.json +0 -31
  533. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +0 -32
  534. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/024-unquoted-string-param.json +0 -31
  535. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +0 -43
  536. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/026-non-ascii-host.json +0 -31
  537. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +0 -25
  538. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +0 -26
  539. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/001-basic-post.json +0 -30
  540. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/002-post-with-content-digest.json +0 -31
  541. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/003-es256-post.json +0 -30
  542. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/004-multiple-signature-labels.json +0 -26
  543. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/005-default-port-stripped.json +0 -30
  544. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/006-dot-segment-path.json +0 -30
  545. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/007-query-byte-preserved.json +0 -30
  546. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/008-percent-encoded-path.json +0 -30
  547. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +0 -30
  548. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +0 -30
  549. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/011-ipv6-authority.json +0 -30
  550. package/compliance/cache/3.1.0-beta.7/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +0 -30
  551. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/README.md +0 -211
  552. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/keys.json +0 -61
  553. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/001-wrong-tag.json +0 -26
  554. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/002-expired-signature.json +0 -26
  555. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/003-window-too-long.json +0 -26
  556. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +0 -26
  557. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/005-missing-authority-component.json +0 -26
  558. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/006-missing-content-digest.json +0 -25
  559. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/007-unknown-keyid.json +0 -26
  560. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +0 -26
  561. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +0 -26
  562. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +0 -26
  563. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/011-signature-without-input.json +0 -25
  564. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/012-missing-expires-param.json +0 -26
  565. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/013-expires-le-created.json +0 -26
  566. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +0 -26
  567. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/015-signature-invalid.json +0 -26
  568. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/016-replayed-nonce.json +0 -37
  569. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/017-key-revoked.json +0 -32
  570. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/018-rate-abuse.json +0 -33
  571. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/019-revocation-stale.json +0 -32
  572. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +0 -41
  573. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +0 -26
  574. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/001-basic-post.json +0 -24
  575. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/002-es256-post.json +0 -24
  576. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +0 -24
  577. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/004-default-port-stripped.json +0 -24
  578. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +0 -24
  579. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +0 -24
  580. package/compliance/cache/3.1.0-beta.7/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +0 -25
  581. package/compliance/cache/3.1.0-beta.7/universal/billing-gate-dispatch.yaml +0 -450
  582. package/compliance/cache/3.1.0-beta.7/universal/canonical-format-validate-input.yaml +0 -640
  583. package/compliance/cache/3.1.0-beta.7/universal/capability-discovery.yaml +0 -125
  584. package/compliance/cache/3.1.0-beta.7/universal/collection-lists-pagination-integrity.yaml +0 -306
  585. package/compliance/cache/3.1.0-beta.7/universal/comply-controller-mode-gate.yaml +0 -141
  586. package/compliance/cache/3.1.0-beta.7/universal/content-standards-pagination-integrity.yaml +0 -326
  587. package/compliance/cache/3.1.0-beta.7/universal/deterministic-testing.yaml +0 -1430
  588. package/compliance/cache/3.1.0-beta.7/universal/error-compliance-signals.yaml +0 -377
  589. package/compliance/cache/3.1.0-beta.7/universal/error-compliance.yaml +0 -528
  590. package/compliance/cache/3.1.0-beta.7/universal/fictional-entities.yaml +0 -307
  591. package/compliance/cache/3.1.0-beta.7/universal/get-media-buys-pagination-integrity.yaml +0 -160
  592. package/compliance/cache/3.1.0-beta.7/universal/get-signals-pagination-integrity.yaml +0 -211
  593. package/compliance/cache/3.1.0-beta.7/universal/idempotency.yaml +0 -861
  594. package/compliance/cache/3.1.0-beta.7/universal/notification-config-event-scope.yaml +0 -119
  595. package/compliance/cache/3.1.0-beta.7/universal/notification-config-lifecycle.yaml +0 -337
  596. package/compliance/cache/3.1.0-beta.7/universal/notification-config-rejections.yaml +0 -107
  597. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-creative-formats.yaml +0 -265
  598. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity-list-accounts.yaml +0 -245
  599. package/compliance/cache/3.1.0-beta.7/universal/pagination-integrity.yaml +0 -263
  600. package/compliance/cache/3.1.0-beta.7/universal/property-lists-pagination-integrity.yaml +0 -307
  601. package/compliance/cache/3.1.0-beta.7/universal/read-tool-idempotency.yaml +0 -405
  602. package/compliance/cache/3.1.0-beta.7/universal/runner-output-contract.yaml +0 -1266
  603. package/compliance/cache/3.1.0-beta.7/universal/schema-validation-signals.yaml +0 -181
  604. package/compliance/cache/3.1.0-beta.7/universal/schema-validation.yaml +0 -548
  605. package/compliance/cache/3.1.0-beta.7/universal/security.yaml +0 -539
  606. package/compliance/cache/3.1.0-beta.7/universal/signed-requests.yaml +0 -217
  607. package/compliance/cache/3.1.0-beta.7/universal/stale-response-advisory.yaml +0 -295
  608. package/compliance/cache/3.1.0-beta.7/universal/storyboard-schema.yaml +0 -2136
  609. package/compliance/cache/3.1.0-beta.7/universal/v3-envelope-integrity.yaml +0 -117
  610. package/compliance/cache/3.1.0-beta.7/universal/version-negotiation.yaml +0 -130
  611. package/compliance/cache/3.1.0-beta.7/universal/webhook-emission.yaml +0 -411
  612. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-bulk-webhooks.yaml +0 -82
  613. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-product-webhooks.yaml +0 -83
  614. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-products.yaml +0 -151
  615. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signal-webhooks.yaml +0 -83
  616. package/compliance/cache/3.1.0-beta.7/universal/wholesale-feed-signals.yaml +0 -149
  617. package/dist/lib/types/v3-1-beta/index.d.mts +0 -1
  618. package/dist/lib/types/v3-1-beta/index.d.ts +0 -1
  619. package/dist/lib/types/v3-1-beta/index.mjs +0 -1
  620. package/dist/lib/types/v3-1-beta/tools.generated.d.mts +0 -26788
  621. package/dist/lib/types/v3-1-beta/tools.generated.d.ts +0 -26788
  622. /package/dist/lib/{types/v3-1-beta/tools.generated.mjs → media-buy/action-types.mjs} +0 -0
@@ -28,8 +28,15 @@ __export(reconciliation_exports, {
28
28
  module.exports = __toCommonJS(reconciliation_exports);
29
29
  var import_crypto = require("crypto");
30
30
  var import_idempotency = require('../utils/idempotency.js');
31
+ var import_jcs = require('../utils/jcs.js');
32
+ var import_content_mismatch = require('./content-mismatch.js');
31
33
  var import_evidence = require('./evidence.js');
32
34
  var import_inspection = require('./inspection.js');
35
+ const CONSUMER_STATUS_BATCH_MAX = 100;
36
+ const MAX_CONSUMED_REVISION_BYTES = 256 * 1024 * 1024;
37
+ const MAX_ROW_ESTIMATE_CONTAINERS = 262144;
38
+ const OVERFLOWED_INSTANT = "\0overflow";
39
+ const MAX_ROW_ESTIMATE_DEPTH = 64;
33
40
  class ReportingReconciliationError extends Error {
34
41
  constructor(code, message) {
35
42
  super(message);
@@ -252,6 +259,7 @@ async function loadReportingLedger(client, request, maxSnapshotRestarts = 2, lim
252
259
  const revisions = /* @__PURE__ */ new Map();
253
260
  const materializations = /* @__PURE__ */ new Map();
254
261
  const receipts = /* @__PURE__ */ new Map();
262
+ const consumerStatuses = /* @__PURE__ */ new Map();
255
263
  const seenCursors = /* @__PURE__ */ new Set();
256
264
  let cursor;
257
265
  let snapshotId;
@@ -341,6 +349,14 @@ async function loadReportingLedger(client, request, maxSnapshotRestarts = 2, lim
341
349
  for (const item of response.materializations ?? [])
342
350
  addImmutable(materializations, item.reporting_materialization_id, item, "materialization");
343
351
  for (const item of response.receipts ?? []) addImmutable(receipts, item.reporting_receipt_id, item, "receipt");
352
+ for (const item of response.consumer_statuses ?? [])
353
+ addImmutable(consumerStatuses, item.reporting_status_id, item, "consumer status");
354
+ if (consumerStatuses.size > maxRecords) {
355
+ throw new ReportingReconciliationError(
356
+ "LEDGER_LIMIT_EXCEEDED",
357
+ "reporting consumer status history exceeds record limit"
358
+ );
359
+ }
344
360
  if (obligations.size + revisions.size + materializations.size + receipts.size > maxRecords) {
345
361
  throw new ReportingReconciliationError("LEDGER_LIMIT_EXCEEDED", "reporting ledger exceeds record limit");
346
362
  }
@@ -370,6 +386,7 @@ async function loadReportingLedger(client, request, maxSnapshotRestarts = 2, lim
370
386
  ledgerAsOf,
371
387
  accountId,
372
388
  scope,
389
+ consumerStatuses: [...consumerStatuses.values()],
373
390
  obligations: [...obligations.values()],
374
391
  revisions: [...revisions.values()],
375
392
  materializations: [...materializations.values()],
@@ -510,7 +527,7 @@ function selectCurrent(obligation, ledger, expected) {
510
527
  if (revision.account_id !== obligation.account_id || revision.report_definition_id !== obligation.report_definition_id || revision.reporting_profile !== obligation.reporting_profile || !Array.isArray(revision.media_buy_ids) || !Array.isArray(obligation.media_buy_ids) || !same([...revision.media_buy_ids].sort(), [...obligation.media_buy_ids].sort()) || !same(revision.period, obligation.period)) {
511
528
  reasons.push("REVISION_SCOPE_MISMATCH");
512
529
  }
513
- if (obligation.scope_resolved_at !== obligation.period.end) reasons.push("SCOPE_CUTOFF_MISMATCH");
530
+ if (obligation.scope_resolved_at !== obligation.period?.end) reasons.push("SCOPE_CUTOFF_MISMATCH");
514
531
  if (!isReportingCoverageEvidence(obligation.coverage) || obligation.coverage.evaluated_at !== obligation.scope_resolved_at || !sameStringSet(obligation.coverage.media_buy_ids, obligation.media_buy_ids ?? []) || !isReportingCoverageEvidence(revision.coverage) || !same(revision.coverage, obligation.coverage)) {
515
532
  reasons.push("COVERAGE_SCOPE_MISMATCH");
516
533
  }
@@ -594,7 +611,505 @@ function selectCurrent(obligation, ledger, expected) {
594
611
  function countMismatch(declared, observed, required) {
595
612
  return declared === void 0 ? required : declared !== observed;
596
613
  }
614
+ function planReportingConsumerStatuses(ledger, expectedPeriods, missingExpectedPeriods, now) {
615
+ const missing = new Set(missingExpectedPeriods);
616
+ return expectedPeriods.map((expected) => {
617
+ const obligationForPeriod = ledger.obligations.find(
618
+ (candidate) => expectedPeriodMatches(expected, candidate, ledger)
619
+ );
620
+ const declaredSourceTimezone = obligationForPeriod?.period?.source_timezone;
621
+ const resolvedSourceTimezone = ianaTimeZone(expected.periodSourceTimezone) ?? ianaTimeZone(declaredSourceTimezone);
622
+ const periodIdentityUnknown = resolvedSourceTimezone === void 0 && declaredSourceTimezone !== void 0;
623
+ const period = {
624
+ start: expected.periodStart,
625
+ end: expected.periodEnd,
626
+ source_timezone: resolvedSourceTimezone ?? "UTC"
627
+ };
628
+ const base = {
629
+ deliveryConfigId: expected.deliveryConfigId,
630
+ deliveryConfigVersion: expected.deliveryConfigVersion,
631
+ reportDefinitionId: expected.reportDefinitionId,
632
+ period
633
+ };
634
+ const derivedExpectedAt = reportingExpectedAt(obligationForPeriod, expected);
635
+ const expectedAtOverflowed = derivedExpectedAt === OVERFLOWED_INSTANT;
636
+ const expectedAt = expectedAtOverflowed || derivedExpectedAt === void 0 ? void 0 : latestInstant([derivedExpectedAt, expected.periodEnd]);
637
+ const declaredExpectedAt = obligationForPeriod?.expected_at;
638
+ const malformedExpectedAt = expectedAt === void 0 && !expectedAtOverflowed && declaredExpectedAt !== void 0 ? typeof declaredExpectedAt === "string" ? declaredExpectedAt : `<${typeof declaredExpectedAt}>` : void 0;
639
+ const schedule = consumerStatusSchedule(expectedAt, expected, now, malformedExpectedAt, expectedAtOverflowed);
640
+ const pinnedExpectation = pinnedExpectedAt(expected);
641
+ const deadlineBeyondPin = expectedAt !== void 0 && pinnedExpectation !== void 0 && Date.parse(expectedAt) > Date.parse(pinnedExpectation) + (expected.automatedRecoveryWindowSeconds ?? 0) * 1e3 ? { declared: expectedAt, pinned: pinnedExpectation } : void 0;
642
+ const leaf = currentConsumerLeaf(
643
+ ledger,
644
+ base,
645
+ obligationForPeriod?.current_consumer_status_id
646
+ );
647
+ const establishedAt = latestInstant([expectedAt, expected.periodEnd]) ?? expected.periodEnd;
648
+ if (missing.has(expected) || !obligationForPeriod) {
649
+ return finalizeConsumerStatusPlan(
650
+ {
651
+ ...base,
652
+ ...schedule,
653
+ ...periodIdentityUnknown ? { periodIdentityUnknown: true } : {},
654
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
655
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
656
+ consumerStatus: "obligation_missing",
657
+ establishedAt,
658
+ reason: missing.has(expected) ? "the independently expected period is absent from the seller ledger" : "no obligation in the ledger matches this expected period"
659
+ },
660
+ leaf,
661
+ now
662
+ );
663
+ }
664
+ const obligation = obligationForPeriod;
665
+ const selected = selectCurrent(obligation, ledger, expected);
666
+ const revision = selected.revision;
667
+ const forked = selected.reasons.includes("AMBIGUOUS_REVISION_CHAIN");
668
+ const predecessorMissing = selected.reasons.includes("REVISION_PREDECESSOR_MISSING");
669
+ const indeterminate = forked || predecessorMissing;
670
+ if (!revision || indeterminate) {
671
+ return finalizeConsumerStatusPlan(
672
+ {
673
+ ...base,
674
+ ...schedule,
675
+ ...periodIdentityUnknown ? { periodIdentityUnknown: true } : {},
676
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
677
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
678
+ reportingObligationId: obligation.reporting_obligation_id,
679
+ consumerStatus: "revision_missing",
680
+ ...indeterminate ? { indeterminate: true } : {},
681
+ establishedAt,
682
+ reason: forked ? "the revision chain forks, so no single current revision could be resolved" : predecessorMissing ? `a revision names a predecessor the buyer never saw, so ${revision ? `the head ${boundedDiagnostic(revision.reporting_revision_id)} ` : "no head "}could not be proven current` : "the obligation exists but no required revision was available"
683
+ },
684
+ leaf,
685
+ now
686
+ );
687
+ }
688
+ const disqualifying = selected.reasons.filter((reason) => REVISION_DISQUALIFYING_REASONS.has(reason));
689
+ if (disqualifying.length > 0) {
690
+ return finalizeConsumerStatusPlan(
691
+ {
692
+ ...base,
693
+ ...schedule,
694
+ ...periodIdentityUnknown ? { periodIdentityUnknown: true } : {},
695
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
696
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
697
+ reportingObligationId: obligation.reporting_obligation_id,
698
+ consumerStatus: "revision_missing",
699
+ establishedAt,
700
+ reason: `the published revision does not satisfy the accepted generation (${disqualifying.join(", ")})`
701
+ },
702
+ leaf,
703
+ now
704
+ );
705
+ }
706
+ const mismatch = (0, import_content_mismatch.detectReportingContentMismatch)(contractFactsFor(obligation, expected), revision);
707
+ return finalizeConsumerStatusPlan(
708
+ {
709
+ ...base,
710
+ ...schedule,
711
+ ...periodIdentityUnknown ? { periodIdentityUnknown: true } : {},
712
+ ...deadlineBeyondPin ? { deadlineBeyondPin } : {},
713
+ reportingObligationId: obligation.reporting_obligation_id,
714
+ reportingRevisionId: revision.reporting_revision_id,
715
+ consumerStatus: mismatch ? "content_mismatch" : "received",
716
+ ...mismatch ? { mismatchCode: mismatch.mismatchCode } : {},
717
+ // Not the revision's own `observed_at`: `status_as_of` is when the
718
+ // revision became consumable *to this consumer*, and the spec is
719
+ // explicit that sellers must not silently substitute publication time.
720
+ // The floor stands in until the buyer has actually read it.
721
+ establishedAt,
722
+ requiresConsumption: true,
723
+ reason: mismatch?.detail ?? "the named revision is ready to consume and honors every frozen contract fact"
724
+ },
725
+ leaf,
726
+ now
727
+ );
728
+ });
729
+ }
730
+ const REVISION_DISQUALIFYING_REASONS = /* @__PURE__ */ new Set([
731
+ "FINALITY_NOT_MET",
732
+ "EXPECTED_FINALITY_POLICY_MISMATCH",
733
+ "EXPECTED_CONTRACT_MISMATCH",
734
+ "EXPECTED_CONTRACT_MISSING",
735
+ "REVISION_SCOPE_MISMATCH"
736
+ // Deliberately *not* REVISION_CHAIN_SCOPE_MISMATCH: it fires when any
737
+ // candidate in the chain is off-scope, including a long-superseded one, so a
738
+ // perfectly valid current revision would be reported as missing. Nothing is
739
+ // lost by dropping it — the head-only predicate REVISION_SCOPE_MISMATCH
740
+ // tests the same fields against the revision actually being named.
741
+ //
742
+ // It is a live path, not defence in depth: for a direct-Core obligation the
743
+ // graph assertion does refuse an off-scope revision, but a revision joined
744
+ // through a materialization is checked only for `account_id`, so under
745
+ // managed delivery an off-scope predecessor survives the load and becomes a
746
+ // candidate. The test builds exactly that fixture.
747
+ ]);
748
+ function finalizeConsumerStatusPlan(draft, leaf, now) {
749
+ const statusAsOfFloor = latestInstant([draft.establishedAt, usableLeafInstant(leaf.statement, now)]) ?? draft.establishedAt;
750
+ const { establishedAt: _establishedAt, deadlineGap, indeterminate, periodIdentityUnknown, ...carried } = draft;
751
+ const plan = {
752
+ ...carried,
753
+ ...leaf.statusId ? { supersedesReportingStatusId: leaf.statusId } : {},
754
+ statusAsOfFloor,
755
+ // A statement the buyer can already date is dated now; one that still owes
756
+ // a read is left open for `attestConsumerStatusPlan`.
757
+ ...draft.requiresConsumption ? {} : { statusAsOf: statusAsOfFloor }
758
+ };
759
+ if (periodIdentityUnknown) {
760
+ return {
761
+ ...plan,
762
+ suppressed: "period_identity_unknown",
763
+ reason: suppressionReason("period_identity_unknown", plan.reason)
764
+ };
765
+ }
766
+ if (indeterminate) {
767
+ return {
768
+ ...plan,
769
+ suppressed: "chain_indeterminate",
770
+ reason: suppressionReason("chain_indeterminate", plan.reason)
771
+ };
772
+ }
773
+ if (deadlineGap) {
774
+ return {
775
+ ...plan,
776
+ suppressed: "deadline_unknown",
777
+ reason: deadlineGapReason(deadlineGap)
778
+ };
779
+ }
780
+ const suppressed = consumerStatusSuppression(plan, leaf);
781
+ return suppressed ? { ...plan, suppressed, reason: suppressionReason(suppressed, plan.reason) } : plan;
782
+ }
783
+ function deadlineGapReason(gap) {
784
+ switch (gap.cause) {
785
+ case "missing_pin":
786
+ return `no posting deadline: record ExpectedReportingPeriod.${gap.pin} to derive one`;
787
+ case "deadline_overflow":
788
+ return `no posting deadline: ${gap.field} puts it outside the representable range`;
789
+ default:
790
+ return `no posting deadline: the seller's obligation.expected_at (${boundedDiagnostic(gap.value)}) is not a readable instant, and a present expected_at is never overridden locally \u2014 the seller has to correct it`;
791
+ }
792
+ }
793
+ function suppressionReason(suppressed, reason) {
794
+ switch (suppressed) {
795
+ case "unchanged":
796
+ return `not posted: the current leaf already says this (${reason})`;
797
+ case "leaf_undisclosed":
798
+ return "not posted: the buyer's status chain has more than one unsuperseded leaf, or the seller named a current leaf it did not disclose \u2014 either way the buyer cannot tell whether it has anything new to say";
799
+ case "consumption_unavailable":
800
+ return "not posted: no client.getMediaBuyDelivery is wired, so consumption cannot be attested";
801
+ case "posting_unavailable":
802
+ return "not posted: no client.syncReportingStatus is wired, so the buyer cannot append to the status chain";
803
+ case "period_identity_unknown":
804
+ return "not posted: the seller's period.source_timezone is not a recognized IANA zone, and that value is part of the chain's logical key \u2014 record ExpectedReportingPeriod.periodSourceTimezone, or have the seller correct it";
805
+ case "local_budget_exhausted":
806
+ return "not posted: the buyer's own ledgerLimits read budget ran out before the revision could be consumed";
807
+ case "chain_indeterminate":
808
+ return `not posted: ${reason}`;
809
+ default:
810
+ return reason;
811
+ }
812
+ }
813
+ function consumerStatusSuppression(plan, leaf) {
814
+ if (leaf.undisclosed) return "leaf_undisclosed";
815
+ if (plan.requiresConsumption) return void 0;
816
+ if (leaf.statement && sameConsumerStatement(plan, leaf.statement)) return "unchanged";
817
+ return void 0;
818
+ }
819
+ function sameConsumerStatement(plan, statement) {
820
+ return statement.consumer_status === plan.consumerStatus && (statement.reporting_revision_id ?? void 0) === plan.reportingRevisionId && (statement.mismatch_code ?? void 0) === plan.mismatchCode && (statement.failure_code ?? void 0) === plan.failureCode && sameOptionalSha256(statement.observed_revision_content_sha256, plan.observedRevisionContentSha256);
821
+ }
822
+ function sameOptionalSha256(left, right) {
823
+ if (left === void 0 || right === void 0) return left === right;
824
+ return sameSha256(left, right);
825
+ }
826
+ function currentConsumerLeaf(ledger, key, declaredLeafId) {
827
+ const declared = typeof declaredLeafId === "string" ? declaredLeafId : void 0;
828
+ const chain = (ledger.consumerStatuses ?? []).filter(
829
+ (statement2) => statement2.delivery_config_id === key.deliveryConfigId && statement2.delivery_config_version === key.deliveryConfigVersion && statement2.report_definition_id === key.reportDefinitionId && statement2.period?.start === key.period.start && statement2.period?.end === key.period.end
830
+ );
831
+ if (declared) {
832
+ const statement2 = chain.find((candidate) => candidate.reporting_status_id === declared);
833
+ return statement2 ? { statusId: declared, statement: statement2, undisclosed: false } : { statusId: declared, undisclosed: true };
834
+ }
835
+ const superseded = new Set(
836
+ chain.map((statement2) => statement2.supersedes_reporting_status_id).filter((value) => typeof value === "string")
837
+ );
838
+ const leaves = chain.filter((statement2) => !superseded.has(statement2.reporting_status_id));
839
+ if (leaves.length !== 1) return { undisclosed: leaves.length > 1 };
840
+ const statement = leaves[0];
841
+ return { statusId: statement.reporting_status_id, statement, undisclosed: false };
842
+ }
843
+ function reportingExpectedAt(obligation, expected) {
844
+ const declared = normalizedInstant(obligation?.expected_at);
845
+ if (declared !== void 0) return declared;
846
+ if (obligation?.expected_at !== void 0) return void 0;
847
+ const slaSeconds = expected.requiredFinality === "official" ? expected.officialAfterSeconds ?? expected.deliverySlaSeconds : expected.deliverySlaSeconds;
848
+ const periodEnd = Date.parse(expected.periodEnd);
849
+ if (typeof slaSeconds === "number" && Number.isFinite(slaSeconds) && slaSeconds >= 0 && Number.isFinite(periodEnd)) {
850
+ const pinned = periodEnd + slaSeconds * 1e3;
851
+ return isRepresentableInstant(pinned) ? new Date(pinned).toISOString() : OVERFLOWED_INSTANT;
852
+ }
853
+ return reportingScheduledExpectedAt(obligation, expected.periodEnd);
854
+ }
855
+ function pinnedExpectedAt(expected) {
856
+ const slaSeconds = expected.requiredFinality === "official" ? expected.officialAfterSeconds ?? expected.deliverySlaSeconds : expected.deliverySlaSeconds;
857
+ const periodEnd = Date.parse(expected.periodEnd);
858
+ if (typeof slaSeconds !== "number" || !Number.isFinite(slaSeconds) || slaSeconds < 0) return void 0;
859
+ if (!Number.isFinite(periodEnd)) return void 0;
860
+ const pinned = periodEnd + slaSeconds * 1e3;
861
+ return isRepresentableInstant(pinned) ? new Date(pinned).toISOString() : void 0;
862
+ }
863
+ function localExpectedAtPin(expected) {
864
+ return expected.requiredFinality === "official" ? "officialAfterSeconds" : "deliverySlaSeconds";
865
+ }
866
+ function reportingScheduledExpectedAt(obligation, periodEnd) {
867
+ const schedule = obligation?.schedule;
868
+ if (typeof schedule?.delivery_sla !== "string") return void 0;
869
+ const duration = parseIso8601Duration(schedule.delivery_sla);
870
+ const anchor = Date.parse(periodEnd);
871
+ if (!duration || !Number.isFinite(anchor)) return void 0;
872
+ if (duration.years === 0 && duration.months === 0 && duration.days === 0) {
873
+ const exact = anchor + duration.seconds * 1e3;
874
+ return isRepresentableInstant(exact) ? new Date(exact).toISOString() : OVERFLOWED_INSTANT;
875
+ }
876
+ const timeZone = calendarTimeZone(obligation, schedule);
877
+ if (timeZone === void 0) return void 0;
878
+ const shifted = addCalendarDuration(anchor, duration, timeZone);
879
+ if (shifted === void 0) return void 0;
880
+ return isRepresentableInstant(shifted) ? new Date(shifted).toISOString() : OVERFLOWED_INSTANT;
881
+ }
882
+ function calendarTimeZone(obligation, schedule) {
883
+ if (schedule.period_timezone !== void 0) return ianaTimeZone(schedule.period_timezone);
884
+ if (schedule.alignment === "utc") return "UTC";
885
+ return ianaTimeZone(obligation?.period?.source_timezone);
886
+ }
887
+ function ianaTimeZone(value) {
888
+ const name = boundedSourceTimezone(value);
889
+ if (name === void 0) return void 0;
890
+ if (/^[+-]/.test(name)) return void 0;
891
+ try {
892
+ new Intl.DateTimeFormat("en-US", { timeZone: name });
893
+ return name;
894
+ } catch {
895
+ return void 0;
896
+ }
897
+ }
898
+ function parseIso8601Duration(value) {
899
+ const match = /^P(?=\d|T)(?=.*\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?=\d)(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/.exec(value);
900
+ if (!match) return void 0;
901
+ const [, years, months, days, hours, minutes, seconds] = match;
902
+ return {
903
+ years: Number(years ?? 0),
904
+ months: Number(months ?? 0),
905
+ days: Number(days ?? 0),
906
+ seconds: Number(hours ?? 0) * 3600 + Number(minutes ?? 0) * 60 + Number(seconds ?? 0)
907
+ };
908
+ }
909
+ function addCalendarDuration(instant, duration, timeZone) {
910
+ const parts = zonedParts(instant, timeZone);
911
+ if (!parts) return void 0;
912
+ const totalMonths = parts.month - 1 + duration.years * 12 + duration.months;
913
+ const year = parts.year + Math.floor(totalMonths / 12);
914
+ const month = totalMonths % 12 + 1;
915
+ const clamped = Math.min(parts.day, daysInMonth(year, month));
916
+ const wall = utcWallTime(year, month, clamped + duration.days, parts.hour, parts.minute, parts.second);
917
+ if (wall === void 0) return void 0;
918
+ const resolved = instantForWallTime(wall, timeZone);
919
+ if (resolved === void 0) return void 0;
920
+ const subSecond = (instant % 1e3 + 1e3) % 1e3;
921
+ return resolved + subSecond + duration.seconds * 1e3;
922
+ }
923
+ function isRepresentableInstant(value) {
924
+ return Number.isFinite(value) && value >= MIN_RFC3339_INSTANT && value <= MAX_RFC3339_INSTANT;
925
+ }
926
+ const MIN_RFC3339_INSTANT = -621672192e5;
927
+ const MAX_RFC3339_INSTANT = 253402300799999;
928
+ function daysInMonth(year, month) {
929
+ const probe = /* @__PURE__ */ new Date(0);
930
+ probe.setUTCFullYear(year, month, 0);
931
+ return probe.getUTCDate();
932
+ }
933
+ function utcWallTime(year, month, day, hour, minute, second) {
934
+ const value = /* @__PURE__ */ new Date(0);
935
+ value.setUTCFullYear(year, month - 1, day);
936
+ value.setUTCHours(hour, minute, second, 0);
937
+ const time = value.getTime();
938
+ return isRepresentableInstant(time) ? time : void 0;
939
+ }
940
+ function zonedParts(instant, timeZone) {
941
+ try {
942
+ const formatted = new Intl.DateTimeFormat("en-US", {
943
+ timeZone,
944
+ // Read the era so a proleptic year can be refused rather than silently
945
+ // relocated: without it `en-US` renders year 0 (1 BC) as year `1`.
946
+ era: "short",
947
+ hour12: false,
948
+ year: "numeric",
949
+ month: "2-digit",
950
+ day: "2-digit",
951
+ hour: "2-digit",
952
+ minute: "2-digit",
953
+ second: "2-digit"
954
+ }).formatToParts(new Date(instant));
955
+ const field = (type) => Number(formatted.find((part) => part.type === type)?.value);
956
+ if (/^b/i.test(formatted.find((part) => part.type === "era")?.value ?? "")) return void 0;
957
+ const parts = {
958
+ year: field("year"),
959
+ month: field("month"),
960
+ day: field("day"),
961
+ // Intl renders midnight as hour 24 in some locales' hourCycle.
962
+ hour: field("hour") % 24,
963
+ minute: field("minute"),
964
+ second: field("second")
965
+ };
966
+ return Object.values(parts).every(Number.isFinite) ? parts : void 0;
967
+ } catch {
968
+ return void 0;
969
+ }
970
+ }
971
+ function instantForWallTime(wall, timeZone) {
972
+ const dayMs = 864e5;
973
+ const offsetBefore = zoneOffset(wall - dayMs, timeZone);
974
+ const offsetAfter = zoneOffset(wall + dayMs, timeZone);
975
+ if (offsetBefore === void 0 || offsetAfter === void 0) return void 0;
976
+ const fromBefore = wall - offsetBefore;
977
+ const fromAfter = wall - offsetAfter;
978
+ if (readsBackAs(fromBefore, wall, timeZone)) return fromBefore;
979
+ if (readsBackAs(fromAfter, wall, timeZone)) return fromAfter;
980
+ return fromBefore;
981
+ }
982
+ function zoneOffset(instant, timeZone) {
983
+ if (!isRepresentableInstant(instant)) return void 0;
984
+ const parts = zonedParts(instant, timeZone);
985
+ if (!parts) return void 0;
986
+ const asUtc = utcWallTime(parts.year, parts.month, parts.day, parts.hour, parts.minute, parts.second);
987
+ return asUtc === void 0 ? void 0 : asUtc - instant;
988
+ }
989
+ function readsBackAs(instant, wall, timeZone) {
990
+ if (!isRepresentableInstant(instant)) return false;
991
+ const parts = zonedParts(instant, timeZone);
992
+ if (!parts) return false;
993
+ return utcWallTime(parts.year, parts.month, parts.day, parts.hour, parts.minute, parts.second) === wall;
994
+ }
995
+ function consumerStatusSchedule(expectedAt, expected, now, malformedExpectedAt, expectedAtOverflowed = false, overflowField = "the derived expected_at") {
996
+ const windowSeconds = expected.automatedRecoveryWindowSeconds;
997
+ if (expectedAtOverflowed) {
998
+ return {
999
+ overdue: false,
1000
+ deadlineGap: { cause: "deadline_overflow", field: overflowField }
1001
+ };
1002
+ }
1003
+ if (expectedAt === void 0) {
1004
+ return {
1005
+ overdue: false,
1006
+ deadlineGap: malformedExpectedAt !== void 0 ? { cause: "unreadable_expected_at", value: malformedExpectedAt } : { cause: "missing_pin", pin: localExpectedAtPin(expected) }
1007
+ };
1008
+ }
1009
+ if (typeof windowSeconds !== "number" || !Number.isFinite(windowSeconds) || windowSeconds < 0) {
1010
+ return { overdue: false, deadlineGap: { cause: "missing_pin", pin: "automatedRecoveryWindowSeconds" } };
1011
+ }
1012
+ const deadlineAt = Date.parse(expectedAt) + windowSeconds * 1e3;
1013
+ if (!isRepresentableInstant(deadlineAt)) {
1014
+ return {
1015
+ overdue: false,
1016
+ deadlineGap: { cause: "deadline_overflow", field: "ExpectedReportingPeriod.automatedRecoveryWindowSeconds" }
1017
+ };
1018
+ }
1019
+ const deadline = new Date(deadlineAt).toISOString();
1020
+ return { deadline, overdue: now.getTime() >= Date.parse(deadline) };
1021
+ }
1022
+ const RFC3339_INSTANT = /^(\d{4})-(\d{2})-(\d{2})[Tt\s](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:[Zz]|[+-]\d{2}(?::?(\d{2}))?)$/;
1023
+ function normalizedInstant(value) {
1024
+ if (typeof value !== "string") return void 0;
1025
+ const match = RFC3339_INSTANT.exec(value);
1026
+ if (!match) return void 0;
1027
+ const [, isoYear, isoMonth, isoDay, isoHour, isoMinute, isoSecond, offsetMinute] = match;
1028
+ const year = Number(isoYear);
1029
+ const month = Number(isoMonth);
1030
+ const day = Number(isoDay);
1031
+ if (month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month)) return void 0;
1032
+ if (Number(isoHour) > 23 || Number(isoMinute) > 59) return void 0;
1033
+ if (offsetMinute !== void 0 && Number(offsetMinute) > 59) return void 0;
1034
+ const leapSecond = isoSecond === "60";
1035
+ if (leapSecond && utcMinuteOfDay(value, Number(isoHour), Number(isoMinute)) !== 23 * 60 + 59) return void 0;
1036
+ let candidate = value.replace(/([+-]\d{2})$/, "$1:00");
1037
+ if (leapSecond) candidate = candidate.replace(/:60/, ":59");
1038
+ const parsed = Date.parse(candidate);
1039
+ if (!Number.isFinite(parsed)) return void 0;
1040
+ const instant = parsed + (leapSecond ? 1e3 : 0);
1041
+ return isRepresentableInstant(instant) ? new Date(instant).toISOString() : void 0;
1042
+ }
1043
+ function boundedSourceTimezone(value) {
1044
+ return typeof value === "string" && value.length > 0 && value.length <= 255 ? value : void 0;
1045
+ }
1046
+ function utcMinuteOfDay(value, hour, minute) {
1047
+ const offset = /([+-])(\d{2}):?(\d{2})?$/.exec(value);
1048
+ const offsetMinutes = offset ? (offset[1] === "-" ? -1 : 1) * (Number(offset[2]) * 60 + Number(offset[3] ?? 0)) : 0;
1049
+ return ((hour * 60 + minute - offsetMinutes) % 1440 + 1440) % 1440;
1050
+ }
1051
+ function boundedDiagnostic(value) {
1052
+ if (typeof value !== "string") return "";
1053
+ return value.slice(0, 256).replace(/[\u0000-\u001f\u007f]+/g, " ");
1054
+ }
1055
+ function latestInstant(values) {
1056
+ let latest;
1057
+ for (const value of values) {
1058
+ const normalized = normalizedInstant(value);
1059
+ if (normalized === void 0) continue;
1060
+ const parsed = Date.parse(normalized);
1061
+ if (latest === void 0 || parsed > Date.parse(latest)) latest = normalized;
1062
+ }
1063
+ return latest;
1064
+ }
1065
+ function usableLeafInstant(statement, now) {
1066
+ const value = normalizedInstant(statement?.status_as_of);
1067
+ if (value === void 0 || Date.parse(value) > now.getTime()) return void 0;
1068
+ return value;
1069
+ }
1070
+ function contractFactsFor(obligation, expected) {
1071
+ return {
1072
+ ...Array.isArray(obligation.media_buy_ids) ? { mediaBuyIds: obligation.media_buy_ids } : {},
1073
+ ...obligation.coverage?.covered_package_ids ? { coveredPackageIds: obligation.coverage.covered_package_ids } : {},
1074
+ period: { start: expected.periodStart, end: expected.periodEnd },
1075
+ ...expected.committedMetrics ? { committedMetrics: expected.committedMetrics } : {},
1076
+ ...expected.metricUnits ? { metricUnits: expected.metricUnits } : {}
1077
+ };
1078
+ }
1079
+ function collectReportingEscalations(ledger, options) {
1080
+ const operationsContact = options?.operationsContact;
1081
+ const escalations = [];
1082
+ for (const obligation of ledger.obligations) {
1083
+ const declaredIssues = obligation.issues;
1084
+ for (const candidate of Array.isArray(declaredIssues) ? declaredIssues : []) {
1085
+ if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) continue;
1086
+ const issue = candidate;
1087
+ const recommendedAction = boundedDiagnostic(String(issue.recommended_action ?? ""));
1088
+ escalations.push({
1089
+ reportingObligationId: obligation.reporting_obligation_id,
1090
+ issueId: boundedDiagnostic(String(issue.issue_id ?? "")),
1091
+ code: boundedDiagnostic(String(issue.code ?? "")),
1092
+ severity: boundedDiagnostic(String(issue.severity ?? "")),
1093
+ responsibleParty: boundedDiagnostic(String(issue.responsible_party ?? "")),
1094
+ recommendedAction,
1095
+ ...typeof issue.opened_at === "string" ? { openedAt: issue.opened_at } : {},
1096
+ ...typeof issue.issue_state === "string" ? { issueState: issue.issue_state } : {},
1097
+ ...typeof issue.external_ref === "string" ? { externalRef: boundedDiagnostic(issue.external_ref) } : {},
1098
+ ...typeof issue.reporting_status_id === "string" ? { reportingStatusId: issue.reporting_status_id } : {},
1099
+ ...operationsContact ? { operationsContact } : {},
1100
+ requiresHumanContact: recommendedAction.startsWith("contact_")
1101
+ });
1102
+ }
1103
+ }
1104
+ return escalations;
1105
+ }
1106
+ function isReportingPeriodShape(value) {
1107
+ if (typeof value !== "object" || value === null) return false;
1108
+ const period = value;
1109
+ return typeof period.start === "string" && typeof period.end === "string";
1110
+ }
597
1111
  function expectedPeriodMatches(expected, obligation, ledger) {
1112
+ if (!isReportingPeriodShape(obligation.period)) return false;
598
1113
  if (obligation.delivery_config_id !== expected.deliveryConfigId || obligation.delivery_config_version !== expected.deliveryConfigVersion || obligation.report_definition_id !== expected.reportDefinitionId || obligation.feed_purpose !== expected.feedPurpose || obligation.reporting_profile !== expected.reportingProfile || !Array.isArray(obligation.media_buy_ids) || !same([...obligation.media_buy_ids].sort(), [...expected.mediaBuyIds].sort()) || obligation.destination_ref !== expected.destinationRef || obligation.required_finality !== expected.requiredFinality || obligation.reconciliation_mode !== expected.reconciliationMode || expected.coverageRequirement === "full" && obligation.coverage?.status !== "full" || obligation.period.start !== expected.periodStart || obligation.period.end !== expected.periodEnd || !isReportingCoverageEvidence(obligation.coverage) || !coverageMatchesExpected(obligation.coverage, expected.coverage)) {
599
1114
  return false;
600
1115
  }
@@ -623,8 +1138,8 @@ function expectedIdentityKey(value) {
623
1138
  value.feed_purpose,
624
1139
  value.reporting_profile,
625
1140
  value.destination_ref,
626
- value.period.start,
627
- value.period.end
1141
+ value.period?.start,
1142
+ value.period?.end
628
1143
  ]);
629
1144
  }
630
1145
  function buildExpectedIdentityIndex(obligations, expectedPeriods) {
@@ -640,7 +1155,7 @@ function buildExpectedIdentityIndex(obligations, expectedPeriods) {
640
1155
  }
641
1156
  return { expectedByIdentity, obligationCounts };
642
1157
  }
643
- function evaluateReportingLedger(ledger, expectedPeriods, now = /* @__PURE__ */ new Date()) {
1158
+ function evaluateReportingLedger(ledger, expectedPeriods, now = /* @__PURE__ */ new Date(), operationsContact) {
644
1159
  assertDirectReportingLedgerGraph(ledger);
645
1160
  const obligationResults = [];
646
1161
  const uniqueRevisions = /* @__PURE__ */ new Map();
@@ -656,7 +1171,10 @@ function evaluateReportingLedger(ledger, expectedPeriods, now = /* @__PURE__ */
656
1171
  const selected = selectCurrent(obligation, ledger, expected);
657
1172
  const reasons = [...selected.reasons];
658
1173
  if (matchingExpected.length > 0 && !bijective) reasons.push("EXPECTED_PERIOD_NOT_BIJECTIVE");
659
- if (obligation.health !== "complete") reasons.push(`OBLIGATION_${obligation.health.toUpperCase()}`);
1174
+ if (obligation.health !== "complete") {
1175
+ const health = typeof obligation.health === "string" ? boundedDiagnostic(obligation.health) : "UNKNOWN";
1176
+ reasons.push(`OBLIGATION_${health.toUpperCase()}`);
1177
+ }
660
1178
  if (selected.materialization?.resource && new Date(selected.materialization.resource.expires_at) <= now)
661
1179
  reasons.push("RESOURCE_EXPIRED");
662
1180
  if (!obligation.resource_retained_until || selected.materialization?.resource && Date.parse(selected.materialization.resource.expires_at) < Date.parse(obligation.resource_retained_until)) {
@@ -680,12 +1198,18 @@ function evaluateReportingLedger(ledger, expectedPeriods, now = /* @__PURE__ */
680
1198
  const missingExpectedPeriods = (expectedPeriods ?? []).filter(
681
1199
  (expected) => !ledger.obligations.some((obligation) => expectedPeriodMatches(expected, obligation, ledger))
682
1200
  );
1201
+ const consumerStatuses = planReportingConsumerStatuses(ledger, expectedPeriods ?? [], missingExpectedPeriods, now);
1202
+ const escalations = collectReportingEscalations(ledger, { ...operationsContact ? { operationsContact } : {} });
683
1203
  const scopeDefinitive = ledger.scope.scope_closed && ledger.scope.coverage_complete;
684
1204
  return {
685
1205
  definitive: expectedPeriods !== void 0 && scopeDefinitive && missingExpectedPeriods.length === 0 && obligationResults.every((item) => item.definitive),
686
1206
  ledger,
687
1207
  obligations: obligationResults,
688
1208
  missingExpectedPeriods,
1209
+ consumerStatuses,
1210
+ postedConsumerStatuses: [],
1211
+ failedConsumerStatuses: [],
1212
+ escalations,
689
1213
  totalsByRevision: [...uniqueRevisions.values()].map((item) => ({
690
1214
  reportingRevisionId: item.reporting_revision_id,
691
1215
  rowCount: item.row_count,
@@ -896,11 +1420,531 @@ async function reconcileReporting(options) {
896
1420
  options.ledgerLimits
897
1421
  );
898
1422
  }
1423
+ const now = options.now ?? /* @__PURE__ */ new Date();
1424
+ const evaluated = evaluateReportingLedger(ledger, options.expectedPeriods, now, options.operationsContact);
1425
+ const readDeadline = Date.now() + (options.ledgerLimits?.maxLoadMs ?? 6e4);
1426
+ const attested = [];
1427
+ let budgetExhausted = false;
1428
+ for (const plan of evaluated.consumerStatuses) {
1429
+ if (!plan.overdue) {
1430
+ attested.push(plan);
1431
+ continue;
1432
+ }
1433
+ if (plan.suppressed !== void 0) {
1434
+ attested.push(plan);
1435
+ continue;
1436
+ }
1437
+ if (budgetExhausted || plan.requiresConsumption && Date.now() >= readDeadline) {
1438
+ attested.push(
1439
+ plan.requiresConsumption ? {
1440
+ ...plan,
1441
+ suppressed: "local_budget_exhausted",
1442
+ reason: suppressionReason("local_budget_exhausted", plan.reason)
1443
+ } : plan
1444
+ );
1445
+ continue;
1446
+ }
1447
+ const next = await attestConsumerStatusPlan(plan, ledger, options, readDeadline, now);
1448
+ if (next.suppressed === "local_budget_exhausted" && next.budgetScope === "run") budgetExhausted = true;
1449
+ const { budgetScope: _scope, ...carried } = next;
1450
+ attested.push(carried);
1451
+ }
1452
+ const consumerStatuses = attested;
1453
+ const postedConsumerStatuses = [];
1454
+ const failedConsumerStatuses = [];
1455
+ const confirmed = [];
1456
+ if (!options.client.syncReportingStatus) {
1457
+ for (const [index, plan] of consumerStatuses.entries()) {
1458
+ if (!plan.overdue || plan.suppressed !== void 0) continue;
1459
+ consumerStatuses[index] = {
1460
+ ...plan,
1461
+ suppressed: "posting_unavailable",
1462
+ reason: suppressionReason("posting_unavailable", plan.reason)
1463
+ };
1464
+ }
1465
+ }
1466
+ const owed = [];
1467
+ const claimedChains = /* @__PURE__ */ new Set();
1468
+ for (const plan of consumerStatuses) {
1469
+ if (!plan.overdue || plan.suppressed !== void 0) continue;
1470
+ const chain = canonical(pendingConsumerStatusKey(ledger.accountId, plan));
1471
+ if (claimedChains.has(chain)) {
1472
+ failedConsumerStatuses.push({
1473
+ plan,
1474
+ errors: [
1475
+ {
1476
+ code: "DUPLICATE_STATUS_CHAIN",
1477
+ message: "two expected periods resolve to one consumer-status chain; a batch may carry at most one statement per chain"
1478
+ }
1479
+ ]
1480
+ });
1481
+ continue;
1482
+ }
1483
+ claimedChains.add(chain);
1484
+ owed.push(plan);
1485
+ }
1486
+ if (owed.length > 0 && options.client.syncReportingStatus) {
1487
+ for (let offset = 0; offset < owed.length; offset += CONSUMER_STATUS_BATCH_MAX) {
1488
+ const batch = owed.slice(offset, offset + CONSUMER_STATUS_BATCH_MAX);
1489
+ const deadline = Date.now() + (options.ledgerLimits?.maxLoadMs ?? 6e4);
1490
+ const wireStatuses = [];
1491
+ const posted = [];
1492
+ for (const plan of batch) {
1493
+ const key = pendingConsumerStatusKey(ledger.accountId, plan);
1494
+ const fingerprint = consumerStatusClaimFingerprint(plan);
1495
+ const pending = await options.pendingConsumerStatusStore?.get(key);
1496
+ if (pending && pending.claimFingerprint === fingerprint && replayMatchesPlan(pending.statement, plan, now)) {
1497
+ wireStatuses.push(pending.statement);
1498
+ posted.push({
1499
+ ...plan,
1500
+ statusAsOf: String(pending.statement.status_as_of),
1501
+ ...typeof pending.statement.observed_revision_content_sha256 === "string" ? { observedRevisionContentSha256: pending.statement.observed_revision_content_sha256 } : {}
1502
+ });
1503
+ continue;
1504
+ }
1505
+ const statement = wireConsumerStatus(plan);
1506
+ await options.pendingConsumerStatusStore?.put(key, { statement, claimFingerprint: fingerprint });
1507
+ wireStatuses.push(statement);
1508
+ posted.push(plan);
1509
+ }
1510
+ let response;
1511
+ try {
1512
+ response = await callBeforeDeadline(
1513
+ (signal) => options.client.syncReportingStatus(
1514
+ {
1515
+ ...options.request.account ? { account: options.request.account } : {},
1516
+ idempotency_key: consumerStatusBatchKey(wireStatuses),
1517
+ statuses: wireStatuses
1518
+ },
1519
+ { signal }
1520
+ ),
1521
+ deadline,
1522
+ "CONSUMER_STATUS_WRITE_FAILED",
1523
+ "sync_reporting_status exceeded the reporting request deadline"
1524
+ );
1525
+ } catch (error) {
1526
+ recordConsumerStatusBatchFailure(
1527
+ failedConsumerStatuses,
1528
+ posted.length === batch.length ? posted : batch,
1529
+ boundedDiagnostic(error instanceof Error ? error.message : "sync_reporting_status failed")
1530
+ );
1531
+ break;
1532
+ }
1533
+ const results = Array.isArray(response.results) ? response.results : [];
1534
+ if (response.status !== "completed" || results.length !== batch.length) {
1535
+ recordConsumerStatusBatchFailure(
1536
+ failedConsumerStatuses,
1537
+ batch,
1538
+ "seller did not return one result per submitted consumer status"
1539
+ );
1540
+ break;
1541
+ }
1542
+ posted.forEach((plan, index) => {
1543
+ const result = results[index];
1544
+ if (result && ["recorded", "unchanged"].includes(result.result ?? "")) {
1545
+ postedConsumerStatuses.push(plan);
1546
+ confirmed.push(pendingConsumerStatusKey(ledger.accountId, plan));
1547
+ return;
1548
+ }
1549
+ failedConsumerStatuses.push({
1550
+ plan,
1551
+ ...typeof result?.reporting_status_id === "string" ? { reportingStatusId: result.reporting_status_id } : {},
1552
+ // Bounded: seller objects of arbitrary size and shape that land
1553
+ // wherever the adopter logs its reconciliation result.
1554
+ errors: Array.isArray(result?.errors) ? result.errors.slice(0, 16) : []
1555
+ });
1556
+ });
1557
+ }
1558
+ }
1559
+ for (const key of confirmed) await options.pendingConsumerStatusStore?.clear(key);
1560
+ const consumerStatusPending = await readReportingConsumerStatusPending(options);
1561
+ return {
1562
+ ...evaluated,
1563
+ consumerStatuses,
1564
+ submittedReceipts: newReceipts,
1565
+ postedConsumerStatuses,
1566
+ failedConsumerStatuses,
1567
+ ...consumerStatusPending !== void 0 ? { consumerStatusPending } : {}
1568
+ };
1569
+ }
1570
+ async function attestConsumerStatusPlan(plan, ledger, options, deadline, now) {
1571
+ if (!plan.requiresConsumption || !plan.reportingRevisionId) return plan;
1572
+ if (!options.client.getMediaBuyDelivery) {
1573
+ return {
1574
+ ...plan,
1575
+ suppressed: "consumption_unavailable",
1576
+ reason: suppressionReason("consumption_unavailable", plan.reason)
1577
+ };
1578
+ }
1579
+ const outcome = await consumeReportingRevision(options, plan.reportingRevisionId, deadline, now);
1580
+ const leaf = currentConsumerLeaf(ledger, plan, plan.supersedesReportingStatusId);
1581
+ if ("budgetExhausted" in outcome) {
1582
+ return {
1583
+ ...plan,
1584
+ suppressed: "local_budget_exhausted",
1585
+ reason: suppressionReason("local_budget_exhausted", plan.reason),
1586
+ budgetScope: outcome.budgetExhausted
1587
+ };
1588
+ }
1589
+ if ("failureCode" in outcome) {
1590
+ return withSuppression(
1591
+ {
1592
+ ...plan,
1593
+ consumerStatus: "unreadable",
1594
+ failureCode: outcome.failureCode,
1595
+ mismatchCode: void 0,
1596
+ observedRevisionContentSha256: void 0,
1597
+ requiresConsumption: false,
1598
+ statusAsOf: latestInstant([now.toISOString(), plan.statusAsOfFloor]) ?? plan.statusAsOfFloor,
1599
+ reason: outcome.detail
1600
+ },
1601
+ leaf
1602
+ );
1603
+ }
1604
+ const declared = ledger.revisions.find(
1605
+ (revision2) => revision2.reporting_revision_id === plan.reportingRevisionId
1606
+ )?.revision_content_sha256;
1607
+ if (declared !== void 0 && !sameSha256(outcome.digest, declared)) {
1608
+ return withSuppression(
1609
+ {
1610
+ ...plan,
1611
+ consumerStatus: "unreadable",
1612
+ failureCode: "integrity_mismatch",
1613
+ mismatchCode: void 0,
1614
+ observedRevisionContentSha256: void 0,
1615
+ requiresConsumption: false,
1616
+ statusAsOf: latestInstant([outcome.consumedAt, plan.statusAsOfFloor]) ?? plan.statusAsOfFloor,
1617
+ reason: "the consumed rows do not hash to the revision_content_sha256 the ledger declares"
1618
+ },
1619
+ leaf
1620
+ );
1621
+ }
1622
+ const expected = options.expectedPeriods.find(
1623
+ (candidate) => candidate.deliveryConfigId === plan.deliveryConfigId && candidate.deliveryConfigVersion === plan.deliveryConfigVersion && candidate.reportDefinitionId === plan.reportDefinitionId && candidate.periodStart === plan.period.start && candidate.periodEnd === plan.period.end
1624
+ );
1625
+ const obligation = ledger.obligations.find(
1626
+ (candidate) => candidate.reporting_obligation_id === plan.reportingObligationId
1627
+ );
1628
+ const revision = ledger.revisions.find((candidate) => candidate.reporting_revision_id === plan.reportingRevisionId);
1629
+ const mismatch = expected && obligation && revision ? (0, import_content_mismatch.detectReportingContentMismatch)(
1630
+ contractFactsFor(obligation, expected),
1631
+ revision,
1632
+ rowEvidenceFor(contractFactsFor(obligation, expected), revision, outcome.rows)
1633
+ ) : void 0;
1634
+ return withSuppression(
1635
+ {
1636
+ ...plan,
1637
+ consumerStatus: mismatch ? "content_mismatch" : "received",
1638
+ mismatchCode: mismatch?.mismatchCode,
1639
+ observedRevisionContentSha256: outcome.digest,
1640
+ requiresConsumption: false,
1641
+ // `status_as_of` is when the revision became consumable to *this*
1642
+ // consumer, floored by the superseded leaf so the chain never moves
1643
+ // backwards.
1644
+ statusAsOf: latestInstant([outcome.consumedAt, plan.statusAsOfFloor]) ?? plan.statusAsOfFloor,
1645
+ reason: mismatch?.detail ?? "the exact revision content was consumed and honors every frozen contract fact"
1646
+ },
1647
+ leaf
1648
+ );
1649
+ }
1650
+ function withSuppression(plan, leaf) {
1651
+ const suppressed = consumerStatusSuppression(plan, leaf);
1652
+ if (suppressed) return { ...plan, suppressed, reason: suppressionReason(suppressed, plan.reason) };
1653
+ const { suppressed: _cleared, ...unsuppressed } = plan;
1654
+ return unsuppressed;
1655
+ }
1656
+ async function consumeReportingRevision(options, reportingRevisionId, deadline, now) {
1657
+ const read = options.client.getMediaBuyDelivery;
1658
+ const maxPages = options.ledgerLimits?.maxPages ?? 1e3;
1659
+ const maxRows = options.ledgerLimits?.maxRevisionRows ?? 1e5;
1660
+ const rows = [];
1661
+ let bytes = 0;
1662
+ let totalCount;
1663
+ const seenCursors = /* @__PURE__ */ new Set();
1664
+ let binding;
1665
+ let cursor;
1666
+ let pages = 0;
1667
+ try {
1668
+ do {
1669
+ pages += 1;
1670
+ if (pages > maxPages) return { budgetExhausted: "revision" };
1671
+ const response = await callBeforeDeadline(
1672
+ (signal) => read(
1673
+ {
1674
+ ...options.request.account ? { account: options.request.account } : {},
1675
+ reporting_revision_id: reportingRevisionId,
1676
+ ...cursor ? { pagination: { cursor } } : {}
1677
+ },
1678
+ { signal }
1679
+ ),
1680
+ deadline,
1681
+ "CONSUMER_STATUS_READ_FAILED",
1682
+ "get_media_buy_delivery exceeded the reporting request deadline"
1683
+ );
1684
+ if (response.status !== void 0 && response.status !== "completed") {
1685
+ return { failureCode: "reader_incompatible", detail: "the exact-revision read did not complete" };
1686
+ }
1687
+ const page = response.reporting_revision_binding;
1688
+ if (!page || page.reporting_revision_id !== reportingRevisionId || typeof page.content_sha256 !== "string" || typeof page.row_count !== "number" || !Array.isArray(page.control_totals)) {
1689
+ return {
1690
+ failureCode: "reader_incompatible",
1691
+ detail: "the seller did not return a reporting_revision_binding for the exact revision requested"
1692
+ };
1693
+ }
1694
+ if (binding && !same(binding, page)) {
1695
+ return { failureCode: "integrity_mismatch", detail: "the revision binding changed between cursor pages" };
1696
+ }
1697
+ binding = page;
1698
+ if (typeof response.pagination?.total_count === "number") totalCount = response.pagination.total_count;
1699
+ for (const row of response.reporting_rows ?? []) {
1700
+ rows.push(row);
1701
+ const sized = approximateRowBytes(row);
1702
+ if (sized === TOO_DEEP_TO_SIZE) {
1703
+ return {
1704
+ failureCode: "reader_incompatible",
1705
+ detail: "a revision row nests deeper than this reader will walk"
1706
+ };
1707
+ }
1708
+ if (sized === void 0) {
1709
+ return { budgetExhausted: "revision" };
1710
+ }
1711
+ bytes += sized;
1712
+ if (rows.length > maxRows || bytes > MAX_CONSUMED_REVISION_BYTES) {
1713
+ return { budgetExhausted: "revision" };
1714
+ }
1715
+ }
1716
+ if (response.pagination?.has_more) {
1717
+ const next = response.pagination.cursor;
1718
+ if (!next || seenCursors.has(next)) {
1719
+ return { failureCode: "transport_failed", detail: "revision row pagination did not advance" };
1720
+ }
1721
+ seenCursors.add(next);
1722
+ cursor = next;
1723
+ } else {
1724
+ cursor = void 0;
1725
+ }
1726
+ } while (cursor);
1727
+ } catch (error) {
1728
+ if (error instanceof ReportingReconciliationError && error.code === "CONSUMER_STATUS_READ_FAILED") {
1729
+ return { budgetExhausted: "run" };
1730
+ }
1731
+ return { failureCode: "transport_failed", detail: "the exact-revision read failed before the rows were complete" };
1732
+ }
1733
+ const consumedAt = now.toISOString();
1734
+ if (!binding) {
1735
+ return { failureCode: "reader_incompatible", detail: "the exact-revision read returned no binding" };
1736
+ }
1737
+ if (totalCount !== void 0 && totalCount !== binding.row_count) {
1738
+ return {
1739
+ failureCode: "integrity_mismatch",
1740
+ detail: `the read declares ${totalCount} total rows and the binding declares ${binding.row_count}`
1741
+ };
1742
+ }
1743
+ if (rows.length !== binding.row_count) {
1744
+ return {
1745
+ failureCode: "integrity_mismatch",
1746
+ detail: `the revision declares ${binding.row_count} rows and the read returned ${rows.length}`
1747
+ };
1748
+ }
1749
+ let digest;
1750
+ try {
1751
+ digest = (0, import_crypto.createHash)("sha256").update(
1752
+ (0, import_jcs.canonicalize)({
1753
+ reporting_revision_id: reportingRevisionId,
1754
+ row_count: binding.row_count,
1755
+ control_totals: binding.control_totals,
1756
+ reporting_rows: rows
1757
+ }),
1758
+ "utf8"
1759
+ ).digest("hex");
1760
+ } catch (error) {
1761
+ if (error instanceof RangeError) return { budgetExhausted: "revision" };
1762
+ const detail = error instanceof Error ? boundedDiagnostic(error.message) : "";
1763
+ return {
1764
+ failureCode: "reader_incompatible",
1765
+ detail: detail ? `the revision rows could not be canonicalized: ${detail}` : "the revision rows could not be canonicalized"
1766
+ };
1767
+ }
1768
+ if (!sameSha256(digest, binding.content_sha256)) {
1769
+ return {
1770
+ failureCode: "integrity_mismatch",
1771
+ detail: "the recomputed revision binding digest does not match the content_sha256 the seller published"
1772
+ };
1773
+ }
1774
+ return { digest, consumedAt, rowCount: rows.length, rows };
1775
+ }
1776
+ const TOO_DEEP_TO_SIZE = -1;
1777
+ function approximateRowBytes(row) {
1778
+ let containers = MAX_ROW_ESTIMATE_CONTAINERS;
1779
+ const visit = (value, depth) => {
1780
+ if (typeof value === "string") return 16 + value.length * 2;
1781
+ if (value === null || typeof value !== "object") return 8;
1782
+ if (depth >= MAX_ROW_ESTIMATE_DEPTH) return TOO_DEEP_TO_SIZE;
1783
+ containers -= 1;
1784
+ if (containers < 0) return void 0;
1785
+ if (Array.isArray(value)) {
1786
+ let total2 = 40 + 8 * value.length;
1787
+ for (const item of value) {
1788
+ const child = visit(item, depth + 1);
1789
+ if (child === void 0 || child === TOO_DEEP_TO_SIZE) return child;
1790
+ total2 += child;
1791
+ }
1792
+ return total2;
1793
+ }
1794
+ const entries = Object.entries(value);
1795
+ let total = 40 + 8 * entries.length;
1796
+ for (const [key, child] of entries) {
1797
+ const sized = visit(child, depth + 1);
1798
+ if (sized === void 0 || sized === TOO_DEEP_TO_SIZE) return sized;
1799
+ total += key.length * 2 + sized;
1800
+ }
1801
+ return total;
1802
+ };
1803
+ return visit(row, 0);
1804
+ }
1805
+ function rowEvidenceFor(facts, revision, rows) {
1806
+ if (!facts.committedMetrics) return {};
1807
+ const observed = new Set((revision.control_totals ?? []).map((total) => total.name));
1808
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
1809
+ for (const row of rows) {
1810
+ const fields = record(row);
1811
+ if (!fields) continue;
1812
+ for (const key of Object.keys(fields)) observed.add(key);
1813
+ const totals = record(fields.totals);
1814
+ if (totals) for (const key of Object.keys(totals)) observed.add(key);
1815
+ }
1816
+ return { observedMetricNames: [...observed] };
1817
+ }
1818
+ const REPLAYABLE_STATEMENT_KEYS = /* @__PURE__ */ new Set([
1819
+ "reporting_status_id",
1820
+ "supersedes_reporting_status_id",
1821
+ "delivery_config_id",
1822
+ "delivery_config_version",
1823
+ "report_definition_id",
1824
+ "period",
1825
+ "consumer_status",
1826
+ "status_as_of",
1827
+ "reporting_obligation_id",
1828
+ "reporting_revision_id",
1829
+ "observed_revision_content_sha256",
1830
+ "mismatch_code",
1831
+ "failure_code"
1832
+ ]);
1833
+ function replayMatchesPlan(statement, plan, now) {
1834
+ const period = statement.period;
1835
+ if (typeof statement.status_as_of !== "string") return false;
1836
+ if (usableLeafInstant({ status_as_of: statement.status_as_of }, now) === void 0) {
1837
+ return false;
1838
+ }
1839
+ if (Object.keys(statement).some((key) => !REPLAYABLE_STATEMENT_KEYS.has(key))) return false;
1840
+ if (!sameOptionalSha256(
1841
+ statement.observed_revision_content_sha256,
1842
+ plan.observedRevisionContentSha256
1843
+ )) {
1844
+ return false;
1845
+ }
1846
+ if (statement.reporting_status_id !== consumerStatusId({ ...plan, statusAsOf: statement.status_as_of })) {
1847
+ return false;
1848
+ }
1849
+ return statement.delivery_config_id === plan.deliveryConfigId && statement.delivery_config_version === plan.deliveryConfigVersion && statement.report_definition_id === plan.reportDefinitionId && period?.start === plan.period.start && period?.end === plan.period.end && period?.source_timezone === plan.period.source_timezone && statement.consumer_status === plan.consumerStatus && (statement.reporting_revision_id ?? void 0) === plan.reportingRevisionId && (statement.mismatch_code ?? void 0) === plan.mismatchCode && (statement.failure_code ?? void 0) === plan.failureCode && (statement.supersedes_reporting_status_id ?? void 0) === plan.supersedesReportingStatusId && typeof statement.reporting_status_id === "string" && typeof statement.status_as_of === "string";
1850
+ }
1851
+ function recordConsumerStatusBatchFailure(failed, batch, message) {
1852
+ for (const plan of batch) {
1853
+ failed.push({ plan, errors: [{ code: "CONSUMER_STATUS_WRITE_FAILED", message }] });
1854
+ }
1855
+ }
1856
+ function consumerStatusId(plan) {
1857
+ return `adcp-sdk.${(0, import_crypto.createHash)("sha256").update((0, import_jcs.canonicalize)([...consumerStatusClaim(plan), plan.statusAsOf ?? null])).digest("hex").slice(0, 32)}`;
1858
+ }
1859
+ function consumerStatusClaim(plan) {
1860
+ return [
1861
+ plan.deliveryConfigId,
1862
+ plan.deliveryConfigVersion,
1863
+ plan.reportDefinitionId,
1864
+ plan.period,
1865
+ plan.consumerStatus,
1866
+ plan.mismatchCode ?? null,
1867
+ plan.failureCode ?? null,
1868
+ plan.reportingRevisionId ?? null,
1869
+ plan.observedRevisionContentSha256 ?? null,
1870
+ plan.supersedesReportingStatusId ?? null
1871
+ ];
1872
+ }
1873
+ function consumerStatusClaimFingerprint(plan) {
1874
+ return (0, import_crypto.createHash)("sha256").update((0, import_jcs.canonicalize)(consumerStatusClaim(plan))).digest("hex");
1875
+ }
1876
+ function pendingConsumerStatusKey(accountId, plan) {
899
1877
  return {
900
- ...evaluateReportingLedger(ledger, options.expectedPeriods, options.now),
901
- submittedReceipts: newReceipts
1878
+ accountId,
1879
+ deliveryConfigId: plan.deliveryConfigId,
1880
+ deliveryConfigVersion: plan.deliveryConfigVersion,
1881
+ reportDefinitionId: plan.reportDefinitionId,
1882
+ periodStart: plan.period.start,
1883
+ periodEnd: plan.period.end
902
1884
  };
903
1885
  }
1886
+ function consumerStatusBatchKey(statuses) {
1887
+ return `adcp-sdk-batch.${(0, import_crypto.createHash)("sha256").update((0, import_jcs.canonicalize)(statuses)).digest("hex").slice(0, 32)}`;
1888
+ }
1889
+ function wireConsumerStatus(plan) {
1890
+ if (!plan.statusAsOf) {
1891
+ throw new ReportingReconciliationError(
1892
+ "CONSUMER_STATUS_UNATTESTED",
1893
+ "cannot post a consumer status before its status_as_of is established"
1894
+ );
1895
+ }
1896
+ if ((plan.consumerStatus === "received" || plan.consumerStatus === "content_mismatch") && !plan.observedRevisionContentSha256) {
1897
+ throw new ReportingReconciliationError(
1898
+ "CONSUMER_STATUS_UNATTESTED",
1899
+ "received and content_mismatch require a locally recomputed revision binding digest"
1900
+ );
1901
+ }
1902
+ return {
1903
+ reporting_status_id: consumerStatusId(plan),
1904
+ ...plan.supersedesReportingStatusId ? { supersedes_reporting_status_id: plan.supersedesReportingStatusId } : {},
1905
+ delivery_config_id: plan.deliveryConfigId,
1906
+ delivery_config_version: plan.deliveryConfigVersion,
1907
+ report_definition_id: plan.reportDefinitionId,
1908
+ period: plan.period,
1909
+ consumer_status: plan.consumerStatus,
1910
+ // The buyer's own instant, and part of the ID derivation above so the two
1911
+ // can never disagree. For `received` the spec wants when the revision
1912
+ // became consumable to this consumer, which genuinely moves between
1913
+ // re-plans; `pendingConsumerStatusStore` is what makes a retry reuse it.
1914
+ status_as_of: plan.statusAsOf,
1915
+ ...plan.reportingObligationId ? { reporting_obligation_id: plan.reportingObligationId } : {},
1916
+ ...plan.reportingRevisionId ? { reporting_revision_id: plan.reportingRevisionId } : {},
1917
+ ...plan.observedRevisionContentSha256 ? { observed_revision_content_sha256: plan.observedRevisionContentSha256 } : {},
1918
+ ...plan.mismatchCode ? { mismatch_code: plan.mismatchCode } : {},
1919
+ ...plan.failureCode ? { failure_code: plan.failureCode } : {}
1920
+ };
1921
+ }
1922
+ async function readReportingConsumerStatusPending(options) {
1923
+ if (!options.client.syncReportingStatus) return void 0;
1924
+ const {
1925
+ health: _health,
1926
+ changes_after: _changesAfter,
1927
+ pagination: _pagination,
1928
+ reporting_revision_id: _revisionId,
1929
+ ...summaryRequest
1930
+ } = options.request;
1931
+ try {
1932
+ const summary = await callBeforeDeadline(
1933
+ (signal) => options.client.getReportingStatus(
1934
+ { ...summaryRequest, view: "summary" },
1935
+ { signal }
1936
+ ),
1937
+ Date.now() + (options.ledgerLimits?.maxLoadMs ?? 6e4),
1938
+ "CONSUMER_STATUS_PENDING_READ_FAILED",
1939
+ "summary get_reporting_status exceeded the reporting request deadline"
1940
+ );
1941
+ const counts = summary.obligation_counts;
1942
+ const pending = counts?.consumer_status_pending;
1943
+ return typeof pending === "number" && Number.isInteger(pending) && pending >= 0 ? pending : void 0;
1944
+ } catch {
1945
+ return void 0;
1946
+ }
1947
+ }
904
1948
  // Annotate the CommonJS export names for ESM import in node:
905
1949
  0 && (module.exports = {
906
1950
  ReportingReconciliationError,