@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
@@ -1267,12 +1267,14 @@ function createAdcpServerFromPlatform(platform, opts) {
1267
1267
  mediaBuy: opts.legacyHandlers?.mediaBuy ?? runtimeLegacyOptions.mediaBuy,
1268
1268
  creative: opts.legacyHandlers?.creative ?? runtimeLegacyOptions.creative,
1269
1269
  governance: opts.legacyHandlers?.governance ?? runtimeLegacyOptions.governance,
1270
- brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights
1270
+ brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights,
1271
+ signals: opts.legacyHandlers?.signals ?? runtimeLegacyOptions.signals
1271
1272
  };
1272
1273
  (0, import_validate_platform.validatePlatform)(platform, {
1273
1274
  creative: legacyHandlers.creative,
1274
1275
  campaignGovernance: legacyHandlers.governance,
1275
- brandRights: legacyHandlers.brandRights
1276
+ brandRights: legacyHandlers.brandRights,
1277
+ signals: legacyHandlers.signals
1276
1278
  });
1277
1279
  {
1278
1280
  const specialisms = platform.capabilities.specialisms;
@@ -1281,7 +1283,8 @@ function createAdcpServerFromPlatform(platform, opts) {
1281
1283
  mediaBuy: legacyHandlers.mediaBuy,
1282
1284
  creative: platform.creative ?? legacyHandlers.creative,
1283
1285
  governance: legacyHandlers.governance,
1284
- brandRights: platform.brandRights ?? legacyHandlers.brandRights
1286
+ brandRights: platform.brandRights ?? legacyHandlers.brandRights,
1287
+ signals: platform.signals ?? legacyHandlers.signals
1285
1288
  };
1286
1289
  const issues = (0, import_validate_specialisms.validateSpecialismRequiredTools)(effectiveSpecialismSurface, specialisms);
1287
1290
  if (issues.length > 0) {
@@ -1698,7 +1701,7 @@ function createAdcpServerFromPlatform(platform, opts) {
1698
1701
  mergeOpts
1699
1702
  ),
1700
1703
  signals: mergeHandlers(
1701
- opts.signals,
1704
+ legacyHandlers.signals,
1702
1705
  buildSignalsHandlers(
1703
1706
  platform,
1704
1707
  taskRegistry,
@@ -2535,6 +2538,17 @@ async function routeIfHandoff(taskRegistry, opts, result, project) {
2535
2538
  return await project(result);
2536
2539
  }
2537
2540
  const { fn: taskFn, options } = entry;
2541
+ if (options && "settlement" in options && options.settlement === "external") {
2542
+ return dispatchHitl(
2543
+ taskRegistry,
2544
+ opts,
2545
+ async (taskRef) => {
2546
+ await taskFn((0, import_to_context.buildHandoffContext)(taskRegistry, taskRef));
2547
+ },
2548
+ options.task_id,
2549
+ "external"
2550
+ );
2551
+ }
2538
2552
  return dispatchHitl(
2539
2553
  taskRegistry,
2540
2554
  opts,
@@ -2550,7 +2564,10 @@ async function routeIfHandoff(taskRegistry, opts, result, project) {
2550
2564
  rejectResponseSummary(result);
2551
2565
  return await project(result);
2552
2566
  }
2553
- async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId) {
2567
+ async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId, settlement = "framework") {
2568
+ if (settlement === "external" && taskRegistry.durability !== "durable") {
2569
+ throw new Error("External task settlement requires a durable task registry with a stable identity");
2570
+ }
2554
2571
  const createStart = Date.now();
2555
2572
  const createdRef = await taskRegistry.create({
2556
2573
  tool: opts.tool,
@@ -2599,6 +2616,20 @@ async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId) {
2599
2616
  opts.logger
2600
2617
  );
2601
2618
  };
2619
+ if (settlement === "external") {
2620
+ if (typeof taskRef.registryId !== "string" || taskRef.registryId.length === 0) {
2621
+ throw new Error("External task settlement requires a durable task registry with a stable identity");
2622
+ }
2623
+ try {
2624
+ await taskFn(taskRef);
2625
+ } catch (taskFnError) {
2626
+ opts.logger.error(
2627
+ `[adcp/decisioning] external task producer for ${taskId} (${opts.tool}) failed before durable handoff. Task remains submitted internally; no terminal state, webhook, or buyer acknowledgment was written. Error type: ${taskFnError instanceof Error ? "Error" : typeof taskFnError}`
2628
+ );
2629
+ throw new Error("External task producer failed before durable handoff");
2630
+ }
2631
+ return { status: "submitted", task_id: taskId };
2632
+ }
2602
2633
  const completion = (async () => {
2603
2634
  const registryScope = taskRef;
2604
2635
  let result;
@@ -3137,12 +3168,13 @@ function validatePushNotificationUrl(rawUrl, opts = {}) {
3137
3168
  }
3138
3169
  return { ok: true };
3139
3170
  }
3140
- const TOKEN_MAX_LENGTH = 255;
3171
+ const TOKEN_MIN_LENGTH = 16;
3172
+ const TOKEN_MAX_LENGTH = 4096;
3141
3173
  const TOKEN_CONTROL_CHAR_RE = /[\x00-\x1f\x7f]/;
3142
3174
  const PUSH_OPERATION_ID_RE = /^[A-Za-z0-9_.:-]{1,255}$/;
3143
3175
  function validatePushNotificationToken(token) {
3144
- if (token.length === 0) {
3145
- return { ok: false, reason: "token is empty" };
3176
+ if (token.length < TOKEN_MIN_LENGTH) {
3177
+ return { ok: false, reason: `token shorter than ${TOKEN_MIN_LENGTH} chars` };
3146
3178
  }
3147
3179
  if (token.length > TOKEN_MAX_LENGTH) {
3148
3180
  return { ok: false, reason: `token longer than ${TOKEN_MAX_LENGTH} chars` };
@@ -1287,12 +1287,14 @@ function createAdcpServerFromPlatform(platform, opts) {
1287
1287
  mediaBuy: opts.legacyHandlers?.mediaBuy ?? runtimeLegacyOptions.mediaBuy,
1288
1288
  creative: opts.legacyHandlers?.creative ?? runtimeLegacyOptions.creative,
1289
1289
  governance: opts.legacyHandlers?.governance ?? runtimeLegacyOptions.governance,
1290
- brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights
1290
+ brandRights: opts.legacyHandlers?.brandRights ?? runtimeLegacyOptions.brandRights,
1291
+ signals: opts.legacyHandlers?.signals ?? runtimeLegacyOptions.signals
1291
1292
  };
1292
1293
  validatePlatform(platform, {
1293
1294
  creative: legacyHandlers.creative,
1294
1295
  campaignGovernance: legacyHandlers.governance,
1295
- brandRights: legacyHandlers.brandRights
1296
+ brandRights: legacyHandlers.brandRights,
1297
+ signals: legacyHandlers.signals
1296
1298
  });
1297
1299
  {
1298
1300
  const specialisms = platform.capabilities.specialisms;
@@ -1301,7 +1303,8 @@ function createAdcpServerFromPlatform(platform, opts) {
1301
1303
  mediaBuy: legacyHandlers.mediaBuy,
1302
1304
  creative: platform.creative ?? legacyHandlers.creative,
1303
1305
  governance: legacyHandlers.governance,
1304
- brandRights: platform.brandRights ?? legacyHandlers.brandRights
1306
+ brandRights: platform.brandRights ?? legacyHandlers.brandRights,
1307
+ signals: platform.signals ?? legacyHandlers.signals
1305
1308
  };
1306
1309
  const issues = validateSpecialismRequiredTools(effectiveSpecialismSurface, specialisms);
1307
1310
  if (issues.length > 0) {
@@ -1718,7 +1721,7 @@ function createAdcpServerFromPlatform(platform, opts) {
1718
1721
  mergeOpts
1719
1722
  ),
1720
1723
  signals: mergeHandlers(
1721
- opts.signals,
1724
+ legacyHandlers.signals,
1722
1725
  buildSignalsHandlers(
1723
1726
  platform,
1724
1727
  taskRegistry,
@@ -2555,6 +2558,17 @@ async function routeIfHandoff(taskRegistry, opts, result, project) {
2555
2558
  return await project(result);
2556
2559
  }
2557
2560
  const { fn: taskFn, options } = entry;
2561
+ if (options && "settlement" in options && options.settlement === "external") {
2562
+ return dispatchHitl(
2563
+ taskRegistry,
2564
+ opts,
2565
+ async (taskRef) => {
2566
+ await taskFn(buildHandoffContext(taskRegistry, taskRef));
2567
+ },
2568
+ options.task_id,
2569
+ "external"
2570
+ );
2571
+ }
2558
2572
  return dispatchHitl(
2559
2573
  taskRegistry,
2560
2574
  opts,
@@ -2570,7 +2584,10 @@ async function routeIfHandoff(taskRegistry, opts, result, project) {
2570
2584
  rejectResponseSummary(result);
2571
2585
  return await project(result);
2572
2586
  }
2573
- async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId) {
2587
+ async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId, settlement = "framework") {
2588
+ if (settlement === "external" && taskRegistry.durability !== "durable") {
2589
+ throw new Error("External task settlement requires a durable task registry with a stable identity");
2590
+ }
2574
2591
  const createStart = Date.now();
2575
2592
  const createdRef = await taskRegistry.create({
2576
2593
  tool: opts.tool,
@@ -2619,6 +2636,20 @@ async function dispatchHitl(taskRegistry, opts, taskFn, overrideTaskId) {
2619
2636
  opts.logger
2620
2637
  );
2621
2638
  };
2639
+ if (settlement === "external") {
2640
+ if (typeof taskRef.registryId !== "string" || taskRef.registryId.length === 0) {
2641
+ throw new Error("External task settlement requires a durable task registry with a stable identity");
2642
+ }
2643
+ try {
2644
+ await taskFn(taskRef);
2645
+ } catch (taskFnError) {
2646
+ opts.logger.error(
2647
+ `[adcp/decisioning] external task producer for ${taskId} (${opts.tool}) failed before durable handoff. Task remains submitted internally; no terminal state, webhook, or buyer acknowledgment was written. Error type: ${taskFnError instanceof Error ? "Error" : typeof taskFnError}`
2648
+ );
2649
+ throw new Error("External task producer failed before durable handoff");
2650
+ }
2651
+ return { status: "submitted", task_id: taskId };
2652
+ }
2622
2653
  const completion = (async () => {
2623
2654
  const registryScope = taskRef;
2624
2655
  let result;
@@ -3157,12 +3188,13 @@ function validatePushNotificationUrl(rawUrl, opts = {}) {
3157
3188
  }
3158
3189
  return { ok: true };
3159
3190
  }
3160
- const TOKEN_MAX_LENGTH = 255;
3191
+ const TOKEN_MIN_LENGTH = 16;
3192
+ const TOKEN_MAX_LENGTH = 4096;
3161
3193
  const TOKEN_CONTROL_CHAR_RE = /[\x00-\x1f\x7f]/;
3162
3194
  const PUSH_OPERATION_ID_RE = /^[A-Za-z0-9_.:-]{1,255}$/;
3163
3195
  function validatePushNotificationToken(token) {
3164
- if (token.length === 0) {
3165
- return { ok: false, reason: "token is empty" };
3196
+ if (token.length < TOKEN_MIN_LENGTH) {
3197
+ return { ok: false, reason: `token shorter than ${TOKEN_MIN_LENGTH} chars` };
3166
3198
  }
3167
3199
  if (token.length > TOKEN_MAX_LENGTH) {
3168
3200
  return { ok: false, reason: `token longer than ${TOKEN_MAX_LENGTH} chars` };
@@ -44,7 +44,8 @@
44
44
  * process boundaries may use `completeScopedTask()` / `failScopedTask()` for
45
45
  * polling-only tasks after persisting the full issued reference. Registry-only
46
46
  * settlement rejects buyer push-notification tasks because it cannot durably
47
- * deliver their terminal webhook; those must finish through the live handoff.
47
+ * deliver their terminal webhook; settle those with
48
+ * `createPostgresTaskSettlementCoordinator()` in a trusted worker.
48
49
  * The MCP `tasks/get` wire path reads via `getTask` and is cross-instance.
49
50
  *
50
51
  * Status: Preview / 6.0.
@@ -63,6 +64,12 @@ export interface PgQueryable {
63
64
  rowCount: number | null;
64
65
  }>;
65
66
  }
67
+ export interface PgTransactionClient extends PgQueryable {
68
+ release(): void;
69
+ }
70
+ export interface PgTransactionalPool extends PgQueryable {
71
+ connect(): Promise<PgTransactionClient>;
72
+ }
66
73
  export interface CreatePostgresTaskRegistryOptions {
67
74
  /** A `pg.Pool` instance (or any `PgQueryable`). */
68
75
  pool: PgQueryable;
@@ -44,7 +44,8 @@
44
44
  * process boundaries may use `completeScopedTask()` / `failScopedTask()` for
45
45
  * polling-only tasks after persisting the full issued reference. Registry-only
46
46
  * settlement rejects buyer push-notification tasks because it cannot durably
47
- * deliver their terminal webhook; those must finish through the live handoff.
47
+ * deliver their terminal webhook; settle those with
48
+ * `createPostgresTaskSettlementCoordinator()` in a trusted worker.
48
49
  * The MCP `tasks/get` wire path reads via `getTask` and is cross-instance.
49
50
  *
50
51
  * Status: Preview / 6.0.
@@ -63,6 +64,12 @@ export interface PgQueryable {
63
64
  rowCount: number | null;
64
65
  }>;
65
66
  }
67
+ export interface PgTransactionClient extends PgQueryable {
68
+ release(): void;
69
+ }
70
+ export interface PgTransactionalPool extends PgQueryable {
71
+ connect(): Promise<PgTransactionClient>;
72
+ }
66
73
  export interface CreatePostgresTaskRegistryOptions {
67
74
  /** A `pg.Pool` instance (or any `PgQueryable`). */
68
75
  pool: PgQueryable;
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var postgres_task_registry_exports = {};
20
20
  __export(postgres_task_registry_exports, {
21
+ _postgresTaskRegistryBinding: () => _postgresTaskRegistryBinding,
21
22
  createPostgresTaskRegistry: () => createPostgresTaskRegistry,
22
23
  getDecisioningTaskRegistryBootstrap: () => getDecisioningTaskRegistryBootstrap,
23
24
  getDecisioningTaskRegistryMigration: () => getDecisioningTaskRegistryMigration,
@@ -26,6 +27,10 @@ __export(postgres_task_registry_exports, {
26
27
  module.exports = __toCommonJS(postgres_task_registry_exports);
27
28
  var import_node_crypto = require("node:crypto");
28
29
  var import_task_registry = require('./task-registry.js');
30
+ const postgresTaskRegistryBindings = /* @__PURE__ */ new WeakMap();
31
+ function _postgresTaskRegistryBinding(registry) {
32
+ return postgresTaskRegistryBindings.get(registry);
33
+ }
29
34
  const DEFAULT_TABLE = "adcp_decisioning_tasks";
30
35
  const VALID_IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
31
36
  const VALID_NAMESPACE = /^[A-Za-z0-9_.:-]{1,255}$/;
@@ -416,8 +421,9 @@ function createPostgresTaskRegistry(opts) {
416
421
  throw payloadError;
417
422
  };
418
423
  const backgrounds = /* @__PURE__ */ new Map();
419
- return {
424
+ const registry = {
420
425
  scopeVersion: 1,
426
+ durability: "durable",
421
427
  registryId,
422
428
  async create(createOpts) {
423
429
  const taskId = createOpts.overrideTaskId ?? `task_${(0, import_node_crypto.randomUUID)()}`;
@@ -581,9 +587,12 @@ function createPostgresTaskRegistry(opts) {
581
587
  await Promise.all(pending);
582
588
  }
583
589
  };
590
+ postgresTaskRegistryBindings.set(registry, { pool, namespace, tableName: table });
591
+ return registry;
584
592
  }
585
593
  // Annotate the CommonJS export names for ESM import in node:
586
594
  0 && (module.exports = {
595
+ _postgresTaskRegistryBinding,
587
596
  createPostgresTaskRegistry,
588
597
  getDecisioningTaskRegistryBootstrap,
589
598
  getDecisioningTaskRegistryMigration,
@@ -1,5 +1,9 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { sanitizeTaskProgressForStorage } from "./task-registry.mjs";
3
+ const postgresTaskRegistryBindings = /* @__PURE__ */ new WeakMap();
4
+ function _postgresTaskRegistryBinding(registry) {
5
+ return postgresTaskRegistryBindings.get(registry);
6
+ }
3
7
  const DEFAULT_TABLE = "adcp_decisioning_tasks";
4
8
  const VALID_IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
5
9
  const VALID_NAMESPACE = /^[A-Za-z0-9_.:-]{1,255}$/;
@@ -390,8 +394,9 @@ function createPostgresTaskRegistry(opts) {
390
394
  throw payloadError;
391
395
  };
392
396
  const backgrounds = /* @__PURE__ */ new Map();
393
- return {
397
+ const registry = {
394
398
  scopeVersion: 1,
399
+ durability: "durable",
395
400
  registryId,
396
401
  async create(createOpts) {
397
402
  const taskId = createOpts.overrideTaskId ?? `task_${randomUUID()}`;
@@ -555,8 +560,11 @@ function createPostgresTaskRegistry(opts) {
555
560
  await Promise.all(pending);
556
561
  }
557
562
  };
563
+ postgresTaskRegistryBindings.set(registry, { pool, namespace, tableName: table });
564
+ return registry;
558
565
  }
559
566
  export {
567
+ _postgresTaskRegistryBinding,
560
568
  createPostgresTaskRegistry,
561
569
  getDecisioningTaskRegistryBootstrap,
562
570
  getDecisioningTaskRegistryMigration,
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Crash-safe PostgreSQL settlement for push-enabled decisioning tasks.
3
+ *
4
+ * The task transition and terminal webhook outbox checkpoint commit in one
5
+ * database transaction. Delivery remains the existing webhook recovery
6
+ * worker's responsibility, so a process can die after commit without losing
7
+ * the buyer's promised terminal notification.
8
+ */
9
+ import type { AdcpStructuredError } from '../async-outcome.mjs';
10
+ import type { WebhookAuthentication, WebhookRetryOptions } from '../../webhook-emitter.mjs';
11
+ import { type CreateWebhookDeliveryRecoveryOptions, type DurableWebhookDeliveryRecovery, type WebhookAuthenticationAdapter } from '../../webhook-delivery/recovery.mjs';
12
+ import { type PgWebhookDeliveryRecoveryOptions } from '../../webhook-delivery/pg.mjs';
13
+ import { type ScopedTaskRef, type TaskRegistry, type TaskStatus } from './task-registry.mjs';
14
+ export interface TaskPushSettlementConfig {
15
+ /** Validated destination from the original push_notification_config. */
16
+ url: string;
17
+ /** Original buyer correlation identity. */
18
+ operationId?: string;
19
+ /** Negotiated AdCP version; required when operationId is absent to prove a legacy route. */
20
+ servedAdcpVersion?: string;
21
+ /** Optional validation token echoed in the task-webhook payload. */
22
+ token?: string;
23
+ /** Optional legacy transport authentication. RFC 9421 remains the baseline. */
24
+ authentication?: WebhookAuthentication;
25
+ }
26
+ export type TaskPushDeliveryState = 'durably_bound' | 'recoverable' | 'delivered' | 'terminal';
27
+ export type TaskPushSettlementOutcome = {
28
+ outcome: 'applied';
29
+ delivery: 'durably_bound';
30
+ } | {
31
+ outcome: 'already_terminal';
32
+ status: TaskStatus;
33
+ compatibility: 'compatible';
34
+ delivery: TaskPushDeliveryState;
35
+ } | {
36
+ outcome: 'already_terminal';
37
+ status: TaskStatus;
38
+ compatibility: 'conflicting';
39
+ delivery: 'not_applicable';
40
+ } | {
41
+ outcome: 'not_found_in_scope';
42
+ delivery: 'not_applicable';
43
+ };
44
+ type TerminalSettlement = {
45
+ status: 'completed';
46
+ result: unknown;
47
+ } | {
48
+ status: 'failed';
49
+ error: AdcpStructuredError;
50
+ result?: unknown;
51
+ };
52
+ export interface PostgresTaskSettlementCoordinatorOptions {
53
+ /** The exact PostgreSQL registry that issued the ScopedTaskRef. */
54
+ registry: TaskRegistry;
55
+ /** Stable publisher namespace; normally the server's configured name. */
56
+ publisherScope: string;
57
+ /** PostgreSQL outbox options. The outbox is always created on the registry's pool. */
58
+ outbox?: PgWebhookDeliveryRecoveryOptions;
59
+ /** Required when push tokens or legacy transport credentials are present. */
60
+ authenticationAdapter?: WebhookAuthenticationAdapter;
61
+ /** Recovery lease/snapshot limits shared with the returned recovery worker. */
62
+ recovery?: Omit<CreateWebhookDeliveryRecoveryOptions, 'backend' | 'authenticationAdapter'>;
63
+ /** Retry policy persisted with every terminal snapshot. */
64
+ retries?: WebhookRetryOptions;
65
+ }
66
+ export interface PostgresTaskSettlementCoordinator {
67
+ readonly durability: 'durable';
68
+ /** Wire this into the normal webhook recovery poller/emitter. */
69
+ readonly recovery: DurableWebhookDeliveryRecovery;
70
+ settle(ref: ScopedTaskRef, terminal: TerminalSettlement, push: TaskPushSettlementConfig): Promise<TaskPushSettlementOutcome>;
71
+ }
72
+ /** Configuration or immutable-delivery conflict detected before commit. */
73
+ export declare class TaskPushSettlementConfigurationError extends Error {
74
+ readonly name = "TaskPushSettlementConfigurationError";
75
+ }
76
+ export declare function createPostgresTaskSettlementCoordinator(options: PostgresTaskSettlementCoordinatorOptions): PostgresTaskSettlementCoordinator;
77
+ export declare function completeScopedPushTask<TResult>(coordinator: PostgresTaskSettlementCoordinator, ref: ScopedTaskRef, push: TaskPushSettlementConfig, result: TResult): Promise<TaskPushSettlementOutcome>;
78
+ export declare function failScopedPushTask(coordinator: PostgresTaskSettlementCoordinator, ref: ScopedTaskRef, push: TaskPushSettlementConfig, error: AdcpStructuredError, result?: unknown): Promise<TaskPushSettlementOutcome>;
79
+ export {};
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Crash-safe PostgreSQL settlement for push-enabled decisioning tasks.
3
+ *
4
+ * The task transition and terminal webhook outbox checkpoint commit in one
5
+ * database transaction. Delivery remains the existing webhook recovery
6
+ * worker's responsibility, so a process can die after commit without losing
7
+ * the buyer's promised terminal notification.
8
+ */
9
+ import type { AdcpStructuredError } from '../async-outcome';
10
+ import type { WebhookAuthentication, WebhookRetryOptions } from '../../webhook-emitter';
11
+ import { type CreateWebhookDeliveryRecoveryOptions, type DurableWebhookDeliveryRecovery, type WebhookAuthenticationAdapter } from '../../webhook-delivery/recovery';
12
+ import { type PgWebhookDeliveryRecoveryOptions } from '../../webhook-delivery/pg';
13
+ import { type ScopedTaskRef, type TaskRegistry, type TaskStatus } from './task-registry';
14
+ export interface TaskPushSettlementConfig {
15
+ /** Validated destination from the original push_notification_config. */
16
+ url: string;
17
+ /** Original buyer correlation identity. */
18
+ operationId?: string;
19
+ /** Negotiated AdCP version; required when operationId is absent to prove a legacy route. */
20
+ servedAdcpVersion?: string;
21
+ /** Optional validation token echoed in the task-webhook payload. */
22
+ token?: string;
23
+ /** Optional legacy transport authentication. RFC 9421 remains the baseline. */
24
+ authentication?: WebhookAuthentication;
25
+ }
26
+ export type TaskPushDeliveryState = 'durably_bound' | 'recoverable' | 'delivered' | 'terminal';
27
+ export type TaskPushSettlementOutcome = {
28
+ outcome: 'applied';
29
+ delivery: 'durably_bound';
30
+ } | {
31
+ outcome: 'already_terminal';
32
+ status: TaskStatus;
33
+ compatibility: 'compatible';
34
+ delivery: TaskPushDeliveryState;
35
+ } | {
36
+ outcome: 'already_terminal';
37
+ status: TaskStatus;
38
+ compatibility: 'conflicting';
39
+ delivery: 'not_applicable';
40
+ } | {
41
+ outcome: 'not_found_in_scope';
42
+ delivery: 'not_applicable';
43
+ };
44
+ type TerminalSettlement = {
45
+ status: 'completed';
46
+ result: unknown;
47
+ } | {
48
+ status: 'failed';
49
+ error: AdcpStructuredError;
50
+ result?: unknown;
51
+ };
52
+ export interface PostgresTaskSettlementCoordinatorOptions {
53
+ /** The exact PostgreSQL registry that issued the ScopedTaskRef. */
54
+ registry: TaskRegistry;
55
+ /** Stable publisher namespace; normally the server's configured name. */
56
+ publisherScope: string;
57
+ /** PostgreSQL outbox options. The outbox is always created on the registry's pool. */
58
+ outbox?: PgWebhookDeliveryRecoveryOptions;
59
+ /** Required when push tokens or legacy transport credentials are present. */
60
+ authenticationAdapter?: WebhookAuthenticationAdapter;
61
+ /** Recovery lease/snapshot limits shared with the returned recovery worker. */
62
+ recovery?: Omit<CreateWebhookDeliveryRecoveryOptions, 'backend' | 'authenticationAdapter'>;
63
+ /** Retry policy persisted with every terminal snapshot. */
64
+ retries?: WebhookRetryOptions;
65
+ }
66
+ export interface PostgresTaskSettlementCoordinator {
67
+ readonly durability: 'durable';
68
+ /** Wire this into the normal webhook recovery poller/emitter. */
69
+ readonly recovery: DurableWebhookDeliveryRecovery;
70
+ settle(ref: ScopedTaskRef, terminal: TerminalSettlement, push: TaskPushSettlementConfig): Promise<TaskPushSettlementOutcome>;
71
+ }
72
+ /** Configuration or immutable-delivery conflict detected before commit. */
73
+ export declare class TaskPushSettlementConfigurationError extends Error {
74
+ readonly name = "TaskPushSettlementConfigurationError";
75
+ }
76
+ export declare function createPostgresTaskSettlementCoordinator(options: PostgresTaskSettlementCoordinatorOptions): PostgresTaskSettlementCoordinator;
77
+ export declare function completeScopedPushTask<TResult>(coordinator: PostgresTaskSettlementCoordinator, ref: ScopedTaskRef, push: TaskPushSettlementConfig, result: TResult): Promise<TaskPushSettlementOutcome>;
78
+ export declare function failScopedPushTask(coordinator: PostgresTaskSettlementCoordinator, ref: ScopedTaskRef, push: TaskPushSettlementConfig, error: AdcpStructuredError, result?: unknown): Promise<TaskPushSettlementOutcome>;
79
+ export {};