@astrasyncai/verification-gateway 4.2.1 → 4.4.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 (138) hide show
  1. package/README.md +45 -21
  2. package/dist/adapter-interface/interface.d.mts +2 -2
  3. package/dist/adapter-interface/interface.d.ts +2 -2
  4. package/dist/adapters/express.d.mts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +145 -21
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +145 -21
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +38 -30
  11. package/dist/adapters/mcp.d.ts +38 -30
  12. package/dist/adapters/mcp.js +72 -16
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +72 -16
  15. package/dist/adapters/mcp.mjs.map +1 -1
  16. package/dist/adapters/nextjs.d.mts +2 -2
  17. package/dist/adapters/nextjs.d.ts +2 -2
  18. package/dist/adapters/nextjs.js +141 -19
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +141 -19
  21. package/dist/adapters/nextjs.mjs.map +1 -1
  22. package/dist/adapters/sdk.d.mts +2 -2
  23. package/dist/adapters/sdk.d.ts +2 -2
  24. package/dist/adapters/sdk.js +24 -6
  25. package/dist/adapters/sdk.js.map +1 -1
  26. package/dist/adapters/sdk.mjs +24 -6
  27. package/dist/adapters/sdk.mjs.map +1 -1
  28. package/dist/agent/index.d.mts +2 -2
  29. package/dist/agent/index.d.ts +2 -2
  30. package/dist/agent/index.js +24 -3
  31. package/dist/agent/index.js.map +1 -1
  32. package/dist/agent/index.mjs +24 -3
  33. package/dist/agent/index.mjs.map +1 -1
  34. package/dist/bin/astrasync-claude-hook.js +22 -4
  35. package/dist/bin/astrasync-codex-hook.js +22 -4
  36. package/dist/bin/astrasync-guard.js +26 -8
  37. package/dist/bin/astrasync.js +76 -23
  38. package/dist/browser/background.js +22 -4
  39. package/dist/browser/background.js.map +1 -1
  40. package/dist/browser/background.mjs +22 -4
  41. package/dist/browser/background.mjs.map +1 -1
  42. package/dist/browser/browser-adapter.d.mts +2 -2
  43. package/dist/browser/browser-adapter.d.ts +2 -2
  44. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  45. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  46. package/dist/cli/index.d.mts +2 -2
  47. package/dist/cli/index.d.ts +2 -2
  48. package/dist/cli/index.js +23 -2
  49. package/dist/cli/index.js.map +1 -1
  50. package/dist/cli/index.mjs +23 -2
  51. package/dist/cli/index.mjs.map +1 -1
  52. package/dist/codex/index.d.mts +2 -2
  53. package/dist/codex/index.d.ts +2 -2
  54. package/dist/codex/index.js +22 -4
  55. package/dist/codex/index.js.map +1 -1
  56. package/dist/codex/index.mjs +22 -4
  57. package/dist/codex/index.mjs.map +1 -1
  58. package/dist/cursor/cursor-adapter.d.mts +2 -2
  59. package/dist/cursor/cursor-adapter.d.ts +2 -2
  60. package/dist/cursor/extension.d.mts +2 -2
  61. package/dist/cursor/extension.d.ts +2 -2
  62. package/dist/cursor/extension.js +22 -4
  63. package/dist/cursor/extension.js.map +1 -1
  64. package/dist/cursor/extension.mjs +22 -4
  65. package/dist/cursor/extension.mjs.map +1 -1
  66. package/dist/edge-config.d.mts +1 -1
  67. package/dist/edge-config.d.ts +1 -1
  68. package/dist/edge-config.js +24 -1
  69. package/dist/edge-config.js.map +1 -1
  70. package/dist/edge-config.mjs +22 -1
  71. package/dist/edge-config.mjs.map +1 -1
  72. package/dist/edge-core/index.d.mts +1 -1
  73. package/dist/edge-core/index.d.ts +1 -1
  74. package/dist/edge-core/index.js +121 -16
  75. package/dist/edge-core/index.js.map +1 -1
  76. package/dist/edge-core/index.mjs +121 -16
  77. package/dist/edge-core/index.mjs.map +1 -1
  78. package/dist/{express-D_4hTn5Z.d.mts → express-CR6F3njD.d.mts} +1 -1
  79. package/dist/{express-BVd1_3FE.d.ts → express-DaqL11tx.d.ts} +1 -1
  80. package/dist/gateway/gateway.d.mts +2 -2
  81. package/dist/gateway/gateway.d.ts +2 -2
  82. package/dist/gateway/gateway.js +22 -4
  83. package/dist/gateway/gateway.js.map +1 -1
  84. package/dist/gateway/gateway.mjs +22 -4
  85. package/dist/gateway/gateway.mjs.map +1 -1
  86. package/dist/git-trigger/git-hooks.d.mts +2 -2
  87. package/dist/git-trigger/git-hooks.d.ts +2 -2
  88. package/dist/{index-BqHKlLOU.d.ts → index-B5Ts1WtM.d.ts} +1 -1
  89. package/dist/{index-T1aBoUcc.d.ts → index-BfIxCYIZ.d.ts} +1 -1
  90. package/dist/{index-BTeQ9fgV.d.mts → index-Cub7lK-T.d.mts} +1 -1
  91. package/dist/{index-DQb5-_1X.d.mts → index-CwAh7Tln.d.mts} +1 -1
  92. package/dist/index.d.mts +58 -9
  93. package/dist/index.d.ts +58 -9
  94. package/dist/index.js +218 -54
  95. package/dist/index.js.map +1 -1
  96. package/dist/index.mjs +214 -54
  97. package/dist/index.mjs.map +1 -1
  98. package/dist/local-evaluator/evaluator.d.mts +2 -2
  99. package/dist/local-evaluator/evaluator.d.ts +2 -2
  100. package/dist/metadata-capture.d.mts +35 -5
  101. package/dist/metadata-capture.d.ts +35 -5
  102. package/dist/metadata-capture.js +44 -6
  103. package/dist/metadata-capture.js.map +1 -1
  104. package/dist/metadata-capture.mjs +43 -6
  105. package/dist/metadata-capture.mjs.map +1 -1
  106. package/dist/{nextjs-w7RTbP1P.d.ts → nextjs-DL6uE1ye.d.ts} +1 -1
  107. package/dist/{nextjs-WyeVr2Kp.d.mts → nextjs-DlX6xwbU.d.mts} +1 -1
  108. package/dist/platform-signatures.d.mts +18 -1
  109. package/dist/platform-signatures.d.ts +18 -1
  110. package/dist/platform-signatures.js +35 -2
  111. package/dist/platform-signatures.js.map +1 -1
  112. package/dist/platform-signatures.mjs +35 -2
  113. package/dist/platform-signatures.mjs.map +1 -1
  114. package/dist/registration/index.js +25 -4
  115. package/dist/registration/index.js.map +1 -1
  116. package/dist/registration/index.mjs +25 -4
  117. package/dist/registration/index.mjs.map +1 -1
  118. package/dist/{sdk-CbTNIkAa.d.mts → sdk-Bbh9B_dw.d.mts} +1 -1
  119. package/dist/{sdk-QeX0Z8Ho.d.ts → sdk-C6SASmsh.d.ts} +1 -1
  120. package/dist/transport/index.d.mts +2 -2
  121. package/dist/transport/index.d.ts +2 -2
  122. package/dist/transport/index.js +22 -1
  123. package/dist/transport/index.js.map +1 -1
  124. package/dist/transport/index.mjs +22 -1
  125. package/dist/transport/index.mjs.map +1 -1
  126. package/dist/{types-r850cOt0.d.mts → types-C0zfSXMB.d.mts} +22 -0
  127. package/dist/{types-DqfPU5Bl.d.mts → types-C7Rb-w0d.d.mts} +1 -1
  128. package/dist/{types-sMxBT-nM.d.ts → types-DwSfO7Sb.d.ts} +22 -0
  129. package/dist/{types-BLUx92FJ.d.ts → types-nIh3HtuA.d.ts} +1 -1
  130. package/dist/ui/index.d.mts +1 -1
  131. package/dist/ui/index.d.ts +1 -1
  132. package/dist/verify.d.mts +1 -1
  133. package/dist/verify.d.ts +1 -1
  134. package/dist/verify.js +29 -11
  135. package/dist/verify.js.map +1 -1
  136. package/dist/verify.mjs +29 -11
  137. package/dist/verify.mjs.map +1 -1
  138. package/package.json +1 -1
@@ -1,3 +1,24 @@
1
+ // src/version.ts
2
+ var SDK_VERSION = "4.4.0";
3
+
4
+ // src/http.ts
5
+ var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
6
+ function withUserAgent(initHeaders) {
7
+ if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
8
+ if (initHeaders instanceof Headers) {
9
+ const copy = new Headers(initHeaders);
10
+ if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
11
+ return copy;
12
+ }
13
+ if (Array.isArray(initHeaders)) {
14
+ const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
15
+ return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
16
+ }
17
+ const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
18
+ return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
19
+ }
20
+ var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
21
+
1
22
  // src/edge-config.ts
2
23
  var DEFAULT_EDGE_CONFIG = Object.freeze({
3
24
  version: 1,
@@ -30,7 +51,9 @@ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
30
51
  "x-astrasync-signature",
31
52
  "x-astrasync-secret",
32
53
  "x-hub-signature",
33
- "x-hub-signature-256"
54
+ "x-hub-signature-256",
55
+ // Short-lived verify dedupe token — must never persist in stored metadata.
56
+ "x-astra-verified-hop"
34
57
  ]);
35
58
  var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
36
59
  var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
@@ -55,7 +78,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
55
78
  "x-agent-card-url",
56
79
  "x-agent-provider"
57
80
  ]);
58
- var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
81
+ var PLATFORM_HEADER_PREFIXES = [
82
+ "x-goog-",
83
+ "x-stainless-",
84
+ "x-anthropic-",
85
+ "x-openai-",
86
+ "sec-ch-"
87
+ ];
59
88
  var KEY_FORMAT_PREFIXES = [
60
89
  "sk-ant-api03",
61
90
  "sk-ant-api",
@@ -127,6 +156,7 @@ function sanitizeHeaders(raw) {
127
156
  const headers = {};
128
157
  const platformHeaders = {};
129
158
  let apiKeyFormat;
159
+ let cookieCount;
130
160
  let totalBytes = 0;
131
161
  let count = 0;
132
162
  if (!raw) return { headers };
@@ -141,6 +171,9 @@ function sanitizeHeaders(raw) {
141
171
  if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
142
172
  continue;
143
173
  }
174
+ if (name === "cookie") {
175
+ cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
176
+ }
144
177
  if (isSecretHeader(name)) continue;
145
178
  let value = joined;
146
179
  if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
@@ -156,6 +189,7 @@ function sanitizeHeaders(raw) {
156
189
  const result = { headers };
157
190
  if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
158
191
  if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
192
+ if (cookieCount !== void 0) result.cookieCount = cookieCount;
159
193
  return result;
160
194
  }
161
195
 
@@ -203,12 +237,43 @@ var PLATFORM_AGENT_SIGNATURES = [
203
237
  uaPatterns: [/perplexity/i],
204
238
  agentCardPatterns: [/perplexity\.ai/i],
205
239
  apiKeyFormatPatterns: [/^pplx-/i]
240
+ },
241
+ // Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
242
+ // never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
243
+ // browser product is a different surface than the assistant service, and
244
+ // the DB registry mirrors one row per vendor. These sit after the primary
245
+ // vendor entries so a UA carrying an explicit vendor token keeps its
246
+ // primary attribution; a browser-shaped UA with the agentic token is
247
+ // caught here BEFORE classify's human tier, which is what makes these
248
+ // visits observable at all. Token drift is real (some builds mimic Chrome
249
+ // outright) — re-verify against captured events when a new browser ships,
250
+ // and check `sec-ch-ua` platformHeaders for the real brand.
251
+ {
252
+ vendor: "chatgpt-atlas",
253
+ displayName: "ChatGPT Atlas browser",
254
+ uaPatterns: [/\batlas\/\d/i],
255
+ headerPatterns: [/^sec-ch-ua: .*atlas/i]
256
+ },
257
+ {
258
+ vendor: "perplexity-comet",
259
+ displayName: "Perplexity Comet browser",
260
+ uaPatterns: [/\bcomet\/\d/i],
261
+ headerPatterns: [/^sec-ch-ua: .*comet/i]
262
+ },
263
+ // Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
264
+ // traffic must never pollute the unknown/anonymous pool it exists to audit.
265
+ {
266
+ vendor: "astrasync-sdk",
267
+ displayName: "AstraSync SDK",
268
+ uaPatterns: [/^astrasync-sdk\//i]
206
269
  }
207
270
  ];
208
271
  function matchPlatformSignature(signatures, input) {
209
272
  const ua = input.userAgent ?? "";
210
273
  const cardUrl = input.agentCardUrl ?? "";
211
274
  const apiKeyFormat = input.apiKeyFormat ?? "";
275
+ const ja4 = input.ja4 ?? "";
276
+ const asn = input.asn ?? "";
212
277
  const headerLines = [];
213
278
  if (input.platformHeaders) {
214
279
  for (const [name, value] of Object.entries(input.platformHeaders)) {
@@ -220,7 +285,9 @@ function matchPlatformSignature(signatures, input) {
220
285
  const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
221
286
  const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
222
287
  const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
223
- if (uaMatch || cardMatch || keyMatch || headerMatch) {
288
+ const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
289
+ const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
290
+ if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
224
291
  const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
225
292
  const cardHost = (() => {
226
293
  try {
@@ -229,7 +296,7 @@ function matchPlatformSignature(signatures, input) {
229
296
  return "";
230
297
  }
231
298
  })();
232
- const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
299
+ const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
233
300
  return {
234
301
  vendor: sig.vendor,
235
302
  fingerprintKey: `${sig.vendor}:${keyBasis}`,
@@ -251,9 +318,6 @@ function getTrustLevel(score) {
251
318
  return "BRONZE";
252
319
  }
253
320
 
254
- // src/version.ts
255
- var SDK_VERSION = "4.1.0";
256
-
257
321
  // src/well-known.ts
258
322
  var CACHE_TTL_MS = 60 * 60 * 1e3;
259
323
  var cache = /* @__PURE__ */ new Map();
@@ -282,7 +346,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
282
346
  initCheckPerformed = true;
283
347
  try {
284
348
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
285
- const response = await fetch(probeUrl, { method: "HEAD" });
349
+ const response = await sdkFetch(probeUrl, { method: "HEAD" });
286
350
  const contentType = response.headers.get("content-type") ?? "";
287
351
  if (contentType.startsWith("text/html")) {
288
352
  const message = `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). This usually means apiBaseUrl is pointing at a marketing site instead of the API. Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging).`;
@@ -296,7 +360,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
296
360
  );
297
361
  }
298
362
  if (apiKey) {
299
- const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
363
+ const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
300
364
  headers: { Authorization: `Bearer ${apiKey}` }
301
365
  });
302
366
  if (selfCheck.status === 401) {
@@ -543,7 +607,7 @@ async function callVerifyAccessAPI(config, request) {
543
607
  headers["X-API-Key"] = config.apiKey;
544
608
  }
545
609
  try {
546
- const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
610
+ const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
547
611
  method: "POST",
548
612
  headers,
549
613
  body: JSON.stringify(body),
@@ -788,7 +852,7 @@ async function reportUnregisteredAttempt(config, data) {
788
852
  ...counterpartyUrl && { counterpartyUrl },
789
853
  ...config.counterpartyId && { counterpartyId: config.counterpartyId }
790
854
  };
791
- await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
855
+ await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
792
856
  method: "POST",
793
857
  headers: { "Content-Type": "application/json" },
794
858
  body: JSON.stringify(body)
@@ -805,16 +869,39 @@ function requestUrl(req, host) {
805
869
  return `https://${host}${req.uri}${qs}`;
806
870
  }
807
871
  function buildObservedMetadata(req) {
808
- const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(req.headers);
872
+ const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(req.headers);
809
873
  const connection = req.connection ?? {};
874
+ const queryKeys = extractQueryKeys(req.querystring);
810
875
  return {
811
876
  headers,
812
877
  ...apiKeyFormat && { apiKeyFormat },
813
878
  ...platformHeaders && { platformHeaders },
814
879
  ...Object.keys(connection).length > 0 && { connection },
880
+ ...cookieCount !== void 0 && { cookieCount },
881
+ ...queryKeys && { queryKeys },
815
882
  schemaVersion: CAPTURE_SCHEMA_VERSION
816
883
  };
817
884
  }
885
+ var MAX_QUERY_KEYS = 32;
886
+ var MAX_QUERY_KEY_CHARS = 64;
887
+ function extractQueryKeys(querystring) {
888
+ if (!querystring) return void 0;
889
+ let params;
890
+ try {
891
+ params = new URLSearchParams(querystring);
892
+ } catch {
893
+ return void 0;
894
+ }
895
+ const keys = [];
896
+ for (const key of params.keys()) {
897
+ const normalized = key.toLowerCase().slice(0, MAX_QUERY_KEY_CHARS);
898
+ if (normalized && !keys.includes(normalized)) {
899
+ keys.push(normalized);
900
+ if (keys.length >= MAX_QUERY_KEYS) break;
901
+ }
902
+ }
903
+ return keys.length > 0 ? keys : void 0;
904
+ }
818
905
 
819
906
  // src/edge-core/detect.ts
820
907
  var SD_JWT_PATTERN = /^eyJ[\w-]+\.[\w-]*\.[\w-]+~/;
@@ -1054,6 +1141,12 @@ function buildManualReviewBody(outcome) {
1054
1141
  };
1055
1142
  }
1056
1143
 
1144
+ // src/verified-hop.ts
1145
+ var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
1146
+ function serializeVerifiedHop(marker) {
1147
+ return `${marker.astraId};${marker.sessionId ?? ""};${marker.checkedAt}`;
1148
+ }
1149
+
1057
1150
  // src/edge-core/enforce.ts
1058
1151
  var ASAT_HEADERS = {
1059
1152
  trustScore: "X-AstraSync-Trust-Score",
@@ -1062,6 +1155,7 @@ var ASAT_HEADERS = {
1062
1155
  permissions: "X-AstraSync-Permissions",
1063
1156
  observedDecision: "X-AstraSync-Observed-Decision"
1064
1157
  };
1158
+ var STRIP_HEADER_PREFIXES = ["x-astrasync-", "x-astra-verified-hop"];
1065
1159
  function passUntouched() {
1066
1160
  return { action: "pass", injectHeaders: {}, stripHeaderPrefixes: [] };
1067
1161
  }
@@ -1074,8 +1168,8 @@ function applyOutcome(options, outcome, policy) {
1074
1168
  if (outcome.decision !== "allow") {
1075
1169
  injectHeaders[ASAT_HEADERS.observedDecision] = outcome.decision;
1076
1170
  }
1077
- Object.assign(injectHeaders, asatHeaders(outcome));
1078
- return { action: "pass", injectHeaders, stripHeaderPrefixes: ["x-astrasync-"] };
1171
+ Object.assign(injectHeaders, asatHeaders(outcome), verifiedHopHeader(outcome));
1172
+ return { action: "pass", injectHeaders, stripHeaderPrefixes: STRIP_HEADER_PREFIXES };
1079
1173
  }
1080
1174
  switch (outcome.decision) {
1081
1175
  case "deny":
@@ -1093,8 +1187,8 @@ function applyOutcome(options, outcome, policy) {
1093
1187
  bodyJson: buildManualReviewBody(outcome)
1094
1188
  };
1095
1189
  default:
1096
- Object.assign(injectHeaders, asatHeaders(outcome));
1097
- return { action: "pass", injectHeaders, stripHeaderPrefixes: ["x-astrasync-"] };
1190
+ Object.assign(injectHeaders, asatHeaders(outcome), verifiedHopHeader(outcome));
1191
+ return { action: "pass", injectHeaders, stripHeaderPrefixes: STRIP_HEADER_PREFIXES };
1098
1192
  }
1099
1193
  }
1100
1194
  function asatHeaders(outcome) {
@@ -1107,6 +1201,17 @@ function asatHeaders(outcome) {
1107
1201
  ...accessLevel && { [ASAT_HEADERS.permissions]: accessLevel }
1108
1202
  };
1109
1203
  }
1204
+ function verifiedHopHeader(outcome) {
1205
+ const agentId = outcome.asat?.agentId;
1206
+ if (!agentId) return {};
1207
+ return {
1208
+ [MCP_VERIFIED_HOP_HEADER]: serializeVerifiedHop({
1209
+ astraId: agentId,
1210
+ ...outcome.sessionId && { sessionId: outcome.sessionId },
1211
+ checkedAt: Date.now()
1212
+ })
1213
+ };
1214
+ }
1110
1215
 
1111
1216
  // src/adapters/http-pdlss.ts
1112
1217
  var HTTP_METHOD_ACTION_TABLE = {