@astrasyncai/verification-gateway 5.18.1 → 5.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +232 -0
  2. package/README.md +217 -4
  3. package/dist/adapter-interface/interface.d.mts +2 -2
  4. package/dist/adapter-interface/interface.d.ts +2 -2
  5. package/dist/adapters/express.d.mts +9 -1
  6. package/dist/adapters/express.d.ts +9 -1
  7. package/dist/adapters/express.js +160 -52
  8. package/dist/adapters/express.js.map +1 -1
  9. package/dist/adapters/express.mjs +160 -52
  10. package/dist/adapters/express.mjs.map +1 -1
  11. package/dist/adapters/http-pdlss.d.mts +7 -1
  12. package/dist/adapters/http-pdlss.d.ts +7 -1
  13. package/dist/adapters/http-pdlss.js +18 -2
  14. package/dist/adapters/http-pdlss.js.map +1 -1
  15. package/dist/adapters/http-pdlss.mjs +16 -1
  16. package/dist/adapters/http-pdlss.mjs.map +1 -1
  17. package/dist/adapters/kit-express.d.mts +93 -1
  18. package/dist/adapters/kit-express.d.ts +93 -1
  19. package/dist/adapters/kit-express.js +181 -2
  20. package/dist/adapters/kit-express.js.map +1 -1
  21. package/dist/adapters/kit-express.mjs +180 -2
  22. package/dist/adapters/kit-express.mjs.map +1 -1
  23. package/dist/adapters/mcp.d.mts +102 -9
  24. package/dist/adapters/mcp.d.ts +102 -9
  25. package/dist/adapters/mcp.js +242 -19
  26. package/dist/adapters/mcp.js.map +1 -1
  27. package/dist/adapters/mcp.mjs +240 -19
  28. package/dist/adapters/mcp.mjs.map +1 -1
  29. package/dist/adapters/nextjs.d.mts +1 -1
  30. package/dist/adapters/nextjs.d.ts +1 -1
  31. package/dist/adapters/nextjs.js +97 -14
  32. package/dist/adapters/nextjs.js.map +1 -1
  33. package/dist/adapters/nextjs.mjs +97 -14
  34. package/dist/adapters/nextjs.mjs.map +1 -1
  35. package/dist/adapters/sdk.d.mts +101 -2
  36. package/dist/adapters/sdk.d.ts +101 -2
  37. package/dist/adapters/sdk.js +199 -12
  38. package/dist/adapters/sdk.js.map +1 -1
  39. package/dist/adapters/sdk.mjs +199 -12
  40. package/dist/adapters/sdk.mjs.map +1 -1
  41. package/dist/agent/index.d.mts +1 -1
  42. package/dist/agent/index.d.ts +1 -1
  43. package/dist/agent/index.js +1 -1
  44. package/dist/agent/index.js.map +1 -1
  45. package/dist/agent/index.mjs +1 -1
  46. package/dist/agent/index.mjs.map +1 -1
  47. package/dist/bin/astrasync-claude-hook.js +94 -16
  48. package/dist/bin/astrasync-codex-hook.js +94 -16
  49. package/dist/bin/astrasync-guard.js +94 -16
  50. package/dist/bin/astrasync.js +127 -16
  51. package/dist/browser/background.js +94 -16
  52. package/dist/browser/background.js.map +1 -1
  53. package/dist/browser/background.mjs +94 -16
  54. package/dist/browser/background.mjs.map +1 -1
  55. package/dist/cli/index.js +1 -1
  56. package/dist/cli/index.js.map +1 -1
  57. package/dist/cli/index.mjs +1 -1
  58. package/dist/cli/index.mjs.map +1 -1
  59. package/dist/codex/index.js +94 -16
  60. package/dist/codex/index.js.map +1 -1
  61. package/dist/codex/index.mjs +94 -16
  62. package/dist/codex/index.mjs.map +1 -1
  63. package/dist/cursor/extension.js +94 -16
  64. package/dist/cursor/extension.js.map +1 -1
  65. package/dist/cursor/extension.mjs +94 -16
  66. package/dist/cursor/extension.mjs.map +1 -1
  67. package/dist/edge-config.d.mts +1 -1
  68. package/dist/edge-config.d.ts +1 -1
  69. package/dist/edge-config.js +1 -1
  70. package/dist/edge-config.js.map +1 -1
  71. package/dist/edge-config.mjs +1 -1
  72. package/dist/edge-config.mjs.map +1 -1
  73. package/dist/edge-core/index.d.mts +1 -1
  74. package/dist/edge-core/index.d.ts +1 -1
  75. package/dist/edge-core/index.js +69 -12
  76. package/dist/edge-core/index.js.map +1 -1
  77. package/dist/edge-core/index.mjs +69 -12
  78. package/dist/edge-core/index.mjs.map +1 -1
  79. package/dist/gateway/gateway.d.mts +2 -2
  80. package/dist/gateway/gateway.d.ts +2 -2
  81. package/dist/gateway/gateway.js +94 -16
  82. package/dist/gateway/gateway.js.map +1 -1
  83. package/dist/gateway/gateway.mjs +94 -16
  84. package/dist/gateway/gateway.mjs.map +1 -1
  85. package/dist/git-trigger/git-hooks.d.mts +1 -1
  86. package/dist/git-trigger/git-hooks.d.ts +1 -1
  87. package/dist/index.d.mts +706 -34
  88. package/dist/index.d.ts +706 -34
  89. package/dist/index.js +1391 -205
  90. package/dist/index.js.map +1 -1
  91. package/dist/index.mjs +1374 -195
  92. package/dist/index.mjs.map +1 -1
  93. package/dist/local-evaluator/evaluator.d.mts +2 -2
  94. package/dist/local-evaluator/evaluator.d.ts +2 -2
  95. package/dist/registration/index.d.mts +11 -2
  96. package/dist/registration/index.d.ts +11 -2
  97. package/dist/registration/index.js +1 -1
  98. package/dist/registration/index.js.map +1 -1
  99. package/dist/registration/index.mjs +1 -1
  100. package/dist/registration/index.mjs.map +1 -1
  101. package/dist/transport/index.d.mts +1 -1
  102. package/dist/transport/index.d.ts +1 -1
  103. package/dist/transport/index.js +3 -2
  104. package/dist/transport/index.js.map +1 -1
  105. package/dist/transport/index.mjs +3 -2
  106. package/dist/transport/index.mjs.map +1 -1
  107. package/dist/{types-BRz2U0Pn.d.ts → types-B_HLhZ9n.d.ts} +1 -1
  108. package/dist/{types-BfILnheI.d.mts → types-CU17R4Nr.d.mts} +11 -0
  109. package/dist/{types-BfILnheI.d.ts → types-CU17R4Nr.d.ts} +11 -0
  110. package/dist/{types-Cns4l8gX.d.mts → types-CxjqmPl-.d.mts} +115 -13
  111. package/dist/{types-Cns4l8gX.d.ts → types-CxjqmPl-.d.ts} +115 -13
  112. package/dist/{types-3ObBpsnf.d.mts → types-D37aSQ9c.d.mts} +106 -3
  113. package/dist/{types-CfBpm3w5.d.mts → types-Djpz-L0w.d.mts} +1 -1
  114. package/dist/{types-BoxZEYPS.d.ts → types-Dn8tXnei.d.ts} +106 -3
  115. package/dist/ui/index.d.mts +1 -1
  116. package/dist/ui/index.d.ts +1 -1
  117. package/dist/verify.d.mts +50 -4
  118. package/dist/verify.d.ts +50 -4
  119. package/dist/verify.js +93 -14
  120. package/dist/verify.js.map +1 -1
  121. package/dist/verify.mjs +91 -14
  122. package/dist/verify.mjs.map +1 -1
  123. package/dist/webhooks.d.mts +16 -3
  124. package/dist/webhooks.d.ts +16 -3
  125. package/dist/webhooks.js +24 -13
  126. package/dist/webhooks.js.map +1 -1
  127. package/dist/webhooks.mjs +24 -13
  128. package/dist/webhooks.mjs.map +1 -1
  129. package/package.json +1 -1
@@ -36,7 +36,7 @@ var SDK_VERSION;
36
36
  var init_version = __esm({
37
37
  "src/version.ts"() {
38
38
  "use strict";
39
- SDK_VERSION = "5.18.1";
39
+ SDK_VERSION = "5.20.0";
40
40
  }
41
41
  });
42
42
 
@@ -5186,7 +5186,12 @@ function getCacheKey(request2, counterpartyId) {
5186
5186
  // its start_checkout quote was served the cached quote-leg grant (no
5187
5187
  // settlementOutcome) and never reached the backend. Same F-A1-07 bug class.
5188
5188
  request2.commercePhase || "",
5189
- request2.checkoutSessionId || ""
5189
+ request2.checkoutSessionId || "",
5190
+ // 5.19.0: a route_config purpose claim is checked server-side against
5191
+ // the stored rule for this method + path, so it changes the verdict.
5192
+ request2.purposeSource || "",
5193
+ request2.requestMethod || "",
5194
+ request2.requestPath || ""
5190
5195
  ].join("|");
5191
5196
  }
5192
5197
  function getCachedResult(request2, counterpartyId) {
@@ -5342,6 +5347,9 @@ async function callVerifyAccessAPI(config, request2) {
5342
5347
  if (requestData.enableRuntimeChallenge)
5343
5348
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
5344
5349
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
5350
+ if (config.actingProof?.connectorToken) {
5351
+ body.actingProof = { connectorToken: config.actingProof.connectorToken };
5352
+ }
5345
5353
  if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
5346
5354
  if (requestData.createSession) body.createSession = requestData.createSession;
5347
5355
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
@@ -5358,6 +5366,11 @@ async function callVerifyAccessAPI(config, request2) {
5358
5366
  if (requestData.buyerEmail) body.buyerEmail = requestData.buyerEmail;
5359
5367
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
5360
5368
  if (requestData.attemptId) body.attemptId = requestData.attemptId;
5369
+ if (requestData.purposeSource) body.purposeSource = requestData.purposeSource;
5370
+ if (requestData.agentArtifacts) body.agentArtifacts = requestData.agentArtifacts;
5371
+ if (requestData.metadata) body.metadata = requestData.metadata;
5372
+ if (requestData.requestMethod) body.requestMethod = requestData.requestMethod;
5373
+ if (requestData.requestPath) body.requestPath = requestData.requestPath;
5361
5374
  if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
5362
5375
  body.sdkVersion = SDK_VERSION;
5363
5376
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
@@ -5504,22 +5517,41 @@ async function verify(config, request2, options) {
5504
5517
  "[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
5505
5518
  );
5506
5519
  }
5507
- const uncacheable = Boolean(request2.commerceArtifacts);
5520
+ const uncacheable = Boolean(request2.commerceArtifacts) || Boolean(mergedConfig.actingProof);
5508
5521
  if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
5509
5522
  const cached = getCachedResult(request2, mergedConfig.counterpartyId);
5510
5523
  if (cached) {
5511
5524
  if (mergedConfig.debug) {
5512
5525
  console.log("[VerificationGateway] Returning cached result");
5513
5526
  }
5514
- const hit = { ...cached };
5515
- if (request2.attemptId) {
5516
- hit.attemptId = request2.attemptId;
5517
- } else {
5518
- delete hit.attemptId;
5519
- }
5520
- return hit;
5527
+ return sharedVerdict(cached, request2);
5528
+ }
5529
+ }
5530
+ if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
5531
+ const key = getCacheKey(request2, mergedConfig.counterpartyId);
5532
+ const pending = inflightVerifies.get(key);
5533
+ if (pending) return sharedVerdict(await pending, request2);
5534
+ const flight = verifyViaApi(mergedConfig, request2, urls, uncacheable);
5535
+ inflightVerifies.set(key, flight);
5536
+ try {
5537
+ return await flight;
5538
+ } finally {
5539
+ inflightVerifies.delete(key);
5521
5540
  }
5522
5541
  }
5542
+ return verifyViaApi(mergedConfig, request2, urls, uncacheable);
5543
+ }
5544
+ function sharedVerdict(source, request2) {
5545
+ const hit = { ...source };
5546
+ if (request2.attemptId) {
5547
+ hit.attemptId = request2.attemptId;
5548
+ } else {
5549
+ delete hit.attemptId;
5550
+ }
5551
+ sharedVerdicts.add(hit);
5552
+ return hit;
5553
+ }
5554
+ async function verifyViaApi(mergedConfig, request2, urls, uncacheable) {
5523
5555
  const enrichedRequest = { ...request2 };
5524
5556
  if (!enrichedRequest.counterpartyUrl && mergedConfig.counterpartyUrl) {
5525
5557
  enrichedRequest.counterpartyUrl = mergedConfig.counterpartyUrl;
@@ -5547,9 +5579,18 @@ async function verify(config, request2, options) {
5547
5579
  if (!apiResponse.access?.allowed) {
5548
5580
  const aggregatedFailures = apiResponse.access?.failures;
5549
5581
  const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
5582
+ const denyAgent = idVerifiedFromBackend && apiResponse.agent ? {
5583
+ astraId: apiResponse.agent.astraId,
5584
+ name: apiResponse.agent.name,
5585
+ trustScore: apiResponse.agent.trustScore,
5586
+ trustLevel: getTrustLevel(apiResponse.agent.trustScore),
5587
+ blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
5588
+ status: apiResponse.agent.agentStatus
5589
+ } : void 0;
5550
5590
  const result2 = {
5551
5591
  identityVerified: idVerifiedFromBackend,
5552
5592
  policyAllowed: false,
5593
+ ...denyAgent && { agent: denyAgent },
5553
5594
  // 3.6.0: the server now emits top-level denialReasons on every deny
5554
5595
  // path — prefer it verbatim; the failure-message reconstruction remains
5555
5596
  // as the fallback for older backends.
@@ -5589,7 +5630,9 @@ async function verify(config, request2, options) {
5589
5630
  fulfilment: apiResponse.fulfilment,
5590
5631
  mandates: apiResponse.mandates,
5591
5632
  kyaToken: apiResponse.kyaToken,
5592
- aep: apiResponse.aep
5633
+ aep: apiResponse.aep,
5634
+ // 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
5635
+ warnings: apiResponse.warnings
5593
5636
  };
5594
5637
  return result2;
5595
5638
  }
@@ -5657,7 +5700,9 @@ async function verify(config, request2, options) {
5657
5700
  // 5.15.0: merchant-lane AP2 mandates + KYAPay identity token.
5658
5701
  mandates: apiResponse.mandates,
5659
5702
  kyaToken: apiResponse.kyaToken,
5660
- aep: apiResponse.aep
5703
+ aep: apiResponse.aep,
5704
+ // 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
5705
+ warnings: apiResponse.warnings
5661
5706
  };
5662
5707
  if (result.recommendation === "deny") {
5663
5708
  result.policyAllowed = false;
@@ -5683,9 +5728,18 @@ async function verify(config, request2, options) {
5683
5728
  cacheResult(request2, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
5684
5729
  }
5685
5730
  }
5731
+ notifyVerificationListeners(request2, result);
5686
5732
  return result;
5687
5733
  }
5688
- var DEFAULT_CONFIG, initCheckPerformed, deprecationWarningShown, verificationCache, DEFAULT_CACHE_TTL_SECONDS, MAX_RETRY_AFTER_MS;
5734
+ function notifyVerificationListeners(request2, result) {
5735
+ for (const listener of verificationListeners) {
5736
+ try {
5737
+ listener(result, request2);
5738
+ } catch {
5739
+ }
5740
+ }
5741
+ }
5742
+ var DEFAULT_CONFIG, initCheckPerformed, deprecationWarningShown, verificationCache, DEFAULT_CACHE_TTL_SECONDS, MAX_RETRY_AFTER_MS, inflightVerifies, sharedVerdicts, verificationListeners;
5689
5743
  var init_verify = __esm({
5690
5744
  "src/verify.ts"() {
5691
5745
  "use strict";
@@ -5708,6 +5762,9 @@ var init_verify = __esm({
5708
5762
  verificationCache = /* @__PURE__ */ new Map();
5709
5763
  DEFAULT_CACHE_TTL_SECONDS = 60;
5710
5764
  MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
5765
+ inflightVerifies = /* @__PURE__ */ new Map();
5766
+ sharedVerdicts = /* @__PURE__ */ new WeakSet();
5767
+ verificationListeners = /* @__PURE__ */ new Set();
5711
5768
  }
5712
5769
  });
5713
5770
 
@@ -5772,6 +5829,16 @@ var init_commerce_detect = __esm({
5772
5829
  }
5773
5830
  });
5774
5831
 
5832
+ // src/adapters/routes-cache.ts
5833
+ var DEFAULT_ROUTES_REFRESH_MS;
5834
+ var init_routes_cache = __esm({
5835
+ "src/adapters/routes-cache.ts"() {
5836
+ "use strict";
5837
+ init_verify();
5838
+ DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
5839
+ }
5840
+ });
5841
+
5775
5842
  // src/transport/http.ts
5776
5843
  var init_http2 = __esm({
5777
5844
  "src/transport/http.ts"() {
@@ -6101,7 +6168,6 @@ var init_anonymous_beacon = __esm({
6101
6168
  });
6102
6169
 
6103
6170
  // src/adapters/express.ts
6104
- var DEFAULT_ROUTES_REFRESH_MS;
6105
6171
  var init_express = __esm({
6106
6172
  "src/adapters/express.ts"() {
6107
6173
  "use strict";
@@ -6109,6 +6175,7 @@ var init_express = __esm({
6109
6175
  init_types2();
6110
6176
  init_stepup_poll();
6111
6177
  init_verify();
6178
+ init_routes_cache();
6112
6179
  init_http2();
6113
6180
  init_verified_hop();
6114
6181
  init_http_pdlss();
@@ -6119,7 +6186,6 @@ var init_express = __esm({
6119
6186
  init_anonymous_beacon();
6120
6187
  init_failure_posture();
6121
6188
  init_route_pattern();
6122
- DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
6123
6189
  }
6124
6190
  });
6125
6191
 
@@ -6460,6 +6526,7 @@ var init_mcp2 = __esm({
6460
6526
  init_approval_gate();
6461
6527
  init_stepup_poll();
6462
6528
  init_well_known();
6529
+ init_routes_cache();
6463
6530
  init_failure_posture();
6464
6531
  init_mcp_server();
6465
6532
  }
@@ -6648,6 +6715,7 @@ var init_report_amount = __esm({
6648
6715
  var init_kit_shared = __esm({
6649
6716
  "src/ucp/kit-shared.ts"() {
6650
6717
  "use strict";
6718
+ init_sign();
6651
6719
  }
6652
6720
  });
6653
6721
 
@@ -6667,6 +6735,41 @@ var init_checkout_kit = __esm({
6667
6735
  init_signatures();
6668
6736
  init_report_amount();
6669
6737
  init_kit_shared();
6738
+ init_errors();
6739
+ init_stepup_poll();
6740
+ }
6741
+ });
6742
+
6743
+ // src/webhooks.ts
6744
+ var init_webhooks = __esm({
6745
+ "src/webhooks.ts"() {
6746
+ "use strict";
6747
+ }
6748
+ });
6749
+
6750
+ // src/ucp/approval-events.ts
6751
+ var MemorySeenEvents, defaultSeen;
6752
+ var init_approval_events = __esm({
6753
+ "src/ucp/approval-events.ts"() {
6754
+ "use strict";
6755
+ init_webhooks();
6756
+ MemorySeenEvents = class {
6757
+ constructor(max = 1e4) {
6758
+ this.max = max;
6759
+ this.ids = /* @__PURE__ */ new Set();
6760
+ }
6761
+ async has(eventId) {
6762
+ return this.ids.has(eventId);
6763
+ }
6764
+ async add(eventId) {
6765
+ if (this.ids.size >= this.max) {
6766
+ const first = this.ids.values().next().value;
6767
+ if (first !== void 0) this.ids.delete(first);
6768
+ }
6769
+ this.ids.add(eventId);
6770
+ }
6771
+ };
6772
+ defaultSeen = new MemorySeenEvents();
6670
6773
  }
6671
6774
  });
6672
6775
 
@@ -6681,6 +6784,7 @@ var init_ucp2 = __esm({
6681
6784
  init_signatures();
6682
6785
  init_checkout_kit();
6683
6786
  init_jcs();
6787
+ init_approval_events();
6684
6788
  }
6685
6789
  });
6686
6790
 
@@ -6740,8 +6844,11 @@ var init_checkout_kit2 = __esm({
6740
6844
  "src/acp/checkout-kit.ts"() {
6741
6845
  "use strict";
6742
6846
  init_idempotency();
6847
+ init_checkout_kit();
6743
6848
  init_report_amount();
6744
6849
  init_kit_shared();
6850
+ init_errors();
6851
+ init_stepup_poll();
6745
6852
  }
6746
6853
  });
6747
6854
 
@@ -6750,6 +6857,7 @@ var init_acp2 = __esm({
6750
6857
  "src/acp/index.ts"() {
6751
6858
  "use strict";
6752
6859
  init_checkout_kit2();
6860
+ init_approval_events();
6753
6861
  }
6754
6862
  });
6755
6863
 
@@ -6758,6 +6866,7 @@ var init_kit_express = __esm({
6758
6866
  "src/adapters/kit-express.ts"() {
6759
6867
  "use strict";
6760
6868
  init_kit_shared();
6869
+ init_approval_events();
6761
6870
  }
6762
6871
  });
6763
6872
 
@@ -6846,7 +6955,9 @@ function toDecision(result) {
6846
6955
  if (result.identityVerified && result.policyAllowed) {
6847
6956
  return {
6848
6957
  recommendation: "ALLOW",
6849
- reason: result.agent?.trustScore ? `Verified (trust score ${result.agent.trustScore})` : "Verified",
6958
+ // 5.19.0: the score is on `trustScore` for the merchant; `reason` is
6959
+ // text a merchant may relay to the agent, so it never embeds the number.
6960
+ reason: "Verified",
6850
6961
  trustScore: result.agent?.trustScore,
6851
6962
  sessionId: "sessionId" in result ? result.sessionId : void 0
6852
6963
  };
@@ -3988,7 +3988,7 @@ function getTrustLevel(score) {
3988
3988
  }
3989
3989
 
3990
3990
  // src/version.ts
3991
- var SDK_VERSION = "5.18.1";
3991
+ var SDK_VERSION = "5.20.0";
3992
3992
 
3993
3993
  // src/http.ts
3994
3994
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -4143,7 +4143,12 @@ function getCacheKey(request, counterpartyId) {
4143
4143
  // its start_checkout quote was served the cached quote-leg grant (no
4144
4144
  // settlementOutcome) and never reached the backend. Same F-A1-07 bug class.
4145
4145
  request.commercePhase || "",
4146
- request.checkoutSessionId || ""
4146
+ request.checkoutSessionId || "",
4147
+ // 5.19.0: a route_config purpose claim is checked server-side against
4148
+ // the stored rule for this method + path, so it changes the verdict.
4149
+ request.purposeSource || "",
4150
+ request.requestMethod || "",
4151
+ request.requestPath || ""
4147
4152
  ].join("|");
4148
4153
  }
4149
4154
  function getCachedResult(request, counterpartyId) {
@@ -4301,6 +4306,9 @@ async function callVerifyAccessAPI(config, request) {
4301
4306
  if (requestData.enableRuntimeChallenge)
4302
4307
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
4303
4308
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
4309
+ if (config.actingProof?.connectorToken) {
4310
+ body.actingProof = { connectorToken: config.actingProof.connectorToken };
4311
+ }
4304
4312
  if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
4305
4313
  if (requestData.createSession) body.createSession = requestData.createSession;
4306
4314
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
@@ -4317,6 +4325,11 @@ async function callVerifyAccessAPI(config, request) {
4317
4325
  if (requestData.buyerEmail) body.buyerEmail = requestData.buyerEmail;
4318
4326
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
4319
4327
  if (requestData.attemptId) body.attemptId = requestData.attemptId;
4328
+ if (requestData.purposeSource) body.purposeSource = requestData.purposeSource;
4329
+ if (requestData.agentArtifacts) body.agentArtifacts = requestData.agentArtifacts;
4330
+ if (requestData.metadata) body.metadata = requestData.metadata;
4331
+ if (requestData.requestMethod) body.requestMethod = requestData.requestMethod;
4332
+ if (requestData.requestPath) body.requestPath = requestData.requestPath;
4320
4333
  if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
4321
4334
  body.sdkVersion = SDK_VERSION;
4322
4335
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
@@ -4463,22 +4476,43 @@ async function verify(config, request, options) {
4463
4476
  "[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
4464
4477
  );
4465
4478
  }
4466
- const uncacheable = Boolean(request.commerceArtifacts);
4479
+ const uncacheable = Boolean(request.commerceArtifacts) || Boolean(mergedConfig.actingProof);
4467
4480
  if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
4468
4481
  const cached = getCachedResult(request, mergedConfig.counterpartyId);
4469
4482
  if (cached) {
4470
4483
  if (mergedConfig.debug) {
4471
4484
  console.log("[VerificationGateway] Returning cached result");
4472
4485
  }
4473
- const hit = { ...cached };
4474
- if (request.attemptId) {
4475
- hit.attemptId = request.attemptId;
4476
- } else {
4477
- delete hit.attemptId;
4478
- }
4479
- return hit;
4486
+ return sharedVerdict(cached, request);
4487
+ }
4488
+ }
4489
+ if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
4490
+ const key = getCacheKey(request, mergedConfig.counterpartyId);
4491
+ const pending = inflightVerifies.get(key);
4492
+ if (pending) return sharedVerdict(await pending, request);
4493
+ const flight = verifyViaApi(mergedConfig, request, urls, uncacheable);
4494
+ inflightVerifies.set(key, flight);
4495
+ try {
4496
+ return await flight;
4497
+ } finally {
4498
+ inflightVerifies.delete(key);
4480
4499
  }
4481
4500
  }
4501
+ return verifyViaApi(mergedConfig, request, urls, uncacheable);
4502
+ }
4503
+ var inflightVerifies = /* @__PURE__ */ new Map();
4504
+ var sharedVerdicts = /* @__PURE__ */ new WeakSet();
4505
+ function sharedVerdict(source, request) {
4506
+ const hit = { ...source };
4507
+ if (request.attemptId) {
4508
+ hit.attemptId = request.attemptId;
4509
+ } else {
4510
+ delete hit.attemptId;
4511
+ }
4512
+ sharedVerdicts.add(hit);
4513
+ return hit;
4514
+ }
4515
+ async function verifyViaApi(mergedConfig, request, urls, uncacheable) {
4482
4516
  const enrichedRequest = { ...request };
4483
4517
  if (!enrichedRequest.counterpartyUrl && mergedConfig.counterpartyUrl) {
4484
4518
  enrichedRequest.counterpartyUrl = mergedConfig.counterpartyUrl;
@@ -4506,9 +4540,18 @@ async function verify(config, request, options) {
4506
4540
  if (!apiResponse.access?.allowed) {
4507
4541
  const aggregatedFailures = apiResponse.access?.failures;
4508
4542
  const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
4543
+ const denyAgent = idVerifiedFromBackend && apiResponse.agent ? {
4544
+ astraId: apiResponse.agent.astraId,
4545
+ name: apiResponse.agent.name,
4546
+ trustScore: apiResponse.agent.trustScore,
4547
+ trustLevel: getTrustLevel(apiResponse.agent.trustScore),
4548
+ blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
4549
+ status: apiResponse.agent.agentStatus
4550
+ } : void 0;
4509
4551
  const result2 = {
4510
4552
  identityVerified: idVerifiedFromBackend,
4511
4553
  policyAllowed: false,
4554
+ ...denyAgent && { agent: denyAgent },
4512
4555
  // 3.6.0: the server now emits top-level denialReasons on every deny
4513
4556
  // path — prefer it verbatim; the failure-message reconstruction remains
4514
4557
  // as the fallback for older backends.
@@ -4548,7 +4591,9 @@ async function verify(config, request, options) {
4548
4591
  fulfilment: apiResponse.fulfilment,
4549
4592
  mandates: apiResponse.mandates,
4550
4593
  kyaToken: apiResponse.kyaToken,
4551
- aep: apiResponse.aep
4594
+ aep: apiResponse.aep,
4595
+ // 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
4596
+ warnings: apiResponse.warnings
4552
4597
  };
4553
4598
  return result2;
4554
4599
  }
@@ -4616,7 +4661,9 @@ async function verify(config, request, options) {
4616
4661
  // 5.15.0: merchant-lane AP2 mandates + KYAPay identity token.
4617
4662
  mandates: apiResponse.mandates,
4618
4663
  kyaToken: apiResponse.kyaToken,
4619
- aep: apiResponse.aep
4664
+ aep: apiResponse.aep,
4665
+ // 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
4666
+ warnings: apiResponse.warnings
4620
4667
  };
4621
4668
  if (result.recommendation === "deny") {
4622
4669
  result.policyAllowed = false;
@@ -4642,8 +4689,18 @@ async function verify(config, request, options) {
4642
4689
  cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
4643
4690
  }
4644
4691
  }
4692
+ notifyVerificationListeners(request, result);
4645
4693
  return result;
4646
4694
  }
4695
+ var verificationListeners = /* @__PURE__ */ new Set();
4696
+ function notifyVerificationListeners(request, result) {
4697
+ for (const listener of verificationListeners) {
4698
+ try {
4699
+ listener(result, request);
4700
+ } catch {
4701
+ }
4702
+ }
4703
+ }
4647
4704
 
4648
4705
  // src/adapters/stepup-poll.ts
4649
4706
  var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
@@ -4654,6 +4711,9 @@ var MAX_TOTAL_BYTES = 16 * 1024;
4654
4711
  // src/adapters/commerce-detect.ts
4655
4712
  var MAX_BODY_BYTES = 64 * 1024;
4656
4713
 
4714
+ // src/adapters/routes-cache.ts
4715
+ var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
4716
+
4657
4717
  // src/edge-config.ts
4658
4718
  var DEFAULT_EDGE_CONFIG = Object.freeze({
4659
4719
  version: 1,
@@ -4895,9 +4955,6 @@ var BeaconBuffer = class {
4895
4955
  };
4896
4956
  var beaconBuffer = new BeaconBuffer();
4897
4957
 
4898
- // src/adapters/express.ts
4899
- var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
4900
-
4901
4958
  // src/adapters/nextjs.ts
4902
4959
  var DEFAULT_ROUTES_REFRESH_MS2 = 5 * 60 * 1e3;
4903
4960
 
@@ -4983,6 +5040,25 @@ var import_jose2 = require("jose");
4983
5040
  // src/idempotency/index.ts
4984
5041
  var DEFAULT_IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1e3;
4985
5042
 
5043
+ // src/ucp/approval-events.ts
5044
+ var MemorySeenEvents = class {
5045
+ constructor(max = 1e4) {
5046
+ this.max = max;
5047
+ this.ids = /* @__PURE__ */ new Set();
5048
+ }
5049
+ async has(eventId) {
5050
+ return this.ids.has(eventId);
5051
+ }
5052
+ async add(eventId) {
5053
+ if (this.ids.size >= this.max) {
5054
+ const first = this.ids.values().next().value;
5055
+ if (first !== void 0) this.ids.delete(first);
5056
+ }
5057
+ this.ids.add(eventId);
5058
+ }
5059
+ };
5060
+ var defaultSeen = new MemorySeenEvents();
5061
+
4986
5062
  // src/payments/kyapay.ts
4987
5063
  var import_jose4 = require("jose");
4988
5064
 
@@ -5022,7 +5098,9 @@ function toDecision(result) {
5022
5098
  if (result.identityVerified && result.policyAllowed) {
5023
5099
  return {
5024
5100
  recommendation: "ALLOW",
5025
- reason: result.agent?.trustScore ? `Verified (trust score ${result.agent.trustScore})` : "Verified",
5101
+ // 5.19.0: the score is on `trustScore` for the merchant; `reason` is
5102
+ // text a merchant may relay to the agent, so it never embeds the number.
5103
+ reason: "Verified",
5026
5104
  trustScore: result.agent?.trustScore,
5027
5105
  sessionId: "sessionId" in result ? result.sessionId : void 0
5028
5106
  };