@astrasyncai/verification-gateway 5.17.0 → 5.17.2

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 (94) hide show
  1. package/README.md +94 -18
  2. package/dist/adapters/express.d.mts +1 -1
  3. package/dist/adapters/express.d.ts +1 -1
  4. package/dist/adapters/express.js +33 -5
  5. package/dist/adapters/express.js.map +1 -1
  6. package/dist/adapters/express.mjs +33 -5
  7. package/dist/adapters/express.mjs.map +1 -1
  8. package/dist/adapters/mcp.d.mts +1 -1
  9. package/dist/adapters/mcp.d.ts +1 -1
  10. package/dist/adapters/mcp.js +24 -5
  11. package/dist/adapters/mcp.js.map +1 -1
  12. package/dist/adapters/mcp.mjs +24 -5
  13. package/dist/adapters/mcp.mjs.map +1 -1
  14. package/dist/adapters/nextjs.d.mts +1 -1
  15. package/dist/adapters/nextjs.d.ts +1 -1
  16. package/dist/adapters/nextjs.js +24 -5
  17. package/dist/adapters/nextjs.js.map +1 -1
  18. package/dist/adapters/nextjs.mjs +24 -5
  19. package/dist/adapters/nextjs.mjs.map +1 -1
  20. package/dist/adapters/sdk.d.mts +1 -1
  21. package/dist/adapters/sdk.d.ts +1 -1
  22. package/dist/adapters/sdk.js +5 -1
  23. package/dist/adapters/sdk.js.map +1 -1
  24. package/dist/adapters/sdk.mjs +5 -1
  25. package/dist/adapters/sdk.mjs.map +1 -1
  26. package/dist/agent/index.js +1 -1
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +1 -1
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +5 -1
  31. package/dist/bin/astrasync-codex-hook.js +5 -1
  32. package/dist/bin/astrasync-guard.js +34 -7
  33. package/dist/bin/astrasync.js +34 -7
  34. package/dist/browser/background.js +5 -1
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +5 -1
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/cli/index.js +1 -1
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/index.mjs +1 -1
  41. package/dist/cli/index.mjs.map +1 -1
  42. package/dist/codex/index.js +5 -1
  43. package/dist/codex/index.js.map +1 -1
  44. package/dist/codex/index.mjs +5 -1
  45. package/dist/codex/index.mjs.map +1 -1
  46. package/dist/cursor/extension.js +5 -1
  47. package/dist/cursor/extension.js.map +1 -1
  48. package/dist/cursor/extension.mjs +5 -1
  49. package/dist/cursor/extension.mjs.map +1 -1
  50. package/dist/edge-config.d.mts +1 -1
  51. package/dist/edge-config.d.ts +1 -1
  52. package/dist/edge-config.js +1 -1
  53. package/dist/edge-config.js.map +1 -1
  54. package/dist/edge-config.mjs +1 -1
  55. package/dist/edge-config.mjs.map +1 -1
  56. package/dist/edge-core/index.d.mts +1 -1
  57. package/dist/edge-core/index.d.ts +1 -1
  58. package/dist/edge-core/index.js +5 -1
  59. package/dist/edge-core/index.js.map +1 -1
  60. package/dist/edge-core/index.mjs +5 -1
  61. package/dist/edge-core/index.mjs.map +1 -1
  62. package/dist/gateway/gateway.js +5 -1
  63. package/dist/gateway/gateway.js.map +1 -1
  64. package/dist/gateway/gateway.mjs +5 -1
  65. package/dist/gateway/gateway.mjs.map +1 -1
  66. package/dist/git-trigger/git-hooks.d.mts +1 -1
  67. package/dist/git-trigger/git-hooks.d.ts +1 -1
  68. package/dist/index.d.mts +16 -2
  69. package/dist/index.d.ts +16 -2
  70. package/dist/index.js +33 -5
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +33 -5
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/registration/index.js +1 -1
  75. package/dist/registration/index.js.map +1 -1
  76. package/dist/registration/index.mjs +1 -1
  77. package/dist/registration/index.mjs.map +1 -1
  78. package/dist/transport/index.js +1 -1
  79. package/dist/transport/index.js.map +1 -1
  80. package/dist/transport/index.mjs +1 -1
  81. package/dist/transport/index.mjs.map +1 -1
  82. package/dist/{types-Bm1QvGqI.d.ts → types-DA8LzAOB.d.ts} +6 -0
  83. package/dist/{types-Blz520bR.d.mts → types-DRb_plOh.d.mts} +14 -0
  84. package/dist/{types-Blz520bR.d.ts → types-DRb_plOh.d.ts} +14 -0
  85. package/dist/{types-DBe4hgfT.d.mts → types-vNBvYD7Z.d.mts} +6 -0
  86. package/dist/ui/index.d.mts +1 -1
  87. package/dist/ui/index.d.ts +1 -1
  88. package/dist/verify.d.mts +1 -1
  89. package/dist/verify.d.ts +1 -1
  90. package/dist/verify.js +5 -1
  91. package/dist/verify.js.map +1 -1
  92. package/dist/verify.mjs +5 -1
  93. package/dist/verify.mjs.map +1 -1
  94. package/package.json +1 -1
@@ -3752,7 +3752,7 @@ function getTrustLevel(score) {
3752
3752
  }
3753
3753
 
3754
3754
  // src/version.ts
3755
- var SDK_VERSION = "5.17.0";
3755
+ var SDK_VERSION = "5.17.2";
3756
3756
 
3757
3757
  // src/http.ts
3758
3758
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -3891,6 +3891,7 @@ function getCacheKey(request, counterpartyId) {
3891
3891
  request.enableRuntimeChallenge ? "1" : "0",
3892
3892
  // 5.16.0: route policy changes the verdict (owners / challenge).
3893
3893
  request.routePolicy ? JSON.stringify(request.routePolicy) : "",
3894
+ request.approvalHeldByRoute ? "1" : "0",
3894
3895
  // callerMetadata fields contribute to risk model; include the ones
3895
3896
  // backend reads. sourceIp/userAgent/forwardedFor change per-request
3896
3897
  // so their inclusion effectively forces a re-check for any varying
@@ -4064,6 +4065,7 @@ async function callVerifyAccessAPI(config, request) {
4064
4065
  if (requestData.enableRuntimeChallenge)
4065
4066
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
4066
4067
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
4068
+ if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
4067
4069
  if (requestData.createSession) body.createSession = requestData.createSession;
4068
4070
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
4069
4071
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
@@ -4395,6 +4397,8 @@ async function verify(config, request, options) {
4395
4397
  } else if (result.recommendation === "step_up_required" && result.identityVerified) {
4396
4398
  result.requiresStepUp = true;
4397
4399
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
4400
+ const stepUpFailures = apiResponse.access?.failures;
4401
+ if (stepUpFailures?.length) result.failures = stepUpFailures;
4398
4402
  }
4399
4403
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
4400
4404
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
@@ -3751,7 +3751,7 @@ function getTrustLevel(score) {
3751
3751
  }
3752
3752
 
3753
3753
  // src/version.ts
3754
- var SDK_VERSION = "5.17.0";
3754
+ var SDK_VERSION = "5.17.2";
3755
3755
 
3756
3756
  // src/http.ts
3757
3757
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -3890,6 +3890,7 @@ function getCacheKey(request, counterpartyId) {
3890
3890
  request.enableRuntimeChallenge ? "1" : "0",
3891
3891
  // 5.16.0: route policy changes the verdict (owners / challenge).
3892
3892
  request.routePolicy ? JSON.stringify(request.routePolicy) : "",
3893
+ request.approvalHeldByRoute ? "1" : "0",
3893
3894
  // callerMetadata fields contribute to risk model; include the ones
3894
3895
  // backend reads. sourceIp/userAgent/forwardedFor change per-request
3895
3896
  // so their inclusion effectively forces a re-check for any varying
@@ -4063,6 +4064,7 @@ async function callVerifyAccessAPI(config, request) {
4063
4064
  if (requestData.enableRuntimeChallenge)
4064
4065
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
4065
4066
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
4067
+ if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
4066
4068
  if (requestData.createSession) body.createSession = requestData.createSession;
4067
4069
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
4068
4070
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
@@ -4394,6 +4396,8 @@ async function verify(config, request, options) {
4394
4396
  } else if (result.recommendation === "step_up_required" && result.identityVerified) {
4395
4397
  result.requiresStepUp = true;
4396
4398
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
4399
+ const stepUpFailures = apiResponse.access?.failures;
4400
+ if (stepUpFailures?.length) result.failures = stepUpFailures;
4397
4401
  }
4398
4402
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
4399
4403
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
@@ -3713,7 +3713,7 @@ Policy saved to ${outputPath}`);
3713
3713
  };
3714
3714
 
3715
3715
  // src/version.ts
3716
- var SDK_VERSION = "5.17.0";
3716
+ var SDK_VERSION = "5.17.2";
3717
3717
 
3718
3718
  // src/http.ts
3719
3719
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -4756,6 +4756,7 @@ function getCacheKey(request2, counterpartyId) {
4756
4756
  request2.enableRuntimeChallenge ? "1" : "0",
4757
4757
  // 5.16.0: route policy changes the verdict (owners / challenge).
4758
4758
  request2.routePolicy ? JSON.stringify(request2.routePolicy) : "",
4759
+ request2.approvalHeldByRoute ? "1" : "0",
4759
4760
  // callerMetadata fields contribute to risk model; include the ones
4760
4761
  // backend reads. sourceIp/userAgent/forwardedFor change per-request
4761
4762
  // so their inclusion effectively forces a re-check for any varying
@@ -4929,6 +4930,7 @@ async function callVerifyAccessAPI(config, request2) {
4929
4930
  if (requestData.enableRuntimeChallenge)
4930
4931
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
4931
4932
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
4933
+ if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
4932
4934
  if (requestData.createSession) body.createSession = requestData.createSession;
4933
4935
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
4934
4936
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
@@ -5260,6 +5262,8 @@ async function verify(config, request2, options) {
5260
5262
  } else if (result.recommendation === "step_up_required" && result.identityVerified) {
5261
5263
  result.requiresStepUp = true;
5262
5264
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
5265
+ const stepUpFailures = apiResponse.access?.failures;
5266
+ if (stepUpFailures?.length) result.failures = stepUpFailures;
5263
5267
  }
5264
5268
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
5265
5269
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
@@ -7362,6 +7366,12 @@ async function startBrowseProxy(opts) {
7362
7366
  }
7363
7367
 
7364
7368
  // src/fleet/browse.ts
7369
+ function refusal(body) {
7370
+ const e = body.error;
7371
+ if (e && typeof e === "object")
7372
+ return { code: e.code ?? body.code, message: e.message ?? body.message };
7373
+ return { code: body.code, message: body.message ?? (typeof e === "string" ? e : void 0) };
7374
+ }
7365
7375
  async function runBrowse(paths, opts) {
7366
7376
  const log = opts.log ?? ((l) => console.log(l));
7367
7377
  const f = opts.fetchImpl ?? fetch;
@@ -7387,25 +7397,42 @@ async function runBrowse(paths, opts) {
7387
7397
  );
7388
7398
  const body = await signin.json().catch(() => ({}));
7389
7399
  if (signin.status !== 201 && signin.status !== 202) {
7400
+ const r = refusal(body);
7390
7401
  throw new Error(
7391
- `Sign-in refused (${signin.status}${body.code ? ` ${body.code}` : ""}): ${body.message ?? "no detail"}`
7402
+ `Sign-in refused (${signin.status}${r.code ? ` ${r.code}` : ""}): ${r.message ?? "no detail"}`
7392
7403
  );
7393
7404
  }
7394
7405
  const sessionId = String(body.data?.sessionId ?? "");
7395
7406
  let code = body.data?.code;
7396
7407
  if (!code) {
7397
7408
  log("Waiting for the owner to approve this sign-in with their passkey\u2026");
7409
+ const approvalUrl = body.data?.approvalUrl;
7410
+ if (typeof approvalUrl === "string" && approvalUrl) log(` Approve it at: ${approvalUrl}`);
7398
7411
  const deadline = Date.now() + (opts.waitMs ?? 10 * 6e4);
7412
+ let failures = 0;
7399
7413
  while (!code) {
7400
7414
  if (Date.now() > deadline) throw new Error("The owner did not approve in time.");
7401
7415
  await new Promise((r) => setTimeout(r, opts.pollIntervalMs ?? 3e3));
7402
- const poll = await f(
7403
- `${apiBaseUrl.replace(/\/+$/, "")}/agent-sessions/${sessionId}/status`,
7404
- {
7416
+ let poll;
7417
+ try {
7418
+ poll = await f(`${apiBaseUrl.replace(/\/+$/, "")}/agent-sessions/${sessionId}/status`, {
7405
7419
  headers: { "x-astra-device": device }
7406
- }
7407
- );
7420
+ });
7421
+ } catch (err) {
7422
+ if (++failures >= 3)
7423
+ throw new Error(`Couldn't check the sign-in status: ${err.message}`);
7424
+ continue;
7425
+ }
7408
7426
  const p = await poll.json().catch(() => ({}));
7427
+ if (!poll.ok) {
7428
+ const r = refusal(p);
7429
+ const why = `(${poll.status}${r.code ? ` ${r.code}` : ""}): ${r.message ?? "no detail"}`;
7430
+ if (poll.status === 401 || poll.status === 403 || poll.status === 404)
7431
+ throw new Error(`Sign-in status check refused ${why}`);
7432
+ if (++failures >= 3) throw new Error(`Couldn't check the sign-in status ${why}`);
7433
+ continue;
7434
+ }
7435
+ failures = 0;
7409
7436
  const status = p.data?.status;
7410
7437
  if (status === "approved") code = p.data?.code;
7411
7438
  else if (status === "denied" || status === "ended")
@@ -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.17.0";
39
+ SDK_VERSION = "5.17.2";
40
40
  }
41
41
  });
42
42
 
@@ -5170,6 +5170,7 @@ function getCacheKey(request2, counterpartyId) {
5170
5170
  request2.enableRuntimeChallenge ? "1" : "0",
5171
5171
  // 5.16.0: route policy changes the verdict (owners / challenge).
5172
5172
  request2.routePolicy ? JSON.stringify(request2.routePolicy) : "",
5173
+ request2.approvalHeldByRoute ? "1" : "0",
5173
5174
  // callerMetadata fields contribute to risk model; include the ones
5174
5175
  // backend reads. sourceIp/userAgent/forwardedFor change per-request
5175
5176
  // so their inclusion effectively forces a re-check for any varying
@@ -5341,6 +5342,7 @@ async function callVerifyAccessAPI(config, request2) {
5341
5342
  if (requestData.enableRuntimeChallenge)
5342
5343
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
5343
5344
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
5345
+ if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
5344
5346
  if (requestData.createSession) body.createSession = requestData.createSession;
5345
5347
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
5346
5348
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
@@ -5672,6 +5674,8 @@ async function verify(config, request2, options) {
5672
5674
  } else if (result.recommendation === "step_up_required" && result.identityVerified) {
5673
5675
  result.requiresStepUp = true;
5674
5676
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
5677
+ const stepUpFailures = apiResponse.access?.failures;
5678
+ if (stepUpFailures?.length) result.failures = stepUpFailures;
5675
5679
  }
5676
5680
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
5677
5681
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
@@ -8651,6 +8655,12 @@ var init_browse_proxy = __esm({
8651
8655
  });
8652
8656
 
8653
8657
  // src/fleet/browse.ts
8658
+ function refusal(body) {
8659
+ const e = body.error;
8660
+ if (e && typeof e === "object")
8661
+ return { code: e.code ?? body.code, message: e.message ?? body.message };
8662
+ return { code: body.code, message: body.message ?? (typeof e === "string" ? e : void 0) };
8663
+ }
8654
8664
  async function runBrowse(paths, opts) {
8655
8665
  const log = opts.log ?? ((l) => console.log(l));
8656
8666
  const f = opts.fetchImpl ?? fetch;
@@ -8676,25 +8686,42 @@ async function runBrowse(paths, opts) {
8676
8686
  );
8677
8687
  const body = await signin.json().catch(() => ({}));
8678
8688
  if (signin.status !== 201 && signin.status !== 202) {
8689
+ const r = refusal(body);
8679
8690
  throw new Error(
8680
- `Sign-in refused (${signin.status}${body.code ? ` ${body.code}` : ""}): ${body.message ?? "no detail"}`
8691
+ `Sign-in refused (${signin.status}${r.code ? ` ${r.code}` : ""}): ${r.message ?? "no detail"}`
8681
8692
  );
8682
8693
  }
8683
8694
  const sessionId = String(body.data?.sessionId ?? "");
8684
8695
  let code = body.data?.code;
8685
8696
  if (!code) {
8686
8697
  log("Waiting for the owner to approve this sign-in with their passkey\u2026");
8698
+ const approvalUrl = body.data?.approvalUrl;
8699
+ if (typeof approvalUrl === "string" && approvalUrl) log(` Approve it at: ${approvalUrl}`);
8687
8700
  const deadline = Date.now() + (opts.waitMs ?? 10 * 6e4);
8701
+ let failures = 0;
8688
8702
  while (!code) {
8689
8703
  if (Date.now() > deadline) throw new Error("The owner did not approve in time.");
8690
8704
  await new Promise((r) => setTimeout(r, opts.pollIntervalMs ?? 3e3));
8691
- const poll = await f(
8692
- `${apiBaseUrl.replace(/\/+$/, "")}/agent-sessions/${sessionId}/status`,
8693
- {
8705
+ let poll;
8706
+ try {
8707
+ poll = await f(`${apiBaseUrl.replace(/\/+$/, "")}/agent-sessions/${sessionId}/status`, {
8694
8708
  headers: { "x-astra-device": device }
8695
- }
8696
- );
8709
+ });
8710
+ } catch (err) {
8711
+ if (++failures >= 3)
8712
+ throw new Error(`Couldn't check the sign-in status: ${err.message}`);
8713
+ continue;
8714
+ }
8697
8715
  const p = await poll.json().catch(() => ({}));
8716
+ if (!poll.ok) {
8717
+ const r = refusal(p);
8718
+ const why = `(${poll.status}${r.code ? ` ${r.code}` : ""}): ${r.message ?? "no detail"}`;
8719
+ if (poll.status === 401 || poll.status === 403 || poll.status === 404)
8720
+ throw new Error(`Sign-in status check refused ${why}`);
8721
+ if (++failures >= 3) throw new Error(`Couldn't check the sign-in status ${why}`);
8722
+ continue;
8723
+ }
8724
+ failures = 0;
8698
8725
  const status = p.data?.status;
8699
8726
  if (status === "approved") code = p.data?.code;
8700
8727
  else if (status === "denied" || status === "ended")
@@ -3988,7 +3988,7 @@ function getTrustLevel(score) {
3988
3988
  }
3989
3989
 
3990
3990
  // src/version.ts
3991
- var SDK_VERSION = "5.17.0";
3991
+ var SDK_VERSION = "5.17.2";
3992
3992
 
3993
3993
  // src/http.ts
3994
3994
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -4127,6 +4127,7 @@ function getCacheKey(request, counterpartyId) {
4127
4127
  request.enableRuntimeChallenge ? "1" : "0",
4128
4128
  // 5.16.0: route policy changes the verdict (owners / challenge).
4129
4129
  request.routePolicy ? JSON.stringify(request.routePolicy) : "",
4130
+ request.approvalHeldByRoute ? "1" : "0",
4130
4131
  // callerMetadata fields contribute to risk model; include the ones
4131
4132
  // backend reads. sourceIp/userAgent/forwardedFor change per-request
4132
4133
  // so their inclusion effectively forces a re-check for any varying
@@ -4300,6 +4301,7 @@ async function callVerifyAccessAPI(config, request) {
4300
4301
  if (requestData.enableRuntimeChallenge)
4301
4302
  body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
4302
4303
  if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
4304
+ if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
4303
4305
  if (requestData.createSession) body.createSession = requestData.createSession;
4304
4306
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
4305
4307
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
@@ -4631,6 +4633,8 @@ async function verify(config, request, options) {
4631
4633
  } else if (result.recommendation === "step_up_required" && result.identityVerified) {
4632
4634
  result.requiresStepUp = true;
4633
4635
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
4636
+ const stepUpFailures = apiResponse.access?.failures;
4637
+ if (stepUpFailures?.length) result.failures = stepUpFailures;
4634
4638
  }
4635
4639
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
4636
4640
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {