@atbash/sdk 0.9.2 → 0.10.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.
package/dist/browser.mjs CHANGED
@@ -40585,7 +40585,7 @@ function requireFailoverStrategies() {
40585
40585
  exports.createTimeoutPromise = createTimeoutPromise;
40586
40586
  const utils_12 = requireUtils$1();
40587
40587
  const httpUtil_1 = httpUtil;
40588
- const logger2 = __importStar2(logger$3);
40588
+ const logger3 = __importStar2(logger$3);
40589
40589
  const http_utils_1 = httpUtils;
40590
40590
  function getUnreachableDuration(statusCode, error4) {
40591
40591
  if ((0, http_utils_1.isNetworkError)(error4)) {
@@ -40686,7 +40686,7 @@ function requireFailoverStrategies() {
40686
40686
  while (true) {
40687
40687
  if (groupedSuccessfulResponses.maxNumberOfEqualResponses() >= bftMajorityThreshold) {
40688
40688
  if (groupedSuccessfulResponses.numberOfDistinctResponses() > 1) {
40689
- logger2.warning(`Got disagreeing responses, but could still reach BFT majority`);
40689
+ logger3.warning(`Got disagreeing responses, but could still reach BFT majority`);
40690
40690
  }
40691
40691
  return groupedSuccessfulResponses.majorityResponse();
40692
40692
  }
@@ -40724,7 +40724,7 @@ function requireFailoverStrategies() {
40724
40724
  if (!isError4 && !error4) {
40725
40725
  return { error: error4, statusCode, rspBody, transactionTimestamp };
40726
40726
  }
40727
- logger2.info(`${method} request failed on ${endpoint.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
40727
+ logger3.info(`${method} request failed on ${endpoint.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
40728
40728
  yield (0, utils_12.sleep)(config2.attemptInterval);
40729
40729
  }
40730
40730
  return { error: error4, statusCode, rspBody, transactionTimestamp };
@@ -40760,7 +40760,7 @@ function requireFailoverStrategies() {
40760
40760
  if (isServerError) {
40761
40761
  const duration = getUnreachableDuration(statusCode !== null && statusCode !== void 0 ? statusCode : void 0, response.error);
40762
40762
  nodeManager2.makeNodeUnavailable(node2.url, duration);
40763
- logger2.info(`request failed with server error on ${node2.url} trying next node`);
40763
+ logger3.info(`request failed with server error on ${node2.url} trying next node`);
40764
40764
  break;
40765
40765
  }
40766
40766
  if (isClientError) {
@@ -40768,11 +40768,11 @@ function requireFailoverStrategies() {
40768
40768
  return { error: error4, statusCode, rspBody, transactionTimestamp };
40769
40769
  }
40770
40770
  if (!nodeManager2.useStickyNode) {
40771
- logger2.info(`request failed client error on ${node2.url} trying next node`);
40771
+ logger3.info(`request failed client error on ${node2.url} trying next node`);
40772
40772
  break;
40773
40773
  }
40774
40774
  }
40775
- logger2.info(`${method} request failed on ${node2.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
40775
+ logger3.info(`${method} request failed on ${node2.url}. Attempt: ${attempt + 1} / ${config2.attemptsPerEndpoint}`);
40776
40776
  if (config2.attemptInterval > 0) {
40777
40777
  yield (0, utils_12.sleep)(config2.attemptInterval);
40778
40778
  }
@@ -41001,7 +41001,7 @@ function requireUtils$1() {
41001
41001
  exports.getBlockchainRidFromIid = getBlockchainRidFromIid;
41002
41002
  exports.convertToPrintable = convertToPrintable;
41003
41003
  const buffer_12 = buffer$3;
41004
- const logger2 = __importStar2(logger$3);
41004
+ const logger3 = __importStar2(logger$3);
41005
41005
  const errors_12 = errors;
41006
41006
  const gtxTool = __importStar2(gtx$1);
41007
41007
  const errors_2 = errors;
@@ -41084,7 +41084,7 @@ function requireUtils$1() {
41084
41084
  function validTxRid(txRID) {
41085
41085
  if (txRID.length != 32) {
41086
41086
  const error4 = new errors_12.InvalidTxRidException(txRID);
41087
- logger2.error(error4.toString());
41087
+ logger3.error(error4.toString());
41088
41088
  return false;
41089
41089
  }
41090
41090
  return true;
@@ -41487,7 +41487,7 @@ function requireUtils$1() {
41487
41487
  function handleGetResponse(error4, statusCode, responseObject, callback) {
41488
41488
  try {
41489
41489
  const responseObjectPrintable = convertToPrintable(responseObject);
41490
- logger2.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
41490
+ logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
41491
41491
  if (error4) {
41492
41492
  return callback(error4, null);
41493
41493
  }
@@ -41497,16 +41497,16 @@ function requireUtils$1() {
41497
41497
  return callback(null, responseObject);
41498
41498
  } catch (error5) {
41499
41499
  callback(error5, null);
41500
- logger2.error(`client.handleGetResponse(): Failed to call the callback function. ${error5}`);
41500
+ logger3.error(`client.handleGetResponse(): Failed to call the callback function. ${error5}`);
41501
41501
  }
41502
41502
  }
41503
41503
  function handlePostResponse(error4, statusCode, responseObject, callback) {
41504
41504
  var _a2;
41505
41505
  const responseObjectPrintable = convertToPrintable(responseObject);
41506
- logger2.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
41506
+ logger3.debug(`error: ${error4}, status code: ${statusCode}, response body: ${responseObjectPrintable}`);
41507
41507
  try {
41508
41508
  if (error4) {
41509
- logger2.error(`In client post(). ${error4}`);
41509
+ logger3.error(`In client post(). ${error4}`);
41510
41510
  callback(error4, null);
41511
41511
  } else if (!statusCode || !(0, http_utils_1.isSuccessfulStatusCode)(statusCode)) {
41512
41512
  let errorMessage2 = `Unexpected status code from server. Code: ${statusCode}.`;
@@ -41514,14 +41514,14 @@ function requireUtils$1() {
41514
41514
  if (responseObjectPrintable) {
41515
41515
  errorMessage2 += ` Message: ${responseObjectPrintable}.`;
41516
41516
  }
41517
- logger2.error(errorMessage2);
41517
+ logger3.error(errorMessage2);
41518
41518
  callback(new errors_12.UnexpectedStatusError(statusCode !== null && statusCode !== void 0 ? statusCode : 400, errorMessageInResponseBody || responseObjectPrintable), responseObject);
41519
41519
  } else {
41520
- logger2.info(`Calling responseCallback with responseObject: ${responseObjectPrintable}`);
41520
+ logger3.info(`Calling responseCallback with responseObject: ${responseObjectPrintable}`);
41521
41521
  callback(null, responseObject);
41522
41522
  }
41523
41523
  } catch (error5) {
41524
- logger2.error(`client.handlePostResponse(): Failed to call callback function ${error5}`);
41524
+ logger3.error(`client.handlePostResponse(): Failed to call callback function ${error5}`);
41525
41525
  }
41526
41526
  }
41527
41527
  function getBlockchainRidFromIid(_a2) {
@@ -42259,7 +42259,7 @@ function requireBlockchainClient() {
42259
42259
  const crypto_12 = requireCryptoBrowserify();
42260
42260
  const cloneDeep_1$1 = __importDefault2(cloneDeep_1);
42261
42261
  const IccfProofTxMaterialBuilder_1 = requireIccfProofTxMaterialBuilder();
42262
- const logger2 = __importStar2(logger$3);
42262
+ const logger3 = __importStar2(logger$3);
42263
42263
  const formatter_12 = formatter;
42264
42264
  const serialization_12 = serialization$2;
42265
42265
  const gtxTool = __importStar2(gtx$1);
@@ -42301,7 +42301,7 @@ function requireBlockchainClient() {
42301
42301
  },
42302
42302
  signTransaction(transaction, signMethod2, callback) {
42303
42303
  return __awaiter2(this, void 0, void 0, function* () {
42304
- logger2.debug(`Signing transaction with ${!(0, utils_12.isKeyPair)(signMethod2) ? "signature provider containing " : ""}pubKey: ${(0, formatter_12.toString)(signMethod2.pubKey)}`);
42304
+ logger3.debug(`Signing transaction with ${!(0, utils_12.isKeyPair)(signMethod2) ? "signature provider containing " : ""}pubKey: ${(0, formatter_12.toString)(signMethod2.pubKey)}`);
42305
42305
  const gtx2 = (0, utils_12.getGTXFromBufferOrTransactionOrOperation)(transaction, config2.blockchainRid);
42306
42306
  try {
42307
42307
  const signedTx = yield (0, utils_12.isKeyPair)(signMethod2) ? gtxTool.sign(gtx2, signMethod2.privKey, config2.merkleHashVersion, signMethod2.pubKey) : gtxTool.sign(gtx2, signMethod2, config2.merkleHashVersion);
@@ -42326,7 +42326,7 @@ function requireBlockchainClient() {
42326
42326
  const promiEvent = new promiEvents_12.Web3PromiEvent((resolve2, reject) => __awaiter2(this, void 0, void 0, function* () {
42327
42327
  let error4 = null;
42328
42328
  for (let i = 0; i < config2.retryTransactionPolling.count; i++) {
42329
- logger2.info(`sendTransactionWithRetries attempt ${i + 1} of ${config2.retryTransactionPolling.count}`);
42329
+ logger3.info(`sendTransactionWithRetries attempt ${i + 1} of ${config2.retryTransactionPolling.count}`);
42330
42330
  const tmpPromiEvent = sendOnce().on(enums_12.TransactionEvent.ClusterAnchoringConfirmation, (receipt) => {
42331
42331
  promiEvent.emit(enums_12.TransactionEvent.ClusterAnchoringConfirmation, receipt);
42332
42332
  }).on(enums_12.TransactionEvent.SystemAnchoringConfirmation, (receipt) => {
@@ -42338,7 +42338,7 @@ function requireBlockchainClient() {
42338
42338
  }).on(enums_12.TransactionEvent.DappConfirmed, (receipt) => {
42339
42339
  promiEvent.emit(enums_12.TransactionEvent.DappConfirmed, receipt);
42340
42340
  }).catch((tmpError) => {
42341
- logger2.warning(`sendTransactionWithRetries error on attempt ${i + 1} of ${config2.retryTransactionPolling.count}: ${tmpError}`);
42341
+ logger3.warning(`sendTransactionWithRetries error on attempt ${i + 1} of ${config2.retryTransactionPolling.count}: ${tmpError}`);
42342
42342
  promiEvent.emit(enums_12.TransactionEvent.Rejected, tmpError);
42343
42343
  error4 = tmpError;
42344
42344
  });
@@ -43073,11 +43073,11 @@ function requireDecodeTransactionToGtx() {
43073
43073
  Object.defineProperty(decodeTransactionToGtx, "__esModule", { value: true });
43074
43074
  decodeTransactionToGtx.decodeTransactionToGtx = decodeTransactionToGtx$1;
43075
43075
  const gtxTool = __importStar2(gtx$1);
43076
- const logger2 = __importStar2(logger$3);
43076
+ const logger3 = __importStar2(logger$3);
43077
43077
  const dump_1 = requireDump();
43078
43078
  function decodeTransactionToGtx$1(encodedTransaction) {
43079
43079
  const gtx2 = gtxTool.deserialize(encodedTransaction);
43080
- logger2.debug(`Output from deserializing a raw transaction: ${(0, dump_1.dumpGtv)(gtx2)}`);
43080
+ logger3.debug(`Output from deserializing a raw transaction: ${(0, dump_1.dumpGtv)(gtx2)}`);
43081
43081
  return gtx2;
43082
43082
  }
43083
43083
  return decodeTransactionToGtx;
@@ -43455,6 +43455,17 @@ var native = {
43455
43455
  defaultChromiaNodeUrls: () => [...DEFAULT_CHROMIA_NODE_URLS_ARR],
43456
43456
  defaultPrivateNodeUrls: () => [...DEFAULT_PRIVATE_NODE_URLS_ARR],
43457
43457
  // Server-only surfaces — throw at runtime, keep types satisfied.
43458
+ // The memory signers are here and not with the other signing shims because
43459
+ // their args are encrypted by `encryptMemoryContent`, which this build does
43460
+ // not have: a browser could sign the transaction but never produce one worth
43461
+ // sending.
43462
+ signAddAgentMemory: stub("signAddAgentMemory"),
43463
+ signRollbackAgentMemory: stub("signRollbackAgentMemory"),
43464
+ extractMemoryEdits: stub("extractMemoryEdits"),
43465
+ applyMemoryEdits: stub("applyMemoryEdits"),
43466
+ memorySlotForPath: stub("memorySlotForPath"),
43467
+ isSafeMemorySlot: stub("isSafeMemorySlot"),
43468
+ defaultAgentHomeDirs: stub("defaultAgentHomeDirs"),
43458
43469
  classifyMemoryWrite: stub("classifyMemoryWrite"),
43459
43470
  classifyMemoryRead: stub("classifyMemoryRead"),
43460
43471
  defaultMemoryWriteToolNames: stub("defaultMemoryWriteToolNames"),
@@ -43531,6 +43542,32 @@ function randomHex(size) {
43531
43542
  return hex;
43532
43543
  }
43533
43544
 
43545
+ // src-ts/auth-bearer.ts
43546
+ init_define_ATBASH_CHROMIA_NODE_URLS();
43547
+ init_define_ATBASH_PRIVATE_NODE_URLS();
43548
+ var BEARER_TTL_MS = 4 * 60 * 1e3;
43549
+ var bearers = /* @__PURE__ */ new Map();
43550
+ function agentAuthBearer(auth, blockchainRid) {
43551
+ const key3 = `${auth.pubkey}:${blockchainRid}`;
43552
+ const now = Date.now();
43553
+ const cached = bearers.get(key3);
43554
+ if (cached && now - cached.issuedAt < BEARER_TTL_MS) return cached.hex;
43555
+ const hex = native.signLogToolCall(
43556
+ `auth-${now.toString(36)}-${randomHex(4)}`,
43557
+ `auth:${now}`,
43558
+ "",
43559
+ "auth-bearer",
43560
+ "",
43561
+ auth.privkey,
43562
+ blockchainRid
43563
+ );
43564
+ bearers.set(key3, { hex, issuedAt: now });
43565
+ return hex;
43566
+ }
43567
+ function agentAuthHeaders(auth, blockchainRid) {
43568
+ return { Authorization: `Bearer ${agentAuthBearer(auth, blockchainRid)}` };
43569
+ }
43570
+
43534
43571
  // src-ts/chain-config.ts
43535
43572
  init_define_ATBASH_CHROMIA_NODE_URLS();
43536
43573
  init_define_ATBASH_PRIVATE_NODE_URLS();
@@ -44588,9 +44625,19 @@ init_define_ATBASH_PRIVATE_NODE_URLS();
44588
44625
  // src-ts/normalize.ts
44589
44626
  init_define_ATBASH_CHROMIA_NODE_URLS();
44590
44627
  init_define_ATBASH_PRIVATE_NODE_URLS();
44628
+ function wireText(raw2, fallback = "") {
44629
+ if (raw2 === null || raw2 === void 0) return fallback;
44630
+ if (typeof raw2 === "object" || typeof raw2 === "function") return fallback;
44631
+ return String(raw2);
44632
+ }
44633
+ function wireNumber(raw2, fallback = 0) {
44634
+ if (raw2 === null || raw2 === void 0) return fallback;
44635
+ if (typeof raw2 === "object" || typeof raw2 === "function") return fallback;
44636
+ return Number(raw2);
44637
+ }
44591
44638
  function normalizeVerdict(raw2) {
44592
44639
  if (raw2 === null || raw2 === void 0) return "No verdict";
44593
- const v = String(raw2).toUpperCase();
44640
+ const v = wireText(raw2).trim().toUpperCase();
44594
44641
  if (v === "ALLOW" || v === "GREEN") return "ALLOW";
44595
44642
  if (v === "HOLD" || v === "YELLOW") return "HOLD";
44596
44643
  if (v === "BLOCK" || v === "RED") return "BLOCK";
@@ -44600,7 +44647,7 @@ function normalizeActionType(raw2) {
44600
44647
  return typeof raw2 === "string" ? raw2.trim().toLowerCase() : "";
44601
44648
  }
44602
44649
  function normalizeStatus(raw2) {
44603
- const s2 = String(raw2 ?? "").toLowerCase();
44650
+ const s2 = wireText(raw2).toLowerCase();
44604
44651
  if (s2 === "pending" || s2 === "answered" || s2 === "error") return s2;
44605
44652
  return "error";
44606
44653
  }
@@ -44627,17 +44674,58 @@ function allowSignalsPermit(data) {
44627
44674
  }
44628
44675
  return signals.length === 0 || signals.every((value) => value === true);
44629
44676
  }
44677
+ function explicitRefusal(data) {
44678
+ let hold = false;
44679
+ for (const source of decisionSources(data)) {
44680
+ const verdict = verdictOf(source);
44681
+ if (verdict === "BLOCK" || verdict === "RED") return "BLOCK";
44682
+ if (verdict === "HOLD" || verdict === "YELLOW") hold = true;
44683
+ const actionType = actionTypeOf(source);
44684
+ if (actionType === "block") return "BLOCK";
44685
+ if (actionType === "hold_for_user_confirm") hold = true;
44686
+ }
44687
+ if (!allowSignalsPermit(data)) return "BLOCK";
44688
+ return hold ? "HOLD" : "";
44689
+ }
44690
+ function decisionSources(data) {
44691
+ return [data, isRecord(data.decision) ? data.decision : {}];
44692
+ }
44693
+ function verdictOf(source) {
44694
+ return typeof source.verdict === "string" ? source.verdict.trim().toUpperCase() : "";
44695
+ }
44696
+ function actionTypeRank(actionType) {
44697
+ if (actionType === "block") return 4;
44698
+ if (actionType === "hold_for_user_confirm") return 3;
44699
+ if (actionType === "") return 1;
44700
+ if (actionType === "allow") return 0;
44701
+ return 2;
44702
+ }
44703
+ function actionTypeOf(source) {
44704
+ let winner = "";
44705
+ for (const key3 of ["action_type", "actionType"]) {
44706
+ const raw2 = source[key3];
44707
+ if (raw2 === void 0 || raw2 === null) continue;
44708
+ const actionType = normalizeActionType(raw2);
44709
+ if (actionTypeRank(actionType) > actionTypeRank(winner)) winner = actionType;
44710
+ }
44711
+ return winner;
44712
+ }
44630
44713
  function wireActionType(data) {
44631
- if (data.action_type !== void 0)
44632
- return normalizeActionType(data.action_type);
44633
- return normalizeActionType(data.actionType);
44714
+ for (const source of decisionSources(data)) {
44715
+ const actionType = actionTypeOf(source);
44716
+ if (actionType !== "") return actionType;
44717
+ }
44718
+ return "";
44634
44719
  }
44635
44720
  function isAuditTier(data) {
44636
44721
  const absentVerdict = data.verdict === null || data.verdict === void 0;
44637
44722
  return absentVerdict && data.status === "logged";
44638
44723
  }
44724
+ function isAuditTierBody(data) {
44725
+ return isAuditTier(data);
44726
+ }
44639
44727
  function canonicalAllow(data) {
44640
- if (!allowSignalsPermit(data)) return false;
44728
+ if (explicitRefusal(data) !== "") return false;
44641
44729
  const actionType = wireActionType(data);
44642
44730
  if (actionType && actionType !== "allow") return false;
44643
44731
  if (isAuditTier(data)) return true;
@@ -44646,6 +44734,62 @@ function canonicalAllow(data) {
44646
44734
  return verdict === "ALLOW" || verdict === "GREEN";
44647
44735
  }
44648
44736
 
44737
+ // src-ts/opentel/events.ts
44738
+ init_define_ATBASH_CHROMIA_NODE_URLS();
44739
+ init_define_ATBASH_PRIVATE_NODE_URLS();
44740
+ var SLOW_MS = 1500;
44741
+ var SUCCESS_SAMPLE_RATE = 10;
44742
+ var logger2 = null;
44743
+ var eventsEnabled = false;
44744
+ var sdkVersion = "";
44745
+ var eventSource = "sdk";
44746
+ var hashAgentKey = null;
44747
+ function eventsOptedOut() {
44748
+ const flag = process.env.ATBASH_TELEMETRY_EVENTS_DISABLED?.trim().toLowerCase();
44749
+ return Boolean(flag && ["1", "true", "yes", "on"].includes(flag));
44750
+ }
44751
+ var SOURCE_SHAPE = /^(?:sdk|cli|plugin:[a-z0-9][a-z0-9._-]{0,31})$/;
44752
+ function configureEvents(next, opts = {}) {
44753
+ logger2 = next;
44754
+ eventsEnabled = next !== null && !eventsOptedOut();
44755
+ if (opts.version) sdkVersion = opts.version;
44756
+ if (opts.source && SOURCE_SHAPE.test(opts.source)) eventSource = opts.source;
44757
+ hashAgentKey = opts.hashAgentKey ?? null;
44758
+ }
44759
+ function eventsAreOn() {
44760
+ return eventsEnabled && logger2 !== null;
44761
+ }
44762
+ function sampleRateFor(e) {
44763
+ if (e.status === "error") return 1;
44764
+ if (e.durationMs >= SLOW_MS) return 1;
44765
+ return Math.random() < 1 / SUCCESS_SAMPLE_RATE ? SUCCESS_SAMPLE_RATE : 0;
44766
+ }
44767
+ function recordEvent(e) {
44768
+ if (!eventsAreOn()) return;
44769
+ const sampleRate = sampleRateFor(e);
44770
+ if (sampleRate === 0) return;
44771
+ try {
44772
+ const attributes = {
44773
+ "function.name": e.functionName,
44774
+ "duration_ms": Math.round(e.durationMs),
44775
+ status: e.status,
44776
+ source: eventSource,
44777
+ // Honeycomb reweights counts and percentiles by this. It is per-event
44778
+ // because the sampling is biased by outcome and latency.
44779
+ sampleRate
44780
+ };
44781
+ if (sdkVersion) attributes["sdk.version"] = sdkVersion;
44782
+ if (e.agentPubkey && hashAgentKey) attributes["agent.hash"] = hashAgentKey(e.agentPubkey);
44783
+ if (e.chain) attributes["chain"] = e.chain;
44784
+ if (e.errorClass) attributes["error.class"] = e.errorClass;
44785
+ if (e.errorStatus !== void 0) attributes["error.status"] = e.errorStatus;
44786
+ if (e.errorPath) attributes["error.path"] = e.errorPath;
44787
+ if (e.outcome) attributes["outcome"] = e.outcome;
44788
+ logger2.emit({ body: e.functionName, attributes });
44789
+ } catch {
44790
+ }
44791
+ }
44792
+
44649
44793
  // src-ts/browser/opentel/telemetry.ts
44650
44794
  init_define_ATBASH_CHROMIA_NODE_URLS();
44651
44795
  init_define_ATBASH_PRIVATE_NODE_URLS();
@@ -44682,6 +44826,12 @@ function resolve(_key, flagValue) {
44682
44826
  function forcedChainNetwork(flagValue) {
44683
44827
  return flagValue === "public" || flagValue === "private" ? flagValue : void 0;
44684
44828
  }
44829
+ function agentKeyFromEnv() {
44830
+ return "";
44831
+ }
44832
+ function strandedAgentKey() {
44833
+ return "";
44834
+ }
44685
44835
 
44686
44836
  // src-ts/client.ts
44687
44837
  function generateToolCallId() {
@@ -44707,6 +44857,13 @@ function resolveConstructorChain(options) {
44707
44857
  }
44708
44858
  return chainForNetwork(options.network ?? forcedChainNetwork() ?? "private");
44709
44859
  }
44860
+ function errorDetail(err) {
44861
+ if (!(err instanceof AtbashAPIError)) return {};
44862
+ return {
44863
+ errorStatus: err.status,
44864
+ ...err.path ? { errorPath: err.path } : {}
44865
+ };
44866
+ }
44710
44867
  var Atbash = class _Atbash {
44711
44868
  auth;
44712
44869
  endpoint;
@@ -44720,6 +44877,10 @@ var Atbash = class _Atbash {
44720
44877
  orgEncryptionPubKey;
44721
44878
  /** When true (default), `auditToolCall` denies on any error. */
44722
44879
  failClosed;
44880
+ /** When true (default), an unenforced (audit-tier) answer is refused. */
44881
+ requireEnforcement;
44882
+ /** Overall deadline for one auditToolCall decision, in ms. */
44883
+ decisionTimeoutMs;
44723
44884
  /** Org key learned from the last agent-exists check, for this agent only. */
44724
44885
  _orgKeyFromChain = null;
44725
44886
  debug;
@@ -44761,16 +44922,6 @@ var Atbash = class _Atbash {
44761
44922
  */
44762
44923
  _agentExistsCache = null;
44763
44924
  static AGENT_EXISTS_TTL_MS = 5e3;
44764
- /**
44765
- * Cached bearer token for risk-engine / insurance read calls. Built
44766
- * lazily as a signed `log_tool_call` tx and refreshed every 4 min so
44767
- * server-side replay protection windows never expire it mid-session.
44768
- */
44769
- // Keyed by blockchainRid so bearers for the public and private chains can
44770
- // coexist. The dashboard derives `authNetwork` from the BRID inside the
44771
- // signed envelope, so a bearer signed for chain A cannot authenticate a
44772
- // request routed to chain B — every chain the client talks to needs its own.
44773
- _authBearers = /* @__PURE__ */ new Map();
44774
44925
  /** Guards `logEnvironmentOnce` — hosts construct several clients. */
44775
44926
  static environmentLogged = false;
44776
44927
  constructor(privkey, options = {}) {
@@ -44793,6 +44944,8 @@ var Atbash = class _Atbash {
44793
44944
  this.verifyPubKey = validated.verifyPubKey ?? void 0;
44794
44945
  this.orgEncryptionPubKey = options.orgEncryptionPubKey;
44795
44946
  this.failClosed = options.failClosed !== false;
44947
+ this.requireEnforcement = options.requireEnforcement !== false;
44948
+ this.decisionTimeoutMs = options.decisionTimeoutMs ?? DEFAULT_DECISION_TIMEOUT_MS;
44796
44949
  this.debug = options.debug === true;
44797
44950
  this.logger = options.logger ?? {};
44798
44951
  this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 12e4);
@@ -44856,6 +45009,84 @@ var Atbash = class _Atbash {
44856
45009
  * validated against the trusted allowlist / self-hosted policy; a
44857
45010
  * self-hosted endpoint's `verifyPubKey` becomes the client default.
44858
45011
  */
45012
+ /**
45013
+ * Decide which key this client signs as.
45014
+ *
45015
+ * Most specific wins: a key passed in code, then a key file the host named,
45016
+ * then the environment, then the default key file. `config.json` is absent
45017
+ * from that list on purpose — it is a settings file, writable by anything
45018
+ * that can write the user's home and read by every Atbash integration on the
45019
+ * machine, so letting it name the key meant one stray value silently
45020
+ * re-pointed who each of them signed as.
45021
+ *
45022
+ * A named `keyPath` that does not exist throws rather than falling through.
45023
+ * The caller said which file holds its identity; quietly signing as a
45024
+ * different one is the outcome worth refusing.
45025
+ *
45026
+ * @param options - The `fromConfig` options, read for `agentKey` and `keyPath`.
45027
+ * @returns The resolved agent identity.
45028
+ * @throws When a named key file is missing, or no identity can be found.
45029
+ */
45030
+ static resolveIdentity(options) {
45031
+ if (options.agentKey) return native.loadAgent(options.agentKey);
45032
+ if (options.keyPath) return loadAgentFromFile(options.keyPath);
45033
+ const fromEnv = agentKeyFromEnv();
45034
+ if (fromEnv) return native.loadAgent(fromEnv);
45035
+ try {
45036
+ return loadAgentFromFile();
45037
+ } catch (err) {
45038
+ throw _Atbash.explainStrandedKey(err);
45039
+ }
45040
+ }
45041
+ /**
45042
+ * Add the one thing a machine with no key file needs to hear.
45043
+ *
45044
+ * This is the only path where the operator cannot see what happened: no key
45045
+ * file, and the key they are looking for sits in `config.json`, which no
45046
+ * longer selects the identity. A bare "key file not found" sends them hunting
45047
+ * for a key they already have. Only this branch gets the hint — a caller who
45048
+ * named a `keyPath` is told about that path, where a stranded key is noise.
45049
+ *
45050
+ * @param err - The "key file not found" error from the default lookup.
45051
+ * @returns The same error, or one that also names the key in config.json.
45052
+ */
45053
+ static explainStrandedKey(err) {
45054
+ const stranded = strandedAgentKey();
45055
+ if (!stranded) return err;
45056
+ let identity;
45057
+ try {
45058
+ identity = native.derivePublicKey(stranded);
45059
+ } catch {
45060
+ identity = "(unreadable)";
45061
+ }
45062
+ const message = err instanceof Error ? err.message : String(err);
45063
+ return new Error(
45064
+ `${message}
45065
+ config.json still holds an "agentKey" (${identity}), but a settings file no longer chooses the signing key. Move it into one of the key files above, or set ATBASH_AGENT_KEY.`
45066
+ );
45067
+ }
45068
+ /**
45069
+ * Say so when `config.json` still holds an agent key.
45070
+ *
45071
+ * Nothing signs with it any more, and silence would leave an operator
45072
+ * believing one identity is in force while another is. The pubkey is named,
45073
+ * not the key, so the line is safe in a log.
45074
+ *
45075
+ * @param logger - The host logger, when one was supplied.
45076
+ */
45077
+ static warnOnStrandedKey(logger3) {
45078
+ const stranded = strandedAgentKey();
45079
+ if (!stranded) return;
45080
+ let identity;
45081
+ try {
45082
+ identity = native.derivePublicKey(stranded);
45083
+ } catch {
45084
+ identity = "(unreadable)";
45085
+ }
45086
+ logger3?.warn?.(
45087
+ `[atbash] "agentKey" in config.json is ignored \u2014 settings do not choose the signing key. It holds ${identity}; this client signs as the key file or ATBASH_AGENT_KEY instead. Move it into the key file, or delete the field, to silence this.`
45088
+ );
45089
+ }
44859
45090
  static fromConfig(options = {}) {
44860
45091
  const configuredEndpoint = resolve("judgeEndpoint") || void 0;
44861
45092
  const configuredVerifyPubKey = resolve("judgeVerifyPubKey") || void 0;
@@ -44871,8 +45102,8 @@ var Atbash = class _Atbash {
44871
45102
  verifyPubKey: configuredVerifyPubKey
44872
45103
  } : { endpoint: configuredEndpoint })
44873
45104
  );
44874
- const agentKey = resolve("agentKey", options.agentKey);
44875
- const auth = agentKey ? native.loadAgent(agentKey) : loadAgentFromFile(options.keyPath);
45105
+ const auth = _Atbash.resolveIdentity(options);
45106
+ _Atbash.warnOnStrandedKey(options.logger);
44876
45107
  return new _Atbash(auth.privkey, {
44877
45108
  endpoint: validated.url,
44878
45109
  chain: options.chain,
@@ -44883,6 +45114,8 @@ var Atbash = class _Atbash {
44883
45114
  orgName: options.orgName,
44884
45115
  verifyPubKey: validated.verifyPubKey ?? void 0,
44885
45116
  failClosed: options.failClosed,
45117
+ requireEnforcement: options.requireEnforcement,
45118
+ decisionTimeoutMs: options.decisionTimeoutMs,
44886
45119
  // ATBASH_DEBUG lets an operator turn diagnostics on without editing a
44887
45120
  // host's plugin config, which is usually the harder half.
44888
45121
  debug: options.debug ?? /^(1|true|yes)$/i.test(resolve("debug")),
@@ -45081,45 +45314,28 @@ var Atbash = class _Atbash {
45081
45314
  }
45082
45315
  if (!resp.ok) throw await this.httpError(resp);
45083
45316
  const bodyBytes = Buffer.from(await resp.arrayBuffer());
45084
- const verifyPubKey = options.verifyPubKey ?? this.verifyPubKey;
45317
+ const verifyPubKey = this.effectiveVerifyKey(options.verifyPubKey);
45085
45318
  if (verifyPubKey !== void 0) {
45086
- const sig = resp.headers.get("X-Atbash-Signature");
45087
- if (!sig) {
45088
- throw new SignatureVerificationError(
45089
- "missing X-Atbash-Signature header"
45090
- );
45091
- }
45092
- let ok;
45093
- try {
45094
- ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
45095
- } catch (err) {
45096
- throw new SignatureVerificationError(
45097
- `signature verification threw: ${errorMessage(err)}`
45098
- );
45099
- }
45100
- if (!ok) {
45101
- throw new SignatureVerificationError(
45102
- "signature does not verify against configured verifyPubKey"
45103
- );
45104
- }
45319
+ verifyResponseSignature(bodyBytes, resp, verifyPubKey);
45105
45320
  }
45106
45321
  const data = parseJson(bodyBytes);
45107
45322
  const rawScore = data.score;
45108
45323
  const score = typeof rawScore === "number" && Number.isInteger(rawScore) && rawScore >= 1 && rawScore <= 10 ? rawScore : void 0;
45109
45324
  return {
45110
45325
  verdict: normalizeVerdict(data.verdict),
45111
- allow: canonicalAllow(data),
45326
+ allow: this.executable(data),
45112
45327
  actionType: normalizeActionType(data.action_type),
45113
- reason: String(data.reason ?? ""),
45114
- confidence: Number(data.confidence ?? 0),
45115
- provider: String(data.provider ?? ""),
45116
- latencyMs: Number(data.latency_ms ?? 0),
45117
- toolCallId: String(data.tool_call_id ?? logResult.toolCallId),
45328
+ reason: wireText(data.reason),
45329
+ confidence: wireNumber(data.confidence),
45330
+ provider: wireText(data.provider),
45331
+ latencyMs: wireNumber(data.latency_ms),
45332
+ toolCallId: wireText(data.tool_call_id, logResult.toolCallId),
45118
45333
  onChain: Boolean(data.on_chain),
45119
45334
  enforced: Boolean(data.enforced),
45120
- enforcementMode: String(data.enforcement_mode ?? ""),
45121
- status: String(data.status ?? ""),
45122
- score
45335
+ enforcementMode: wireText(data.enforcement_mode),
45336
+ status: wireText(data.status),
45337
+ score,
45338
+ refusal: explicitRefusal(data)
45123
45339
  };
45124
45340
  }
45125
45341
  /* ── audit_tool_call (redact → judge → decision) ───────────────────────── */
@@ -45152,77 +45368,125 @@ var Atbash = class _Atbash {
45152
45368
  }
45153
45369
  try {
45154
45370
  this.logger.info?.("[atbash] judge API called", { tool: toolName });
45155
- const result = await this.judgeAction(actionText, contextText, {
45156
- toolName,
45157
- toolArgsJson: argsJson,
45158
- orgName: this.orgName,
45159
- // Passed through unredacted — caller vouches for the contents.
45160
- resolved: input.resolved
45161
- });
45162
- if (result.verdict === "No verdict") {
45163
- if (result.status !== "logged") {
45164
- return this.failJudge(
45165
- `judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
45166
- void 0,
45167
- result.toolCallId
45168
- );
45169
- }
45170
- return {
45171
- allow: true,
45172
- verdict: "ALLOW",
45173
- reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
45174
- toolCallId: result.toolCallId
45175
- };
45176
- }
45177
- const action = result.actionType;
45178
- if (action === "block") {
45371
+ const result = await withDeadline(
45372
+ this.judgeAction(actionText, contextText, {
45373
+ toolName,
45374
+ toolArgsJson: argsJson,
45375
+ orgName: this.orgName,
45376
+ // Passed through unredacted — caller vouches for the contents.
45377
+ resolved: input.resolved
45378
+ }),
45379
+ this.decisionTimeoutMs
45380
+ );
45381
+ return this.decide(result);
45382
+ } catch (err) {
45383
+ if (err instanceof SignatureVerificationError) {
45384
+ this.failJudge(errorMessage(err), err);
45179
45385
  return {
45180
45386
  allow: false,
45181
- verdict: "BLOCK",
45182
- reason: result.reason,
45183
- toolCallId: result.toolCallId
45387
+ verdict: "ERROR",
45388
+ reason: `The judge's reply failed its signature check (${errorMessage(err)}), so it was not trusted.`
45184
45389
  };
45185
45390
  }
45186
- if (action === "hold_for_user_confirm") {
45187
- return {
45188
- allow: false,
45189
- verdict: "HOLD",
45190
- reason: result.reason || "held for human confirmation",
45191
- toolCallId: result.toolCallId
45192
- };
45391
+ return this.failJudge(errorMessage(err), err);
45392
+ }
45393
+ }
45394
+ /**
45395
+ * The verify key for one call (R4, governor tier-2 review). A per-call key
45396
+ * may only narrow what the client accepts: on a client pinned to a judge
45397
+ * key it must be that same key, never a replacement; on an unpinned client
45398
+ * it adds the check.
45399
+ */
45400
+ effectiveVerifyKey(perCall) {
45401
+ if (perCall === void 0) return this.verifyPubKey;
45402
+ const key3 = perCall.trim().toLowerCase();
45403
+ if (this.verifyPubKey !== void 0 && key3 !== this.verifyPubKey) {
45404
+ throw new SignatureVerificationError(
45405
+ "a per-call verifyPubKey cannot replace the judge key this client is pinned to"
45406
+ );
45407
+ }
45408
+ return key3;
45409
+ }
45410
+ /**
45411
+ * Collapse a judge result into a {@link Decision}. The most restrictive
45412
+ * signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
45413
+ * and the canonical `allow` are each able to deny, and only a result where
45414
+ * all three agree may execute. A present `allow` / `decision.allow` that is
45415
+ * not exactly `true` is the judge declining to grant permission, so it
45416
+ * denies even under `failClosed: false` — that option relaxes *errors*, it
45417
+ * never overrides a refusal.
45418
+ */
45419
+ decide(result) {
45420
+ const toolCallId = result.toolCallId;
45421
+ const deny = (verdict, reason) => ({
45422
+ allow: false,
45423
+ verdict,
45424
+ reason,
45425
+ toolCallId
45426
+ });
45427
+ const notGranted = "the judge response did not grant permission";
45428
+ const held = deny("HOLD", result.reason || "held for human confirmation");
45429
+ const blocked = deny("BLOCK", result.reason || notGranted);
45430
+ if (result.refusal === "BLOCK") return blocked;
45431
+ if (result.verdict === "No verdict") {
45432
+ if (result.actionType === "block") {
45433
+ return blocked;
45434
+ }
45435
+ if (result.actionType === "hold_for_user_confirm") {
45436
+ return held;
45437
+ }
45438
+ if (result.refusal === "HOLD") return held;
45439
+ if (result.status !== "logged") {
45440
+ return this.failJudge(
45441
+ `judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
45442
+ void 0,
45443
+ toolCallId
45444
+ );
45193
45445
  }
45194
- if (action === "allow") {
45195
- if (result.verdict === "HOLD") {
45196
- return {
45197
- allow: false,
45198
- verdict: "HOLD",
45199
- reason: result.reason,
45200
- toolCallId: result.toolCallId
45201
- };
45202
- }
45203
- if (result.verdict === "BLOCK") {
45204
- return {
45205
- allow: false,
45206
- verdict: "BLOCK",
45207
- reason: result.reason,
45208
- toolCallId: result.toolCallId
45209
- };
45210
- }
45446
+ if (this.requireEnforcement) {
45447
+ this.logger.warn?.(
45448
+ "[atbash] judge did not enforce this action (audit tier) and requireEnforcement is on: denied",
45449
+ { toolCallId }
45450
+ );
45211
45451
  return {
45212
- allow: true,
45213
- verdict: "ALLOW",
45214
- reason: result.reason,
45215
- toolCallId: result.toolCallId
45452
+ allow: false,
45453
+ verdict: "ERROR",
45454
+ reason: "Atbash logged this action but did not check it (audit-tier plan), and this client requires a checked decision. Upgrade the plan, or set requireEnforcement: false for log-only mode.",
45455
+ toolCallId
45216
45456
  };
45217
45457
  }
45218
- return this.failJudge(
45219
- "unrecognized action_type from judge",
45220
- void 0,
45221
- result.toolCallId
45222
- );
45223
- } catch (err) {
45224
- return this.failJudge(errorMessage(err), err);
45458
+ if (result.allow !== true) return deny("BLOCK", notGranted);
45459
+ return {
45460
+ allow: true,
45461
+ verdict: "ALLOW",
45462
+ reason: result.reason || "audit tier \u2014 request logged on-chain, no AI enforcement",
45463
+ toolCallId
45464
+ };
45465
+ }
45466
+ const action = result.actionType;
45467
+ if (action === "block") {
45468
+ return deny("BLOCK", result.reason || "Blocked by your organisation's Atbash policy.");
45469
+ }
45470
+ if (action === "hold_for_user_confirm") {
45471
+ return held;
45225
45472
  }
45473
+ if (result.refusal === "HOLD") return held;
45474
+ if (action === "allow") {
45475
+ if (result.verdict === "HOLD") return held;
45476
+ if (result.verdict === "BLOCK") return blocked;
45477
+ if (result.allow !== true) return deny("BLOCK", notGranted);
45478
+ return {
45479
+ allow: true,
45480
+ verdict: "ALLOW",
45481
+ reason: result.reason,
45482
+ toolCallId
45483
+ };
45484
+ }
45485
+ return this.failJudge(
45486
+ "unrecognized action_type from judge",
45487
+ void 0,
45488
+ toolCallId
45489
+ );
45226
45490
  }
45227
45491
  /**
45228
45492
  * One exit for every judge failure.
@@ -45234,18 +45498,30 @@ var Atbash = class _Atbash {
45234
45498
  */
45235
45499
  failJudge(reason, cause, toolCallId) {
45236
45500
  const api2 = cause instanceof AtbashAPIError ? cause : null;
45501
+ const userReason = userFacingReason(reason, api2);
45237
45502
  const status = api2 ? ` status=${api2.status || "no-response"}` : "";
45503
+ const detail = this.debug ? ` detail=${truncate(reason, 500)}` : "";
45238
45504
  const body = this.debug && api2?.body ? ` body=${truncate(api2.body, 500)}` : "";
45239
45505
  this.logger.warn?.(
45240
- `[atbash] judge API failed \u2014${status} reason=${truncate(reason, 300)}${body}`,
45506
+ `[atbash] judge API failed \u2014${status} reason=${truncate(userReason, 300)}${detail}${body}`,
45241
45507
  {
45242
- reason,
45243
- ...api2 ? { status: api2.status, body: api2.body } : {},
45508
+ reason: userReason,
45509
+ ...api2 ? { status: api2.status } : {},
45510
+ ...this.debug && api2 ? { body: api2.body, detail: reason } : {},
45244
45511
  endpoint: this.endpoint,
45245
45512
  ...toolCallId ? { toolCallId } : {}
45246
45513
  }
45247
45514
  );
45248
- return this.fail(reason, toolCallId);
45515
+ return this.fail(userReason, toolCallId);
45516
+ }
45517
+ /**
45518
+ * The canonical permission for a response body under this client's
45519
+ * settings: {@link canonicalAllow}, minus the audit tier when
45520
+ * `requireEnforcement` is on. Never more permissive than `auditToolCall`.
45521
+ */
45522
+ executable(data) {
45523
+ if (!canonicalAllow(data)) return false;
45524
+ return !(this.requireEnforcement && isAuditTierBody(data));
45249
45525
  }
45250
45526
  fail(reason, toolCallId) {
45251
45527
  return { allow: !this.failClosed, verdict: "ERROR", reason, toolCallId };
@@ -45271,13 +45547,18 @@ var Atbash = class _Atbash {
45271
45547
  this.authHeaders(brid)
45272
45548
  );
45273
45549
  await this.raiseIfError(resp);
45274
- const data = await this.json(resp) ?? {};
45550
+ const bytes = Buffer.from(await resp.arrayBuffer());
45551
+ if (this.verifyPubKey !== void 0) {
45552
+ verifyResponseSignature(bytes, resp, this.verifyPubKey);
45553
+ }
45554
+ const parsed = tryParseJson(bytes.toString("utf-8"));
45555
+ const data = isRecord2(parsed) ? parsed : {};
45275
45556
  return {
45276
45557
  status: normalizeStatus(data.status),
45277
45558
  verdict: normalizeVerdict(data.verdict),
45278
- allow: canonicalAllow(data),
45279
- reason: String(data.reason ?? ""),
45280
- judgmentId: String(data.judgmentId ?? judgmentId),
45559
+ allow: this.executable(data),
45560
+ reason: wireText(data.reason),
45561
+ judgmentId: wireText(data.judgmentId, judgmentId),
45281
45562
  onChain: optBool(data.onChain),
45282
45563
  cached: optBool(data.cached),
45283
45564
  responseTimeMs: optNumber(data.responseTimeMs)
@@ -45561,10 +45842,28 @@ var Atbash = class _Atbash {
45561
45842
  recordCall(name2, void 0, agentPubkey);
45562
45843
  try {
45563
45844
  const result = await fn();
45564
- recordDuration(name2, performance.now() - start, "success");
45845
+ const durationMs = performance.now() - start;
45846
+ recordDuration(name2, durationMs, "success");
45847
+ recordEvent({
45848
+ functionName: name2,
45849
+ durationMs,
45850
+ status: "success",
45851
+ agentPubkey,
45852
+ chain: this.blockchainRid
45853
+ });
45565
45854
  return result;
45566
45855
  } catch (err) {
45567
- recordDuration(name2, performance.now() - start, "error");
45856
+ const durationMs = performance.now() - start;
45857
+ recordDuration(name2, durationMs, "error");
45858
+ recordEvent({
45859
+ functionName: name2,
45860
+ durationMs,
45861
+ status: "error",
45862
+ agentPubkey,
45863
+ chain: this.blockchainRid,
45864
+ errorClass: err instanceof Error ? err.constructor.name : typeof err,
45865
+ ...errorDetail(err)
45866
+ });
45568
45867
  throw err;
45569
45868
  }
45570
45869
  }
@@ -45602,25 +45901,10 @@ var Atbash = class _Atbash {
45602
45901
  * trips the server's replay window.
45603
45902
  */
45604
45903
  getAuthBearer(brid) {
45605
- const chainBrid = brid ?? this.blockchainRid;
45606
- const now = Date.now();
45607
- const cached = this._authBearers.get(chainBrid);
45608
- if (cached && now - cached.issuedAt < 4 * 60 * 1e3) return cached.hex;
45609
- const nonce = `auth-${now.toString(36)}-${randomHex(4)}`;
45610
- const hex = native.signLogToolCall(
45611
- nonce,
45612
- `auth:${now}`,
45613
- "",
45614
- "auth-bearer",
45615
- "",
45616
- this.auth.privkey,
45617
- chainBrid
45618
- );
45619
- this._authBearers.set(chainBrid, { hex, issuedAt: now });
45620
- return hex;
45904
+ return agentAuthBearer(this.auth, brid ?? this.blockchainRid);
45621
45905
  }
45622
45906
  authHeaders(brid) {
45623
- return { Authorization: `Bearer ${this.getAuthBearer(brid)}` };
45907
+ return agentAuthHeaders(this.auth, brid ?? this.blockchainRid);
45624
45908
  }
45625
45909
  async riskEngineGet(action, params, brid) {
45626
45910
  let resp;
@@ -45750,6 +46034,66 @@ var Atbash = class _Atbash {
45750
46034
  return native.containsEvasionCharacters(text);
45751
46035
  }
45752
46036
  };
46037
+ function userFacingReason(reason, api2) {
46038
+ if (api2 && api2.status > 0) {
46039
+ const where = ` (HTTP ${api2.status}${api2.path ? ` from ${api2.path}` : ""})`;
46040
+ const b = api2.body.toLowerCase();
46041
+ if (b.includes("agent not registered")) {
46042
+ return `Agent not registered with Atbash: onboard it in the Atbash dashboard${where}.`;
46043
+ }
46044
+ if (b.includes("jailed")) {
46045
+ return `This agent is jailed; unjail it in the Atbash dashboard${where}.`;
46046
+ }
46047
+ if (b.includes("agent has no policy") || b.includes("no policy configured")) {
46048
+ return `This agent has no policy; attach one in the Atbash dashboard${where}.`;
46049
+ }
46050
+ if (b.includes("audit tier") || b.includes("verdict disabled") || b.includes("verdict not supported")) {
46051
+ return `The organisation's plan does not include checked decisions${where}.`;
46052
+ }
46053
+ return `The Atbash judge answered with an error${where}, so the action was not approved.`;
46054
+ }
46055
+ const text = api2 ? api2.body || reason : reason;
46056
+ return truncate(text.replace(/https?:\/\/[^\s)]+/g, "the judge"), 300);
46057
+ }
46058
+ var DEFAULT_DECISION_TIMEOUT_MS = 6e4;
46059
+ async function withDeadline(p, ms) {
46060
+ let timer;
46061
+ const deadline = new Promise((_, reject) => {
46062
+ timer = setTimeout(
46063
+ () => reject(
46064
+ new Error(
46065
+ `The judge did not give a decision within ${Math.round(ms / 1e3)} s, so the action was not approved. Check the network, or raise decisionTimeoutMs.`
46066
+ )
46067
+ ),
46068
+ ms
46069
+ );
46070
+ });
46071
+ p.catch(() => void 0);
46072
+ try {
46073
+ return await Promise.race([p, deadline]);
46074
+ } finally {
46075
+ clearTimeout(timer);
46076
+ }
46077
+ }
46078
+ function verifyResponseSignature(bodyBytes, resp, verifyPubKey) {
46079
+ const sig = resp.headers.get("X-Atbash-Signature");
46080
+ if (!sig) {
46081
+ throw new SignatureVerificationError("missing X-Atbash-Signature header");
46082
+ }
46083
+ let ok;
46084
+ try {
46085
+ ok = native.verifySignature(bodyBytes, sig, verifyPubKey);
46086
+ } catch (err) {
46087
+ throw new SignatureVerificationError(
46088
+ `signature verification threw: ${errorMessage(err)}`
46089
+ );
46090
+ }
46091
+ if (!ok) {
46092
+ throw new SignatureVerificationError(
46093
+ "signature does not verify against configured verifyPubKey"
46094
+ );
46095
+ }
46096
+ }
45753
46097
  function baseToolCall(raw2) {
45754
46098
  return {
45755
46099
  toolCallId: String(raw2.tool_call_id ?? ""),
@@ -45821,10 +46165,12 @@ function isRecord2(v) {
45821
46165
  }
45822
46166
  function optString(v) {
45823
46167
  if (v === null || v === void 0) return void 0;
46168
+ if (typeof v === "object" || typeof v === "function") return void 0;
45824
46169
  return typeof v === "string" ? v : String(v);
45825
46170
  }
45826
46171
  function optNumber(v) {
45827
46172
  if (v === null || v === void 0) return void 0;
46173
+ if (typeof v === "object" || typeof v === "function") return void 0;
45828
46174
  const n = Number(v);
45829
46175
  return Number.isFinite(n) ? n : void 0;
45830
46176
  }
@@ -45951,22 +46297,6 @@ function bootSyncFailureLine(cause) {
45951
46297
  );
45952
46298
  }
45953
46299
 
45954
- // src-ts/memory/_gtv_bytes.ts
45955
- init_define_ATBASH_CHROMIA_NODE_URLS();
45956
- init_define_ATBASH_PRIVATE_NODE_URLS();
45957
- function gtvToFfiSafe(value) {
45958
- if (value instanceof Uint8Array) return Buffer.from(value).toString("hex");
45959
- if (Array.isArray(value)) return value.map(gtvToFfiSafe);
45960
- if (value !== null && typeof value === "object") {
45961
- const out = {};
45962
- for (const [key3, val] of Object.entries(value)) {
45963
- out[key3] = gtvToFfiSafe(val);
45964
- }
45965
- return out;
45966
- }
45967
- return value;
45968
- }
45969
-
45970
46300
  // src-ts/memory/index.ts
45971
46301
  init_define_ATBASH_CHROMIA_NODE_URLS();
45972
46302
  init_define_ATBASH_PRIVATE_NODE_URLS();
@@ -46309,6 +46639,7 @@ export {
46309
46639
  classifyMemoryWrite,
46310
46640
  columnAad,
46311
46641
  commitMemoryVersion,
46642
+ configureEvents,
46312
46643
  containsEvasionCharacters2 as containsEvasionCharacters,
46313
46644
  containsSecret2 as containsSecret,
46314
46645
  createFileLogger,
@@ -46324,6 +46655,7 @@ export {
46324
46655
  encryptForOrg,
46325
46656
  encryptMemoryContent2 as encryptMemoryContent,
46326
46657
  encryptedLength,
46658
+ eventsAreOn,
46327
46659
  flushTelemetry,
46328
46660
  generateKeypair2 as generateKeypair,
46329
46661
  getActiveAgentMemory,
@@ -46334,7 +46666,6 @@ export {
46334
46666
  getMemoryHistory,
46335
46667
  getRecentAgentMemory,
46336
46668
  getRollbackHistory,
46337
- gtvToFfiSafe,
46338
46669
  guardMemoryWrite,
46339
46670
  isEnvelope,
46340
46671
  isValidPrivateKey2 as isValidPrivateKey,
@@ -46353,6 +46684,7 @@ export {
46353
46684
  pubkeyToHex,
46354
46685
  recordCall,
46355
46686
  recordDuration,
46687
+ recordEvent,
46356
46688
  redactJsonStrings,
46357
46689
  redactSecrets2 as redactSecrets,
46358
46690
  resolve,