@atbash/sdk 0.10.6-dev.0 → 0.10.7-dev.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/index.d.mts CHANGED
@@ -310,6 +310,12 @@ interface AtbashOptions {
310
310
  orgEncryptionPubKey?: string;
311
311
  /** When true (default), `auditToolCall` denies on any error. */
312
312
  failClosed?: boolean;
313
+ /**
314
+ * Verbose diagnostics. Off by default. When on, a failed judge call also
315
+ * logs the response body, which is the difference between "judge API failed"
316
+ * and knowing why it failed. Opt-in because that body can echo the action.
317
+ */
318
+ debug?: boolean;
313
319
  logger?: AtbashLogger;
314
320
  }
315
321
  /** Canonical decision returned by `auditToolCall`. */
@@ -350,6 +356,8 @@ interface FromConfigOptions {
350
356
  /** Default org name — see {@link AtbashOptions.orgName}. */
351
357
  orgName?: string;
352
358
  failClosed?: boolean;
359
+ /** See {@link AtbashOptions.debug}. */
360
+ debug?: boolean;
353
361
  logger?: AtbashLogger;
354
362
  }
355
363
  /** Options accepted by `judgeAction`. */
@@ -414,6 +422,7 @@ declare class Atbash {
414
422
  readonly failClosed: boolean;
415
423
  /** Org key learned from the last agent-exists check, for this agent only. */
416
424
  private _orgKeyFromChain;
425
+ private readonly debug;
417
426
  private readonly logger;
418
427
  private readonly http;
419
428
  /**
@@ -427,7 +436,20 @@ declare class Atbash {
427
436
  * server-side replay protection windows never expire it mid-session.
428
437
  */
429
438
  private _authBearer;
439
+ /** Guards `logEnvironmentOnce` — hosts construct several clients. */
440
+ private static environmentLogged;
430
441
  constructor(privkey: string, options?: AtbashOptions);
442
+ /**
443
+ * Say which environment this build talks to, once per process.
444
+ *
445
+ * The endpoint and both chain RIDs are compiled in, chosen by the npm tag,
446
+ * and no configuration repoints a released build. So installing the build
447
+ * for the wrong environment is invisible: the plugin loads, the hook fires,
448
+ * and every judge call fails because the agent does not exist on the chain
449
+ * this build targets. Organisation names are not unique across environments
450
+ * either, so an org resolving is not evidence the build is right.
451
+ */
452
+ private logEnvironmentOnce;
431
453
  /**
432
454
  * Construct from resolved config: explicit overrides → env vars → the
433
455
  * `~/.config/atbash/config.json` file (see userConfig.resolve). The private
@@ -470,6 +492,15 @@ declare class Atbash {
470
492
  * explicitly false.
471
493
  */
472
494
  auditToolCall(input: ToolCallInput): Promise<Decision>;
495
+ /**
496
+ * One exit for every judge failure.
497
+ *
498
+ * Status and reason go in the *message*, not only in the meta object: hosts
499
+ * print the message and drop the meta, which is why this read as a bare
500
+ * "judge API failed" while the judge was answering with a precise reason.
501
+ * The response body follows only under `debug`, since it can echo the action.
502
+ */
503
+ private failJudge;
473
504
  private fail;
474
505
  getJudgmentStatus(judgmentId: string, agentPubkey?: string): Promise<JudgmentStatus>;
475
506
  getToolCalls(maxCount: number): Promise<ToolCallRecord[]>;
@@ -585,6 +616,8 @@ interface AtbashUserConfig {
585
616
  blockchainRid?: string;
586
617
  provider?: string;
587
618
  providerModel?: string;
619
+ /** "1" / "true" turns on verbose diagnostics. See AtbashOptions.debug. */
620
+ debug?: string;
588
621
  }
589
622
  declare function getConfigDir(): string;
590
623
  declare function getConfigPath(): string;
@@ -595,6 +628,26 @@ declare function resolve(key: keyof AtbashUserConfig, flagValue?: string): strin
595
628
  declare function resolveKeyPath(input?: string): string;
596
629
  declare function loadAgentFromFile(keyPath?: string): AgentAuth;
597
630
 
631
+ /**
632
+ * Accepted key filenames, in precedence order.
633
+ *
634
+ * `guard-client-key` stays first: it is the name every existing install
635
+ * already has, and changing which file wins would silently switch agent
636
+ * identity for anyone holding both. `atbash-client-key` is accepted because
637
+ * it is the name people actually create — the old one carries retired
638
+ * branding — and hitting ENOENT on a key you just wrote, from a plugin that
639
+ * still reports itself installed, is a miserable first run.
640
+ */
641
+ declare const KEY_FILENAMES: readonly ["guard-client-key", "atbash-client-key"];
642
+ /** Every path checked when no explicit key path is given, in order. */
643
+ declare function keyPathCandidates(): string[];
644
+ /**
645
+ * Pick the key path: an explicit input wins untouched; otherwise the first
646
+ * accepted filename that exists, falling back to the preferred name so the
647
+ * error names something recognisable when nothing is there.
648
+ */
649
+ declare function chooseKeyPath(input: string | undefined, exists: (p: string) => boolean): string;
650
+
598
651
  /**
599
652
  * Canonical secret kinds reported by the Rust core in `SecretMatch.kind`.
600
653
  * Wire is permissive (modelled as a free string in {@link SecretMatch})
@@ -613,6 +666,26 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
613
666
  reason?: string;
614
667
  };
615
668
 
669
+ /**
670
+ * The boot memory-sync failure line.
671
+ *
672
+ * Split out of `guard-manager.ts` so it can be asserted without constructing a
673
+ * guard manager, which needs the native addon. The message is the whole point
674
+ * of AT-304: hosts print the message and drop the structured meta, so a cause
675
+ * that lives only in meta never reaches the operator.
676
+ */
677
+ /** Advice, not a diagnosis — appended only when the cause is unhelpful. */
678
+ declare const BOOT_SYNC_HINT = "check the chain endpoint and orgName if the cause above does not explain it";
679
+ /**
680
+ * Lead with the real cause.
681
+ *
682
+ * The previous wording named the chain endpoint and orgName as the things to
683
+ * check, which sent operators to verify configuration that was already correct
684
+ * while the actual cause (a node answering `404 Can't find blockchain with
685
+ * blockchainRID: …` for a chain it does not host) stayed hidden.
686
+ */
687
+ declare function bootSyncFailureLine(cause: unknown): string;
688
+
616
689
  /** Derive the 32-byte AES key from an agent's secp256k1 privkey (hex). Deterministic — same privkey always yields the same key. */
617
690
  declare function deriveMemoryKey(privkey: string): Promise<Buffer>;
618
691
  /** Encrypt UTF-8 plaintext. `ciphertext` has the 16-byte GCM auth tag appended, matching the SDK's on-chain byte layout. */
@@ -1164,4 +1237,4 @@ declare function containsSecret(text: string): boolean;
1164
1237
  declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
1165
1238
  declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
1166
1239
 
1167
- export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, buildAllowedJudgeHosts, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
1240
+ export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, KEY_FILENAMES, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, bootSyncFailureLine, buildAllowedJudgeHosts, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, keyPathCandidates, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
package/dist/index.d.ts CHANGED
@@ -310,6 +310,12 @@ interface AtbashOptions {
310
310
  orgEncryptionPubKey?: string;
311
311
  /** When true (default), `auditToolCall` denies on any error. */
312
312
  failClosed?: boolean;
313
+ /**
314
+ * Verbose diagnostics. Off by default. When on, a failed judge call also
315
+ * logs the response body, which is the difference between "judge API failed"
316
+ * and knowing why it failed. Opt-in because that body can echo the action.
317
+ */
318
+ debug?: boolean;
313
319
  logger?: AtbashLogger;
314
320
  }
315
321
  /** Canonical decision returned by `auditToolCall`. */
@@ -350,6 +356,8 @@ interface FromConfigOptions {
350
356
  /** Default org name — see {@link AtbashOptions.orgName}. */
351
357
  orgName?: string;
352
358
  failClosed?: boolean;
359
+ /** See {@link AtbashOptions.debug}. */
360
+ debug?: boolean;
353
361
  logger?: AtbashLogger;
354
362
  }
355
363
  /** Options accepted by `judgeAction`. */
@@ -414,6 +422,7 @@ declare class Atbash {
414
422
  readonly failClosed: boolean;
415
423
  /** Org key learned from the last agent-exists check, for this agent only. */
416
424
  private _orgKeyFromChain;
425
+ private readonly debug;
417
426
  private readonly logger;
418
427
  private readonly http;
419
428
  /**
@@ -427,7 +436,20 @@ declare class Atbash {
427
436
  * server-side replay protection windows never expire it mid-session.
428
437
  */
429
438
  private _authBearer;
439
+ /** Guards `logEnvironmentOnce` — hosts construct several clients. */
440
+ private static environmentLogged;
430
441
  constructor(privkey: string, options?: AtbashOptions);
442
+ /**
443
+ * Say which environment this build talks to, once per process.
444
+ *
445
+ * The endpoint and both chain RIDs are compiled in, chosen by the npm tag,
446
+ * and no configuration repoints a released build. So installing the build
447
+ * for the wrong environment is invisible: the plugin loads, the hook fires,
448
+ * and every judge call fails because the agent does not exist on the chain
449
+ * this build targets. Organisation names are not unique across environments
450
+ * either, so an org resolving is not evidence the build is right.
451
+ */
452
+ private logEnvironmentOnce;
431
453
  /**
432
454
  * Construct from resolved config: explicit overrides → env vars → the
433
455
  * `~/.config/atbash/config.json` file (see userConfig.resolve). The private
@@ -470,6 +492,15 @@ declare class Atbash {
470
492
  * explicitly false.
471
493
  */
472
494
  auditToolCall(input: ToolCallInput): Promise<Decision>;
495
+ /**
496
+ * One exit for every judge failure.
497
+ *
498
+ * Status and reason go in the *message*, not only in the meta object: hosts
499
+ * print the message and drop the meta, which is why this read as a bare
500
+ * "judge API failed" while the judge was answering with a precise reason.
501
+ * The response body follows only under `debug`, since it can echo the action.
502
+ */
503
+ private failJudge;
473
504
  private fail;
474
505
  getJudgmentStatus(judgmentId: string, agentPubkey?: string): Promise<JudgmentStatus>;
475
506
  getToolCalls(maxCount: number): Promise<ToolCallRecord[]>;
@@ -585,6 +616,8 @@ interface AtbashUserConfig {
585
616
  blockchainRid?: string;
586
617
  provider?: string;
587
618
  providerModel?: string;
619
+ /** "1" / "true" turns on verbose diagnostics. See AtbashOptions.debug. */
620
+ debug?: string;
588
621
  }
589
622
  declare function getConfigDir(): string;
590
623
  declare function getConfigPath(): string;
@@ -595,6 +628,26 @@ declare function resolve(key: keyof AtbashUserConfig, flagValue?: string): strin
595
628
  declare function resolveKeyPath(input?: string): string;
596
629
  declare function loadAgentFromFile(keyPath?: string): AgentAuth;
597
630
 
631
+ /**
632
+ * Accepted key filenames, in precedence order.
633
+ *
634
+ * `guard-client-key` stays first: it is the name every existing install
635
+ * already has, and changing which file wins would silently switch agent
636
+ * identity for anyone holding both. `atbash-client-key` is accepted because
637
+ * it is the name people actually create — the old one carries retired
638
+ * branding — and hitting ENOENT on a key you just wrote, from a plugin that
639
+ * still reports itself installed, is a miserable first run.
640
+ */
641
+ declare const KEY_FILENAMES: readonly ["guard-client-key", "atbash-client-key"];
642
+ /** Every path checked when no explicit key path is given, in order. */
643
+ declare function keyPathCandidates(): string[];
644
+ /**
645
+ * Pick the key path: an explicit input wins untouched; otherwise the first
646
+ * accepted filename that exists, falling back to the preferred name so the
647
+ * error names something recognisable when nothing is there.
648
+ */
649
+ declare function chooseKeyPath(input: string | undefined, exists: (p: string) => boolean): string;
650
+
598
651
  /**
599
652
  * Canonical secret kinds reported by the Rust core in `SecretMatch.kind`.
600
653
  * Wire is permissive (modelled as a free string in {@link SecretMatch})
@@ -613,6 +666,26 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
613
666
  reason?: string;
614
667
  };
615
668
 
669
+ /**
670
+ * The boot memory-sync failure line.
671
+ *
672
+ * Split out of `guard-manager.ts` so it can be asserted without constructing a
673
+ * guard manager, which needs the native addon. The message is the whole point
674
+ * of AT-304: hosts print the message and drop the structured meta, so a cause
675
+ * that lives only in meta never reaches the operator.
676
+ */
677
+ /** Advice, not a diagnosis — appended only when the cause is unhelpful. */
678
+ declare const BOOT_SYNC_HINT = "check the chain endpoint and orgName if the cause above does not explain it";
679
+ /**
680
+ * Lead with the real cause.
681
+ *
682
+ * The previous wording named the chain endpoint and orgName as the things to
683
+ * check, which sent operators to verify configuration that was already correct
684
+ * while the actual cause (a node answering `404 Can't find blockchain with
685
+ * blockchainRID: …` for a chain it does not host) stayed hidden.
686
+ */
687
+ declare function bootSyncFailureLine(cause: unknown): string;
688
+
616
689
  /** Derive the 32-byte AES key from an agent's secp256k1 privkey (hex). Deterministic — same privkey always yields the same key. */
617
690
  declare function deriveMemoryKey(privkey: string): Promise<Buffer>;
618
691
  /** Encrypt UTF-8 plaintext. `ciphertext` has the 16-byte GCM auth tag appended, matching the SDK's on-chain byte layout. */
@@ -1164,4 +1237,4 @@ declare function containsSecret(text: string): boolean;
1164
1237
  declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
1165
1238
  declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
1166
1239
 
1167
- export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, buildAllowedJudgeHosts, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
1240
+ export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, KEY_FILENAMES, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, bootSyncFailureLine, buildAllowedJudgeHosts, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, keyPathCandidates, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
package/dist/index.js CHANGED
@@ -2856,6 +2856,7 @@ var src_ts_exports = {};
2856
2856
  __export(src_ts_exports, {
2857
2857
  Atbash: () => Atbash,
2858
2858
  AtbashAPIError: () => AtbashAPIError,
2859
+ BOOT_SYNC_HINT: () => BOOT_SYNC_HINT,
2859
2860
  DEFAULT_BLOCKCHAIN_RID: () => DEFAULT_BLOCKCHAIN_RID,
2860
2861
  DEFAULT_CHROMIA_NODE_URLS: () => DEFAULT_CHROMIA_NODE_URLS,
2861
2862
  DEFAULT_ENDPOINT: () => DEFAULT_ENDPOINT,
@@ -2863,11 +2864,14 @@ __export(src_ts_exports, {
2863
2864
  DEFAULT_MEMORY_READ_TOOL_NAMES: () => DEFAULT_MEMORY_READ_TOOL_NAMES,
2864
2865
  DEFAULT_MEMORY_WRITE_TOOL_NAMES: () => DEFAULT_MEMORY_WRITE_TOOL_NAMES,
2865
2866
  EciesDomain: () => EciesDomain,
2867
+ KEY_FILENAMES: () => KEY_FILENAMES,
2866
2868
  MemoryGuardManager: () => MemoryGuardManager,
2867
2869
  MemoryIntegrityError: () => MemoryIntegrityError,
2868
2870
  PointerStore: () => PointerStore,
2869
2871
  SignatureVerificationError: () => SignatureVerificationError,
2872
+ bootSyncFailureLine: () => bootSyncFailureLine,
2870
2873
  buildAllowedJudgeHosts: () => buildAllowedJudgeHosts,
2874
+ chooseKeyPath: () => chooseKeyPath,
2871
2875
  claimHashHex: () => claimHashHex,
2872
2876
  classifyMemoryRead: () => classifyMemoryRead,
2873
2877
  classifyMemoryWrite: () => classifyMemoryWrite,
@@ -2902,6 +2906,7 @@ __export(src_ts_exports, {
2902
2906
  isEnvelope: () => isEnvelope,
2903
2907
  isValidPrivateKey: () => isValidPrivateKey,
2904
2908
  keyFingerprintOf: () => keyFingerprintOf,
2909
+ keyPathCandidates: () => keyPathCandidates,
2905
2910
  loadAgent: () => loadAgent,
2906
2911
  loadAgentFromFile: () => loadAgentFromFile,
2907
2912
  loadUserConfig: () => loadUserConfig,
@@ -3135,18 +3140,31 @@ var HttpClient = class {
3135
3140
 
3136
3141
  // src-ts/keyLoader.ts
3137
3142
  var import_node_fs = require("fs");
3143
+
3144
+ // src-ts/key-path.ts
3138
3145
  var import_node_os = require("os");
3139
3146
  var import_node_path = require("path");
3140
- var DEFAULT_KEY_PATH_REL = ".config/atbash/guard-client-key";
3141
- function resolveKeyPath(input) {
3142
- if (input) return expandHome(input);
3143
- const home = process.env.HOME || (0, import_node_os.homedir)() || "";
3144
- return (0, import_node_path.join)(home, DEFAULT_KEY_PATH_REL);
3147
+ var KEY_DIR_REL = ".config/atbash";
3148
+ var KEY_FILENAMES = ["guard-client-key", "atbash-client-key"];
3149
+ function home() {
3150
+ return process.env.HOME || (0, import_node_os.homedir)() || "";
3145
3151
  }
3146
3152
  function expandHome(p) {
3147
3153
  if (!p.startsWith("~/")) return p;
3148
- const home = process.env.HOME || (0, import_node_os.homedir)() || "";
3149
- return (0, import_node_path.join)(home, p.slice(2));
3154
+ return (0, import_node_path.join)(home(), p.slice(2));
3155
+ }
3156
+ function keyPathCandidates() {
3157
+ return KEY_FILENAMES.map((name2) => (0, import_node_path.join)(home(), KEY_DIR_REL, name2));
3158
+ }
3159
+ function chooseKeyPath(input, exists) {
3160
+ if (input) return expandHome(input);
3161
+ const candidates = keyPathCandidates();
3162
+ return candidates.find(exists) ?? candidates[0];
3163
+ }
3164
+
3165
+ // src-ts/keyLoader.ts
3166
+ function resolveKeyPath(input) {
3167
+ return chooseKeyPath(input, import_node_fs.existsSync);
3150
3168
  }
3151
3169
  function readKeyFile(keyPath) {
3152
3170
  const content = String((0, import_node_fs.readFileSync)(keyPath, "utf8") || "").trim();
@@ -3176,6 +3194,12 @@ function readKeyFile(keyPath) {
3176
3194
  }
3177
3195
  function loadAgentFromFile(keyPath) {
3178
3196
  const resolved = resolveKeyPath(keyPath);
3197
+ if (!(0, import_node_fs.existsSync)(resolved)) {
3198
+ const looked = keyPath ? [resolved] : keyPathCandidates();
3199
+ throw new Error(
3200
+ `atbash key file not found. Looked for: ${looked.join(", ")}`
3201
+ );
3202
+ }
3179
3203
  const { privKey } = readKeyFile(resolved);
3180
3204
  return native.loadAgent(privKey);
3181
3205
  }
@@ -3218,8 +3242,8 @@ var durationHistogram = null;
3218
3242
  var defaultSource = "sdk";
3219
3243
  function isTelemetryOptedOut() {
3220
3244
  try {
3221
- const home = process.env.HOME || (0, import_node_os2.homedir)() || "";
3222
- const filePath = (0, import_node_path2.join)(home, ".config", "atbash", "telemetry.json");
3245
+ const home2 = process.env.HOME || (0, import_node_os2.homedir)() || "";
3246
+ const filePath = (0, import_node_path2.join)(home2, ".config", "atbash", "telemetry.json");
3223
3247
  const raw2 = (0, import_node_fs2.readFileSync)(filePath, "utf-8").trim();
3224
3248
  if (!raw2) return false;
3225
3249
  const config2 = JSON.parse(raw2);
@@ -3304,11 +3328,12 @@ var ENV_MAP = {
3304
3328
  judgeEndpoint: "ATBASH_ENDPOINT",
3305
3329
  blockchainRid: "ATBASH_BLOCKCHAIN_RID",
3306
3330
  provider: "ATBASH_PROVIDER",
3307
- providerModel: "ATBASH_PROVIDER_MODEL"
3331
+ providerModel: "ATBASH_PROVIDER_MODEL",
3332
+ debug: "ATBASH_DEBUG"
3308
3333
  };
3309
3334
  function getConfigDir() {
3310
- const home = process.env.HOME || (0, import_node_os3.homedir)() || "";
3311
- return (0, import_node_path3.join)(home, ".config", "atbash");
3335
+ const home2 = process.env.HOME || (0, import_node_os3.homedir)() || "";
3336
+ return (0, import_node_path3.join)(home2, ".config", "atbash");
3312
3337
  }
3313
3338
  function getConfigPath() {
3314
3339
  return (0, import_node_path3.join)(getConfigDir(), "config.json");
@@ -3367,6 +3392,7 @@ var Atbash = class _Atbash {
3367
3392
  failClosed;
3368
3393
  /** Org key learned from the last agent-exists check, for this agent only. */
3369
3394
  _orgKeyFromChain = null;
3395
+ debug;
3370
3396
  logger;
3371
3397
  http;
3372
3398
  /**
@@ -3380,6 +3406,8 @@ var Atbash = class _Atbash {
3380
3406
  * server-side replay protection windows never expire it mid-session.
3381
3407
  */
3382
3408
  _authBearer = null;
3409
+ /** Guards `logEnvironmentOnce` — hosts construct several clients. */
3410
+ static environmentLogged = false;
3383
3411
  constructor(privkey, options = {}) {
3384
3412
  this.auth = native.loadAgent(privkey);
3385
3413
  this.endpoint = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "") || DEFAULT_ENDPOINT;
@@ -3389,8 +3417,10 @@ var Atbash = class _Atbash {
3389
3417
  this.verifyPubKey = options.verifyPubKey;
3390
3418
  this.orgEncryptionPubKey = options.orgEncryptionPubKey;
3391
3419
  this.failClosed = options.failClosed !== false;
3420
+ this.debug = options.debug === true;
3392
3421
  this.logger = options.logger ?? {};
3393
3422
  this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 3e4);
3423
+ this.logEnvironmentOnce();
3394
3424
  if (this.endpoint !== DEFAULT_ENDPOINT) {
3395
3425
  this.logger.warn?.("[atbash] running on non-default judge endpoint", {
3396
3426
  endpoint: this.endpoint,
@@ -3398,6 +3428,31 @@ var Atbash = class _Atbash {
3398
3428
  });
3399
3429
  }
3400
3430
  }
3431
+ /**
3432
+ * Say which environment this build talks to, once per process.
3433
+ *
3434
+ * The endpoint and both chain RIDs are compiled in, chosen by the npm tag,
3435
+ * and no configuration repoints a released build. So installing the build
3436
+ * for the wrong environment is invisible: the plugin loads, the hook fires,
3437
+ * and every judge call fails because the agent does not exist on the chain
3438
+ * this build targets. Organisation names are not unique across environments
3439
+ * either, so an org resolving is not evidence the build is right.
3440
+ */
3441
+ logEnvironmentOnce() {
3442
+ if (_Atbash.environmentLogged) return;
3443
+ _Atbash.environmentLogged = true;
3444
+ const brief = (rid) => rid ? `${rid.slice(0, 8)}\u2026` : "(unset)";
3445
+ this.logger.info?.(
3446
+ `[atbash] environment \u2014 judge=${this.endpoint} publicChain=${brief(native.DEFAULT_BLOCKCHAIN_RID)} privateChain=${brief(native.DEFAULT_PRIVATE_BLOCKCHAIN_RID)} activeChain=${brief(this.blockchainRid)} responseSignatureCheck=${this.verifyPubKey ? "on" : "off"}`,
3447
+ {
3448
+ judgeEndpoint: this.endpoint,
3449
+ publicBlockchainRid: native.DEFAULT_BLOCKCHAIN_RID,
3450
+ privateBlockchainRid: native.DEFAULT_PRIVATE_BLOCKCHAIN_RID,
3451
+ activeBlockchainRid: this.blockchainRid,
3452
+ responseSignatureCheck: Boolean(this.verifyPubKey)
3453
+ }
3454
+ );
3455
+ }
3401
3456
  /**
3402
3457
  * Construct from resolved config: explicit overrides → env vars → the
3403
3458
  * `~/.config/atbash/config.json` file (see userConfig.resolve). The private
@@ -3421,6 +3476,9 @@ var Atbash = class _Atbash {
3421
3476
  orgName: options.orgName,
3422
3477
  verifyPubKey: validated.verifyPubKey ?? void 0,
3423
3478
  failClosed: options.failClosed,
3479
+ // ATBASH_DEBUG lets an operator turn diagnostics on without editing a
3480
+ // host's plugin config, which is usually the harder half.
3481
+ debug: options.debug ?? /^(1|true|yes)$/i.test(resolve("debug")),
3424
3482
  logger: options.logger
3425
3483
  });
3426
3484
  }
@@ -3666,8 +3724,9 @@ var Atbash = class _Atbash {
3666
3724
  });
3667
3725
  if (result.verdict === "No verdict") {
3668
3726
  if (result.status !== "logged") {
3669
- return this.fail(
3727
+ return this.failJudge(
3670
3728
  `judge returned no verdict without an audit-tier marker (status: ${result.status || "absent"})`,
3729
+ void 0,
3671
3730
  result.toolCallId
3672
3731
  );
3673
3732
  }
@@ -3719,16 +3778,38 @@ var Atbash = class _Atbash {
3719
3778
  toolCallId: result.toolCallId
3720
3779
  };
3721
3780
  }
3722
- return this.fail(
3781
+ return this.failJudge(
3723
3782
  "unrecognized action_type from judge",
3783
+ void 0,
3724
3784
  result.toolCallId
3725
3785
  );
3726
3786
  } catch (err) {
3727
- const message = errorMessage(err);
3728
- this.logger.warn?.("[atbash] judge API failed", { reason: message });
3729
- return this.fail(message);
3787
+ return this.failJudge(errorMessage(err), err);
3730
3788
  }
3731
3789
  }
3790
+ /**
3791
+ * One exit for every judge failure.
3792
+ *
3793
+ * Status and reason go in the *message*, not only in the meta object: hosts
3794
+ * print the message and drop the meta, which is why this read as a bare
3795
+ * "judge API failed" while the judge was answering with a precise reason.
3796
+ * The response body follows only under `debug`, since it can echo the action.
3797
+ */
3798
+ failJudge(reason, cause, toolCallId) {
3799
+ const api2 = cause instanceof AtbashAPIError ? cause : null;
3800
+ const status = api2 ? ` status=${api2.status || "no-response"}` : "";
3801
+ const body = this.debug && api2?.body ? ` body=${truncate(api2.body, 500)}` : "";
3802
+ this.logger.warn?.(
3803
+ `[atbash] judge API failed \u2014${status} reason=${truncate(reason, 300)}${body}`,
3804
+ {
3805
+ reason,
3806
+ ...api2 ? { status: api2.status, body: api2.body } : {},
3807
+ endpoint: this.endpoint,
3808
+ ...toolCallId ? { toolCallId } : {}
3809
+ }
3810
+ );
3811
+ return this.fail(reason, toolCallId);
3812
+ }
3732
3813
  fail(reason, toolCallId) {
3733
3814
  return { allow: !this.failClosed, verdict: "ERROR", reason, toolCallId };
3734
3815
  }
@@ -4216,9 +4297,9 @@ function stringifyArgs(args) {
4216
4297
  }
4217
4298
  }
4218
4299
  var MAX_ACTION_LEN = 4e3;
4219
- function truncate(text) {
4220
- if (text.length <= MAX_ACTION_LEN) return text;
4221
- return text.slice(0, MAX_ACTION_LEN) + "\u2026";
4300
+ function truncate(text, limit = MAX_ACTION_LEN) {
4301
+ if (text.length <= limit) return text;
4302
+ return text.slice(0, limit) + "\u2026";
4222
4303
  }
4223
4304
 
4224
4305
  // src-ts/redact.ts
@@ -4261,6 +4342,17 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
4261
4342
  };
4262
4343
  }
4263
4344
 
4345
+ // src-ts/memory/boot-sync-message.ts
4346
+ var BOOT_SYNC_HINT = "check the chain endpoint and orgName if the cause above does not explain it";
4347
+ function bootSyncFailureLine(cause) {
4348
+ const reason = cause instanceof Error ? cause.message : String(cause);
4349
+ const trimmed = reason.trim();
4350
+ return trimmed ? `[atbash] boot memory sync failed: ${trimmed}` : (
4351
+ // No cause to show: fall back to the advice rather than a bare colon.
4352
+ `[atbash] boot memory sync failed \u2014 ${BOOT_SYNC_HINT}`
4353
+ );
4354
+ }
4355
+
4264
4356
  // src-ts/memory/crypto.ts
4265
4357
  async function deriveMemoryKey(privkey) {
4266
4358
  return native.deriveMemoryKey(privkey);
@@ -4286,6 +4378,19 @@ async function scanMemory(entry, auth, opts) {
4286
4378
  toolArgsJson: opts?.toolArgsJson ?? JSON.stringify({ key: entry.key, source: entry.source }),
4287
4379
  mode: "memory-scan"
4288
4380
  });
4381
+ const knownAction = result.actionType === "allow" || result.actionType === "block" || result.actionType === "hold_for_user_confirm";
4382
+ const missingVerdict = result.verdict === "No verdict" && result.status !== "logged";
4383
+ const unknownAction = result.actionType !== "" && !knownAction;
4384
+ if (missingVerdict || unknownAction) {
4385
+ return {
4386
+ safe: false,
4387
+ verdict: "red",
4388
+ reason: unknownAction ? `judge returned unrecognised action_type "${result.actionType}"` : "judge returned no verdict",
4389
+ confidence: result.confidence,
4390
+ score: native.defaultScoreForVerdict("red"),
4391
+ toolCallId: result.toolCallId
4392
+ };
4393
+ }
4289
4394
  const verdict = native.mapVerdict(
4290
4395
  result.actionType,
4291
4396
  result.confidence,
@@ -42436,6 +42541,10 @@ var index = /* @__PURE__ */ getDefaultExportFromCjs(builtExports);
42436
42541
 
42437
42542
  // src-ts/memory/chain.ts
42438
42543
  var { createClient, encryption: encryption2, newSignatureProvider: newSignatureProvider2, Buffer: PolyBuffer } = index;
42544
+ var FAILOVER_CONFIG = {
42545
+ strategy: "tryNextOnError",
42546
+ attemptsPerEndpoint: 1
42547
+ };
42439
42548
  function toGtxBytes(bytes) {
42440
42549
  return PolyBuffer.from(new Uint8Array(bytes));
42441
42550
  }
@@ -42465,7 +42574,11 @@ function materializeChain(chainOpts) {
42465
42574
  }
42466
42575
  async function buildChainClient(chainOpts) {
42467
42576
  const { nodeUrls, blockchainRid } = materializeChain(chainOpts);
42468
- return createClient({ nodeUrlPool: [...nodeUrls], blockchainRid });
42577
+ return createClient({
42578
+ nodeUrlPool: [...nodeUrls],
42579
+ blockchainRid,
42580
+ failOverConfig: FAILOVER_CONFIG
42581
+ });
42469
42582
  }
42470
42583
  function buildSigner(auth) {
42471
42584
  const privKeyBuf = Buffer.from(auth.privkey, "hex");
@@ -42903,7 +43016,10 @@ var MemoryGuardManager = class {
42903
43016
  await this.pointerStore.set(this.agentPubkeyHex, result.pointer);
42904
43017
  } catch (err) {
42905
43018
  const msg = err instanceof Error ? err.message : String(err);
42906
- this.logger.warn("[atbash] boot memory sync failed \u2014 check chain endpoint / orgName", { error: msg });
43019
+ this.logger.warn(bootSyncFailureLine(err), {
43020
+ error: msg,
43021
+ hint: BOOT_SYNC_HINT
43022
+ });
42907
43023
  }
42908
43024
  }
42909
43025
  /**
@@ -43132,6 +43248,7 @@ function diffMemorySnapshots(before, after) {
43132
43248
  0 && (module.exports = {
43133
43249
  Atbash,
43134
43250
  AtbashAPIError,
43251
+ BOOT_SYNC_HINT,
43135
43252
  DEFAULT_BLOCKCHAIN_RID,
43136
43253
  DEFAULT_CHROMIA_NODE_URLS,
43137
43254
  DEFAULT_ENDPOINT,
@@ -43139,11 +43256,14 @@ function diffMemorySnapshots(before, after) {
43139
43256
  DEFAULT_MEMORY_READ_TOOL_NAMES,
43140
43257
  DEFAULT_MEMORY_WRITE_TOOL_NAMES,
43141
43258
  EciesDomain,
43259
+ KEY_FILENAMES,
43142
43260
  MemoryGuardManager,
43143
43261
  MemoryIntegrityError,
43144
43262
  PointerStore,
43145
43263
  SignatureVerificationError,
43264
+ bootSyncFailureLine,
43146
43265
  buildAllowedJudgeHosts,
43266
+ chooseKeyPath,
43147
43267
  claimHashHex,
43148
43268
  classifyMemoryRead,
43149
43269
  classifyMemoryWrite,
@@ -43178,6 +43298,7 @@ function diffMemorySnapshots(before, after) {
43178
43298
  isEnvelope,
43179
43299
  isValidPrivateKey,
43180
43300
  keyFingerprintOf,
43301
+ keyPathCandidates,
43181
43302
  loadAgent,
43182
43303
  loadAgentFromFile,
43183
43304
  loadUserConfig,