@adcp/sdk 14.0.0-beta.14 → 14.0.0-beta.15

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 (127) hide show
  1. package/dist/lib/auth/oauth/authorization-required.d.mts +25 -11
  2. package/dist/lib/auth/oauth/authorization-required.d.ts +25 -11
  3. package/dist/lib/auth/oauth/authorization-required.js +18 -4
  4. package/dist/lib/auth/oauth/authorization-required.mjs +17 -4
  5. package/dist/lib/auth/oauth/index.d.mts +1 -1
  6. package/dist/lib/auth/oauth/index.d.ts +1 -1
  7. package/dist/lib/auth/oauth/index.js +2 -0
  8. package/dist/lib/auth/oauth/index.mjs +2 -0
  9. package/dist/lib/auth/oauth/resource-url.d.mts +8 -0
  10. package/dist/lib/auth/oauth/resource-url.d.ts +8 -0
  11. package/dist/lib/auth/oauth/resource-url.js +42 -0
  12. package/dist/lib/auth/oauth/resource-url.mjs +40 -0
  13. package/dist/lib/core/ConversationTypes.d.mts +10 -0
  14. package/dist/lib/core/ConversationTypes.d.ts +10 -0
  15. package/dist/lib/core/SingleAgentClient.d.mts +5 -2
  16. package/dist/lib/core/SingleAgentClient.d.ts +5 -2
  17. package/dist/lib/core/SingleAgentClient.js +133 -28
  18. package/dist/lib/core/SingleAgentClient.mjs +138 -29
  19. package/dist/lib/core/TaskExecutor.d.mts +1 -0
  20. package/dist/lib/core/TaskExecutor.d.ts +1 -0
  21. package/dist/lib/core/TaskExecutor.js +7 -1
  22. package/dist/lib/core/TaskExecutor.mjs +7 -1
  23. package/dist/lib/core/webhook-registration.d.mts +8 -1
  24. package/dist/lib/core/webhook-registration.d.ts +8 -1
  25. package/dist/lib/core/webhook-registration.js +65 -5
  26. package/dist/lib/core/webhook-registration.mjs +61 -4
  27. package/dist/lib/errors/index.d.mts +9 -0
  28. package/dist/lib/errors/index.d.ts +9 -0
  29. package/dist/lib/errors/index.js +33 -0
  30. package/dist/lib/errors/index.mjs +32 -0
  31. package/dist/lib/index.d.mts +3 -2
  32. package/dist/lib/index.d.ts +3 -2
  33. package/dist/lib/index.js +4 -0
  34. package/dist/lib/index.mjs +4 -0
  35. package/dist/lib/media-buy/compatibility.js +14 -2
  36. package/dist/lib/media-buy/compatibility.mjs +14 -2
  37. package/dist/lib/protocols/index.js +23 -7
  38. package/dist/lib/protocols/index.mjs +24 -8
  39. package/dist/lib/protocols/mcp.js +8 -6
  40. package/dist/lib/protocols/mcp.mjs +9 -7
  41. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  42. package/dist/lib/server/decisioning/async-outcome.d.mts +11 -0
  43. package/dist/lib/server/decisioning/async-outcome.d.ts +11 -0
  44. package/dist/lib/server/decisioning/context.d.mts +11 -1
  45. package/dist/lib/server/decisioning/context.d.ts +11 -1
  46. package/dist/lib/server/decisioning/index.d.mts +3 -2
  47. package/dist/lib/server/decisioning/index.d.ts +3 -2
  48. package/dist/lib/server/decisioning/index.js +9 -0
  49. package/dist/lib/server/decisioning/index.mjs +10 -0
  50. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -2
  51. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -2
  52. package/dist/lib/server/decisioning/runtime/from-platform.js +40 -8
  53. package/dist/lib/server/decisioning/runtime/from-platform.mjs +40 -8
  54. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +8 -1
  55. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +8 -1
  56. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +10 -1
  57. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +9 -1
  58. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +79 -0
  59. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +79 -0
  60. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +391 -0
  61. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +369 -0
  62. package/dist/lib/server/decisioning/runtime/task-registry.d.mts +2 -0
  63. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +2 -0
  64. package/dist/lib/server/decisioning/runtime/task-registry.js +2 -1
  65. package/dist/lib/server/decisioning/runtime/task-registry.mjs +2 -1
  66. package/dist/lib/server/decisioning/runtime/to-context.js +15 -11
  67. package/dist/lib/server/decisioning/runtime/to-context.mjs +15 -11
  68. package/dist/lib/server/index.d.mts +2 -2
  69. package/dist/lib/server/index.d.ts +2 -2
  70. package/dist/lib/server/index.js +4 -0
  71. package/dist/lib/server/index.mjs +4 -0
  72. package/dist/lib/server/webhook-delivery/index.d.mts +2 -2
  73. package/dist/lib/server/webhook-delivery/index.d.ts +2 -2
  74. package/dist/lib/server/webhook-delivery/index.js +4 -0
  75. package/dist/lib/server/webhook-delivery/index.mjs +5 -1
  76. package/dist/lib/server/webhook-delivery/pg.d.mts +3 -1
  77. package/dist/lib/server/webhook-delivery/pg.d.ts +3 -1
  78. package/dist/lib/server/webhook-delivery/pg.js +25 -2
  79. package/dist/lib/server/webhook-delivery/pg.mjs +25 -2
  80. package/dist/lib/server/webhook-delivery/recovery.d.mts +44 -0
  81. package/dist/lib/server/webhook-delivery/recovery.d.ts +44 -0
  82. package/dist/lib/server/webhook-delivery/recovery.js +146 -43
  83. package/dist/lib/server/webhook-delivery/recovery.mjs +144 -43
  84. package/dist/lib/signing/agent-resolver/index.d.mts +1 -1
  85. package/dist/lib/signing/agent-resolver/index.d.ts +1 -1
  86. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +9 -0
  87. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +9 -0
  88. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +4 -1
  89. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +4 -1
  90. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +17 -4
  91. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +17 -4
  92. package/dist/lib/signing/jwks.d.mts +7 -0
  93. package/dist/lib/signing/jwks.d.ts +7 -0
  94. package/dist/lib/signing/server.d.mts +2 -2
  95. package/dist/lib/signing/server.d.ts +2 -2
  96. package/dist/lib/signing/webhook-verifier.d.mts +6 -0
  97. package/dist/lib/signing/webhook-verifier.d.ts +6 -0
  98. package/dist/lib/signing/webhook-verifier.js +38 -4
  99. package/dist/lib/signing/webhook-verifier.mjs +38 -4
  100. package/dist/lib/testing/client.d.mts +1 -0
  101. package/dist/lib/testing/client.d.ts +1 -0
  102. package/dist/lib/testing/client.js +6 -2
  103. package/dist/lib/testing/client.mjs +6 -2
  104. package/dist/lib/testing/compliance/comply.d.mts +2 -2
  105. package/dist/lib/testing/compliance/comply.d.ts +2 -2
  106. package/dist/lib/testing/compliance/comply.js +41 -31
  107. package/dist/lib/testing/compliance/comply.mjs +44 -21
  108. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.mts +1 -7
  109. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.ts +1 -7
  110. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.js +6 -42
  111. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.mjs +10 -40
  112. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  113. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  114. package/dist/lib/utils/adcp-version-config.d.mts +2 -0
  115. package/dist/lib/utils/adcp-version-config.d.ts +2 -0
  116. package/dist/lib/utils/adcp-version-config.js +5 -0
  117. package/dist/lib/utils/adcp-version-config.mjs +4 -0
  118. package/dist/lib/version.d.mts +3 -3
  119. package/dist/lib/version.d.ts +3 -3
  120. package/dist/lib/version.js +3 -3
  121. package/dist/lib/version.mjs +3 -3
  122. package/docs/llms.txt +3 -1
  123. package/docs/migration-12-to-14.md +6 -5
  124. package/docs/migration-13-to-14.md +48 -7
  125. package/docs/migration-task-registry-scoping.md +164 -11
  126. package/package.json +1 -1
  127. package/skills/build-decisioning-platform/advanced/REFERENCE.md +1 -1
@@ -0,0 +1,369 @@
1
+ import { createHash } from "node:crypto";
2
+ import { canonicalJsonSha256 } from "../../../utils/jcs.mjs";
3
+ import { isAdcpVersionAtLeast, isValidAdcpVersion } from "../../../utils/adcp-version-config.mjs";
4
+ import { sanitizeStructuredAdcpError } from "../../errors.mjs";
5
+ import { quoteWebhookTable } from "../../webhook-delivery/common.mjs";
6
+ import {
7
+ createWebhookDeliveryRecovery,
8
+ WebhookAuthenticationProtectionError
9
+ } from "../../webhook-delivery/recovery.mjs";
10
+ import { pgWebhookDeliveryRecoveryBackend } from "../../webhook-delivery/pg.mjs";
11
+ import { protocolForTool, SPEC_WEBHOOK_TASK_TYPES } from "./protocol-for-tool.mjs";
12
+ import {
13
+ _postgresTaskRegistryBinding
14
+ } from "./postgres-task-registry.mjs";
15
+ import { sanitizeTaskResultForWire } from "./task-registry.mjs";
16
+ class TaskPushSettlementConfigurationError extends Error {
17
+ name = "TaskPushSettlementConfigurationError";
18
+ }
19
+ const TERMINAL = /* @__PURE__ */ new Set(["completed", "failed", "rejected", "canceled"]);
20
+ const MAX_RESULT_BYTES = 4 * 1024 * 1024;
21
+ const TOKEN_CONTROL_CHAR_RE = /[\x00-\x1f\x7f]/;
22
+ function createPostgresTaskSettlementCoordinator(options) {
23
+ const binding = _postgresTaskRegistryBinding(options.registry);
24
+ if (!binding) {
25
+ throw new TypeError("createPostgresTaskSettlementCoordinator requires a registry from createPostgresTaskRegistry");
26
+ }
27
+ const pool = binding.pool;
28
+ if (typeof pool.connect !== "function") {
29
+ throw new TypeError(
30
+ "Crash-safe task settlement requires a pg Pool with connect(); a query-only adapter cannot own a transaction"
31
+ );
32
+ }
33
+ if (typeof options.registry.registryId !== "string" || options.registry.registryId.length === 0) {
34
+ throw new TypeError("Crash-safe task settlement requires task registry storageId/registryId binding");
35
+ }
36
+ if (typeof options.publisherScope !== "string" || options.publisherScope.length === 0) {
37
+ throw new TypeError("publisherScope must be a non-empty string");
38
+ }
39
+ const outboxOptions = options.outbox ?? {};
40
+ const outboxTable = quoteWebhookTable(outboxOptions.tableName ?? "adcp_webhook_outbox");
41
+ const claimScope = {
42
+ publisherScope: options.publisherScope,
43
+ tenantScope: stableRegistryScope(options.registry.registryId, binding.namespace)
44
+ };
45
+ const backend = pgWebhookDeliveryRecoveryBackend(binding.pool, { ...outboxOptions, claimScope });
46
+ const recovery = createWebhookDeliveryRecovery({
47
+ ...options.recovery,
48
+ backend,
49
+ ...options.authenticationAdapter && { authenticationAdapter: options.authenticationAdapter }
50
+ });
51
+ const retries = resolveRetries(options.retries);
52
+ return {
53
+ durability: "durable",
54
+ recovery,
55
+ async settle(ref, terminal, push) {
56
+ if (ref.registryId !== options.registry.registryId) {
57
+ return { outcome: "not_found_in_scope", delivery: "not_applicable" };
58
+ }
59
+ let client;
60
+ try {
61
+ client = await pool.connect();
62
+ await client.query("BEGIN");
63
+ const locked = await client.query(
64
+ `SELECT tool, status, result, error, has_webhook
65
+ FROM ${binding.tableName}
66
+ WHERE task_id = $1 AND registry_namespace = $2 AND account_id = $3 AND owner_scope = $4
67
+ FOR UPDATE`,
68
+ [ref.taskId, binding.namespace, ref.accountId, ref.ownerScope]
69
+ );
70
+ if (locked.rows.length === 0) {
71
+ await client.query("ROLLBACK");
72
+ return { outcome: "not_found_in_scope", delivery: "not_applicable" };
73
+ }
74
+ const row = locked.rows[0];
75
+ validatePush(push);
76
+ if (row.has_webhook !== true) {
77
+ throw new TaskPushSettlementConfigurationError(
78
+ "Crash-safe push settlement requires a task created with hasWebhook: true"
79
+ );
80
+ }
81
+ let result;
82
+ let error;
83
+ try {
84
+ result = terminal.status === "completed" ? sanitizeTaskResultForWire(structuredClone(terminal.result), ref) : terminal.result === void 0 ? { errors: [sanitizeStructuredAdcpError(terminal.error)] } : sanitizeTaskResultForWire(structuredClone(terminal.result), ref);
85
+ error = terminal.status === "failed" ? sanitizeStructuredAdcpError(terminal.error) : void 0;
86
+ canonicalJsonSha256({ result, error });
87
+ assertPayloadSize(result, error);
88
+ } catch (cause) {
89
+ if (cause instanceof TaskPushSettlementConfigurationError) throw cause;
90
+ throw new TaskPushSettlementConfigurationError("Task terminal result/error must be serializable JSON", {
91
+ cause
92
+ });
93
+ }
94
+ const compatible = terminalMatches(row, terminal.status, result, error);
95
+ if (TERMINAL.has(row.status) && !compatible) {
96
+ await client.query("COMMIT");
97
+ return {
98
+ outcome: "already_terminal",
99
+ status: row.status,
100
+ compatibility: "conflicting",
101
+ delivery: "not_applicable"
102
+ };
103
+ }
104
+ const deliveryKey = {
105
+ ...claimScope,
106
+ deliveryId: stableScope("task-webhook", ref)
107
+ };
108
+ const existing = await readOutbox(client, outboxTable, deliveryKey);
109
+ if (TERMINAL.has(row.status) && !existing) {
110
+ throw new TaskPushSettlementConfigurationError(
111
+ "Terminal task has no atomic webhook delivery checkpoint; refusing to create a duplicate notification"
112
+ );
113
+ }
114
+ let inserted = false;
115
+ let delivery = existing ? deliveryState(existing) : void 0;
116
+ if (!SPEC_WEBHOOK_TASK_TYPES.has(row.tool)) {
117
+ throw new TaskPushSettlementConfigurationError(
118
+ `Task type ${row.tool} cannot be emitted by the closed AdCP task-webhook schema`
119
+ );
120
+ }
121
+ const existingTimestamp = existing?.state === "pending" ? existing.snapshot.payload.timestamp : void 0;
122
+ const payload = {
123
+ idempotency_key: `pending.${deliveryKey.deliveryId.slice(-48)}`,
124
+ operation_id: resolveOperationId(push, row.tool, ref.taskId),
125
+ task_id: ref.taskId,
126
+ task_type: row.tool,
127
+ status: terminal.status,
128
+ timestamp: typeof existingTimestamp === "string" ? existingTimestamp : (/* @__PURE__ */ new Date()).toISOString(),
129
+ protocol: protocolForTool(row.tool),
130
+ result,
131
+ ...push.token !== void 0 && { token: push.token },
132
+ ...terminal.status === "failed" && { message: error.message }
133
+ };
134
+ let prepared;
135
+ try {
136
+ prepared = await recovery.prepare(
137
+ deliveryKey,
138
+ {
139
+ url: push.url,
140
+ payload,
141
+ authentication: push.authentication ?? null,
142
+ retries
143
+ },
144
+ { protectPayloadToken: push.token !== void 0 }
145
+ );
146
+ } catch (cause) {
147
+ if (cause instanceof WebhookAuthenticationProtectionError) throw cause;
148
+ throw new TaskPushSettlementConfigurationError("Terminal webhook delivery configuration is invalid", {
149
+ cause
150
+ });
151
+ }
152
+ const intentFingerprint = taskPushIntentFingerprint(prepared.snapshot);
153
+ if (existing?.state === "settled") {
154
+ if (!TERMINAL.has(row.status)) {
155
+ throw new Error("Settled webhook outbox row exists for a non-terminal task");
156
+ }
157
+ if (existing.intent_fingerprint && existing.intent_fingerprint !== intentFingerprint) {
158
+ throw new TaskPushSettlementConfigurationError(
159
+ "Terminal webhook delivery identity is already bound to a conflicting route or payload"
160
+ );
161
+ }
162
+ await client.query("COMMIT");
163
+ return {
164
+ outcome: "already_terminal",
165
+ status: row.status,
166
+ compatibility: "compatible",
167
+ delivery: deliveryState(existing)
168
+ };
169
+ }
170
+ if (existing && existing.snapshot_fingerprint !== prepared.snapshotFingerprint) {
171
+ throw new TaskPushSettlementConfigurationError(
172
+ "Terminal webhook delivery identity is already bound to a conflicting route or payload"
173
+ );
174
+ }
175
+ if (!existing) {
176
+ const write = await client.query(
177
+ `INSERT INTO ${outboxTable} (
178
+ publisher_scope, tenant_scope, delivery_id, snapshot, snapshot_fingerprint,
179
+ storage_fingerprint, intent_fingerprint, state, attempt_count, next_attempt_at
180
+ ) VALUES ($1, $2, $3, $4::jsonb, $5, $6, $7, 'pending', 0, clock_timestamp())
181
+ ON CONFLICT (publisher_scope, tenant_scope, delivery_id) DO NOTHING`,
182
+ [
183
+ deliveryKey.publisherScope,
184
+ deliveryKey.tenantScope,
185
+ deliveryKey.deliveryId,
186
+ JSON.stringify(prepared.snapshot),
187
+ prepared.snapshotFingerprint,
188
+ prepared.storageFingerprint,
189
+ intentFingerprint
190
+ ]
191
+ );
192
+ if ((write.rowCount ?? 0) !== 1) {
193
+ const raced = await readOutbox(client, outboxTable, deliveryKey);
194
+ if (!raced || raced.snapshot_fingerprint !== prepared.snapshotFingerprint) {
195
+ throw new TaskPushSettlementConfigurationError(
196
+ "Terminal webhook delivery identity is already bound to a conflicting route or payload"
197
+ );
198
+ }
199
+ delivery = deliveryState(raced);
200
+ } else {
201
+ inserted = true;
202
+ delivery = "durably_bound";
203
+ }
204
+ }
205
+ if (!TERMINAL.has(row.status)) {
206
+ const update = terminal.status === "completed" ? await client.query(
207
+ `UPDATE ${binding.tableName}
208
+ SET status = 'completed', result = $5::jsonb, error = NULL,
209
+ status_message = NULL, updated_at = clock_timestamp()
210
+ WHERE task_id = $1 AND registry_namespace = $2 AND account_id = $3 AND owner_scope = $4`,
211
+ [ref.taskId, binding.namespace, ref.accountId, ref.ownerScope, JSON.stringify(result)]
212
+ ) : await client.query(
213
+ `UPDATE ${binding.tableName}
214
+ SET status = 'failed', result = $5::jsonb, error = $6::jsonb,
215
+ status_message = $7, updated_at = clock_timestamp()
216
+ WHERE task_id = $1 AND registry_namespace = $2 AND account_id = $3 AND owner_scope = $4`,
217
+ [
218
+ ref.taskId,
219
+ binding.namespace,
220
+ ref.accountId,
221
+ ref.ownerScope,
222
+ JSON.stringify(result),
223
+ JSON.stringify(error),
224
+ error.message
225
+ ]
226
+ );
227
+ if ((update.rowCount ?? 0) !== 1) throw new Error("Task disappeared while holding its settlement lock");
228
+ await client.query("COMMIT");
229
+ return { outcome: "applied", delivery: "durably_bound" };
230
+ }
231
+ await client.query("COMMIT");
232
+ return {
233
+ outcome: "already_terminal",
234
+ status: row.status,
235
+ compatibility: "compatible",
236
+ delivery: inserted ? "durably_bound" : delivery ?? "recoverable"
237
+ };
238
+ } catch (cause) {
239
+ if (client) await rollbackQuietly(client);
240
+ if (cause instanceof TaskPushSettlementConfigurationError) throw cause;
241
+ throw new Error("PostgresTaskSettlementCoordinator.settle: transaction failed", { cause });
242
+ } finally {
243
+ client?.release();
244
+ }
245
+ }
246
+ };
247
+ }
248
+ async function completeScopedPushTask(coordinator, ref, push, result) {
249
+ return coordinator.settle(ref, { status: "completed", result }, push);
250
+ }
251
+ async function failScopedPushTask(coordinator, ref, push, error, result) {
252
+ return coordinator.settle(ref, { status: "failed", error, ...result !== void 0 && { result } }, push);
253
+ }
254
+ function terminalMatches(row, status, result, error) {
255
+ if (row.status !== status) return false;
256
+ return canonicalJsonSha256(row.result) === canonicalJsonSha256(result) && (status === "completed" || canonicalJsonSha256(row.error) === canonicalJsonSha256(error));
257
+ }
258
+ function stableScope(prefix, ref) {
259
+ const digest = createHash("sha256").update(JSON.stringify([ref.registryId, ref.accountId, ref.ownerScope, ref.taskId])).digest("hex");
260
+ return `${prefix}:${digest}`;
261
+ }
262
+ function stableRegistryScope(registryId, namespace) {
263
+ const digest = createHash("sha256").update(JSON.stringify([registryId, namespace])).digest("hex");
264
+ return `task-registry:${digest}`;
265
+ }
266
+ function taskPushIntentFingerprint(snapshot) {
267
+ const { timestamp: _generatedTimestamp, ...payload } = snapshot.payload;
268
+ return canonicalJsonSha256({
269
+ url: snapshot.url,
270
+ payload,
271
+ retries: snapshot.retries,
272
+ authentication: snapshot.authentication.kind === "none" ? { kind: "none" } : { kind: "protected", fingerprint: snapshot.authentication.fingerprint },
273
+ ...snapshot.payloadToken && { payloadToken: { fingerprint: snapshot.payloadToken.fingerprint } }
274
+ });
275
+ }
276
+ function validatePush(push) {
277
+ if (!push || typeof push !== "object") {
278
+ throw new TaskPushSettlementConfigurationError("push settlement config is required");
279
+ }
280
+ const allowHttp = process.env.NODE_ENV === "test" || process.env.NODE_ENV === "development" || process.env.ADCP_DECISIONING_ALLOW_HTTP_WEBHOOKS === "1";
281
+ let parsedUrl;
282
+ try {
283
+ parsedUrl = typeof push.url === "string" ? new URL(push.url) : void 0;
284
+ } catch {
285
+ }
286
+ if (parsedUrl === void 0 || parsedUrl.hostname.length === 0 || parsedUrl.username.length > 0 || parsedUrl.password.length > 0 || parsedUrl.protocol !== "https:" && !(allowHttp && parsedUrl.protocol === "http:")) {
287
+ throw new TaskPushSettlementConfigurationError(
288
+ "push settlement url must be a request-validated HTTPS destination (HTTP requires the development allowlist)"
289
+ );
290
+ }
291
+ if (push.operationId !== void 0 && (typeof push.operationId !== "string" || !/^[A-Za-z0-9_.:-]{1,255}$/.test(push.operationId))) {
292
+ throw new TaskPushSettlementConfigurationError("push settlement operationId must match /^[A-Za-z0-9_.:-]{1,255}$/");
293
+ }
294
+ if (push.operationId === void 0 && (!isValidAdcpVersion(push.servedAdcpVersion) || isAdcpVersionAtLeast(push.servedAdcpVersion, "3.2.0-beta.5"))) {
295
+ throw new TaskPushSettlementConfigurationError(
296
+ "push settlement operationId is required unless servedAdcpVersion is an explicit valid pre-3.2.0-beta.5 version"
297
+ );
298
+ }
299
+ if (push.token !== void 0 && (typeof push.token !== "string" || push.token.length < 16 || push.token.length > 4096 || TOKEN_CONTROL_CHAR_RE.test(push.token))) {
300
+ throw new TaskPushSettlementConfigurationError(
301
+ "push settlement token must be a string from 16 through 4096 characters"
302
+ );
303
+ }
304
+ if (push.authentication !== void 0 && push.authentication !== null) {
305
+ const authentication = push.authentication;
306
+ const validBearer = authentication.type === "bearer" && typeof authentication.token === "string" && authentication.token.length >= 32;
307
+ const validHmac = authentication.type === "hmac_sha256" && typeof authentication.secret === "string" && authentication.secret.length >= 32;
308
+ if (!validBearer && !validHmac) {
309
+ throw new TaskPushSettlementConfigurationError(
310
+ "push settlement authentication must be a WebhookAuthentication value"
311
+ );
312
+ }
313
+ }
314
+ }
315
+ function resolveOperationId(push, tool, taskId) {
316
+ return push.operationId ?? `${tool}.${taskId}`;
317
+ }
318
+ function resolveRetries(retries) {
319
+ const resolved = {
320
+ maxAttempts: retries?.maxAttempts ?? 5,
321
+ initialDelayMs: retries?.initialDelayMs ?? 1e3,
322
+ maxDelayMs: retries?.maxDelayMs ?? 6e4,
323
+ jitter: retries?.jitter ?? 0.25
324
+ };
325
+ if (!Number.isSafeInteger(resolved.maxAttempts) || resolved.maxAttempts < 1) {
326
+ throw new TypeError("retries.maxAttempts must be an integer of at least 1");
327
+ }
328
+ for (const key of ["initialDelayMs", "maxDelayMs"]) {
329
+ if (!Number.isFinite(resolved[key]) || resolved[key] < 0) {
330
+ throw new TypeError(`retries.${key} must be a finite non-negative number`);
331
+ }
332
+ }
333
+ if (!Number.isFinite(resolved.jitter) || resolved.jitter < 0 || resolved.jitter > 1) {
334
+ throw new TypeError("retries.jitter must be a finite number from 0 through 1");
335
+ }
336
+ return resolved;
337
+ }
338
+ function assertPayloadSize(result, error) {
339
+ const bytes = Buffer.byteLength(JSON.stringify({ result, error }), "utf8");
340
+ if (bytes > MAX_RESULT_BYTES) {
341
+ throw new TaskPushSettlementConfigurationError(`Task result/error JSON exceeds ${MAX_RESULT_BYTES} bytes`);
342
+ }
343
+ }
344
+ async function readOutbox(client, table, key) {
345
+ const found = await client.query(
346
+ `SELECT snapshot, snapshot_fingerprint, intent_fingerprint, state, disposition
347
+ FROM ${table}
348
+ WHERE publisher_scope = $1 AND tenant_scope = $2 AND delivery_id = $3
349
+ FOR UPDATE`,
350
+ [key.publisherScope, key.tenantScope, key.deliveryId]
351
+ );
352
+ return found.rows[0];
353
+ }
354
+ function deliveryState(row) {
355
+ if (row.state !== "settled") return "recoverable";
356
+ return row.disposition === "delivered" ? "delivered" : "terminal";
357
+ }
358
+ async function rollbackQuietly(client) {
359
+ try {
360
+ await client.query("ROLLBACK");
361
+ } catch {
362
+ }
363
+ }
364
+ export {
365
+ TaskPushSettlementConfigurationError,
366
+ completeScopedPushTask,
367
+ createPostgresTaskSettlementCoordinator,
368
+ failScopedPushTask
369
+ };
@@ -114,6 +114,8 @@ export interface TaskRegistryListResult<TResult = unknown> {
114
114
  export interface TaskRegistry {
115
115
  /** Confirms that lifecycle methods use the account/principal-scoped v1 signatures. */
116
116
  readonly scopeVersion: 1;
117
+ /** Whether stored rows can be reopened by a different process after restart. */
118
+ readonly durability?: 'durable' | 'process-local';
117
119
  /**
118
120
  * Identity bound into every durable task reference issued by this registry.
119
121
  * It is stable for the lifetime of stored records and rotates when a
@@ -114,6 +114,8 @@ export interface TaskRegistryListResult<TResult = unknown> {
114
114
  export interface TaskRegistry {
115
115
  /** Confirms that lifecycle methods use the account/principal-scoped v1 signatures. */
116
116
  readonly scopeVersion: 1;
117
+ /** Whether stored rows can be reopened by a different process after restart. */
118
+ readonly durability?: 'durable' | 'process-local';
117
119
  /**
118
120
  * Identity bound into every durable task reference issued by this registry.
119
121
  * It is stable for the lifetime of stored records and rotates when a
@@ -107,6 +107,7 @@ function createInMemoryTaskRegistry() {
107
107
  let registryId = `memory:${(0, import_node_crypto.randomUUID)()}`;
108
108
  return {
109
109
  scopeVersion: 1,
110
+ durability: "process-local",
110
111
  get registryId() {
111
112
  return registryId;
112
113
  },
@@ -232,7 +233,7 @@ async function ensureWorkerSettlementIsSafe(registry, ref) {
232
233
  if (record == null) return { outcome: "not_found_in_scope" };
233
234
  if (record.hasWebhook) {
234
235
  throw new Error(
235
- "Direct scoped worker settlement is unavailable for tasks with push notifications because registry-only writes cannot durably deliver the terminal webhook. Return the result through the live handoff instead."
236
+ "Registry-only scoped settlement is unavailable for tasks with push notifications. Use createPostgresTaskSettlementCoordinator() with completeScopedPushTask()/failScopedPushTask() for crash-safe PostgreSQL settlement."
236
237
  );
237
238
  }
238
239
  return void 0;
@@ -77,6 +77,7 @@ function createInMemoryTaskRegistry() {
77
77
  let registryId = `memory:${randomUUID()}`;
78
78
  return {
79
79
  scopeVersion: 1,
80
+ durability: "process-local",
80
81
  get registryId() {
81
82
  return registryId;
82
83
  },
@@ -202,7 +203,7 @@ async function ensureWorkerSettlementIsSafe(registry, ref) {
202
203
  if (record == null) return { outcome: "not_found_in_scope" };
203
204
  if (record.hasWebhook) {
204
205
  throw new Error(
205
- "Direct scoped worker settlement is unavailable for tasks with push notifications because registry-only writes cannot durably deliver the terminal webhook. Return the result through the live handoff instead."
206
+ "Registry-only scoped settlement is unavailable for tasks with push notifications. Use createPostgresTaskSettlementCoordinator() with completeScopedPushTask()/failScopedPushTask() for crash-safe PostgreSQL settlement."
206
207
  );
207
208
  }
208
209
  return void 0;
@@ -61,6 +61,20 @@ function buildCtxMetadataAccessor(store, accountId) {
61
61
  }
62
62
  };
63
63
  }
64
+ function createContextTaskHandoff(fn, options) {
65
+ if (options?.task_id !== void 0) {
66
+ if (typeof options.task_id !== "string" || options.task_id.length === 0) {
67
+ throw new Error("handoffToTask options.task_id must be a non-empty string");
68
+ }
69
+ if (options.task_id.length > 128) {
70
+ throw new Error("handoffToTask options.task_id must be \u2264 128 characters");
71
+ }
72
+ }
73
+ if (options != null && "settlement" in options && options.settlement !== "external") {
74
+ throw new Error("handoffToTask options.settlement must be 'external'");
75
+ }
76
+ return (0, import_async_outcome._createTaskHandoff)(fn, options);
77
+ }
64
78
  function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
65
79
  const account = handlerCtx.account;
66
80
  const stubResolver = (name) => async () => {
@@ -91,17 +105,7 @@ function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
91
105
  creativeFormat: stubResolver("creativeFormat")
92
106
  },
93
107
  ctxMetadata,
94
- handoffToTask(fn, options) {
95
- if (options?.task_id !== void 0) {
96
- if (typeof options.task_id !== "string" || options.task_id.length === 0) {
97
- throw new Error("handoffToTask options.task_id must be a non-empty string");
98
- }
99
- if (options.task_id.length > 128) {
100
- throw new Error("handoffToTask options.task_id must be \u2264 128 characters");
101
- }
102
- }
103
- return (0, import_async_outcome._createTaskHandoff)(fn, options);
104
- }
108
+ handoffToTask: createContextTaskHandoff
105
109
  };
106
110
  }
107
111
  function buildHandoffContext(taskRegistry, taskRef) {
@@ -39,6 +39,20 @@ function buildCtxMetadataAccessor(store, accountId) {
39
39
  }
40
40
  };
41
41
  }
42
+ function createContextTaskHandoff(fn, options) {
43
+ if (options?.task_id !== void 0) {
44
+ if (typeof options.task_id !== "string" || options.task_id.length === 0) {
45
+ throw new Error("handoffToTask options.task_id must be a non-empty string");
46
+ }
47
+ if (options.task_id.length > 128) {
48
+ throw new Error("handoffToTask options.task_id must be \u2264 128 characters");
49
+ }
50
+ }
51
+ if (options != null && "settlement" in options && options.settlement !== "external") {
52
+ throw new Error("handoffToTask options.settlement must be 'external'");
53
+ }
54
+ return _createTaskHandoff(fn, options);
55
+ }
42
56
  function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
43
57
  const account = handlerCtx.account;
44
58
  const stubResolver = (name) => async () => {
@@ -69,17 +83,7 @@ function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
69
83
  creativeFormat: stubResolver("creativeFormat")
70
84
  },
71
85
  ctxMetadata,
72
- handoffToTask(fn, options) {
73
- if (options?.task_id !== void 0) {
74
- if (typeof options.task_id !== "string" || options.task_id.length === 0) {
75
- throw new Error("handoffToTask options.task_id must be a non-empty string");
76
- }
77
- if (options.task_id.length > 128) {
78
- throw new Error("handoffToTask options.task_id must be \u2264 128 characters");
79
- }
80
- }
81
- return _createTaskHandoff(fn, options);
82
- }
86
+ handoffToTask: createContextTaskHandoff
83
87
  };
84
88
  }
85
89
  function buildHandoffContext(taskRegistry, taskRef) {
@@ -65,8 +65,8 @@ export type { IdempotencyStore, IdempotencyStoreConfig, IdempotencyBackend, Idem
65
65
  export { createA2AAdapter, A2AInvocationError } from './a2a-adapter.mjs';
66
66
  export type { A2AAdapter, A2AAdapterOptions, A2AAgentCardOverrides, A2AAgentCapabilitiesOverride, A2AAgentSkillOverride, A2AMountOptions, ExpressAppLike, LegacyHttpSecurityScheme, LegacySecurityScheme, } from './a2a-adapter.mjs';
67
67
  export { createWebhookEmitter, memoryWebhookDeliveryStore, memoryWebhookKeyStore } from './webhook-emitter.mjs';
68
- export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend, getWebhookDeliveryMigration, getWebhookDeliveryRecoveryMigration, WEBHOOK_DELIVERY_MIGRATION, WEBHOOK_DELIVERY_RECOVERY_MIGRATION, createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError, } from './webhook-delivery/index.mjs';
69
- export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions, RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions, ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './webhook-delivery/index.mjs';
68
+ export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend, getWebhookDeliveryMigration, getWebhookDeliveryRecoveryMigration, WEBHOOK_DELIVERY_MIGRATION, WEBHOOK_DELIVERY_RECOVERY_MIGRATION, createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookAuthenticationProtectionError, WebhookAuthenticationResolutionError, WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError, } from './webhook-delivery/index.mjs';
69
+ export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions, RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions, ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, PreparedWebhookDeliverySnapshot, PrepareWebhookDeliveryOptions, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './webhook-delivery/index.mjs';
70
70
  export type { WebhookEmitter, RecoverableWebhookEmitter, WebhookEmitterOptions, WebhookEmitParams, WebhookEmitResult, WebhookRecoveredDelivery, WebhookEmitAttempt, WebhookEmitAttemptResult, WebhookDeliveryBinding, WebhookDeliveryRetired, WebhookDeliveryRecord, WebhookDeliveryKey, WebhookDeliveryProposal, WebhookDeliverySnapshot, WebhookDeliveryRecovery, WebhookDeliveryRecoveryClaim, WebhookDeliveryStore, WebhookIdempotencyKeyStore, WebhookRetryOptions, WebhookAuthentication, } from './webhook-emitter.mjs';
71
71
  export type { SigningProvider } from '../signing/provider.mjs';
72
72
  export { createPinAndBindFetch, WEBHOOK_SSRF_POLICY, LOOPBACK_OK_WEBHOOK_SSRF_POLICY } from './pin-and-bind-fetch.mjs';
@@ -65,8 +65,8 @@ export type { IdempotencyStore, IdempotencyStoreConfig, IdempotencyBackend, Idem
65
65
  export { createA2AAdapter, A2AInvocationError } from './a2a-adapter';
66
66
  export type { A2AAdapter, A2AAdapterOptions, A2AAgentCardOverrides, A2AAgentCapabilitiesOverride, A2AAgentSkillOverride, A2AMountOptions, ExpressAppLike, LegacyHttpSecurityScheme, LegacySecurityScheme, } from './a2a-adapter';
67
67
  export { createWebhookEmitter, memoryWebhookDeliveryStore, memoryWebhookKeyStore } from './webhook-emitter';
68
- export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend, getWebhookDeliveryMigration, getWebhookDeliveryRecoveryMigration, WEBHOOK_DELIVERY_MIGRATION, WEBHOOK_DELIVERY_RECOVERY_MIGRATION, createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError, } from './webhook-delivery';
69
- export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions, RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions, ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './webhook-delivery';
68
+ export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend, getWebhookDeliveryMigration, getWebhookDeliveryRecoveryMigration, WEBHOOK_DELIVERY_MIGRATION, WEBHOOK_DELIVERY_RECOVERY_MIGRATION, createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookAuthenticationProtectionError, WebhookAuthenticationResolutionError, WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError, } from './webhook-delivery';
69
+ export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions, RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions, ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, PreparedWebhookDeliverySnapshot, PrepareWebhookDeliveryOptions, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './webhook-delivery';
70
70
  export type { WebhookEmitter, RecoverableWebhookEmitter, WebhookEmitterOptions, WebhookEmitParams, WebhookEmitResult, WebhookRecoveredDelivery, WebhookEmitAttempt, WebhookEmitAttemptResult, WebhookDeliveryBinding, WebhookDeliveryRetired, WebhookDeliveryRecord, WebhookDeliveryKey, WebhookDeliveryProposal, WebhookDeliverySnapshot, WebhookDeliveryRecovery, WebhookDeliveryRecoveryClaim, WebhookDeliveryStore, WebhookIdempotencyKeyStore, WebhookRetryOptions, WebhookAuthentication, } from './webhook-emitter';
71
71
  export type { SigningProvider } from '../signing/provider';
72
72
  export { createPinAndBindFetch, WEBHOOK_SSRF_POLICY, LOOPBACK_OK_WEBHOOK_SSRF_POLICY } from './pin-and-bind-fetch';
@@ -77,6 +77,8 @@ __export(server_exports, {
77
77
  WEBHOOK_SSRF_POLICY: () => import_pin_and_bind_fetch.WEBHOOK_SSRF_POLICY,
78
78
  WIRE_SPEC_FIELDS: () => import_wire_safe.WIRE_SPEC_FIELDS,
79
79
  WebSocketTransport: () => import_socket_mode.WebSocketTransport,
80
+ WebhookAuthenticationProtectionError: () => import_webhook_delivery.WebhookAuthenticationProtectionError,
81
+ WebhookAuthenticationResolutionError: () => import_webhook_delivery.WebhookAuthenticationResolutionError,
80
82
  WebhookDeliveryTerminalError: () => import_webhook_delivery.WebhookDeliveryTerminalError,
81
83
  adcpError: () => import_errors.adcpError,
82
84
  anyOf: () => import_auth.anyOf,
@@ -373,6 +375,8 @@ var import_socket_mode = require('./socket-mode/index.js');
373
375
  WEBHOOK_SSRF_POLICY,
374
376
  WIRE_SPEC_FIELDS,
375
377
  WebSocketTransport,
378
+ WebhookAuthenticationProtectionError,
379
+ WebhookAuthenticationResolutionError,
376
380
  WebhookDeliveryTerminalError,
377
381
  adcpError,
378
382
  anyOf,
@@ -189,6 +189,8 @@ import {
189
189
  createWebhookDeliveryRecovery,
190
190
  pollWebhookDeliveryRecovery,
191
191
  memoryWebhookDeliveryRecoveryBackend,
192
+ WebhookAuthenticationProtectionError,
193
+ WebhookAuthenticationResolutionError,
192
194
  WebhookDeliveryTerminalError,
193
195
  isWebhookDeliveryTerminalError
194
196
  } from "./webhook-delivery/index.mjs";
@@ -322,6 +324,8 @@ export {
322
324
  WEBHOOK_SSRF_POLICY,
323
325
  WIRE_SPEC_FIELDS,
324
326
  WebSocketTransport,
327
+ WebhookAuthenticationProtectionError,
328
+ WebhookAuthenticationResolutionError,
325
329
  WebhookDeliveryTerminalError,
326
330
  adcpError,
327
331
  anyOf,
@@ -2,6 +2,6 @@ export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, getWebhookDel
2
2
  export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions } from './pg.mjs';
3
3
  export { redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend } from './redis.mjs';
4
4
  export type { RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions } from './redis.mjs';
5
- export { createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, } from './recovery.mjs';
6
- export type { ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './recovery.mjs';
5
+ export { createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookAuthenticationProtectionError, WebhookAuthenticationResolutionError, } from './recovery.mjs';
6
+ export type { ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, PreparedWebhookDeliverySnapshot, PrepareWebhookDeliveryOptions, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './recovery.mjs';
7
7
  export { WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError } from './common.mjs';
@@ -2,6 +2,6 @@ export { pgWebhookDeliveryStore, pgWebhookDeliveryRecoveryBackend, getWebhookDel
2
2
  export type { PgWebhookDeliveryStoreOptions, PgWebhookDeliveryRecoveryOptions } from './pg';
3
3
  export { redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend } from './redis';
4
4
  export type { RedisWebhookDeliveryStoreOptions, RedisWebhookDeliveryRecoveryOptions } from './redis';
5
- export { createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, } from './recovery';
6
- export type { ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './recovery';
5
+ export { createWebhookDeliveryRecovery, pollWebhookDeliveryRecovery, memoryWebhookDeliveryRecoveryBackend, WebhookAuthenticationProtectionError, WebhookAuthenticationResolutionError, } from './recovery';
6
+ export type { ProtectedWebhookAuthentication, WebhookAuthenticationAdapter, WebhookAuthenticationContext, StoredWebhookDeliverySnapshot, PreparedWebhookDeliverySnapshot, PrepareWebhookDeliveryOptions, WebhookRecoveryRecord, WebhookRecoveryLease, WebhookRecoveryCheckpointResult, WebhookRecoveryCheckpointOutcome, WebhookDeliveryRecoveryBackend, DurableWebhookDeliveryRecovery, CreateWebhookDeliveryRecoveryOptions, PollWebhookDeliveryRecoveryOptions, } from './recovery';
7
7
  export { WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError } from './common';
@@ -20,6 +20,8 @@ var webhook_delivery_exports = {};
20
20
  __export(webhook_delivery_exports, {
21
21
  WEBHOOK_DELIVERY_MIGRATION: () => import_pg.WEBHOOK_DELIVERY_MIGRATION,
22
22
  WEBHOOK_DELIVERY_RECOVERY_MIGRATION: () => import_pg.WEBHOOK_DELIVERY_RECOVERY_MIGRATION,
23
+ WebhookAuthenticationProtectionError: () => import_recovery.WebhookAuthenticationProtectionError,
24
+ WebhookAuthenticationResolutionError: () => import_recovery.WebhookAuthenticationResolutionError,
23
25
  WebhookDeliveryTerminalError: () => import_common.WebhookDeliveryTerminalError,
24
26
  createWebhookDeliveryRecovery: () => import_recovery.createWebhookDeliveryRecovery,
25
27
  getWebhookDeliveryMigration: () => import_pg.getWebhookDeliveryMigration,
@@ -41,6 +43,8 @@ var import_common = require('./common.js');
41
43
  0 && (module.exports = {
42
44
  WEBHOOK_DELIVERY_MIGRATION,
43
45
  WEBHOOK_DELIVERY_RECOVERY_MIGRATION,
46
+ WebhookAuthenticationProtectionError,
47
+ WebhookAuthenticationResolutionError,
44
48
  WebhookDeliveryTerminalError,
45
49
  createWebhookDeliveryRecovery,
46
50
  getWebhookDeliveryMigration,
@@ -10,12 +10,16 @@ import { redisWebhookDeliveryStore, redisWebhookDeliveryRecoveryBackend } from "
10
10
  import {
11
11
  createWebhookDeliveryRecovery,
12
12
  pollWebhookDeliveryRecovery,
13
- memoryWebhookDeliveryRecoveryBackend
13
+ memoryWebhookDeliveryRecoveryBackend,
14
+ WebhookAuthenticationProtectionError,
15
+ WebhookAuthenticationResolutionError
14
16
  } from "./recovery.mjs";
15
17
  import { WebhookDeliveryTerminalError, isWebhookDeliveryTerminalError } from "./common.mjs";
16
18
  export {
17
19
  WEBHOOK_DELIVERY_MIGRATION,
18
20
  WEBHOOK_DELIVERY_RECOVERY_MIGRATION,
21
+ WebhookAuthenticationProtectionError,
22
+ WebhookAuthenticationResolutionError,
19
23
  WebhookDeliveryTerminalError,
20
24
  createWebhookDeliveryRecovery,
21
25
  getWebhookDeliveryMigration,
@@ -1,5 +1,5 @@
1
1
  import type { PgQueryable } from '../postgres-task-store.mjs';
2
- import type { WebhookDeliveryStore } from '../webhook-emitter.mjs';
2
+ import type { WebhookDeliveryKey, WebhookDeliveryStore } from '../webhook-emitter.mjs';
3
3
  import type { WebhookDeliveryRecoveryBackend } from './recovery.mjs';
4
4
  export interface PgWebhookDeliveryStoreOptions {
5
5
  /** Defaults to `adcp_webhook_deliveries`. */
@@ -12,6 +12,8 @@ export interface PgWebhookDeliveryRecoveryOptions {
12
12
  tableName?: string;
13
13
  /** Assert that the database/schema is dedicated to this deployment. */
14
14
  acknowledgeIsolatedDatabase?: boolean;
15
+ /** Restrict recovery leases to this trusted publisher/tenant namespace. */
16
+ claimScope?: Pick<WebhookDeliveryKey, 'publisherScope' | 'tenantScope'>;
15
17
  }
16
18
  export declare function getWebhookDeliveryMigration(options?: PgWebhookDeliveryStoreOptions): string;
17
19
  export declare const WEBHOOK_DELIVERY_MIGRATION: string;